xref: /openbmc/linux/drivers/input/keyboard/qt1070.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
174ba9207SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2bd7e4e85SBo Shen /*
3bd7e4e85SBo Shen  *  Atmel AT42QT1070 QTouch Sensor Controller
4bd7e4e85SBo Shen  *
5bd7e4e85SBo Shen  *  Copyright (C) 2011 Atmel
6bd7e4e85SBo Shen  *
7bd7e4e85SBo Shen  *  Authors: Bo Shen <voice.shen@atmel.com>
8bd7e4e85SBo Shen  *
9bd7e4e85SBo Shen  *  Base on AT42QT2160 driver by:
10bd7e4e85SBo Shen  *  Raphael Derosso Pereira <raphaelpereira@gmail.com>
11bd7e4e85SBo Shen  *  Copyright (C) 2009
12bd7e4e85SBo Shen  */
13bd7e4e85SBo Shen #include <linux/kernel.h>
14bd7e4e85SBo Shen #include <linux/module.h>
15bd7e4e85SBo Shen #include <linux/i2c.h>
16bd7e4e85SBo Shen #include <linux/input.h>
17bd7e4e85SBo Shen #include <linux/slab.h>
18bd7e4e85SBo Shen #include <linux/irq.h>
19bd7e4e85SBo Shen #include <linux/interrupt.h>
20bd7e4e85SBo Shen #include <linux/jiffies.h>
21bd7e4e85SBo Shen #include <linux/delay.h>
22bd7e4e85SBo Shen 
23bd7e4e85SBo Shen /* Address for each register */
24bd7e4e85SBo Shen #define CHIP_ID            0x00
25bd7e4e85SBo Shen #define QT1070_CHIP_ID     0x2E
26bd7e4e85SBo Shen 
27bd7e4e85SBo Shen #define FW_VERSION         0x01
28bd7e4e85SBo Shen #define QT1070_FW_VERSION  0x15
29bd7e4e85SBo Shen 
30bd7e4e85SBo Shen #define DET_STATUS         0x02
31bd7e4e85SBo Shen 
32bd7e4e85SBo Shen #define KEY_STATUS         0x03
33bd7e4e85SBo Shen 
34bd7e4e85SBo Shen /* Calibrate */
35bd7e4e85SBo Shen #define CALIBRATE_CMD      0x38
36bd7e4e85SBo Shen #define QT1070_CAL_TIME    200
37bd7e4e85SBo Shen 
38bd7e4e85SBo Shen /* Reset */
39bd7e4e85SBo Shen #define RESET              0x39
40bd7e4e85SBo Shen #define QT1070_RESET_TIME  255
41bd7e4e85SBo Shen 
42bd7e4e85SBo Shen /* AT42QT1070 support up to 7 keys */
43bd7e4e85SBo Shen static const unsigned short qt1070_key2code[] = {
44bd7e4e85SBo Shen 	KEY_0, KEY_1, KEY_2, KEY_3,
45bd7e4e85SBo Shen 	KEY_4, KEY_5, KEY_6,
46bd7e4e85SBo Shen };
47bd7e4e85SBo Shen 
48bd7e4e85SBo Shen struct qt1070_data {
49bd7e4e85SBo Shen 	struct i2c_client *client;
50bd7e4e85SBo Shen 	struct input_dev *input;
51bd7e4e85SBo Shen 	unsigned int irq;
52bd7e4e85SBo Shen 	unsigned short keycodes[ARRAY_SIZE(qt1070_key2code)];
53bd7e4e85SBo Shen 	u8 last_keys;
54bd7e4e85SBo Shen };
55bd7e4e85SBo Shen 
qt1070_read(struct i2c_client * client,u8 reg)56bd7e4e85SBo Shen static int qt1070_read(struct i2c_client *client, u8 reg)
57bd7e4e85SBo Shen {
58bd7e4e85SBo Shen 	int ret;
59bd7e4e85SBo Shen 
60bd7e4e85SBo Shen 	ret = i2c_smbus_read_byte_data(client, reg);
61bd7e4e85SBo Shen 	if (ret < 0)
62bd7e4e85SBo Shen 		dev_err(&client->dev,
63bd7e4e85SBo Shen 			"can not read register, returned %d\n", ret);
64bd7e4e85SBo Shen 
65bd7e4e85SBo Shen 	return ret;
66bd7e4e85SBo Shen }
67bd7e4e85SBo Shen 
qt1070_write(struct i2c_client * client,u8 reg,u8 data)68bd7e4e85SBo Shen static int qt1070_write(struct i2c_client *client, u8 reg, u8 data)
69bd7e4e85SBo Shen {
70bd7e4e85SBo Shen 	int ret;
71bd7e4e85SBo Shen 
72bd7e4e85SBo Shen 	ret = i2c_smbus_write_byte_data(client, reg, data);
73bd7e4e85SBo Shen 	if (ret < 0)
74bd7e4e85SBo Shen 		dev_err(&client->dev,
75bd7e4e85SBo Shen 			"can not write register, returned %d\n", ret);
76bd7e4e85SBo Shen 
77bd7e4e85SBo Shen 	return ret;
78bd7e4e85SBo Shen }
79bd7e4e85SBo Shen 
qt1070_identify(struct i2c_client * client)805298cc4cSBill Pemberton static bool qt1070_identify(struct i2c_client *client)
81bd7e4e85SBo Shen {
82bd7e4e85SBo Shen 	int id, ver;
83bd7e4e85SBo Shen 
84bd7e4e85SBo Shen 	/* Read Chip ID */
85bd7e4e85SBo Shen 	id = qt1070_read(client, CHIP_ID);
86bd7e4e85SBo Shen 	if (id != QT1070_CHIP_ID) {
87bd7e4e85SBo Shen 		dev_err(&client->dev, "ID %d not supported\n", id);
88bd7e4e85SBo Shen 		return false;
89bd7e4e85SBo Shen 	}
90bd7e4e85SBo Shen 
91bd7e4e85SBo Shen 	/* Read firmware version */
92bd7e4e85SBo Shen 	ver = qt1070_read(client, FW_VERSION);
93bd7e4e85SBo Shen 	if (ver < 0) {
94bd7e4e85SBo Shen 		dev_err(&client->dev, "could not read the firmware version\n");
95bd7e4e85SBo Shen 		return false;
96bd7e4e85SBo Shen 	}
97bd7e4e85SBo Shen 
98bd7e4e85SBo Shen 	dev_info(&client->dev, "AT42QT1070 firmware version %x\n", ver);
99bd7e4e85SBo Shen 
100bd7e4e85SBo Shen 	return true;
101bd7e4e85SBo Shen }
102bd7e4e85SBo Shen 
qt1070_interrupt(int irq,void * dev_id)103bd7e4e85SBo Shen static irqreturn_t qt1070_interrupt(int irq, void *dev_id)
104bd7e4e85SBo Shen {
105bd7e4e85SBo Shen 	struct qt1070_data *data = dev_id;
106bd7e4e85SBo Shen 	struct i2c_client *client = data->client;
107bd7e4e85SBo Shen 	struct input_dev *input = data->input;
108bd7e4e85SBo Shen 	int i;
109bd7e4e85SBo Shen 	u8 new_keys, keyval, mask = 0x01;
110bd7e4e85SBo Shen 
111bd7e4e85SBo Shen 	/* Read the detected status register, thus clearing interrupt */
112bd7e4e85SBo Shen 	qt1070_read(client, DET_STATUS);
113bd7e4e85SBo Shen 
114bd7e4e85SBo Shen 	/* Read which key changed */
115bd7e4e85SBo Shen 	new_keys = qt1070_read(client, KEY_STATUS);
116bd7e4e85SBo Shen 
117bd7e4e85SBo Shen 	for (i = 0; i < ARRAY_SIZE(qt1070_key2code); i++) {
118bd7e4e85SBo Shen 		keyval = new_keys & mask;
119bd7e4e85SBo Shen 		if ((data->last_keys & mask) != keyval)
120bd7e4e85SBo Shen 			input_report_key(input, data->keycodes[i], keyval);
121bd7e4e85SBo Shen 		mask <<= 1;
122bd7e4e85SBo Shen 	}
123bd7e4e85SBo Shen 	input_sync(input);
124bd7e4e85SBo Shen 
125bd7e4e85SBo Shen 	data->last_keys = new_keys;
126bd7e4e85SBo Shen 	return IRQ_HANDLED;
127bd7e4e85SBo Shen }
128bd7e4e85SBo Shen 
qt1070_probe(struct i2c_client * client)129ee27fe8aSUwe Kleine-König static int qt1070_probe(struct i2c_client *client)
130bd7e4e85SBo Shen {
131bd7e4e85SBo Shen 	struct qt1070_data *data;
132bd7e4e85SBo Shen 	struct input_dev *input;
133bd7e4e85SBo Shen 	int i;
134bd7e4e85SBo Shen 	int err;
135bd7e4e85SBo Shen 
136bd7e4e85SBo Shen 	err = i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE);
137bd7e4e85SBo Shen 	if (!err) {
138bd7e4e85SBo Shen 		dev_err(&client->dev, "%s adapter not supported\n",
139bd7e4e85SBo Shen 			dev_driver_string(&client->adapter->dev));
140bd7e4e85SBo Shen 		return -ENODEV;
141bd7e4e85SBo Shen 	}
142bd7e4e85SBo Shen 
143bd7e4e85SBo Shen 	if (!client->irq) {
144bd7e4e85SBo Shen 		dev_err(&client->dev, "please assign the irq to this device\n");
145bd7e4e85SBo Shen 		return -EINVAL;
146bd7e4e85SBo Shen 	}
147bd7e4e85SBo Shen 
148bd7e4e85SBo Shen 	/* Identify the qt1070 chip */
149bd7e4e85SBo Shen 	if (!qt1070_identify(client))
150bd7e4e85SBo Shen 		return -ENODEV;
151bd7e4e85SBo Shen 
152*447c0954SYangtao Li 	data = devm_kzalloc(&client->dev, sizeof(struct qt1070_data),
153*447c0954SYangtao Li 			    GFP_KERNEL);
154*447c0954SYangtao Li 	if (!data)
155*447c0954SYangtao Li 		return -ENOMEM;
156*447c0954SYangtao Li 
157*447c0954SYangtao Li 	input = devm_input_allocate_device(&client->dev);
158*447c0954SYangtao Li 	if (!input)
159*447c0954SYangtao Li 		return -ENOMEM;
160bd7e4e85SBo Shen 
161bd7e4e85SBo Shen 	data->client = client;
162bd7e4e85SBo Shen 	data->input = input;
163bd7e4e85SBo Shen 	data->irq = client->irq;
164bd7e4e85SBo Shen 
165bd7e4e85SBo Shen 	input->name = "AT42QT1070 QTouch Sensor";
166bd7e4e85SBo Shen 	input->id.bustype = BUS_I2C;
167bd7e4e85SBo Shen 
168bd7e4e85SBo Shen 	/* Add the keycode */
169bd7e4e85SBo Shen 	input->keycode = data->keycodes;
170bd7e4e85SBo Shen 	input->keycodesize = sizeof(data->keycodes[0]);
171bd7e4e85SBo Shen 	input->keycodemax = ARRAY_SIZE(qt1070_key2code);
172bd7e4e85SBo Shen 
173bd7e4e85SBo Shen 	__set_bit(EV_KEY, input->evbit);
174bd7e4e85SBo Shen 
175bd7e4e85SBo Shen 	for (i = 0; i < ARRAY_SIZE(qt1070_key2code); i++) {
176bd7e4e85SBo Shen 		data->keycodes[i] = qt1070_key2code[i];
177bd7e4e85SBo Shen 		__set_bit(qt1070_key2code[i], input->keybit);
178bd7e4e85SBo Shen 	}
179bd7e4e85SBo Shen 
180bd7e4e85SBo Shen 	/* Calibrate device */
181bd7e4e85SBo Shen 	qt1070_write(client, CALIBRATE_CMD, 1);
182bd7e4e85SBo Shen 	msleep(QT1070_CAL_TIME);
183bd7e4e85SBo Shen 
184bd7e4e85SBo Shen 	/* Soft reset */
185bd7e4e85SBo Shen 	qt1070_write(client, RESET, 1);
186bd7e4e85SBo Shen 	msleep(QT1070_RESET_TIME);
187bd7e4e85SBo Shen 
188*447c0954SYangtao Li 	err = devm_request_threaded_irq(&client->dev, client->irq,
189*447c0954SYangtao Li 					NULL, qt1070_interrupt,
1909b7e31bbSLars-Peter Clausen 					IRQF_TRIGGER_NONE | IRQF_ONESHOT,
1919b7e31bbSLars-Peter Clausen 					client->dev.driver->name, data);
192bd7e4e85SBo Shen 	if (err) {
193bd7e4e85SBo Shen 		dev_err(&client->dev, "fail to request irq\n");
194*447c0954SYangtao Li 		return err;
195bd7e4e85SBo Shen 	}
196bd7e4e85SBo Shen 
197bd7e4e85SBo Shen 	/* Register the input device */
198bd7e4e85SBo Shen 	err = input_register_device(data->input);
199bd7e4e85SBo Shen 	if (err) {
200bd7e4e85SBo Shen 		dev_err(&client->dev, "Failed to register input device\n");
201*447c0954SYangtao Li 		return err;
202bd7e4e85SBo Shen 	}
203bd7e4e85SBo Shen 
204bd7e4e85SBo Shen 	i2c_set_clientdata(client, data);
205bd7e4e85SBo Shen 
206bd7e4e85SBo Shen 	/* Read to clear the chang line */
207bd7e4e85SBo Shen 	qt1070_read(client, DET_STATUS);
208bd7e4e85SBo Shen 
209bd7e4e85SBo Shen 	return 0;
210bd7e4e85SBo Shen }
211bd7e4e85SBo Shen 
qt1070_suspend(struct device * dev)2123719b54bSBo Shen static int qt1070_suspend(struct device *dev)
2133719b54bSBo Shen {
2143719b54bSBo Shen 	struct i2c_client *client = to_i2c_client(dev);
2153719b54bSBo Shen 	struct qt1070_data *data = i2c_get_clientdata(client);
2163719b54bSBo Shen 
2173719b54bSBo Shen 	if (device_may_wakeup(dev))
2183719b54bSBo Shen 		enable_irq_wake(data->irq);
2193719b54bSBo Shen 
2203719b54bSBo Shen 	return 0;
2213719b54bSBo Shen }
2223719b54bSBo Shen 
qt1070_resume(struct device * dev)2233719b54bSBo Shen static int qt1070_resume(struct device *dev)
2243719b54bSBo Shen {
2253719b54bSBo Shen 	struct i2c_client *client = to_i2c_client(dev);
2263719b54bSBo Shen 	struct qt1070_data *data = i2c_get_clientdata(client);
2273719b54bSBo Shen 
2283719b54bSBo Shen 	if (device_may_wakeup(dev))
2293719b54bSBo Shen 		disable_irq_wake(data->irq);
2303719b54bSBo Shen 
2313719b54bSBo Shen 	return 0;
2323719b54bSBo Shen }
2333719b54bSBo Shen 
2349254ed3fSJonathan Cameron static DEFINE_SIMPLE_DEV_PM_OPS(qt1070_pm_ops, qt1070_suspend, qt1070_resume);
2353719b54bSBo Shen 
236bd7e4e85SBo Shen static const struct i2c_device_id qt1070_id[] = {
237bd7e4e85SBo Shen 	{ "qt1070", 0 },
238bd7e4e85SBo Shen 	{ },
239bd7e4e85SBo Shen };
24094bb530cSAxel Lin MODULE_DEVICE_TABLE(i2c, qt1070_id);
241bd7e4e85SBo Shen 
242cf5cd9d4SJavier Martinez Canillas #ifdef CONFIG_OF
243cf5cd9d4SJavier Martinez Canillas static const struct of_device_id qt1070_of_match[] = {
244cf5cd9d4SJavier Martinez Canillas 	{ .compatible = "qt1070", },
245cf5cd9d4SJavier Martinez Canillas 	{ },
246cf5cd9d4SJavier Martinez Canillas };
247cf5cd9d4SJavier Martinez Canillas MODULE_DEVICE_TABLE(of, qt1070_of_match);
248cf5cd9d4SJavier Martinez Canillas #endif
249cf5cd9d4SJavier Martinez Canillas 
250bd7e4e85SBo Shen static struct i2c_driver qt1070_driver = {
251bd7e4e85SBo Shen 	.driver	= {
252bd7e4e85SBo Shen 		.name	= "qt1070",
253cf5cd9d4SJavier Martinez Canillas 		.of_match_table = of_match_ptr(qt1070_of_match),
2549254ed3fSJonathan Cameron 		.pm	= pm_sleep_ptr(&qt1070_pm_ops),
255bd7e4e85SBo Shen 	},
256bd7e4e85SBo Shen 	.id_table	= qt1070_id,
257d8bde56dSUwe Kleine-König 	.probe		= qt1070_probe,
258bd7e4e85SBo Shen };
259bd7e4e85SBo Shen 
2601b92c1cfSAxel Lin module_i2c_driver(qt1070_driver);
261bd7e4e85SBo Shen 
262bd7e4e85SBo Shen MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>");
263bd7e4e85SBo Shen MODULE_DESCRIPTION("Driver for AT42QT1070 QTouch sensor");
264bd7e4e85SBo Shen MODULE_LICENSE("GPL");
265