Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: mpr121 - switch to device tree probe

This driver currently only supports legacy platform data probe. This
change adds device tree support and gets rid of platform data probe code
since no one is actually using mpr121 platform data in the mainline.

The device tree property parsing code is based on the work of
atmel_captouch driver.

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Akinobu Mita and committed by
Dmitry Torokhov
de901cc3 08fea55e

+124 -63
+30
Documentation/devicetree/bindings/input/mpr121-touchkey.txt
··· 1 + * Freescale MPR121 Controllor 2 + 3 + Required Properties: 4 + - compatible: Should be "fsl,mpr121-touchkey" 5 + - reg: The I2C slave address of the device. 6 + - interrupts: The interrupt number to the cpu. 7 + - vdd-supply: Phandle to the Vdd power supply. 8 + - linux,keycodes: Specifies an array of numeric keycode values to 9 + be used for reporting button presses. The array can 10 + contain up to 12 entries. 11 + 12 + Optional Properties: 13 + - wakeup-source: Use any event on keypad as wakeup event. 14 + - autorepeat: Enable autorepeat feature. 15 + 16 + Example: 17 + 18 + #include "dt-bindings/input/input.h" 19 + 20 + touchkey: mpr121@5a { 21 + compatible = "fsl,mpr121-touchkey"; 22 + reg = <0x5a>; 23 + interrupt-parent = <&gpio1>; 24 + interrupts = <28 2>; 25 + autorepeat; 26 + vdd-supply = <&ldo4_reg>; 27 + linux,keycodes = <KEY_0>, <KEY_1>, <KEY_2>, <KEY_3>, 28 + <KEY_4> <KEY_5>, <KEY_6>, <KEY_7>, 29 + <KEY_8>, <KEY_9>, <KEY_A>, <KEY_B>; 30 + };
+94 -43
drivers/input/keyboard/mpr121_touchkey.c
··· 12 12 * 13 13 */ 14 14 15 - #include <linux/module.h> 16 - #include <linux/input.h> 17 - #include <linux/i2c.h> 18 - #include <linux/slab.h> 19 - #include <linux/delay.h> 20 15 #include <linux/bitops.h> 16 + #include <linux/delay.h> 17 + #include <linux/i2c.h> 18 + #include <linux/input.h> 21 19 #include <linux/interrupt.h> 22 - #include <linux/i2c/mpr121_touchkey.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> 23 25 24 26 /* Register definitions */ 25 27 #define ELE_TOUCH_STATUS_0_ADDR 0x0 ··· 63 61 struct input_dev *input_dev; 64 62 unsigned int statusbits; 65 63 unsigned int keycount; 66 - u16 keycodes[MPR121_MAX_KEY_COUNT]; 64 + u32 keycodes[MPR121_MAX_KEY_COUNT]; 67 65 }; 68 66 69 67 struct mpr121_init_register { ··· 82 80 { AFE_CONF_ADDR, 0x0b }, 83 81 { AUTO_CONFIG_CTRL_ADDR, 0x0b }, 84 82 }; 83 + 84 + static void mpr121_vdd_supply_disable(void *data) 85 + { 86 + struct regulator *vdd_supply = data; 87 + 88 + regulator_disable(vdd_supply); 89 + } 90 + 91 + static struct regulator *mpr121_vdd_supply_init(struct device *dev) 92 + { 93 + struct regulator *vdd_supply; 94 + int err; 95 + 96 + vdd_supply = devm_regulator_get(dev, "vdd"); 97 + if (IS_ERR(vdd_supply)) { 98 + dev_err(dev, "failed to get vdd regulator: %ld\n", 99 + PTR_ERR(vdd_supply)); 100 + return vdd_supply; 101 + } 102 + 103 + err = regulator_enable(vdd_supply); 104 + if (err) { 105 + dev_err(dev, "failed to enable vdd regulator: %d\n", err); 106 + return ERR_PTR(err); 107 + } 108 + 109 + err = devm_add_action(dev, mpr121_vdd_supply_disable, vdd_supply); 110 + if (err) { 111 + regulator_disable(vdd_supply); 112 + dev_err(dev, "failed to add disable regulator action: %d\n", 113 + err); 114 + return ERR_PTR(err); 115 + } 116 + 117 + return vdd_supply; 118 + } 85 119 86 120 static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) 87 121 { ··· 164 126 return IRQ_HANDLED; 165 127 } 166 128 167 - static int mpr121_phys_init(const struct mpr121_platform_data *pdata, 168 - struct mpr121_touchkey *mpr121, 169 - struct i2c_client *client) 129 + static int mpr121_phys_init(struct mpr121_touchkey *mpr121, 130 + struct i2c_client *client, int vdd_uv) 170 131 { 171 132 const struct mpr121_init_register *reg; 172 133 unsigned char usl, lsl, tl, eleconf; ··· 195 158 /* 196 159 * Capacitance on sensing input varies and needs to be compensated. 197 160 * The internal MPR121-auto-configuration can do this if it's 198 - * registers are set properly (based on pdata->vdd_uv). 161 + * registers are set properly (based on vdd_uv). 199 162 */ 200 - vdd = pdata->vdd_uv / 1000; 163 + vdd = vdd_uv / 1000; 201 164 usl = ((vdd - 700) * 256) / vdd; 202 165 lsl = (usl * 65) / 100; 203 166 tl = (usl * 90) / 100; ··· 228 191 static int mpr_touchkey_probe(struct i2c_client *client, 229 192 const struct i2c_device_id *id) 230 193 { 231 - const struct mpr121_platform_data *pdata = 232 - dev_get_platdata(&client->dev); 194 + struct device *dev = &client->dev; 195 + struct regulator *vdd_supply; 196 + int vdd_uv; 233 197 struct mpr121_touchkey *mpr121; 234 198 struct input_dev *input_dev; 235 199 int error; 236 200 int i; 237 - 238 - if (!pdata) { 239 - dev_err(&client->dev, "no platform data defined\n"); 240 - return -EINVAL; 241 - } 242 - 243 - if (!pdata->keymap || !pdata->keymap_size) { 244 - dev_err(&client->dev, "missing keymap data\n"); 245 - return -EINVAL; 246 - } 247 - 248 - if (pdata->keymap_size > MPR121_MAX_KEY_COUNT) { 249 - dev_err(&client->dev, "too many keys defined\n"); 250 - return -EINVAL; 251 - } 252 201 253 202 if (!client->irq) { 254 203 dev_err(&client->dev, "irq number should not be zero\n"); 255 204 return -EINVAL; 256 205 } 257 206 258 - mpr121 = devm_kzalloc(&client->dev, sizeof(*mpr121), 259 - GFP_KERNEL); 207 + vdd_supply = mpr121_vdd_supply_init(dev); 208 + if (IS_ERR(vdd_supply)) 209 + return PTR_ERR(vdd_supply); 210 + 211 + vdd_uv = regulator_get_voltage(vdd_supply); 212 + 213 + mpr121 = devm_kzalloc(&client->dev, sizeof(*mpr121), GFP_KERNEL); 260 214 if (!mpr121) 261 215 return -ENOMEM; 262 216 ··· 257 229 258 230 mpr121->client = client; 259 231 mpr121->input_dev = input_dev; 260 - mpr121->keycount = pdata->keymap_size; 232 + mpr121->keycount = device_property_read_u32_array(dev, "linux,keycodes", 233 + NULL, 0); 234 + if (mpr121->keycount > MPR121_MAX_KEY_COUNT) { 235 + dev_err(dev, "too many keys defined (%d)\n", mpr121->keycount); 236 + return -EINVAL; 237 + } 238 + 239 + error = device_property_read_u32_array(dev, "linux,keycodes", 240 + mpr121->keycodes, 241 + mpr121->keycount); 242 + if (error) { 243 + dev_err(dev, 244 + "failed to read linux,keycode property: %d\n", error); 245 + return error; 246 + } 261 247 262 248 input_dev->name = "Freescale MPR121 Touchkey"; 263 249 input_dev->id.bustype = BUS_I2C; 264 250 input_dev->dev.parent = &client->dev; 265 - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); 251 + if (device_property_read_bool(dev, "autorepeat")) 252 + __set_bit(EV_REP, input_dev->evbit); 266 253 input_set_capability(input_dev, EV_MSC, MSC_SCAN); 267 254 268 255 input_dev->keycode = mpr121->keycodes; 269 256 input_dev->keycodesize = sizeof(mpr121->keycodes[0]); 270 257 input_dev->keycodemax = mpr121->keycount; 271 258 272 - for (i = 0; i < pdata->keymap_size; i++) { 273 - input_set_capability(input_dev, EV_KEY, pdata->keymap[i]); 274 - mpr121->keycodes[i] = pdata->keymap[i]; 275 - } 259 + for (i = 0; i < mpr121->keycount; i++) 260 + input_set_capability(input_dev, EV_KEY, mpr121->keycodes[i]); 276 261 277 - error = mpr121_phys_init(pdata, mpr121, client); 262 + error = mpr121_phys_init(mpr121, client, vdd_uv); 278 263 if (error) { 279 264 dev_err(&client->dev, "Failed to init register\n"); 280 265 return error; 281 266 } 282 267 283 - error = devm_request_threaded_irq(&client->dev, client->irq, NULL, 284 - mpr_touchkey_interrupt, 285 - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 286 - client->dev.driver->name, mpr121); 268 + error = devm_request_threaded_irq(&client->dev, client->irq, 269 + NULL, mpr_touchkey_interrupt, 270 + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 271 + client->dev.driver->name, mpr121); 287 272 if (error) { 288 273 dev_err(&client->dev, "Failed to register interrupt\n"); 289 274 return error; ··· 307 266 return error; 308 267 309 268 i2c_set_clientdata(client, mpr121); 310 - device_init_wakeup(&client->dev, pdata->wakeup); 269 + device_init_wakeup(dev, 270 + device_property_read_bool(dev, "wakeup-source")); 311 271 312 272 return 0; 313 273 } ··· 347 305 }; 348 306 MODULE_DEVICE_TABLE(i2c, mpr121_id); 349 307 308 + #ifdef CONFIG_OF 309 + static const struct of_device_id mpr121_touchkey_dt_match_table[] = { 310 + { .compatible = "fsl,mpr121-touchkey" }, 311 + { }, 312 + }; 313 + MODULE_DEVICE_TABLE(of, mpr121_touchkey_dt_match_table); 314 + #endif 315 + 350 316 static struct i2c_driver mpr_touchkey_driver = { 351 317 .driver = { 352 318 .name = "mpr121", 353 319 .pm = &mpr121_touchkey_pm_ops, 320 + .of_match_table = of_match_ptr(mpr121_touchkey_dt_match_table), 354 321 }, 355 322 .id_table = mpr121_id, 356 323 .probe = mpr_touchkey_probe,
-20
include/linux/i2c/mpr121_touchkey.h
··· 1 - /* Header file for Freescale MPR121 Capacitive Touch Sensor */ 2 - 3 - #ifndef _MPR121_TOUCHKEY_H 4 - #define _MPR121_TOUCHKEY_H 5 - 6 - /** 7 - * struct mpr121_platform_data - platform data for mpr121 sensor 8 - * @keymap: pointer to array of KEY_* values representing keymap 9 - * @keymap_size: size of the keymap 10 - * @wakeup: configure the button as a wake-up source 11 - * @vdd_uv: VDD voltage in uV 12 - */ 13 - struct mpr121_platform_data { 14 - const unsigned short *keymap; 15 - unsigned int keymap_size; 16 - bool wakeup; 17 - int vdd_uv; 18 - }; 19 - 20 - #endif /* _MPR121_TOUCHKEY_H */