2 * Driver for keys on TCA6416 I2C IO expander
4 * Copyright (C) 2010 Texas Instruments
6 * Author : Sriramakrishnan.A.G. <srk@ti.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/types.h>
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/delay.h>
17 #include <linux/slab.h>
18 #include <linux/interrupt.h>
19 #include <linux/workqueue.h>
20 #include <linux/gpio.h>
21 #include <linux/i2c.h>
22 #include <linux/input.h>
23 #include <linux/tca6416_keypad.h>
25 #define TCA6416_INPUT 0
26 #define TCA6416_OUTPUT 1
27 #define TCA6416_INVERT 2
28 #define TCA6416_DIRECTION 3
30 static const struct i2c_device_id tca6416_id
[] = {
31 { "tca6416-keys", 16, },
34 MODULE_DEVICE_TABLE(i2c
, tca6416_id
);
36 struct tca6416_drv_data
{
37 struct input_dev
*input
;
38 struct tca6416_button data
[0];
41 struct tca6416_keypad_chip
{
43 uint16_t reg_direction
;
46 struct i2c_client
*client
;
47 struct input_dev
*input
;
48 struct delayed_work dwork
;
52 struct tca6416_button buttons
[0];
55 static int tca6416_write_reg(struct tca6416_keypad_chip
*chip
, int reg
, u16 val
)
59 error
= i2c_smbus_write_word_data(chip
->client
, reg
<< 1, val
);
61 dev_err(&chip
->client
->dev
,
62 "%s failed, reg: %d, val: %d, error: %d\n",
63 __func__
, reg
, val
, error
);
70 static int tca6416_read_reg(struct tca6416_keypad_chip
*chip
, int reg
, u16
*val
)
74 retval
= i2c_smbus_read_word_data(chip
->client
, reg
<< 1);
76 dev_err(&chip
->client
->dev
, "%s failed, reg: %d, error: %d\n",
77 __func__
, reg
, retval
);
85 static void tca6416_keys_scan(struct tca6416_keypad_chip
*chip
)
87 struct input_dev
*input
= chip
->input
;
89 int error
, i
, pin_index
;
91 error
= tca6416_read_reg(chip
, TCA6416_INPUT
, ®_val
);
95 reg_val
&= chip
->pinmask
;
97 /* Figure out which lines have changed */
98 val
= reg_val
^ chip
->reg_input
;
99 chip
->reg_input
= reg_val
;
101 for (i
= 0, pin_index
= 0; i
< 16; i
++) {
102 if (val
& (1 << i
)) {
103 struct tca6416_button
*button
= &chip
->buttons
[pin_index
];
104 unsigned int type
= button
->type
?: EV_KEY
;
105 int state
= ((reg_val
& (1 << i
)) ? 1 : 0)
106 ^ button
->active_low
;
108 input_event(input
, type
, button
->code
, !!state
);
112 if (chip
->pinmask
& (1 << i
))
118 * This is threaded IRQ handler and this can (and will) sleep.
120 static irqreturn_t
tca6416_keys_isr(int irq
, void *dev_id
)
122 struct tca6416_keypad_chip
*chip
= dev_id
;
124 tca6416_keys_scan(chip
);
129 static void tca6416_keys_work_func(struct work_struct
*work
)
131 struct tca6416_keypad_chip
*chip
=
132 container_of(work
, struct tca6416_keypad_chip
, dwork
.work
);
134 tca6416_keys_scan(chip
);
135 schedule_delayed_work(&chip
->dwork
, msecs_to_jiffies(100));
138 static int tca6416_keys_open(struct input_dev
*dev
)
140 struct tca6416_keypad_chip
*chip
= input_get_drvdata(dev
);
142 /* Get initial device state in case it has switches */
143 tca6416_keys_scan(chip
);
145 if (chip
->use_polling
)
146 schedule_delayed_work(&chip
->dwork
, msecs_to_jiffies(100));
148 enable_irq(chip
->irqnum
);
153 static void tca6416_keys_close(struct input_dev
*dev
)
155 struct tca6416_keypad_chip
*chip
= input_get_drvdata(dev
);
157 if (chip
->use_polling
)
158 cancel_delayed_work_sync(&chip
->dwork
);
160 disable_irq(chip
->irqnum
);
163 static int __devinit
tca6416_setup_registers(struct tca6416_keypad_chip
*chip
)
167 error
= tca6416_read_reg(chip
, TCA6416_OUTPUT
, &chip
->reg_output
);
171 error
= tca6416_read_reg(chip
, TCA6416_DIRECTION
, &chip
->reg_direction
);
175 /* ensure that keypad pins are set to input */
176 error
= tca6416_write_reg(chip
, TCA6416_DIRECTION
,
177 chip
->reg_direction
| chip
->pinmask
);
181 error
= tca6416_read_reg(chip
, TCA6416_DIRECTION
, &chip
->reg_direction
);
185 error
= tca6416_read_reg(chip
, TCA6416_INPUT
, &chip
->reg_input
);
189 chip
->reg_input
&= chip
->pinmask
;
194 static int __devinit
tca6416_keypad_probe(struct i2c_client
*client
,
195 const struct i2c_device_id
*id
)
197 struct tca6416_keys_platform_data
*pdata
;
198 struct tca6416_keypad_chip
*chip
;
199 struct input_dev
*input
;
203 /* Check functionality */
204 if (!i2c_check_functionality(client
->adapter
, I2C_FUNC_SMBUS_BYTE
)) {
205 dev_err(&client
->dev
, "%s adapter not supported\n",
206 dev_driver_string(&client
->adapter
->dev
));
210 pdata
= client
->dev
.platform_data
;
212 dev_dbg(&client
->dev
, "no platform data\n");
216 chip
= kzalloc(sizeof(struct tca6416_keypad_chip
) +
217 pdata
->nbuttons
* sizeof(struct tca6416_button
),
219 input
= input_allocate_device();
220 if (!chip
|| !input
) {
225 chip
->client
= client
;
227 chip
->pinmask
= pdata
->pinmask
;
228 chip
->use_polling
= pdata
->use_polling
;
230 INIT_DELAYED_WORK(&chip
->dwork
, tca6416_keys_work_func
);
232 input
->phys
= "tca6416-keys/input0";
233 input
->name
= client
->name
;
234 input
->dev
.parent
= &client
->dev
;
236 input
->open
= tca6416_keys_open
;
237 input
->close
= tca6416_keys_close
;
239 input
->id
.bustype
= BUS_HOST
;
240 input
->id
.vendor
= 0x0001;
241 input
->id
.product
= 0x0001;
242 input
->id
.version
= 0x0100;
244 /* Enable auto repeat feature of Linux input subsystem */
246 __set_bit(EV_REP
, input
->evbit
);
248 for (i
= 0; i
< pdata
->nbuttons
; i
++) {
251 chip
->buttons
[i
] = pdata
->buttons
[i
];
252 type
= (pdata
->buttons
[i
].type
) ?: EV_KEY
;
253 input_set_capability(input
, type
, pdata
->buttons
[i
].code
);
256 input_set_drvdata(input
, chip
);
259 * Initialize cached registers from their original values.
260 * we can't share this chip with another i2c master.
262 error
= tca6416_setup_registers(chip
);
266 if (!chip
->use_polling
) {
267 if (pdata
->irq_is_gpio
)
268 chip
->irqnum
= gpio_to_irq(client
->irq
);
270 chip
->irqnum
= client
->irq
;
272 error
= request_threaded_irq(chip
->irqnum
, NULL
,
274 IRQF_TRIGGER_FALLING
,
275 "tca6416-keypad", chip
);
277 dev_dbg(&client
->dev
,
278 "Unable to claim irq %d; error %d\n",
279 chip
->irqnum
, error
);
282 disable_irq(chip
->irqnum
);
285 error
= input_register_device(input
);
287 dev_dbg(&client
->dev
,
288 "Unable to register input device, error: %d\n", error
);
292 i2c_set_clientdata(client
, chip
);
297 if (!chip
->use_polling
) {
298 free_irq(chip
->irqnum
, chip
);
299 enable_irq(chip
->irqnum
);
302 input_free_device(input
);
307 static int __devexit
tca6416_keypad_remove(struct i2c_client
*client
)
309 struct tca6416_keypad_chip
*chip
= i2c_get_clientdata(client
);
311 if (!chip
->use_polling
) {
312 free_irq(chip
->irqnum
, chip
);
313 enable_irq(chip
->irqnum
);
316 input_unregister_device(chip
->input
);
323 static struct i2c_driver tca6416_keypad_driver
= {
325 .name
= "tca6416-keypad",
327 .probe
= tca6416_keypad_probe
,
328 .remove
= __devexit_p(tca6416_keypad_remove
),
329 .id_table
= tca6416_id
,
332 static int __init
tca6416_keypad_init(void)
334 return i2c_add_driver(&tca6416_keypad_driver
);
337 subsys_initcall(tca6416_keypad_init
);
339 static void __exit
tca6416_keypad_exit(void)
341 i2c_del_driver(&tca6416_keypad_driver
);
343 module_exit(tca6416_keypad_exit
);
345 MODULE_AUTHOR("Sriramakrishnan <srk@ti.com>");
346 MODULE_DESCRIPTION("Keypad driver over tca6146 IO expander");
347 MODULE_LICENSE("GPL");