omap3-pandora-kernel: Add AUFS2 shim and keypad 'WIP' code.
[openpandora.oe.git] / recipes / linux / omap3-pandora-kernel / keypad / 0005-Input-add-twl4030_keypad-driver.patch
1 From 0958f20b0237ef414371c3ff967a5e26649c30fe Mon Sep 17 00:00:00 2001
2 From: David Brownell <dbrownell@users.sourceforge.net>
3 Date: Tue, 3 Nov 2009 15:53:51 +0200
4 Subject: [PATCH 5/7] Input: add twl4030_keypad driver
5
6 Add a driver for the keypad controller on TWL4030 family chips.
7 These support up to an 8x8 key matrix.  The TWL4030 multifunction
8 chips are mostly used on OMAP3 (or OMAP 2430) based boards.
9
10 [dtor@mail.ru: switch to matrix-keypad framework, fix changing
11 keymap from userspace]
12 Reviewed-by: Trilok Soni <soni.trilok@gmail.com>
13 Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
14 Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
15
16 Conflicts:
17
18         drivers/input/keyboard/Kconfig
19         drivers/input/keyboard/Makefile
20 ---
21  drivers/input/keyboard/Kconfig          |   11 +
22  drivers/input/keyboard/Makefile         |    1 +
23  drivers/input/keyboard/twl4030_keypad.c |  480 +++++++++++++++++++++++++++++++
24  include/linux/i2c/twl4030.h             |   19 +-
25  4 files changed, 505 insertions(+), 6 deletions(-)
26  create mode 100644 drivers/input/keyboard/twl4030_keypad.c
27
28 diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
29 index b0a3c78..e6a0584 100644
30 --- a/drivers/input/keyboard/Kconfig
31 +++ b/drivers/input/keyboard/Kconfig
32 @@ -355,4 +355,15 @@ config KEYBOARD_SH_KEYSC
33  
34           To compile this driver as a module, choose M here: the
35           module will be called sh_keysc.
36 +
37 +config KEYBOARD_TWL4030
38 +       tristate "TI TWL4030/TWL5030/TPS659x0 keypad support"
39 +       depends on TWL4030_CORE
40 +       help
41 +         Say Y here if your board use the keypad controller on
42 +         TWL4030 family chips.  It's safe to say enable this
43 +         even on boards that don't use the keypad controller.
44 +
45 +         To compile this driver as a module, choose M here: the
46 +         module will be called twl4030_keypad.
47  endif
48 diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
49 index 7b8bc44..2085127 100644
50 --- a/drivers/input/keyboard/Makefile
51 +++ b/drivers/input/keyboard/Makefile
52 @@ -31,3 +31,4 @@ obj-$(CONFIG_KEYBOARD_MAPLE)          += maple_keyb.o
53  obj-$(CONFIG_KEYBOARD_MATRIX)          += matrix_keypad.o
54  obj-$(CONFIG_KEYBOARD_BFIN)            += bf54x-keys.o
55  obj-$(CONFIG_KEYBOARD_SH_KEYSC)                += sh_keysc.o
56 +obj-$(CONFIG_KEYBOARD_TWL4030)         += twl4030_keypad.o
57 diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c
58 new file mode 100644
59 index 0000000..9a2977c
60 --- /dev/null
61 +++ b/drivers/input/keyboard/twl4030_keypad.c
62 @@ -0,0 +1,480 @@
63 +/*
64 + * twl4030_keypad.c - driver for 8x8 keypad controller in twl4030 chips
65 + *
66 + * Copyright (C) 2007 Texas Instruments, Inc.
67 + * Copyright (C) 2008 Nokia Corporation
68 + *
69 + * Code re-written for 2430SDP by:
70 + * Syed Mohammed Khasim <x0khasim@ti.com>
71 + *
72 + * Initial Code:
73 + * Manjunatha G K <manjugk@ti.com>
74 + *
75 + * This program is free software; you can redistribute it and/or modify
76 + * it under the terms of the GNU General Public License as published by
77 + * the Free Software Foundation; either version 2 of the License, or
78 + * (at your option) any later version.
79 + *
80 + * This program is distributed in the hope that it will be useful,
81 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
82 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
83 + * GNU General Public License for more details.
84 + *
85 + * You should have received a copy of the GNU General Public License
86 + * along with this program; if not, write to the Free Software
87 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
88 + */
89 +
90 +#include <linux/kernel.h>
91 +#include <linux/module.h>
92 +#include <linux/init.h>
93 +#include <linux/interrupt.h>
94 +#include <linux/input.h>
95 +#include <linux/platform_device.h>
96 +#include <linux/i2c/twl4030.h>
97 +
98 +
99 +/*
100 + * The TWL4030 family chips include a keypad controller that supports
101 + * up to an 8x8 switch matrix.  The controller can issue system wakeup
102 + * events, since it uses only the always-on 32KiHz oscillator, and has
103 + * an internal state machine that decodes pressed keys, including
104 + * multi-key combinations.
105 + *
106 + * This driver lets boards define what keycodes they wish to report for
107 + * which scancodes, as part of the "struct twl4030_keypad_data" used in
108 + * the probe() routine.
109 + *
110 + * See the TPS65950 documentation; that's the general availability
111 + * version of the TWL5030 second generation part.
112 + */
113 +#define TWL4030_MAX_ROWS       8       /* TWL4030 hard limit */
114 +#define TWL4030_MAX_COLS       8
115 +#define TWL4030_ROW_SHIFT      3
116 +#define TWL4030_KEYMAP_SIZE    (TWL4030_MAX_ROWS * TWL4030_MAX_COLS)
117 +
118 +struct twl4030_keypad {
119 +       unsigned short  keymap[TWL4030_KEYMAP_SIZE];
120 +       u16             kp_state[TWL4030_MAX_ROWS];
121 +       unsigned        n_rows;
122 +       unsigned        n_cols;
123 +       unsigned        irq;
124 +
125 +       struct device *dbg_dev;
126 +       struct input_dev *input;
127 +};
128 +
129 +/*----------------------------------------------------------------------*/
130 +
131 +/* arbitrary prescaler value 0..7 */
132 +#define PTV_PRESCALER                  4
133 +
134 +/* Register Offsets */
135 +#define KEYP_CTRL                      0x00
136 +#define KEYP_DEB                       0x01
137 +#define KEYP_LONG_KEY                  0x02
138 +#define KEYP_LK_PTV                    0x03
139 +#define KEYP_TIMEOUT_L                 0x04
140 +#define KEYP_TIMEOUT_H                 0x05
141 +#define KEYP_KBC                       0x06
142 +#define KEYP_KBR                       0x07
143 +#define KEYP_SMS                       0x08
144 +#define KEYP_FULL_CODE_7_0             0x09    /* row 0 column status */
145 +#define KEYP_FULL_CODE_15_8            0x0a    /* ... row 1 ... */
146 +#define KEYP_FULL_CODE_23_16           0x0b
147 +#define KEYP_FULL_CODE_31_24           0x0c
148 +#define KEYP_FULL_CODE_39_32           0x0d
149 +#define KEYP_FULL_CODE_47_40           0x0e
150 +#define KEYP_FULL_CODE_55_48           0x0f
151 +#define KEYP_FULL_CODE_63_56           0x10
152 +#define KEYP_ISR1                      0x11
153 +#define KEYP_IMR1                      0x12
154 +#define KEYP_ISR2                      0x13
155 +#define KEYP_IMR2                      0x14
156 +#define KEYP_SIR                       0x15
157 +#define KEYP_EDR                       0x16    /* edge triggers */
158 +#define KEYP_SIH_CTRL                  0x17
159 +
160 +/* KEYP_CTRL_REG Fields */
161 +#define KEYP_CTRL_SOFT_NRST            BIT(0)
162 +#define KEYP_CTRL_SOFTMODEN            BIT(1)
163 +#define KEYP_CTRL_LK_EN                        BIT(2)
164 +#define KEYP_CTRL_TOE_EN               BIT(3)
165 +#define KEYP_CTRL_TOLE_EN              BIT(4)
166 +#define KEYP_CTRL_RP_EN                        BIT(5)
167 +#define KEYP_CTRL_KBD_ON               BIT(6)
168 +
169 +/* KEYP_DEB, KEYP_LONG_KEY, KEYP_TIMEOUT_x*/
170 +#define KEYP_PERIOD_US(t, prescale)    ((t) / (31 << (prescale + 1)) - 1)
171 +
172 +/* KEYP_LK_PTV_REG Fields */
173 +#define KEYP_LK_PTV_PTV_SHIFT          5
174 +
175 +/* KEYP_{IMR,ISR,SIR} Fields */
176 +#define KEYP_IMR1_MIS                  BIT(3)
177 +#define KEYP_IMR1_TO                   BIT(2)
178 +#define KEYP_IMR1_LK                   BIT(1)
179 +#define KEYP_IMR1_KP                   BIT(0)
180 +
181 +/* KEYP_EDR Fields */
182 +#define KEYP_EDR_KP_FALLING            0x01
183 +#define KEYP_EDR_KP_RISING             0x02
184 +#define KEYP_EDR_KP_BOTH               0x03
185 +#define KEYP_EDR_LK_FALLING            0x04
186 +#define KEYP_EDR_LK_RISING             0x08
187 +#define KEYP_EDR_TO_FALLING            0x10
188 +#define KEYP_EDR_TO_RISING             0x20
189 +#define KEYP_EDR_MIS_FALLING           0x40
190 +#define KEYP_EDR_MIS_RISING            0x80
191 +
192 +
193 +/*----------------------------------------------------------------------*/
194 +
195 +static int twl4030_kpread(struct twl4030_keypad *kp,
196 +               u8 *data, u32 reg, u8 num_bytes)
197 +{
198 +       int ret = twl4030_i2c_read(TWL4030_MODULE_KEYPAD, data, reg, num_bytes);
199 +
200 +       if (ret < 0)
201 +               dev_warn(kp->dbg_dev,
202 +                       "Couldn't read TWL4030: %X - ret %d[%x]\n",
203 +                        reg, ret, ret);
204 +
205 +       return ret;
206 +}
207 +
208 +static int twl4030_kpwrite_u8(struct twl4030_keypad *kp, u8 data, u32 reg)
209 +{
210 +       int ret = twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, data, reg);
211 +
212 +       if (ret < 0)
213 +               dev_warn(kp->dbg_dev,
214 +                       "Could not write TWL4030: %X - ret %d[%x]\n",
215 +                        reg, ret, ret);
216 +
217 +       return ret;
218 +}
219 +
220 +static inline u16 twl4030_col_xlate(struct twl4030_keypad *kp, u8 col)
221 +{
222 +       /* If all bits in a row are active for all coloumns then
223 +        * we have that row line connected to gnd. Mark this
224 +        * key on as if it was on matrix position n_cols (ie
225 +        * one higher than the size of the matrix).
226 +        */
227 +       if (col == 0xFF)
228 +               return 1 << kp->n_cols;
229 +       else
230 +               return col & ((1 << kp->n_cols) - 1);
231 +}
232 +
233 +static int twl4030_read_kp_matrix_state(struct twl4030_keypad *kp, u16 *state)
234 +{
235 +       u8 new_state[TWL4030_MAX_ROWS];
236 +       int row;
237 +       int ret = twl4030_kpread(kp, new_state,
238 +                                KEYP_FULL_CODE_7_0, kp->n_rows);
239 +       if (ret >= 0)
240 +               for (row = 0; row < kp->n_rows; row++)
241 +                       state[row] = twl4030_col_xlate(kp, new_state[row]);
242 +
243 +       return ret;
244 +}
245 +
246 +static int twl4030_is_in_ghost_state(struct twl4030_keypad *kp, u16 *key_state)
247 +{
248 +       int i;
249 +       u16 check = 0;
250 +
251 +       for (i = 0; i < kp->n_rows; i++) {
252 +               u16 col = key_state[i];
253 +
254 +               if ((col & check) && hweight16(col) > 1)
255 +                       return 1;
256 +
257 +               check |= col;
258 +       }
259 +
260 +       return 0;
261 +}
262 +
263 +static void twl4030_kp_scan(struct twl4030_keypad *kp, bool release_all)
264 +{
265 +       struct input_dev *input = kp->input;
266 +       u16 new_state[TWL4030_MAX_ROWS];
267 +       int col, row;
268 +
269 +       if (release_all)
270 +               memset(new_state, 0, sizeof(new_state));
271 +       else {
272 +               /* check for any changes */
273 +               int ret = twl4030_read_kp_matrix_state(kp, new_state);
274 +
275 +               if (ret < 0)    /* panic ... */
276 +                       return;
277 +
278 +               if (twl4030_is_in_ghost_state(kp, new_state))
279 +                       return;
280 +       }
281 +
282 +       /* check for changes and print those */
283 +       for (row = 0; row < kp->n_rows; row++) {
284 +               int changed = new_state[row] ^ kp->kp_state[row];
285 +
286 +               if (!changed)
287 +                       continue;
288 +
289 +               for (col = 0; col < kp->n_cols; col++) {
290 +                       int code;
291 +
292 +                       if (!(changed & (1 << col)))
293 +                               continue;
294 +
295 +                       dev_dbg(kp->dbg_dev, "key [%d:%d] %s\n", row, col,
296 +                               (new_state[row] & (1 << col)) ?
297 +                               "press" : "release");
298 +
299 +                       code = MATRIX_SCAN_CODE(row, col, TWL4030_ROW_SHIFT);
300 +                       input_event(input, EV_MSC, MSC_SCAN, code);
301 +                       input_report_key(input, kp->keymap[code],
302 +                                        new_state[row] & (1 << col));
303 +               }
304 +               kp->kp_state[row] = new_state[row];
305 +       }
306 +       input_sync(input);
307 +}
308 +
309 +/*
310 + * Keypad interrupt handler
311 + */
312 +static irqreturn_t do_kp_irq(int irq, void *_kp)
313 +{
314 +       struct twl4030_keypad *kp = _kp;
315 +       u8 reg;
316 +       int ret;
317 +
318 +#ifdef CONFIG_LOCKDEP
319 +       /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
320 +        * we don't want and can't tolerate.  Although it might be
321 +        * friendlier not to borrow this thread context...
322 +        */
323 +       local_irq_enable();
324 +#endif
325 +
326 +       /* Read & Clear TWL4030 pending interrupt */
327 +       ret = twl4030_kpread(kp, &reg, KEYP_ISR1, 1);
328 +
329 +       /* Release all keys if I2C has gone bad or
330 +        * the KEYP has gone to idle state */
331 +       if (ret >= 0 && (reg & KEYP_IMR1_KP))
332 +               twl4030_kp_scan(kp, false);
333 +       else
334 +               twl4030_kp_scan(kp, true);
335 +
336 +       return IRQ_HANDLED;
337 +}
338 +
339 +static int __devinit twl4030_kp_program(struct twl4030_keypad *kp)
340 +{
341 +       u8 reg;
342 +       int i;
343 +
344 +       /* Enable controller, with hardware decoding but not autorepeat */
345 +       reg = KEYP_CTRL_SOFT_NRST | KEYP_CTRL_SOFTMODEN
346 +               | KEYP_CTRL_TOE_EN | KEYP_CTRL_KBD_ON;
347 +       if (twl4030_kpwrite_u8(kp, reg, KEYP_CTRL) < 0)
348 +               return -EIO;
349 +
350 +       /* NOTE:  we could use sih_setup() here to package keypad
351 +        * event sources as four different IRQs ... but we don't.
352 +        */
353 +
354 +       /* Enable TO rising and KP rising and falling edge detection */
355 +       reg = KEYP_EDR_KP_BOTH | KEYP_EDR_TO_RISING;
356 +       if (twl4030_kpwrite_u8(kp, reg, KEYP_EDR) < 0)
357 +               return -EIO;
358 +
359 +       /* Set PTV prescaler Field */
360 +       reg = (PTV_PRESCALER << KEYP_LK_PTV_PTV_SHIFT);
361 +       if (twl4030_kpwrite_u8(kp, reg, KEYP_LK_PTV) < 0)
362 +               return -EIO;
363 +
364 +       /* Set key debounce time to 20 ms */
365 +       i = KEYP_PERIOD_US(20000, PTV_PRESCALER);
366 +       if (twl4030_kpwrite_u8(kp, i, KEYP_DEB) < 0)
367 +               return -EIO;
368 +
369 +       /* Set timeout period to 100 ms */
370 +       i = KEYP_PERIOD_US(200000, PTV_PRESCALER);
371 +       if (twl4030_kpwrite_u8(kp, (i & 0xFF), KEYP_TIMEOUT_L) < 0)
372 +               return -EIO;
373 +
374 +       if (twl4030_kpwrite_u8(kp, (i >> 8), KEYP_TIMEOUT_H) < 0)
375 +               return -EIO;
376 +
377 +       /*
378 +        * Enable Clear-on-Read; disable remembering events that fire
379 +        * after the IRQ but before our handler acks (reads) them,
380 +        */
381 +       reg = TWL4030_SIH_CTRL_COR_MASK | TWL4030_SIH_CTRL_PENDDIS_MASK;
382 +       if (twl4030_kpwrite_u8(kp, reg, KEYP_SIH_CTRL) < 0)
383 +               return -EIO;
384 +
385 +       /* initialize key state; irqs update it from here on */
386 +       if (twl4030_read_kp_matrix_state(kp, kp->kp_state) < 0)
387 +               return -EIO;
388 +
389 +       return 0;
390 +}
391 +
392 +/*
393 + * Registers keypad device with input subsystem
394 + * and configures TWL4030 keypad registers
395 + */
396 +static int __devinit twl4030_kp_probe(struct platform_device *pdev)
397 +{
398 +       struct twl4030_keypad_data *pdata = pdev->dev.platform_data;
399 +       const struct matrix_keymap_data *keymap_data = pdata->keymap_data;
400 +       struct twl4030_keypad *kp;
401 +       struct input_dev *input;
402 +       u8 reg;
403 +       int error;
404 +
405 +       if (!pdata || !pdata->rows || !pdata->cols ||
406 +           pdata->rows > TWL4030_MAX_ROWS || pdata->cols > TWL4030_MAX_COLS) {
407 +               dev_err(&pdev->dev, "Invalid platform_data\n");
408 +               return -EINVAL;
409 +       }
410 +
411 +       kp = kzalloc(sizeof(*kp), GFP_KERNEL);
412 +       input = input_allocate_device();
413 +       if (!kp || !input) {
414 +               error = -ENOMEM;
415 +               goto err1;
416 +       }
417 +
418 +       /* Get the debug Device */
419 +       kp->dbg_dev = &pdev->dev;
420 +       kp->input = input;
421 +
422 +       kp->n_rows = pdata->rows;
423 +       kp->n_cols = pdata->cols;
424 +       kp->irq = platform_get_irq(pdev, 0);
425 +
426 +       /* setup input device */
427 +       __set_bit(EV_KEY, input->evbit);
428 +
429 +       /* Enable auto repeat feature of Linux input subsystem */
430 +       if (pdata->rep)
431 +               __set_bit(EV_REP, input->evbit);
432 +
433 +       input_set_capability(input, EV_MSC, MSC_SCAN);
434 +
435 +       input->name             = "TWL4030 Keypad";
436 +       input->phys             = "twl4030_keypad/input0";
437 +       input->dev.parent       = &pdev->dev;
438 +
439 +       input->id.bustype       = BUS_HOST;
440 +       input->id.vendor        = 0x0001;
441 +       input->id.product       = 0x0001;
442 +       input->id.version       = 0x0003;
443 +
444 +       input->keycode          = kp->keymap;
445 +       input->keycodesize      = sizeof(kp->keymap[0]);
446 +       input->keycodemax       = ARRAY_SIZE(kp->keymap);
447 +
448 +       matrix_keypad_build_keymap(keymap_data, TWL4030_ROW_SHIFT,
449 +                                  input->keycode, input->keybit);
450 +
451 +       error = input_register_device(input);
452 +       if (error) {
453 +               dev_err(kp->dbg_dev,
454 +                       "Unable to register twl4030 keypad device\n");
455 +               goto err1;
456 +       }
457 +
458 +       error = twl4030_kp_program(kp);
459 +       if (error)
460 +               goto err2;
461 +
462 +       /*
463 +        * This ISR will always execute in kernel thread context because of
464 +        * the need to access the TWL4030 over the I2C bus.
465 +        *
466 +        * NOTE:  we assume this host is wired to TWL4040 INT1, not INT2 ...
467 +        */
468 +       error = request_irq(kp->irq, do_kp_irq, 0, pdev->name, kp);
469 +       if (error) {
470 +               dev_info(kp->dbg_dev, "request_irq failed for irq no=%d\n",
471 +                       kp->irq);
472 +               goto err3;
473 +       }
474 +
475 +       /* Enable KP and TO interrupts now. */
476 +       reg = (u8) ~(KEYP_IMR1_KP | KEYP_IMR1_TO);
477 +       if (twl4030_kpwrite_u8(kp, reg, KEYP_IMR1)) {
478 +               error = -EIO;
479 +               goto err4;
480 +       }
481 +
482 +       platform_set_drvdata(pdev, kp);
483 +       return 0;
484 +
485 +err4:
486 +       /* mask all events - we don't care about the result */
487 +       (void) twl4030_kpwrite_u8(kp, 0xff, KEYP_IMR1);
488 +err3:
489 +       free_irq(kp->irq, NULL);
490 +err2:
491 +       input_unregister_device(input);
492 +       input = NULL;
493 +err1:
494 +       input_free_device(input);
495 +       kfree(kp);
496 +       return error;
497 +}
498 +
499 +static int __devexit twl4030_kp_remove(struct platform_device *pdev)
500 +{
501 +       struct twl4030_keypad *kp = platform_get_drvdata(pdev);
502 +
503 +       free_irq(kp->irq, kp);
504 +       input_unregister_device(kp->input);
505 +       platform_set_drvdata(pdev, NULL);
506 +       kfree(kp);
507 +
508 +       return 0;
509 +}
510 +
511 +/*
512 + * NOTE: twl4030 are multi-function devices connected via I2C.
513 + * So this device is a child of an I2C parent, thus it needs to
514 + * support unplug/replug (which most platform devices don't).
515 + */
516 +
517 +static struct platform_driver twl4030_kp_driver = {
518 +       .probe          = twl4030_kp_probe,
519 +       .remove         = __devexit_p(twl4030_kp_remove),
520 +       .driver         = {
521 +               .name   = "twl4030_keypad",
522 +               .owner  = THIS_MODULE,
523 +       },
524 +};
525 +
526 +static int __init twl4030_kp_init(void)
527 +{
528 +       return platform_driver_register(&twl4030_kp_driver);
529 +}
530 +module_init(twl4030_kp_init);
531 +
532 +static void __exit twl4030_kp_exit(void)
533 +{
534 +       platform_driver_unregister(&twl4030_kp_driver);
535 +}
536 +module_exit(twl4030_kp_exit);
537 +
538 +MODULE_AUTHOR("Texas Instruments");
539 +MODULE_DESCRIPTION("TWL4030 Keypad Driver");
540 +MODULE_LICENSE("GPL");
541 +MODULE_ALIAS("platform:twl4030_keypad");
542 +
543 diff --git a/include/linux/i2c/twl4030.h b/include/linux/i2c/twl4030.h
544 index dc40f95..3d6321e 100644
545 --- a/include/linux/i2c/twl4030.h
546 +++ b/include/linux/i2c/twl4030.h
547 @@ -25,6 +25,9 @@
548  #ifndef __TWL4030_H_
549  #define __TWL4030_H_
550  
551 +#include <linux/types.h>
552 +#include <linux/input/matrix_keypad.h>
553 +
554  /*
555   * Using the twl4030 core we address registers using a pair
556   *     { module id, relative register offset }
557 @@ -254,13 +257,17 @@ struct twl4030_madc_platform_data {
558         int             irq_line;
559  };
560  
561 +/* Boards have uniqe mappings of {col, row} --> keycode.
562 + * Column and row are 4 bits, but range only from 0..7.
563 + * a PERSISTENT_KEY is "always on" and never reported.
564 + */
565 +#define PERSISTENT_KEY(c, r)   KEY((c), (r), KEY_RESERVED)
566 +
567  struct twl4030_keypad_data {
568 -       int rows;
569 -       int cols;
570 -       int *keymap;
571 -       int irq;
572 -       unsigned int keymapsize;
573 -       unsigned int rep:1;
574 +       const struct matrix_keymap_data *keymap_data;
575 +       unsigned rows;
576 +       unsigned cols;
577 +       bool rep;
578  };
579  
580  enum twl4030_usb_mode {
581 -- 
582 1.6.3.1
583