diff options
Diffstat (limited to 'drivers/input/keyboard/cap11xx.c')
-rw-r--r-- | drivers/input/keyboard/cap11xx.c | 340 |
1 files changed, 340 insertions, 0 deletions
diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c new file mode 100644 index 000000000000..0da2e838e788 --- /dev/null +++ b/drivers/input/keyboard/cap11xx.c | |||
@@ -0,0 +1,340 @@ | |||
1 | /* | ||
2 | * Input driver for Microchip CAP11xx based capacitive touch sensors | ||
3 | * | ||
4 | * | ||
5 | * (c) 2014 Daniel Mack <linux@zonque.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/input.h> | ||
16 | #include <linux/of_irq.h> | ||
17 | #include <linux/regmap.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/gpio/consumer.h> | ||
20 | |||
21 | #define CAP11XX_REG_MAIN_CONTROL 0x00 | ||
22 | #define CAP11XX_REG_MAIN_CONTROL_GAIN_SHIFT (6) | ||
23 | #define CAP11XX_REG_MAIN_CONTROL_GAIN_MASK (0xc0) | ||
24 | #define CAP11XX_REG_MAIN_CONTROL_DLSEEP BIT(4) | ||
25 | #define CAP11XX_REG_GENERAL_STATUS 0x02 | ||
26 | #define CAP11XX_REG_SENSOR_INPUT 0x03 | ||
27 | #define CAP11XX_REG_NOISE_FLAG_STATUS 0x0a | ||
28 | #define CAP11XX_REG_SENOR_DELTA(X) (0x10 + (X)) | ||
29 | #define CAP11XX_REG_SENSITIVITY_CONTROL 0x1f | ||
30 | #define CAP11XX_REG_CONFIG 0x20 | ||
31 | #define CAP11XX_REG_SENSOR_ENABLE 0x21 | ||
32 | #define CAP11XX_REG_SENSOR_CONFIG 0x22 | ||
33 | #define CAP11XX_REG_SENSOR_CONFIG2 0x23 | ||
34 | #define CAP11XX_REG_SAMPLING_CONFIG 0x24 | ||
35 | #define CAP11XX_REG_CALIBRATION 0x26 | ||
36 | #define CAP11XX_REG_INT_ENABLE 0x27 | ||
37 | #define CAP11XX_REG_REPEAT_RATE 0x28 | ||
38 | #define CAP11XX_REG_MT_CONFIG 0x2a | ||
39 | #define CAP11XX_REG_MT_PATTERN_CONFIG 0x2b | ||
40 | #define CAP11XX_REG_MT_PATTERN 0x2d | ||
41 | #define CAP11XX_REG_RECALIB_CONFIG 0x2f | ||
42 | #define CAP11XX_REG_SENSOR_THRESH(X) (0x30 + (X)) | ||
43 | #define CAP11XX_REG_SENSOR_NOISE_THRESH 0x38 | ||
44 | #define CAP11XX_REG_STANDBY_CHANNEL 0x40 | ||
45 | #define CAP11XX_REG_STANDBY_CONFIG 0x41 | ||
46 | #define CAP11XX_REG_STANDBY_SENSITIVITY 0x42 | ||
47 | #define CAP11XX_REG_STANDBY_THRESH 0x43 | ||
48 | #define CAP11XX_REG_CONFIG2 0x44 | ||
49 | #define CAP11XX_REG_SENSOR_BASE_CNT(X) (0x50 + (X)) | ||
50 | #define CAP11XX_REG_SENSOR_CALIB (0xb1 + (X)) | ||
51 | #define CAP11XX_REG_SENSOR_CALIB_LSB1 0xb9 | ||
52 | #define CAP11XX_REG_SENSOR_CALIB_LSB2 0xba | ||
53 | #define CAP11XX_REG_PRODUCT_ID 0xfd | ||
54 | #define CAP11XX_REG_MANUFACTURER_ID 0xfe | ||
55 | #define CAP11XX_REG_REVISION 0xff | ||
56 | |||
57 | #define CAP11XX_NUM_CHN 6 | ||
58 | #define CAP11XX_PRODUCT_ID 0x55 | ||
59 | #define CAP11XX_MANUFACTURER_ID 0x5d | ||
60 | |||
61 | struct cap11xx_priv { | ||
62 | struct regmap *regmap; | ||
63 | struct input_dev *idev; | ||
64 | |||
65 | /* config */ | ||
66 | unsigned short keycodes[CAP11XX_NUM_CHN]; | ||
67 | }; | ||
68 | |||
69 | static const struct reg_default cap11xx_reg_defaults[] = { | ||
70 | { CAP11XX_REG_MAIN_CONTROL, 0x00 }, | ||
71 | { CAP11XX_REG_GENERAL_STATUS, 0x00 }, | ||
72 | { CAP11XX_REG_SENSOR_INPUT, 0x00 }, | ||
73 | { CAP11XX_REG_NOISE_FLAG_STATUS, 0x00 }, | ||
74 | { CAP11XX_REG_SENSITIVITY_CONTROL, 0x2f }, | ||
75 | { CAP11XX_REG_CONFIG, 0x20 }, | ||
76 | { CAP11XX_REG_SENSOR_ENABLE, 0x3f }, | ||
77 | { CAP11XX_REG_SENSOR_CONFIG, 0xa4 }, | ||
78 | { CAP11XX_REG_SENSOR_CONFIG2, 0x07 }, | ||
79 | { CAP11XX_REG_SAMPLING_CONFIG, 0x39 }, | ||
80 | { CAP11XX_REG_CALIBRATION, 0x00 }, | ||
81 | { CAP11XX_REG_INT_ENABLE, 0x3f }, | ||
82 | { CAP11XX_REG_REPEAT_RATE, 0x3f }, | ||
83 | { CAP11XX_REG_MT_CONFIG, 0x80 }, | ||
84 | { CAP11XX_REG_MT_PATTERN_CONFIG, 0x00 }, | ||
85 | { CAP11XX_REG_MT_PATTERN, 0x3f }, | ||
86 | { CAP11XX_REG_RECALIB_CONFIG, 0x8a }, | ||
87 | { CAP11XX_REG_SENSOR_THRESH(0), 0x40 }, | ||
88 | { CAP11XX_REG_SENSOR_THRESH(1), 0x40 }, | ||
89 | { CAP11XX_REG_SENSOR_THRESH(2), 0x40 }, | ||
90 | { CAP11XX_REG_SENSOR_THRESH(3), 0x40 }, | ||
91 | { CAP11XX_REG_SENSOR_THRESH(4), 0x40 }, | ||
92 | { CAP11XX_REG_SENSOR_THRESH(5), 0x40 }, | ||
93 | { CAP11XX_REG_SENSOR_NOISE_THRESH, 0x01 }, | ||
94 | { CAP11XX_REG_STANDBY_CHANNEL, 0x00 }, | ||
95 | { CAP11XX_REG_STANDBY_CONFIG, 0x39 }, | ||
96 | { CAP11XX_REG_STANDBY_SENSITIVITY, 0x02 }, | ||
97 | { CAP11XX_REG_STANDBY_THRESH, 0x40 }, | ||
98 | { CAP11XX_REG_CONFIG2, 0x40 }, | ||
99 | { CAP11XX_REG_SENSOR_CALIB_LSB1, 0x00 }, | ||
100 | { CAP11XX_REG_SENSOR_CALIB_LSB2, 0x00 }, | ||
101 | }; | ||
102 | |||
103 | static bool cap11xx_volatile_reg(struct device *dev, unsigned int reg) | ||
104 | { | ||
105 | switch (reg) { | ||
106 | case CAP11XX_REG_MAIN_CONTROL: | ||
107 | case CAP11XX_REG_SENSOR_INPUT: | ||
108 | case CAP11XX_REG_SENOR_DELTA(0): | ||
109 | case CAP11XX_REG_SENOR_DELTA(1): | ||
110 | case CAP11XX_REG_SENOR_DELTA(2): | ||
111 | case CAP11XX_REG_SENOR_DELTA(3): | ||
112 | case CAP11XX_REG_SENOR_DELTA(4): | ||
113 | case CAP11XX_REG_SENOR_DELTA(5): | ||
114 | case CAP11XX_REG_PRODUCT_ID: | ||
115 | case CAP11XX_REG_MANUFACTURER_ID: | ||
116 | case CAP11XX_REG_REVISION: | ||
117 | return true; | ||
118 | } | ||
119 | |||
120 | return false; | ||
121 | } | ||
122 | |||
123 | static const struct regmap_config cap11xx_regmap_config = { | ||
124 | .reg_bits = 8, | ||
125 | .val_bits = 8, | ||
126 | |||
127 | .max_register = CAP11XX_REG_REVISION, | ||
128 | .reg_defaults = cap11xx_reg_defaults, | ||
129 | |||
130 | .num_reg_defaults = ARRAY_SIZE(cap11xx_reg_defaults), | ||
131 | .cache_type = REGCACHE_RBTREE, | ||
132 | .volatile_reg = cap11xx_volatile_reg, | ||
133 | }; | ||
134 | |||
135 | static irqreturn_t cap11xx_thread_func(int irq_num, void *data) | ||
136 | { | ||
137 | struct cap11xx_priv *priv = data; | ||
138 | unsigned int status; | ||
139 | int ret, i; | ||
140 | |||
141 | /* | ||
142 | * Deassert interrupt. This needs to be done before reading the status | ||
143 | * registers, which will not carry valid values otherwise. | ||
144 | */ | ||
145 | ret = regmap_update_bits(priv->regmap, CAP11XX_REG_MAIN_CONTROL, 1, 0); | ||
146 | if (ret < 0) | ||
147 | goto out; | ||
148 | |||
149 | ret = regmap_read(priv->regmap, CAP11XX_REG_SENSOR_INPUT, &status); | ||
150 | if (ret < 0) | ||
151 | goto out; | ||
152 | |||
153 | for (i = 0; i < CAP11XX_NUM_CHN; i++) | ||
154 | input_report_key(priv->idev, priv->keycodes[i], | ||
155 | status & (1 << i)); | ||
156 | |||
157 | input_sync(priv->idev); | ||
158 | |||
159 | out: | ||
160 | return IRQ_HANDLED; | ||
161 | } | ||
162 | |||
163 | static int cap11xx_set_sleep(struct cap11xx_priv *priv, bool sleep) | ||
164 | { | ||
165 | return regmap_update_bits(priv->regmap, CAP11XX_REG_MAIN_CONTROL, | ||
166 | CAP11XX_REG_MAIN_CONTROL_DLSEEP, | ||
167 | sleep ? CAP11XX_REG_MAIN_CONTROL_DLSEEP : 0); | ||
168 | } | ||
169 | |||
170 | static int cap11xx_input_open(struct input_dev *idev) | ||
171 | { | ||
172 | struct cap11xx_priv *priv = input_get_drvdata(idev); | ||
173 | |||
174 | return cap11xx_set_sleep(priv, false); | ||
175 | } | ||
176 | |||
177 | static void cap11xx_input_close(struct input_dev *idev) | ||
178 | { | ||
179 | struct cap11xx_priv *priv = input_get_drvdata(idev); | ||
180 | |||
181 | cap11xx_set_sleep(priv, true); | ||
182 | } | ||
183 | |||
184 | static int cap11xx_i2c_probe(struct i2c_client *i2c_client, | ||
185 | const struct i2c_device_id *id) | ||
186 | { | ||
187 | struct device *dev = &i2c_client->dev; | ||
188 | struct cap11xx_priv *priv; | ||
189 | struct device_node *node; | ||
190 | int i, error, irq, gain = 0; | ||
191 | unsigned int val, rev; | ||
192 | u32 gain32, keycodes[CAP11XX_NUM_CHN]; | ||
193 | |||
194 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
195 | if (!priv) | ||
196 | return -ENOMEM; | ||
197 | |||
198 | priv->regmap = devm_regmap_init_i2c(i2c_client, &cap11xx_regmap_config); | ||
199 | if (IS_ERR(priv->regmap)) | ||
200 | return PTR_ERR(priv->regmap); | ||
201 | |||
202 | error = regmap_read(priv->regmap, CAP11XX_REG_PRODUCT_ID, &val); | ||
203 | if (error) | ||
204 | return error; | ||
205 | |||
206 | if (val != CAP11XX_PRODUCT_ID) { | ||
207 | dev_err(dev, "Product ID: Got 0x%02x, expected 0x%02x\n", | ||
208 | val, CAP11XX_PRODUCT_ID); | ||
209 | return -ENODEV; | ||
210 | } | ||
211 | |||
212 | error = regmap_read(priv->regmap, CAP11XX_REG_MANUFACTURER_ID, &val); | ||
213 | if (error) | ||
214 | return error; | ||
215 | |||
216 | if (val != CAP11XX_MANUFACTURER_ID) { | ||
217 | dev_err(dev, "Manufacturer ID: Got 0x%02x, expected 0x%02x\n", | ||
218 | val, CAP11XX_MANUFACTURER_ID); | ||
219 | return -ENODEV; | ||
220 | } | ||
221 | |||
222 | error = regmap_read(priv->regmap, CAP11XX_REG_REVISION, &rev); | ||
223 | if (error < 0) | ||
224 | return error; | ||
225 | |||
226 | dev_info(dev, "CAP11XX detected, revision 0x%02x\n", rev); | ||
227 | i2c_set_clientdata(i2c_client, priv); | ||
228 | node = dev->of_node; | ||
229 | |||
230 | if (!of_property_read_u32(node, "microchip,sensor-gain", &gain32)) { | ||
231 | if (is_power_of_2(gain32) && gain32 <= 8) | ||
232 | gain = ilog2(gain32); | ||
233 | else | ||
234 | dev_err(dev, "Invalid sensor-gain value %d\n", gain32); | ||
235 | } | ||
236 | |||
237 | BUILD_BUG_ON(ARRAY_SIZE(keycodes) != ARRAY_SIZE(priv->keycodes)); | ||
238 | |||
239 | /* Provide some useful defaults */ | ||
240 | for (i = 0; i < ARRAY_SIZE(keycodes); i++) | ||
241 | keycodes[i] = KEY_A + i; | ||
242 | |||
243 | of_property_read_u32_array(node, "linux,keycodes", | ||
244 | keycodes, ARRAY_SIZE(keycodes)); | ||
245 | |||
246 | for (i = 0; i < ARRAY_SIZE(keycodes); i++) | ||
247 | priv->keycodes[i] = keycodes[i]; | ||
248 | |||
249 | error = regmap_update_bits(priv->regmap, CAP11XX_REG_MAIN_CONTROL, | ||
250 | CAP11XX_REG_MAIN_CONTROL_GAIN_MASK, | ||
251 | gain << CAP11XX_REG_MAIN_CONTROL_GAIN_SHIFT); | ||
252 | if (error) | ||
253 | return error; | ||
254 | |||
255 | /* Disable autorepeat. The Linux input system has its own handling. */ | ||
256 | error = regmap_write(priv->regmap, CAP11XX_REG_REPEAT_RATE, 0); | ||
257 | if (error) | ||
258 | return error; | ||
259 | |||
260 | priv->idev = devm_input_allocate_device(dev); | ||
261 | if (!priv->idev) | ||
262 | return -ENOMEM; | ||
263 | |||
264 | priv->idev->name = "CAP11XX capacitive touch sensor"; | ||
265 | priv->idev->id.bustype = BUS_I2C; | ||
266 | priv->idev->evbit[0] = BIT_MASK(EV_KEY); | ||
267 | |||
268 | if (of_property_read_bool(node, "autorepeat")) | ||
269 | __set_bit(EV_REP, priv->idev->evbit); | ||
270 | |||
271 | for (i = 0; i < CAP11XX_NUM_CHN; i++) | ||
272 | __set_bit(priv->keycodes[i], priv->idev->keybit); | ||
273 | |||
274 | __clear_bit(KEY_RESERVED, priv->idev->keybit); | ||
275 | |||
276 | priv->idev->keycode = priv->keycodes; | ||
277 | priv->idev->keycodesize = sizeof(priv->keycodes[0]); | ||
278 | priv->idev->keycodemax = ARRAY_SIZE(priv->keycodes); | ||
279 | |||
280 | priv->idev->id.vendor = CAP11XX_MANUFACTURER_ID; | ||
281 | priv->idev->id.product = CAP11XX_PRODUCT_ID; | ||
282 | priv->idev->id.version = rev; | ||
283 | |||
284 | priv->idev->open = cap11xx_input_open; | ||
285 | priv->idev->close = cap11xx_input_close; | ||
286 | |||
287 | input_set_drvdata(priv->idev, priv); | ||
288 | |||
289 | /* | ||
290 | * Put the device in deep sleep mode for now. | ||
291 | * ->open() will bring it back once the it is actually needed. | ||
292 | */ | ||
293 | cap11xx_set_sleep(priv, true); | ||
294 | |||
295 | error = input_register_device(priv->idev); | ||
296 | if (error) | ||
297 | return error; | ||
298 | |||
299 | irq = irq_of_parse_and_map(node, 0); | ||
300 | if (!irq) { | ||
301 | dev_err(dev, "Unable to parse or map IRQ\n"); | ||
302 | return -ENXIO; | ||
303 | } | ||
304 | |||
305 | error = devm_request_threaded_irq(dev, irq, NULL, cap11xx_thread_func, | ||
306 | IRQF_ONESHOT, dev_name(dev), priv); | ||
307 | if (error) | ||
308 | return error; | ||
309 | |||
310 | return 0; | ||
311 | } | ||
312 | |||
313 | static const struct of_device_id cap11xx_dt_ids[] = { | ||
314 | { .compatible = "microchip,cap1106", }, | ||
315 | {} | ||
316 | }; | ||
317 | MODULE_DEVICE_TABLE(of, cap11xx_dt_ids); | ||
318 | |||
319 | static const struct i2c_device_id cap11xx_i2c_ids[] = { | ||
320 | { "cap1106", 0 }, | ||
321 | {} | ||
322 | }; | ||
323 | MODULE_DEVICE_TABLE(i2c, cap11xx_i2c_ids); | ||
324 | |||
325 | static struct i2c_driver cap11xx_i2c_driver = { | ||
326 | .driver = { | ||
327 | .name = "cap11xx", | ||
328 | .owner = THIS_MODULE, | ||
329 | .of_match_table = cap11xx_dt_ids, | ||
330 | }, | ||
331 | .id_table = cap11xx_i2c_ids, | ||
332 | .probe = cap11xx_i2c_probe, | ||
333 | }; | ||
334 | |||
335 | module_i2c_driver(cap11xx_i2c_driver); | ||
336 | |||
337 | MODULE_ALIAS("platform:cap11xx"); | ||
338 | MODULE_DESCRIPTION("Microchip CAP11XX driver"); | ||
339 | MODULE_AUTHOR("Daniel Mack <linux@zonque.org>"); | ||
340 | MODULE_LICENSE("GPL v2"); | ||