1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Driver for keys on TCA6416 I2C IO expander
4 *
5 * Copyright (C) 2010 Texas Instruments
6 *
7 * Author : Sriramakrishnan.A.G. <srk@ti.com>
8 */
9
10#include <linux/types.h>
11#include <linux/module.h>
12#include <linux/init.h>
13#include <linux/delay.h>
14#include <linux/slab.h>
15#include <linux/interrupt.h>
16#include <linux/workqueue.h>
17#include <linux/gpio.h>
18#include <linux/i2c.h>
19#include <linux/input.h>
20#include <linux/tca6416_keypad.h>
21
22#define TCA6416_INPUT          0
23#define TCA6416_OUTPUT         1
24#define TCA6416_INVERT         2
25#define TCA6416_DIRECTION      3
26
27#define TCA6416_POLL_INTERVAL	100 /* msec */
28
29static const struct i2c_device_id tca6416_id[] = {
30	{ "tca6416-keys", 16, },
31	{ "tca6408-keys", 8, },
32	{ }
33};
34MODULE_DEVICE_TABLE(i2c, tca6416_id);
35
36struct tca6416_drv_data {
37	struct input_dev *input;
38	struct tca6416_button data[];
39};
40
41struct 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	int io_size;
49	int irqnum;
50	u16 pinmask;
51	bool use_polling;
52	struct tca6416_button buttons[];
53};
54
55static int tca6416_write_reg(struct tca6416_keypad_chip *chip, int reg, u16 val)
56{
57	int error;
58
59	error = chip->io_size > 8 ?
60		i2c_smbus_write_word_data(chip->client, reg << 1, val) :
61		i2c_smbus_write_byte_data(chip->client, reg, val);
62	if (error < 0) {
63		dev_err(&chip->client->dev,
64			"%s failed, reg: %d, val: %d, error: %d\n",
65			__func__, reg, val, error);
66		return error;
67	}
68
69	return 0;
70}
71
72static int tca6416_read_reg(struct tca6416_keypad_chip *chip, int reg, u16 *val)
73{
74	int retval;
75
76	retval = chip->io_size > 8 ?
77		 i2c_smbus_read_word_data(chip->client, reg << 1) :
78		 i2c_smbus_read_byte_data(chip->client, reg);
79	if (retval < 0) {
80		dev_err(&chip->client->dev, "%s failed, reg: %d, error: %d\n",
81			__func__, reg, retval);
82		return retval;
83	}
84
85	*val = (u16)retval;
86	return 0;
87}
88
89static void tca6416_keys_scan(struct input_dev *input)
90{
91	struct tca6416_keypad_chip *chip = input_get_drvdata(input);
92	u16 reg_val, val;
93	int error, i, pin_index;
94
95	error = tca6416_read_reg(chip, TCA6416_INPUT, &reg_val);
96	if (error)
97		return;
98
99	reg_val &= chip->pinmask;
100
101	/* Figure out which lines have changed */
102	val = reg_val ^ chip->reg_input;
103	chip->reg_input = reg_val;
104
105	for (i = 0, pin_index = 0; i < 16; i++) {
106		if (val & (1 << i)) {
107			struct tca6416_button *button = &chip->buttons[pin_index];
108			unsigned int type = button->type ?: EV_KEY;
109			int state = ((reg_val & (1 << i)) ? 1 : 0)
110						^ button->active_low;
111
112			input_event(input, type, button->code, !!state);
113			input_sync(input);
114		}
115
116		if (chip->pinmask & (1 << i))
117			pin_index++;
118	}
119}
120
121/*
122 * This is threaded IRQ handler and this can (and will) sleep.
123 */
124static irqreturn_t tca6416_keys_isr(int irq, void *dev_id)
125{
126	tca6416_keys_scan(dev_id);
127
128	return IRQ_HANDLED;
129}
130
131static int tca6416_keys_open(struct input_dev *dev)
132{
133	struct tca6416_keypad_chip *chip = input_get_drvdata(dev);
134
135	if (!chip->use_polling) {
136		/* Get initial device state in case it has switches */
137		tca6416_keys_scan(dev);
138		enable_irq(chip->client->irq);
139	}
140
141	return 0;
142}
143
144static void tca6416_keys_close(struct input_dev *dev)
145{
146	struct tca6416_keypad_chip *chip = input_get_drvdata(dev);
147
148	if (!chip->use_polling)
149		disable_irq(chip->client->irq);
150}
151
152static int tca6416_setup_registers(struct tca6416_keypad_chip *chip)
153{
154	int error;
155
156	error = tca6416_read_reg(chip, TCA6416_OUTPUT, &chip->reg_output);
157	if (error)
158		return error;
159
160	error = tca6416_read_reg(chip, TCA6416_DIRECTION, &chip->reg_direction);
161	if (error)
162		return error;
163
164	/* ensure that keypad pins are set to input */
165	error = tca6416_write_reg(chip, TCA6416_DIRECTION,
166				  chip->reg_direction | chip->pinmask);
167	if (error)
168		return error;
169
170	error = tca6416_read_reg(chip, TCA6416_DIRECTION, &chip->reg_direction);
171	if (error)
172		return error;
173
174	error = tca6416_read_reg(chip, TCA6416_INPUT, &chip->reg_input);
175	if (error)
176		return error;
177
178	chip->reg_input &= chip->pinmask;
179
180	return 0;
181}
182
183static int tca6416_keypad_probe(struct i2c_client *client)
184{
185	const struct i2c_device_id *id = i2c_client_get_device_id(client);
186	struct tca6416_keys_platform_data *pdata;
187	struct tca6416_keypad_chip *chip;
188	struct input_dev *input;
189	int error;
190	int i;
191
192	/* Check functionality */
193	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
194		dev_err(&client->dev, "%s adapter not supported\n",
195			dev_driver_string(&client->adapter->dev));
196		return -ENODEV;
197	}
198
199	pdata = dev_get_platdata(&client->dev);
200	if (!pdata) {
201		dev_dbg(&client->dev, "no platform data\n");
202		return -EINVAL;
203	}
204
205	chip = devm_kzalloc(&client->dev,
206			    struct_size(chip, buttons, pdata->nbuttons),
207			    GFP_KERNEL);
208	if (!chip)
209		return -ENOMEM;
210
211	input = devm_input_allocate_device(&client->dev);
212	if (!input)
213		return -ENOMEM;
214
215	chip->client = client;
216	chip->input = input;
217	chip->io_size = id->driver_data;
218	chip->pinmask = pdata->pinmask;
219	chip->use_polling = pdata->use_polling;
220
221	input->phys = "tca6416-keys/input0";
222	input->name = client->name;
223
224	input->open = tca6416_keys_open;
225	input->close = tca6416_keys_close;
226
227	input->id.bustype = BUS_HOST;
228	input->id.vendor = 0x0001;
229	input->id.product = 0x0001;
230	input->id.version = 0x0100;
231
232	/* Enable auto repeat feature of Linux input subsystem */
233	if (pdata->rep)
234		__set_bit(EV_REP, input->evbit);
235
236	for (i = 0; i < pdata->nbuttons; i++) {
237		unsigned int type;
238
239		chip->buttons[i] = pdata->buttons[i];
240		type = (pdata->buttons[i].type) ?: EV_KEY;
241		input_set_capability(input, type, pdata->buttons[i].code);
242	}
243
244	input_set_drvdata(input, chip);
245
246	/*
247	 * Initialize cached registers from their original values.
248	 * we can't share this chip with another i2c master.
249	 */
250	error = tca6416_setup_registers(chip);
251	if (error)
252		return error;
253
254	if (chip->use_polling) {
255		error = input_setup_polling(input, tca6416_keys_scan);
256		if (error) {
257			dev_err(&client->dev, "Failed to setup polling\n");
258			return error;
259		}
260
261		input_set_poll_interval(input, TCA6416_POLL_INTERVAL);
262	} else {
263		error = devm_request_threaded_irq(&client->dev, client->irq,
264						  NULL, tca6416_keys_isr,
265						  IRQF_TRIGGER_FALLING |
266							IRQF_ONESHOT |
267							IRQF_NO_AUTOEN,
268						  "tca6416-keypad", input);
269		if (error) {
270			dev_dbg(&client->dev,
271				"Unable to claim irq %d; error %d\n",
272				client->irq, error);
273			return error;
274		}
275	}
276
277	error = input_register_device(input);
278	if (error) {
279		dev_dbg(&client->dev,
280			"Unable to register input device, error: %d\n", error);
281		return error;
282	}
283
284	i2c_set_clientdata(client, chip);
285
286	return 0;
287}
288
289static struct i2c_driver tca6416_keypad_driver = {
290	.driver = {
291		.name	= "tca6416-keypad",
292	},
293	.probe		= tca6416_keypad_probe,
294	.id_table	= tca6416_id,
295};
296
297static int __init tca6416_keypad_init(void)
298{
299	return i2c_add_driver(&tca6416_keypad_driver);
300}
301
302subsys_initcall(tca6416_keypad_init);
303
304static void __exit tca6416_keypad_exit(void)
305{
306	i2c_del_driver(&tca6416_keypad_driver);
307}
308module_exit(tca6416_keypad_exit);
309
310MODULE_AUTHOR("Sriramakrishnan <srk@ti.com>");
311MODULE_DESCRIPTION("Keypad driver over tca6416 IO expander");
312MODULE_LICENSE("GPL");
313