dt-bindings: mtd: ingenic: Use standard ecc-engine property
[linux/fpc-iii.git] / drivers / input / keyboard / mpr121_touchkey.c
blob884a74d8a7edf50b26f9e62a4ce731d77d9f2c8e
1 /*
2 * Touchkey driver for Freescale MPR121 Controllor
4 * Copyright (C) 2011 Freescale Semiconductor, Inc.
5 * Author: Zhang Jiejing <jiejing.zhang@freescale.com>
7 * Based on mcs_touchkey.c
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
15 #include <linux/bitops.h>
16 #include <linux/delay.h>
17 #include <linux/i2c.h>
18 #include <linux/input.h>
19 #include <linux/interrupt.h>
20 #include <linux/module.h>
21 #include <linux/of.h>
22 #include <linux/property.h>
23 #include <linux/regulator/consumer.h>
24 #include <linux/slab.h>
26 /* Register definitions */
27 #define ELE_TOUCH_STATUS_0_ADDR 0x0
28 #define ELE_TOUCH_STATUS_1_ADDR 0X1
29 #define MHD_RISING_ADDR 0x2b
30 #define NHD_RISING_ADDR 0x2c
31 #define NCL_RISING_ADDR 0x2d
32 #define FDL_RISING_ADDR 0x2e
33 #define MHD_FALLING_ADDR 0x2f
34 #define NHD_FALLING_ADDR 0x30
35 #define NCL_FALLING_ADDR 0x31
36 #define FDL_FALLING_ADDR 0x32
37 #define ELE0_TOUCH_THRESHOLD_ADDR 0x41
38 #define ELE0_RELEASE_THRESHOLD_ADDR 0x42
39 #define AFE_CONF_ADDR 0x5c
40 #define FILTER_CONF_ADDR 0x5d
43 * ELECTRODE_CONF_ADDR: This register configures the number of
44 * enabled capacitance sensing inputs and its run/suspend mode.
46 #define ELECTRODE_CONF_ADDR 0x5e
47 #define ELECTRODE_CONF_QUICK_CHARGE 0x80
48 #define AUTO_CONFIG_CTRL_ADDR 0x7b
49 #define AUTO_CONFIG_USL_ADDR 0x7d
50 #define AUTO_CONFIG_LSL_ADDR 0x7e
51 #define AUTO_CONFIG_TL_ADDR 0x7f
53 /* Threshold of touch/release trigger */
54 #define TOUCH_THRESHOLD 0x08
55 #define RELEASE_THRESHOLD 0x05
56 /* Masks for touch and release triggers */
57 #define TOUCH_STATUS_MASK 0xfff
58 /* MPR121 has 12 keys */
59 #define MPR121_MAX_KEY_COUNT 12
61 struct mpr121_touchkey {
62 struct i2c_client *client;
63 struct input_dev *input_dev;
64 unsigned int statusbits;
65 unsigned int keycount;
66 u32 keycodes[MPR121_MAX_KEY_COUNT];
69 struct mpr121_init_register {
70 int addr;
71 u8 val;
74 static const struct mpr121_init_register init_reg_table[] = {
75 { MHD_RISING_ADDR, 0x1 },
76 { NHD_RISING_ADDR, 0x1 },
77 { MHD_FALLING_ADDR, 0x1 },
78 { NHD_FALLING_ADDR, 0x1 },
79 { NCL_FALLING_ADDR, 0xff },
80 { FDL_FALLING_ADDR, 0x02 },
81 { FILTER_CONF_ADDR, 0x04 },
82 { AFE_CONF_ADDR, 0x0b },
83 { AUTO_CONFIG_CTRL_ADDR, 0x0b },
86 static void mpr121_vdd_supply_disable(void *data)
88 struct regulator *vdd_supply = data;
90 regulator_disable(vdd_supply);
93 static struct regulator *mpr121_vdd_supply_init(struct device *dev)
95 struct regulator *vdd_supply;
96 int err;
98 vdd_supply = devm_regulator_get(dev, "vdd");
99 if (IS_ERR(vdd_supply)) {
100 dev_err(dev, "failed to get vdd regulator: %ld\n",
101 PTR_ERR(vdd_supply));
102 return vdd_supply;
105 err = regulator_enable(vdd_supply);
106 if (err) {
107 dev_err(dev, "failed to enable vdd regulator: %d\n", err);
108 return ERR_PTR(err);
111 err = devm_add_action(dev, mpr121_vdd_supply_disable, vdd_supply);
112 if (err) {
113 regulator_disable(vdd_supply);
114 dev_err(dev, "failed to add disable regulator action: %d\n",
115 err);
116 return ERR_PTR(err);
119 return vdd_supply;
122 static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id)
124 struct mpr121_touchkey *mpr121 = dev_id;
125 struct i2c_client *client = mpr121->client;
126 struct input_dev *input = mpr121->input_dev;
127 unsigned long bit_changed;
128 unsigned int key_num;
129 int reg;
131 reg = i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_1_ADDR);
132 if (reg < 0) {
133 dev_err(&client->dev, "i2c read error [%d]\n", reg);
134 goto out;
137 reg <<= 8;
138 reg |= i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_0_ADDR);
139 if (reg < 0) {
140 dev_err(&client->dev, "i2c read error [%d]\n", reg);
141 goto out;
144 reg &= TOUCH_STATUS_MASK;
145 /* use old press bit to figure out which bit changed */
146 bit_changed = reg ^ mpr121->statusbits;
147 mpr121->statusbits = reg;
148 for_each_set_bit(key_num, &bit_changed, mpr121->keycount) {
149 unsigned int key_val, pressed;
151 pressed = reg & BIT(key_num);
152 key_val = mpr121->keycodes[key_num];
154 input_event(input, EV_MSC, MSC_SCAN, key_num);
155 input_report_key(input, key_val, pressed);
157 dev_dbg(&client->dev, "key %d %d %s\n", key_num, key_val,
158 pressed ? "pressed" : "released");
161 input_sync(input);
163 out:
164 return IRQ_HANDLED;
167 static int mpr121_phys_init(struct mpr121_touchkey *mpr121,
168 struct i2c_client *client, int vdd_uv)
170 const struct mpr121_init_register *reg;
171 unsigned char usl, lsl, tl, eleconf;
172 int i, t, vdd, ret;
174 /* Set up touch/release threshold for ele0-ele11 */
175 for (i = 0; i <= MPR121_MAX_KEY_COUNT; i++) {
176 t = ELE0_TOUCH_THRESHOLD_ADDR + (i * 2);
177 ret = i2c_smbus_write_byte_data(client, t, TOUCH_THRESHOLD);
178 if (ret < 0)
179 goto err_i2c_write;
180 ret = i2c_smbus_write_byte_data(client, t + 1,
181 RELEASE_THRESHOLD);
182 if (ret < 0)
183 goto err_i2c_write;
186 /* Set up init register */
187 for (i = 0; i < ARRAY_SIZE(init_reg_table); i++) {
188 reg = &init_reg_table[i];
189 ret = i2c_smbus_write_byte_data(client, reg->addr, reg->val);
190 if (ret < 0)
191 goto err_i2c_write;
196 * Capacitance on sensing input varies and needs to be compensated.
197 * The internal MPR121-auto-configuration can do this if it's
198 * registers are set properly (based on vdd_uv).
200 vdd = vdd_uv / 1000;
201 usl = ((vdd - 700) * 256) / vdd;
202 lsl = (usl * 65) / 100;
203 tl = (usl * 90) / 100;
204 ret = i2c_smbus_write_byte_data(client, AUTO_CONFIG_USL_ADDR, usl);
205 ret |= i2c_smbus_write_byte_data(client, AUTO_CONFIG_LSL_ADDR, lsl);
206 ret |= i2c_smbus_write_byte_data(client, AUTO_CONFIG_TL_ADDR, tl);
209 * Quick charge bit will let the capacitive charge to ready
210 * state quickly, or the buttons may not function after system
211 * boot.
213 eleconf = mpr121->keycount | ELECTRODE_CONF_QUICK_CHARGE;
214 ret |= i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR,
215 eleconf);
216 if (ret != 0)
217 goto err_i2c_write;
219 dev_dbg(&client->dev, "set up with %x keys.\n", mpr121->keycount);
221 return 0;
223 err_i2c_write:
224 dev_err(&client->dev, "i2c write error: %d\n", ret);
225 return ret;
228 static int mpr_touchkey_probe(struct i2c_client *client,
229 const struct i2c_device_id *id)
231 struct device *dev = &client->dev;
232 struct regulator *vdd_supply;
233 int vdd_uv;
234 struct mpr121_touchkey *mpr121;
235 struct input_dev *input_dev;
236 int error;
237 int i;
239 if (!client->irq) {
240 dev_err(dev, "irq number should not be zero\n");
241 return -EINVAL;
244 vdd_supply = mpr121_vdd_supply_init(dev);
245 if (IS_ERR(vdd_supply))
246 return PTR_ERR(vdd_supply);
248 vdd_uv = regulator_get_voltage(vdd_supply);
250 mpr121 = devm_kzalloc(dev, sizeof(*mpr121), GFP_KERNEL);
251 if (!mpr121)
252 return -ENOMEM;
254 input_dev = devm_input_allocate_device(dev);
255 if (!input_dev)
256 return -ENOMEM;
258 mpr121->client = client;
259 mpr121->input_dev = input_dev;
260 mpr121->keycount = device_property_read_u32_array(dev, "linux,keycodes",
261 NULL, 0);
262 if (mpr121->keycount > MPR121_MAX_KEY_COUNT) {
263 dev_err(dev, "too many keys defined (%d)\n", mpr121->keycount);
264 return -EINVAL;
267 error = device_property_read_u32_array(dev, "linux,keycodes",
268 mpr121->keycodes,
269 mpr121->keycount);
270 if (error) {
271 dev_err(dev,
272 "failed to read linux,keycode property: %d\n", error);
273 return error;
276 input_dev->name = "Freescale MPR121 Touchkey";
277 input_dev->id.bustype = BUS_I2C;
278 input_dev->dev.parent = dev;
279 if (device_property_read_bool(dev, "autorepeat"))
280 __set_bit(EV_REP, input_dev->evbit);
281 input_set_capability(input_dev, EV_MSC, MSC_SCAN);
283 input_dev->keycode = mpr121->keycodes;
284 input_dev->keycodesize = sizeof(mpr121->keycodes[0]);
285 input_dev->keycodemax = mpr121->keycount;
287 for (i = 0; i < mpr121->keycount; i++)
288 input_set_capability(input_dev, EV_KEY, mpr121->keycodes[i]);
290 error = mpr121_phys_init(mpr121, client, vdd_uv);
291 if (error) {
292 dev_err(dev, "Failed to init register\n");
293 return error;
296 error = devm_request_threaded_irq(dev, client->irq, NULL,
297 mpr_touchkey_interrupt,
298 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
299 dev->driver->name, mpr121);
300 if (error) {
301 dev_err(dev, "Failed to register interrupt\n");
302 return error;
305 error = input_register_device(input_dev);
306 if (error)
307 return error;
309 i2c_set_clientdata(client, mpr121);
310 device_init_wakeup(dev,
311 device_property_read_bool(dev, "wakeup-source"));
313 return 0;
316 static int __maybe_unused mpr_suspend(struct device *dev)
318 struct i2c_client *client = to_i2c_client(dev);
320 if (device_may_wakeup(&client->dev))
321 enable_irq_wake(client->irq);
323 i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR, 0x00);
325 return 0;
328 static int __maybe_unused mpr_resume(struct device *dev)
330 struct i2c_client *client = to_i2c_client(dev);
331 struct mpr121_touchkey *mpr121 = i2c_get_clientdata(client);
333 if (device_may_wakeup(&client->dev))
334 disable_irq_wake(client->irq);
336 i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR,
337 mpr121->keycount);
339 return 0;
342 static SIMPLE_DEV_PM_OPS(mpr121_touchkey_pm_ops, mpr_suspend, mpr_resume);
344 static const struct i2c_device_id mpr121_id[] = {
345 { "mpr121_touchkey", 0 },
348 MODULE_DEVICE_TABLE(i2c, mpr121_id);
350 #ifdef CONFIG_OF
351 static const struct of_device_id mpr121_touchkey_dt_match_table[] = {
352 { .compatible = "fsl,mpr121-touchkey" },
353 { },
355 MODULE_DEVICE_TABLE(of, mpr121_touchkey_dt_match_table);
356 #endif
358 static struct i2c_driver mpr_touchkey_driver = {
359 .driver = {
360 .name = "mpr121",
361 .pm = &mpr121_touchkey_pm_ops,
362 .of_match_table = of_match_ptr(mpr121_touchkey_dt_match_table),
364 .id_table = mpr121_id,
365 .probe = mpr_touchkey_probe,
368 module_i2c_driver(mpr_touchkey_driver);
370 MODULE_LICENSE("GPL");
371 MODULE_AUTHOR("Zhang Jiejing <jiejing.zhang@freescale.com>");
372 MODULE_DESCRIPTION("Touch Key driver for Freescale MPR121 Chip");