Commit | Line | Data |
---|---|---|
9d2e1736 MH |
1 | /* |
2 | * Description: keypad driver for ADP5589 | |
3 | * I2C QWERTY Keypad and IO Expander | |
4 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | |
5 | * | |
6 | * Copyright (C) 2010-2011 Analog Devices Inc. | |
7 | * Licensed under the GPL-2. | |
8 | */ | |
9 | ||
10 | #include <linux/module.h> | |
9d2e1736 MH |
11 | #include <linux/init.h> |
12 | #include <linux/interrupt.h> | |
13 | #include <linux/irq.h> | |
14 | #include <linux/workqueue.h> | |
15 | #include <linux/errno.h> | |
16 | #include <linux/pm.h> | |
17 | #include <linux/platform_device.h> | |
18 | #include <linux/input.h> | |
19 | #include <linux/i2c.h> | |
20 | #include <linux/gpio.h> | |
21 | #include <linux/slab.h> | |
22 | ||
23 | #include <linux/input/adp5589.h> | |
24 | ||
25 | /* GENERAL_CFG Register */ | |
26 | #define OSC_EN (1 << 7) | |
27 | #define CORE_CLK(x) (((x) & 0x3) << 5) | |
28 | #define LCK_TRK_LOGIC (1 << 4) | |
29 | #define LCK_TRK_GPI (1 << 3) | |
30 | #define INT_CFG (1 << 1) | |
31 | #define RST_CFG (1 << 0) | |
32 | ||
33 | /* INT_EN Register */ | |
34 | #define LOGIC2_IEN (1 << 5) | |
35 | #define LOGIC1_IEN (1 << 4) | |
36 | #define LOCK_IEN (1 << 3) | |
37 | #define OVRFLOW_IEN (1 << 2) | |
38 | #define GPI_IEN (1 << 1) | |
39 | #define EVENT_IEN (1 << 0) | |
40 | ||
41 | /* Interrupt Status Register */ | |
42 | #define LOGIC2_INT (1 << 5) | |
43 | #define LOGIC1_INT (1 << 4) | |
44 | #define LOCK_INT (1 << 3) | |
45 | #define OVRFLOW_INT (1 << 2) | |
46 | #define GPI_INT (1 << 1) | |
47 | #define EVENT_INT (1 << 0) | |
48 | ||
49 | /* STATUS Register */ | |
50 | ||
51 | #define LOGIC2_STAT (1 << 7) | |
52 | #define LOGIC1_STAT (1 << 6) | |
53 | #define LOCK_STAT (1 << 5) | |
54 | #define KEC 0xF | |
55 | ||
56 | /* PIN_CONFIG_D Register */ | |
57 | #define C4_EXTEND_CFG (1 << 6) /* RESET2 */ | |
58 | #define R4_EXTEND_CFG (1 << 5) /* RESET1 */ | |
59 | ||
60 | /* LOCK_CFG */ | |
61 | #define LOCK_EN (1 << 0) | |
62 | ||
63 | #define PTIME_MASK 0x3 | |
64 | #define LTIME_MASK 0x3 | |
65 | ||
66 | /* Key Event Register xy */ | |
67 | #define KEY_EV_PRESSED (1 << 7) | |
68 | #define KEY_EV_MASK (0x7F) | |
69 | ||
70 | #define KEYP_MAX_EVENT 16 | |
71 | ||
72 | #define MAXGPIO 19 | |
73 | #define ADP_BANK(offs) ((offs) >> 3) | |
74 | #define ADP_BIT(offs) (1u << ((offs) & 0x7)) | |
75 | ||
76 | struct adp5589_kpad { | |
77 | struct i2c_client *client; | |
78 | struct input_dev *input; | |
79 | unsigned short keycode[ADP5589_KEYMAPSIZE]; | |
80 | const struct adp5589_gpi_map *gpimap; | |
81 | unsigned short gpimapsize; | |
82 | unsigned extend_cfg; | |
83 | #ifdef CONFIG_GPIOLIB | |
84 | unsigned char gpiomap[MAXGPIO]; | |
85 | bool export_gpio; | |
86 | struct gpio_chip gc; | |
87 | struct mutex gpio_lock; /* Protect cached dir, dat_out */ | |
88 | u8 dat_out[3]; | |
89 | u8 dir[3]; | |
90 | #endif | |
91 | }; | |
92 | ||
93 | static int adp5589_read(struct i2c_client *client, u8 reg) | |
94 | { | |
95 | int ret = i2c_smbus_read_byte_data(client, reg); | |
96 | ||
97 | if (ret < 0) | |
98 | dev_err(&client->dev, "Read Error\n"); | |
99 | ||
100 | return ret; | |
101 | } | |
102 | ||
103 | static int adp5589_write(struct i2c_client *client, u8 reg, u8 val) | |
104 | { | |
105 | return i2c_smbus_write_byte_data(client, reg, val); | |
106 | } | |
107 | ||
108 | #ifdef CONFIG_GPIOLIB | |
109 | static int adp5589_gpio_get_value(struct gpio_chip *chip, unsigned off) | |
110 | { | |
111 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); | |
112 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | |
113 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | |
114 | ||
115 | return !!(adp5589_read(kpad->client, ADP5589_GPI_STATUS_A + bank) & | |
116 | bit); | |
117 | } | |
118 | ||
119 | static void adp5589_gpio_set_value(struct gpio_chip *chip, | |
120 | unsigned off, int val) | |
121 | { | |
122 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); | |
123 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | |
124 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | |
125 | ||
126 | mutex_lock(&kpad->gpio_lock); | |
127 | ||
128 | if (val) | |
129 | kpad->dat_out[bank] |= bit; | |
130 | else | |
131 | kpad->dat_out[bank] &= ~bit; | |
132 | ||
133 | adp5589_write(kpad->client, ADP5589_GPO_DATA_OUT_A + bank, | |
134 | kpad->dat_out[bank]); | |
135 | ||
136 | mutex_unlock(&kpad->gpio_lock); | |
137 | } | |
138 | ||
139 | static int adp5589_gpio_direction_input(struct gpio_chip *chip, unsigned off) | |
140 | { | |
141 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); | |
142 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | |
143 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | |
144 | int ret; | |
145 | ||
146 | mutex_lock(&kpad->gpio_lock); | |
147 | ||
148 | kpad->dir[bank] &= ~bit; | |
149 | ret = adp5589_write(kpad->client, ADP5589_GPIO_DIRECTION_A + bank, | |
150 | kpad->dir[bank]); | |
151 | ||
152 | mutex_unlock(&kpad->gpio_lock); | |
153 | ||
154 | return ret; | |
155 | } | |
156 | ||
157 | static int adp5589_gpio_direction_output(struct gpio_chip *chip, | |
158 | unsigned off, int val) | |
159 | { | |
160 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); | |
161 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | |
162 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | |
163 | int ret; | |
164 | ||
165 | mutex_lock(&kpad->gpio_lock); | |
166 | ||
167 | kpad->dir[bank] |= bit; | |
168 | ||
169 | if (val) | |
170 | kpad->dat_out[bank] |= bit; | |
171 | else | |
172 | kpad->dat_out[bank] &= ~bit; | |
173 | ||
174 | ret = adp5589_write(kpad->client, ADP5589_GPO_DATA_OUT_A + bank, | |
175 | kpad->dat_out[bank]); | |
176 | ret |= adp5589_write(kpad->client, ADP5589_GPIO_DIRECTION_A + bank, | |
177 | kpad->dir[bank]); | |
178 | ||
179 | mutex_unlock(&kpad->gpio_lock); | |
180 | ||
181 | return ret; | |
182 | } | |
183 | ||
184 | static int __devinit adp5589_build_gpiomap(struct adp5589_kpad *kpad, | |
185 | const struct adp5589_kpad_platform_data *pdata) | |
186 | { | |
187 | bool pin_used[MAXGPIO]; | |
188 | int n_unused = 0; | |
189 | int i; | |
190 | ||
191 | memset(pin_used, false, sizeof(pin_used)); | |
192 | ||
193 | for (i = 0; i < MAXGPIO; i++) | |
194 | if (pdata->keypad_en_mask & (1 << i)) | |
195 | pin_used[i] = true; | |
196 | ||
197 | for (i = 0; i < kpad->gpimapsize; i++) | |
198 | pin_used[kpad->gpimap[i].pin - ADP5589_GPI_PIN_BASE] = true; | |
199 | ||
200 | if (kpad->extend_cfg & R4_EXTEND_CFG) | |
201 | pin_used[4] = true; | |
202 | ||
203 | if (kpad->extend_cfg & C4_EXTEND_CFG) | |
204 | pin_used[12] = true; | |
205 | ||
206 | for (i = 0; i < MAXGPIO; i++) | |
207 | if (!pin_used[i]) | |
208 | kpad->gpiomap[n_unused++] = i; | |
209 | ||
210 | return n_unused; | |
211 | } | |
212 | ||
213 | static int __devinit adp5589_gpio_add(struct adp5589_kpad *kpad) | |
214 | { | |
215 | struct device *dev = &kpad->client->dev; | |
216 | const struct adp5589_kpad_platform_data *pdata = dev->platform_data; | |
217 | const struct adp5589_gpio_platform_data *gpio_data = pdata->gpio_data; | |
218 | int i, error; | |
219 | ||
220 | if (!gpio_data) | |
221 | return 0; | |
222 | ||
223 | kpad->gc.ngpio = adp5589_build_gpiomap(kpad, pdata); | |
224 | if (kpad->gc.ngpio == 0) { | |
225 | dev_info(dev, "No unused gpios left to export\n"); | |
226 | return 0; | |
227 | } | |
228 | ||
229 | kpad->export_gpio = true; | |
230 | ||
231 | kpad->gc.direction_input = adp5589_gpio_direction_input; | |
232 | kpad->gc.direction_output = adp5589_gpio_direction_output; | |
233 | kpad->gc.get = adp5589_gpio_get_value; | |
234 | kpad->gc.set = adp5589_gpio_set_value; | |
235 | kpad->gc.can_sleep = 1; | |
236 | ||
237 | kpad->gc.base = gpio_data->gpio_start; | |
238 | kpad->gc.label = kpad->client->name; | |
239 | kpad->gc.owner = THIS_MODULE; | |
240 | ||
241 | mutex_init(&kpad->gpio_lock); | |
242 | ||
243 | error = gpiochip_add(&kpad->gc); | |
244 | if (error) { | |
245 | dev_err(dev, "gpiochip_add failed, err: %d\n", error); | |
246 | return error; | |
247 | } | |
248 | ||
249 | for (i = 0; i <= ADP_BANK(MAXGPIO); i++) { | |
250 | kpad->dat_out[i] = adp5589_read(kpad->client, | |
251 | ADP5589_GPO_DATA_OUT_A + i); | |
252 | kpad->dir[i] = adp5589_read(kpad->client, | |
253 | ADP5589_GPIO_DIRECTION_A + i); | |
254 | } | |
255 | ||
256 | if (gpio_data->setup) { | |
257 | error = gpio_data->setup(kpad->client, | |
258 | kpad->gc.base, kpad->gc.ngpio, | |
259 | gpio_data->context); | |
260 | if (error) | |
261 | dev_warn(dev, "setup failed, %d\n", error); | |
262 | } | |
263 | ||
264 | return 0; | |
265 | } | |
266 | ||
267 | static void __devexit adp5589_gpio_remove(struct adp5589_kpad *kpad) | |
268 | { | |
269 | struct device *dev = &kpad->client->dev; | |
270 | const struct adp5589_kpad_platform_data *pdata = dev->platform_data; | |
271 | const struct adp5589_gpio_platform_data *gpio_data = pdata->gpio_data; | |
272 | int error; | |
273 | ||
274 | if (!kpad->export_gpio) | |
275 | return; | |
276 | ||
277 | if (gpio_data->teardown) { | |
278 | error = gpio_data->teardown(kpad->client, | |
279 | kpad->gc.base, kpad->gc.ngpio, | |
280 | gpio_data->context); | |
281 | if (error) | |
282 | dev_warn(dev, "teardown failed %d\n", error); | |
283 | } | |
284 | ||
285 | error = gpiochip_remove(&kpad->gc); | |
286 | if (error) | |
287 | dev_warn(dev, "gpiochip_remove failed %d\n", error); | |
288 | } | |
289 | #else | |
290 | static inline int adp5589_gpio_add(struct adp5589_kpad *kpad) | |
291 | { | |
292 | return 0; | |
293 | } | |
294 | ||
295 | static inline void adp5589_gpio_remove(struct adp5589_kpad *kpad) | |
296 | { | |
297 | } | |
298 | #endif | |
299 | ||
300 | static void adp5589_report_switches(struct adp5589_kpad *kpad, | |
301 | int key, int key_val) | |
302 | { | |
303 | int i; | |
304 | ||
305 | for (i = 0; i < kpad->gpimapsize; i++) { | |
306 | if (key_val == kpad->gpimap[i].pin) { | |
307 | input_report_switch(kpad->input, | |
308 | kpad->gpimap[i].sw_evt, | |
309 | key & KEY_EV_PRESSED); | |
310 | break; | |
311 | } | |
312 | } | |
313 | } | |
314 | ||
315 | static void adp5589_report_events(struct adp5589_kpad *kpad, int ev_cnt) | |
316 | { | |
317 | int i; | |
318 | ||
319 | for (i = 0; i < ev_cnt; i++) { | |
320 | int key = adp5589_read(kpad->client, ADP5589_FIFO_1 + i); | |
321 | int key_val = key & KEY_EV_MASK; | |
322 | ||
323 | if (key_val >= ADP5589_GPI_PIN_BASE && | |
324 | key_val <= ADP5589_GPI_PIN_END) { | |
325 | adp5589_report_switches(kpad, key, key_val); | |
326 | } else { | |
327 | input_report_key(kpad->input, | |
328 | kpad->keycode[key_val - 1], | |
329 | key & KEY_EV_PRESSED); | |
330 | } | |
331 | } | |
332 | } | |
333 | ||
334 | static irqreturn_t adp5589_irq(int irq, void *handle) | |
335 | { | |
336 | struct adp5589_kpad *kpad = handle; | |
337 | struct i2c_client *client = kpad->client; | |
338 | int status, ev_cnt; | |
339 | ||
340 | status = adp5589_read(client, ADP5589_INT_STATUS); | |
341 | ||
342 | if (status & OVRFLOW_INT) /* Unlikely and should never happen */ | |
343 | dev_err(&client->dev, "Event Overflow Error\n"); | |
344 | ||
345 | if (status & EVENT_INT) { | |
346 | ev_cnt = adp5589_read(client, ADP5589_STATUS) & KEC; | |
347 | if (ev_cnt) { | |
348 | adp5589_report_events(kpad, ev_cnt); | |
349 | input_sync(kpad->input); | |
350 | } | |
351 | } | |
352 | ||
353 | adp5589_write(client, ADP5589_INT_STATUS, status); /* Status is W1C */ | |
354 | ||
355 | return IRQ_HANDLED; | |
356 | } | |
357 | ||
358 | static int __devinit adp5589_get_evcode(struct adp5589_kpad *kpad, unsigned short key) | |
359 | { | |
360 | int i; | |
361 | ||
362 | for (i = 0; i < ADP5589_KEYMAPSIZE; i++) | |
363 | if (key == kpad->keycode[i]) | |
364 | return (i + 1) | KEY_EV_PRESSED; | |
365 | ||
366 | dev_err(&kpad->client->dev, "RESET/UNLOCK key not in keycode map\n"); | |
367 | ||
368 | return -EINVAL; | |
369 | } | |
370 | ||
371 | static int __devinit adp5589_setup(struct adp5589_kpad *kpad) | |
372 | { | |
373 | struct i2c_client *client = kpad->client; | |
374 | const struct adp5589_kpad_platform_data *pdata = | |
375 | client->dev.platform_data; | |
376 | int i, ret; | |
377 | unsigned char evt_mode1 = 0, evt_mode2 = 0, evt_mode3 = 0; | |
378 | unsigned char pull_mask = 0; | |
379 | ||
380 | ret = adp5589_write(client, ADP5589_PIN_CONFIG_A, | |
381 | pdata->keypad_en_mask & 0xFF); | |
382 | ret |= adp5589_write(client, ADP5589_PIN_CONFIG_B, | |
383 | (pdata->keypad_en_mask >> 8) & 0xFF); | |
384 | ret |= adp5589_write(client, ADP5589_PIN_CONFIG_C, | |
385 | (pdata->keypad_en_mask >> 16) & 0xFF); | |
386 | ||
387 | if (pdata->en_keylock) { | |
388 | ret |= adp5589_write(client, ADP5589_UNLOCK1, | |
389 | pdata->unlock_key1); | |
390 | ret |= adp5589_write(client, ADP5589_UNLOCK2, | |
391 | pdata->unlock_key2); | |
392 | ret |= adp5589_write(client, ADP5589_UNLOCK_TIMERS, | |
393 | pdata->unlock_timer & LTIME_MASK); | |
394 | ret |= adp5589_write(client, ADP5589_LOCK_CFG, LOCK_EN); | |
395 | } | |
396 | ||
397 | for (i = 0; i < KEYP_MAX_EVENT; i++) | |
398 | ret |= adp5589_read(client, ADP5589_FIFO_1 + i); | |
399 | ||
400 | for (i = 0; i < pdata->gpimapsize; i++) { | |
401 | unsigned short pin = pdata->gpimap[i].pin; | |
402 | ||
403 | if (pin <= ADP5589_GPI_PIN_ROW_END) { | |
404 | evt_mode1 |= (1 << (pin - ADP5589_GPI_PIN_ROW_BASE)); | |
405 | } else { | |
406 | evt_mode2 |= | |
407 | ((1 << (pin - ADP5589_GPI_PIN_COL_BASE)) & 0xFF); | |
408 | evt_mode3 |= | |
409 | ((1 << (pin - ADP5589_GPI_PIN_COL_BASE)) >> 8); | |
410 | } | |
411 | } | |
412 | ||
413 | if (pdata->gpimapsize) { | |
414 | ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_A, evt_mode1); | |
415 | ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_B, evt_mode2); | |
416 | ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_C, evt_mode3); | |
417 | } | |
418 | ||
419 | if (pdata->pull_dis_mask & pdata->pullup_en_100k & | |
420 | pdata->pullup_en_300k & pdata->pulldown_en_300k) | |
421 | dev_warn(&client->dev, "Conflicting pull resistor config\n"); | |
422 | ||
423 | for (i = 0; i < MAXGPIO; i++) { | |
424 | unsigned val = 0; | |
425 | ||
426 | if (pdata->pullup_en_300k & (1 << i)) | |
427 | val = 0; | |
428 | else if (pdata->pulldown_en_300k & (1 << i)) | |
429 | val = 1; | |
430 | else if (pdata->pullup_en_100k & (1 << i)) | |
431 | val = 2; | |
432 | else if (pdata->pull_dis_mask & (1 << i)) | |
433 | val = 3; | |
434 | ||
435 | pull_mask |= val << (2 * (i & 0x3)); | |
436 | ||
437 | if ((i & 0x3) == 0x3 || i == MAXGPIO - 1) { | |
438 | ret |= adp5589_write(client, | |
439 | ADP5589_RPULL_CONFIG_A + (i >> 2), | |
440 | pull_mask); | |
441 | pull_mask = 0; | |
442 | } | |
443 | } | |
444 | ||
445 | if (pdata->reset1_key_1 && pdata->reset1_key_2 && pdata->reset1_key_3) { | |
446 | ret |= adp5589_write(client, ADP5589_RESET1_EVENT_A, | |
447 | adp5589_get_evcode(kpad, | |
448 | pdata->reset1_key_1)); | |
449 | ret |= adp5589_write(client, ADP5589_RESET1_EVENT_B, | |
450 | adp5589_get_evcode(kpad, | |
451 | pdata->reset1_key_2)); | |
452 | ret |= adp5589_write(client, ADP5589_RESET1_EVENT_C, | |
453 | adp5589_get_evcode(kpad, | |
454 | pdata->reset1_key_3)); | |
455 | kpad->extend_cfg |= R4_EXTEND_CFG; | |
456 | } | |
457 | ||
458 | if (pdata->reset2_key_1 && pdata->reset2_key_2) { | |
459 | ret |= adp5589_write(client, ADP5589_RESET2_EVENT_A, | |
460 | adp5589_get_evcode(kpad, | |
461 | pdata->reset2_key_1)); | |
462 | ret |= adp5589_write(client, ADP5589_RESET2_EVENT_B, | |
463 | adp5589_get_evcode(kpad, | |
464 | pdata->reset2_key_2)); | |
465 | kpad->extend_cfg |= C4_EXTEND_CFG; | |
466 | } | |
467 | ||
468 | if (kpad->extend_cfg) { | |
469 | ret |= adp5589_write(client, ADP5589_RESET_CFG, | |
470 | pdata->reset_cfg); | |
471 | ret |= adp5589_write(client, ADP5589_PIN_CONFIG_D, | |
472 | kpad->extend_cfg); | |
473 | } | |
474 | ||
475 | for (i = 0; i <= ADP_BANK(MAXGPIO); i++) | |
476 | ret |= adp5589_write(client, ADP5589_DEBOUNCE_DIS_A + i, | |
477 | pdata->debounce_dis_mask >> (i * 8)); | |
478 | ||
479 | ret |= adp5589_write(client, ADP5589_POLL_PTIME_CFG, | |
480 | pdata->scan_cycle_time & PTIME_MASK); | |
481 | ret |= adp5589_write(client, ADP5589_INT_STATUS, LOGIC2_INT | | |
482 | LOGIC1_INT | OVRFLOW_INT | LOCK_INT | | |
483 | GPI_INT | EVENT_INT); /* Status is W1C */ | |
484 | ||
485 | ret |= adp5589_write(client, ADP5589_GENERAL_CFG, | |
486 | INT_CFG | OSC_EN | CORE_CLK(3)); | |
487 | ret |= adp5589_write(client, ADP5589_INT_EN, | |
488 | OVRFLOW_IEN | GPI_IEN | EVENT_IEN); | |
489 | ||
490 | if (ret < 0) { | |
491 | dev_err(&client->dev, "Write Error\n"); | |
492 | return ret; | |
493 | } | |
494 | ||
495 | return 0; | |
496 | } | |
497 | ||
498 | static void __devinit adp5589_report_switch_state(struct adp5589_kpad *kpad) | |
499 | { | |
500 | int gpi_stat1 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_A); | |
501 | int gpi_stat2 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_B); | |
502 | int gpi_stat3 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_C); | |
503 | int gpi_stat_tmp, pin_loc; | |
504 | int i; | |
505 | ||
506 | for (i = 0; i < kpad->gpimapsize; i++) { | |
507 | unsigned short pin = kpad->gpimap[i].pin; | |
508 | ||
509 | if (pin <= ADP5589_GPI_PIN_ROW_END) { | |
510 | gpi_stat_tmp = gpi_stat1; | |
511 | pin_loc = pin - ADP5589_GPI_PIN_ROW_BASE; | |
512 | } else if ((pin - ADP5589_GPI_PIN_COL_BASE) < 8) { | |
513 | gpi_stat_tmp = gpi_stat2; | |
514 | pin_loc = pin - ADP5589_GPI_PIN_COL_BASE; | |
515 | } else { | |
516 | gpi_stat_tmp = gpi_stat3; | |
517 | pin_loc = pin - ADP5589_GPI_PIN_COL_BASE - 8; | |
518 | } | |
519 | ||
520 | if (gpi_stat_tmp < 0) { | |
521 | dev_err(&kpad->client->dev, | |
522 | "Can't read GPIO_DAT_STAT switch" | |
523 | " %d default to OFF\n", pin); | |
524 | gpi_stat_tmp = 0; | |
525 | } | |
526 | ||
527 | input_report_switch(kpad->input, | |
528 | kpad->gpimap[i].sw_evt, | |
529 | !(gpi_stat_tmp & (1 << pin_loc))); | |
530 | } | |
531 | ||
532 | input_sync(kpad->input); | |
533 | } | |
534 | ||
535 | static int __devinit adp5589_probe(struct i2c_client *client, | |
536 | const struct i2c_device_id *id) | |
537 | { | |
538 | struct adp5589_kpad *kpad; | |
539 | const struct adp5589_kpad_platform_data *pdata; | |
540 | struct input_dev *input; | |
541 | unsigned int revid; | |
542 | int ret, i; | |
543 | int error; | |
544 | ||
545 | if (!i2c_check_functionality(client->adapter, | |
546 | I2C_FUNC_SMBUS_BYTE_DATA)) { | |
547 | dev_err(&client->dev, "SMBUS Byte Data not Supported\n"); | |
548 | return -EIO; | |
549 | } | |
550 | ||
551 | pdata = client->dev.platform_data; | |
552 | if (!pdata) { | |
553 | dev_err(&client->dev, "no platform data?\n"); | |
554 | return -EINVAL; | |
555 | } | |
556 | ||
557 | if (!((pdata->keypad_en_mask & 0xFF) && | |
558 | (pdata->keypad_en_mask >> 8)) || !pdata->keymap) { | |
559 | dev_err(&client->dev, "no rows, cols or keymap from pdata\n"); | |
560 | return -EINVAL; | |
561 | } | |
562 | ||
563 | if (pdata->keymapsize != ADP5589_KEYMAPSIZE) { | |
564 | dev_err(&client->dev, "invalid keymapsize\n"); | |
565 | return -EINVAL; | |
566 | } | |
567 | ||
568 | if (!pdata->gpimap && pdata->gpimapsize) { | |
569 | dev_err(&client->dev, "invalid gpimap from pdata\n"); | |
570 | return -EINVAL; | |
571 | } | |
572 | ||
573 | if (pdata->gpimapsize > ADP5589_GPIMAPSIZE_MAX) { | |
574 | dev_err(&client->dev, "invalid gpimapsize\n"); | |
575 | return -EINVAL; | |
576 | } | |
577 | ||
578 | for (i = 0; i < pdata->gpimapsize; i++) { | |
579 | unsigned short pin = pdata->gpimap[i].pin; | |
580 | ||
581 | if (pin < ADP5589_GPI_PIN_BASE || pin > ADP5589_GPI_PIN_END) { | |
582 | dev_err(&client->dev, "invalid gpi pin data\n"); | |
583 | return -EINVAL; | |
584 | } | |
585 | ||
586 | if ((1 << (pin - ADP5589_GPI_PIN_ROW_BASE)) & | |
587 | pdata->keypad_en_mask) { | |
588 | dev_err(&client->dev, "invalid gpi row/col data\n"); | |
589 | return -EINVAL; | |
590 | } | |
591 | } | |
592 | ||
593 | if (!client->irq) { | |
594 | dev_err(&client->dev, "no IRQ?\n"); | |
595 | return -EINVAL; | |
596 | } | |
597 | ||
598 | kpad = kzalloc(sizeof(*kpad), GFP_KERNEL); | |
599 | input = input_allocate_device(); | |
600 | if (!kpad || !input) { | |
601 | error = -ENOMEM; | |
602 | goto err_free_mem; | |
603 | } | |
604 | ||
605 | kpad->client = client; | |
606 | kpad->input = input; | |
607 | ||
608 | ret = adp5589_read(client, ADP5589_ID); | |
609 | if (ret < 0) { | |
610 | error = ret; | |
611 | goto err_free_mem; | |
612 | } | |
613 | ||
614 | revid = (u8) ret & ADP5589_DEVICE_ID_MASK; | |
615 | ||
616 | input->name = client->name; | |
617 | input->phys = "adp5589-keys/input0"; | |
618 | input->dev.parent = &client->dev; | |
619 | ||
620 | input_set_drvdata(input, kpad); | |
621 | ||
622 | input->id.bustype = BUS_I2C; | |
623 | input->id.vendor = 0x0001; | |
624 | input->id.product = 0x0001; | |
625 | input->id.version = revid; | |
626 | ||
627 | input->keycodesize = sizeof(kpad->keycode[0]); | |
628 | input->keycodemax = pdata->keymapsize; | |
629 | input->keycode = kpad->keycode; | |
630 | ||
631 | memcpy(kpad->keycode, pdata->keymap, | |
632 | pdata->keymapsize * input->keycodesize); | |
633 | ||
634 | kpad->gpimap = pdata->gpimap; | |
635 | kpad->gpimapsize = pdata->gpimapsize; | |
636 | ||
637 | /* setup input device */ | |
638 | __set_bit(EV_KEY, input->evbit); | |
639 | ||
640 | if (pdata->repeat) | |
641 | __set_bit(EV_REP, input->evbit); | |
642 | ||
643 | for (i = 0; i < input->keycodemax; i++) | |
644 | __set_bit(kpad->keycode[i] & KEY_MAX, input->keybit); | |
645 | __clear_bit(KEY_RESERVED, input->keybit); | |
646 | ||
647 | if (kpad->gpimapsize) | |
648 | __set_bit(EV_SW, input->evbit); | |
649 | for (i = 0; i < kpad->gpimapsize; i++) | |
650 | __set_bit(kpad->gpimap[i].sw_evt, input->swbit); | |
651 | ||
652 | error = input_register_device(input); | |
653 | if (error) { | |
654 | dev_err(&client->dev, "unable to register input device\n"); | |
655 | goto err_free_mem; | |
656 | } | |
657 | ||
658 | error = request_threaded_irq(client->irq, NULL, adp5589_irq, | |
659 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | |
660 | client->dev.driver->name, kpad); | |
661 | if (error) { | |
662 | dev_err(&client->dev, "irq %d busy?\n", client->irq); | |
663 | goto err_unreg_dev; | |
664 | } | |
665 | ||
666 | error = adp5589_setup(kpad); | |
667 | if (error) | |
668 | goto err_free_irq; | |
669 | ||
670 | if (kpad->gpimapsize) | |
671 | adp5589_report_switch_state(kpad); | |
672 | ||
673 | error = adp5589_gpio_add(kpad); | |
674 | if (error) | |
675 | goto err_free_irq; | |
676 | ||
677 | device_init_wakeup(&client->dev, 1); | |
678 | i2c_set_clientdata(client, kpad); | |
679 | ||
680 | dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq); | |
681 | return 0; | |
682 | ||
683 | err_free_irq: | |
684 | free_irq(client->irq, kpad); | |
685 | err_unreg_dev: | |
686 | input_unregister_device(input); | |
687 | input = NULL; | |
688 | err_free_mem: | |
689 | input_free_device(input); | |
690 | kfree(kpad); | |
691 | ||
692 | return error; | |
693 | } | |
694 | ||
695 | static int __devexit adp5589_remove(struct i2c_client *client) | |
696 | { | |
697 | struct adp5589_kpad *kpad = i2c_get_clientdata(client); | |
698 | ||
699 | adp5589_write(client, ADP5589_GENERAL_CFG, 0); | |
700 | free_irq(client->irq, kpad); | |
701 | input_unregister_device(kpad->input); | |
702 | adp5589_gpio_remove(kpad); | |
703 | kfree(kpad); | |
704 | ||
705 | return 0; | |
706 | } | |
707 | ||
708 | #ifdef CONFIG_PM_SLEEP | |
709 | static int adp5589_suspend(struct device *dev) | |
710 | { | |
711 | struct adp5589_kpad *kpad = dev_get_drvdata(dev); | |
712 | struct i2c_client *client = kpad->client; | |
713 | ||
714 | disable_irq(client->irq); | |
715 | ||
716 | if (device_may_wakeup(&client->dev)) | |
717 | enable_irq_wake(client->irq); | |
718 | ||
719 | return 0; | |
720 | } | |
721 | ||
722 | static int adp5589_resume(struct device *dev) | |
723 | { | |
724 | struct adp5589_kpad *kpad = dev_get_drvdata(dev); | |
725 | struct i2c_client *client = kpad->client; | |
726 | ||
727 | if (device_may_wakeup(&client->dev)) | |
728 | disable_irq_wake(client->irq); | |
729 | ||
730 | enable_irq(client->irq); | |
731 | ||
732 | return 0; | |
733 | } | |
734 | #endif | |
735 | ||
736 | static SIMPLE_DEV_PM_OPS(adp5589_dev_pm_ops, adp5589_suspend, adp5589_resume); | |
737 | ||
738 | static const struct i2c_device_id adp5589_id[] = { | |
739 | {"adp5589-keys", 0}, | |
740 | {} | |
741 | }; | |
742 | ||
743 | MODULE_DEVICE_TABLE(i2c, adp5589_id); | |
744 | ||
745 | static struct i2c_driver adp5589_driver = { | |
746 | .driver = { | |
747 | .name = KBUILD_MODNAME, | |
748 | .owner = THIS_MODULE, | |
749 | .pm = &adp5589_dev_pm_ops, | |
750 | }, | |
751 | .probe = adp5589_probe, | |
752 | .remove = __devexit_p(adp5589_remove), | |
753 | .id_table = adp5589_id, | |
754 | }; | |
755 | ||
756 | static int __init adp5589_init(void) | |
757 | { | |
758 | return i2c_add_driver(&adp5589_driver); | |
759 | } | |
760 | module_init(adp5589_init); | |
761 | ||
762 | static void __exit adp5589_exit(void) | |
763 | { | |
764 | i2c_del_driver(&adp5589_driver); | |
765 | } | |
766 | module_exit(adp5589_exit); | |
767 | ||
768 | MODULE_LICENSE("GPL"); | |
769 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | |
770 | MODULE_DESCRIPTION("ADP5589 Keypad driver"); |