xref: /linux/drivers/input/keyboard/tca6416-keypad.c (revision b74b953b998bcc2db91b694446f3a2619ec32de6)
1 /*
2  * Driver for keys on TCA6416 I2C IO expander
3  *
4  * Copyright (C) 2010 Texas Instruments
5  *
6  * Author : Sriramakrishnan.A.G. <srk@ti.com>
7  *
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.
11  */
12 
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>
24 
25 #define TCA6416_INPUT          0
26 #define TCA6416_OUTPUT         1
27 #define TCA6416_INVERT         2
28 #define TCA6416_DIRECTION      3
29 
30 static const struct i2c_device_id tca6416_id[] = {
31 	{ "tca6416-keys", 16, },
32 	{ }
33 };
34 MODULE_DEVICE_TABLE(i2c, tca6416_id);
35 
36 struct tca6416_drv_data {
37 	struct input_dev *input;
38 	struct tca6416_button data[0];
39 };
40 
41 struct tca6416_keypad_chip {
42 	uint16_t reg_output;
43 	uint16_t reg_direction;
44 	uint16_t reg_input;
45 
46 	struct i2c_client *client;
47 	struct input_dev *input;
48 	struct delayed_work dwork;
49 	u16 pinmask;
50 	int irqnum;
51 	bool use_polling;
52 	struct tca6416_button buttons[0];
53 };
54 
55 static int tca6416_write_reg(struct tca6416_keypad_chip *chip, int reg, u16 val)
56 {
57 	int error;
58 
59 	error = i2c_smbus_write_word_data(chip->client, reg << 1, val);
60 	if (error < 0) {
61 		dev_err(&chip->client->dev,
62 			"%s failed, reg: %d, val: %d, error: %d\n",
63 			__func__, reg, val, error);
64 		return error;
65 	}
66 
67 	return 0;
68 }
69 
70 static int tca6416_read_reg(struct tca6416_keypad_chip *chip, int reg, u16 *val)
71 {
72 	int retval;
73 
74 	retval = i2c_smbus_read_word_data(chip->client, reg << 1);
75 	if (retval < 0) {
76 		dev_err(&chip->client->dev, "%s failed, reg: %d, error: %d\n",
77 			__func__, reg, retval);
78 		return retval;
79 	}
80 
81 	*val = (u16)retval;
82 	return 0;
83 }
84 
85 static void tca6416_keys_scan(struct tca6416_keypad_chip *chip)
86 {
87 	struct input_dev *input = chip->input;
88 	u16 reg_val, val;
89 	int error, i, pin_index;
90 
91 	error = tca6416_read_reg(chip, TCA6416_INPUT, &reg_val);
92 	if (error)
93 		return;
94 
95 	reg_val &= chip->pinmask;
96 
97 	/* Figure out which lines have changed */
98 	val = reg_val ^ chip->reg_input;
99 	chip->reg_input = reg_val;
100 
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;
107 
108 			input_event(input, type, button->code, !!state);
109 			input_sync(input);
110 		}
111 
112 		if (chip->pinmask & (1 << i))
113 			pin_index++;
114 	}
115 }
116 
117 /*
118  * This is threaded IRQ handler and this can (and will) sleep.
119  */
120 static irqreturn_t tca6416_keys_isr(int irq, void *dev_id)
121 {
122 	struct tca6416_keypad_chip *chip = dev_id;
123 
124 	tca6416_keys_scan(chip);
125 
126 	return IRQ_HANDLED;
127 }
128 
129 static void tca6416_keys_work_func(struct work_struct *work)
130 {
131 	struct tca6416_keypad_chip *chip =
132 		container_of(work, struct tca6416_keypad_chip, dwork.work);
133 
134 	tca6416_keys_scan(chip);
135 	schedule_delayed_work(&chip->dwork, msecs_to_jiffies(100));
136 }
137 
138 static int tca6416_keys_open(struct input_dev *dev)
139 {
140 	struct tca6416_keypad_chip *chip = input_get_drvdata(dev);
141 
142 	/* Get initial device state in case it has switches */
143 	tca6416_keys_scan(chip);
144 
145 	if (chip->use_polling)
146 		schedule_delayed_work(&chip->dwork, msecs_to_jiffies(100));
147 	else
148 		enable_irq(chip->irqnum);
149 
150 	return 0;
151 }
152 
153 static void tca6416_keys_close(struct input_dev *dev)
154 {
155 	struct tca6416_keypad_chip *chip = input_get_drvdata(dev);
156 
157 	if (chip->use_polling)
158 		cancel_delayed_work_sync(&chip->dwork);
159 	else
160 		disable_irq(chip->irqnum);
161 }
162 
163 static int __devinit tca6416_setup_registers(struct tca6416_keypad_chip *chip)
164 {
165 	int error;
166 
167 	error = tca6416_read_reg(chip, TCA6416_OUTPUT, &chip->reg_output);
168 	if (error)
169 		return error;
170 
171 	error = tca6416_read_reg(chip, TCA6416_DIRECTION, &chip->reg_direction);
172 	if (error)
173 		return error;
174 
175 	/* ensure that keypad pins are set to input */
176 	error = tca6416_write_reg(chip, TCA6416_DIRECTION,
177 				  chip->reg_direction | chip->pinmask);
178 	if (error)
179 		return error;
180 
181 	error = tca6416_read_reg(chip, TCA6416_DIRECTION, &chip->reg_direction);
182 	if (error)
183 		return error;
184 
185 	error = tca6416_read_reg(chip, TCA6416_INPUT, &chip->reg_input);
186 	if (error)
187 		return error;
188 
189 	chip->reg_input &= chip->pinmask;
190 
191 	return 0;
192 }
193 
194 static int __devinit tca6416_keypad_probe(struct i2c_client *client,
195 				   const struct i2c_device_id *id)
196 {
197 	struct tca6416_keys_platform_data *pdata;
198 	struct tca6416_keypad_chip *chip;
199 	struct input_dev *input;
200 	int error;
201 	int i;
202 
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));
207 		return -ENODEV;
208 	}
209 
210 	pdata = client->dev.platform_data;
211 	if (!pdata) {
212 		dev_dbg(&client->dev, "no platform data\n");
213 		return -EINVAL;
214 	}
215 
216 	chip = kzalloc(sizeof(struct tca6416_keypad_chip) +
217 		       pdata->nbuttons * sizeof(struct tca6416_button),
218 		       GFP_KERNEL);
219 	input = input_allocate_device();
220 	if (!chip || !input) {
221 		error = -ENOMEM;
222 		goto fail1;
223 	}
224 
225 	chip->client = client;
226 	chip->input = input;
227 	chip->pinmask = pdata->pinmask;
228 	chip->use_polling = pdata->use_polling;
229 
230 	INIT_DELAYED_WORK(&chip->dwork, tca6416_keys_work_func);
231 
232 	input->phys = "tca6416-keys/input0";
233 	input->name = client->name;
234 	input->dev.parent = &client->dev;
235 
236 	input->open = tca6416_keys_open;
237 	input->close = tca6416_keys_close;
238 
239 	input->id.bustype = BUS_HOST;
240 	input->id.vendor = 0x0001;
241 	input->id.product = 0x0001;
242 	input->id.version = 0x0100;
243 
244 	/* Enable auto repeat feature of Linux input subsystem */
245 	if (pdata->rep)
246 		__set_bit(EV_REP, input->evbit);
247 
248 	for (i = 0; i < pdata->nbuttons; i++) {
249 		unsigned int type;
250 
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);
254 	}
255 
256 	input_set_drvdata(input, chip);
257 
258 	/*
259 	 * Initialize cached registers from their original values.
260 	 * we can't share this chip with another i2c master.
261 	 */
262 	error = tca6416_setup_registers(chip);
263 	if (error)
264 		goto fail1;
265 
266 	if (!chip->use_polling) {
267 		if (pdata->irq_is_gpio)
268 			chip->irqnum = gpio_to_irq(client->irq);
269 		else
270 			chip->irqnum = client->irq;
271 
272 		error = request_threaded_irq(chip->irqnum, NULL,
273 					     tca6416_keys_isr,
274 					     IRQF_TRIGGER_FALLING,
275 					     "tca6416-keypad", chip);
276 		if (error) {
277 			dev_dbg(&client->dev,
278 				"Unable to claim irq %d; error %d\n",
279 				chip->irqnum, error);
280 			goto fail1;
281 		}
282 		disable_irq(chip->irqnum);
283 	}
284 
285 	error = input_register_device(input);
286 	if (error) {
287 		dev_dbg(&client->dev,
288 			"Unable to register input device, error: %d\n", error);
289 		goto fail2;
290 	}
291 
292 	i2c_set_clientdata(client, chip);
293 
294 	return 0;
295 
296 fail2:
297 	if (!chip->use_polling) {
298 		free_irq(chip->irqnum, chip);
299 		enable_irq(chip->irqnum);
300 	}
301 fail1:
302 	input_free_device(input);
303 	kfree(chip);
304 	return error;
305 }
306 
307 static int __devexit tca6416_keypad_remove(struct i2c_client *client)
308 {
309 	struct tca6416_keypad_chip *chip = i2c_get_clientdata(client);
310 
311 	if (!chip->use_polling) {
312 		free_irq(chip->irqnum, chip);
313 		enable_irq(chip->irqnum);
314 	}
315 
316 	input_unregister_device(chip->input);
317 	kfree(chip);
318 
319 	return 0;
320 }
321 
322 
323 static struct i2c_driver tca6416_keypad_driver = {
324 	.driver = {
325 		.name	= "tca6416-keypad",
326 	},
327 	.probe		= tca6416_keypad_probe,
328 	.remove		= __devexit_p(tca6416_keypad_remove),
329 	.id_table	= tca6416_id,
330 };
331 
332 static int __init tca6416_keypad_init(void)
333 {
334 	return i2c_add_driver(&tca6416_keypad_driver);
335 }
336 
337 subsys_initcall(tca6416_keypad_init);
338 
339 static void __exit tca6416_keypad_exit(void)
340 {
341 	i2c_del_driver(&tca6416_keypad_driver);
342 }
343 module_exit(tca6416_keypad_exit);
344 
345 MODULE_AUTHOR("Sriramakrishnan <srk@ti.com>");
346 MODULE_DESCRIPTION("Keypad driver over tca6146 IO expander");
347 MODULE_LICENSE("GPL");
348