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

Input: cap11xx - add support for various cap11xx devices

There are variants of the cap11xx device with a varying number of
capacitance detection channels.

Signed-off-by: Matt Ranostay <mranostay@gmail.com>
Reviewed-by: Daniel Mack <daniel@zonque.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Matt Ranostay and committed by
Dmitry Torokhov
7609a5e9 c77fd0a4

+53 -24
+2 -1
Documentation/devicetree/bindings/input/cap11xx.txt
··· 7 7 8 8 compatible: Must contain one of: 9 9 "microchip,cap1106" 10 + "microchip,cap1126" 11 + "microchip,cap1188" 10 12 11 13 reg: The I2C slave address of the device. 12 - Only 0x28 is valid. 13 14 14 15 interrupts: Property describing the interrupt line the 15 16 device's ALERT#/CM_IRQ# pin is connected to.
+51 -23
drivers/input/keyboard/cap11xx.c
··· 1 1 /* 2 2 * Input driver for Microchip CAP11xx based capacitive touch sensors 3 3 * 4 - * 5 4 * (c) 2014 Daniel Mack <linux@zonque.org> 6 5 * 7 6 * This program is free software; you can redistribute it and/or modify ··· 53 54 #define CAP11XX_REG_MANUFACTURER_ID 0xfe 54 55 #define CAP11XX_REG_REVISION 0xff 55 56 56 - #define CAP11XX_NUM_CHN 6 57 - #define CAP11XX_PRODUCT_ID 0x55 58 57 #define CAP11XX_MANUFACTURER_ID 0x5d 59 58 60 59 struct cap11xx_priv { ··· 60 63 struct input_dev *idev; 61 64 62 65 /* config */ 63 - unsigned short keycodes[CAP11XX_NUM_CHN]; 66 + u32 keycodes[]; 67 + }; 68 + 69 + struct cap11xx_hw_model { 70 + u8 product_id; 71 + unsigned int num_channels; 72 + }; 73 + 74 + enum { 75 + CAP1106, 76 + CAP1126, 77 + CAP1188, 78 + }; 79 + 80 + static const struct cap11xx_hw_model cap11xx_devices[] = { 81 + [CAP1106] = { .product_id = 0x55, .num_channels = 6 }, 82 + [CAP1126] = { .product_id = 0x53, .num_channels = 6 }, 83 + [CAP1188] = { .product_id = 0x50, .num_channels = 8 }, 64 84 }; 65 85 66 86 static const struct reg_default cap11xx_reg_defaults[] = { ··· 164 150 if (ret < 0) 165 151 goto out; 166 152 167 - for (i = 0; i < CAP11XX_NUM_CHN; i++) 153 + for (i = 0; i < priv->idev->keycodemax; i++) 168 154 input_report_key(priv->idev, priv->keycodes[i], 169 155 status & (1 << i)); 170 156 ··· 201 187 struct device *dev = &i2c_client->dev; 202 188 struct cap11xx_priv *priv; 203 189 struct device_node *node; 190 + const struct cap11xx_hw_model *cap; 204 191 int i, error, irq, gain = 0; 205 192 unsigned int val, rev; 206 - u32 gain32, keycodes[CAP11XX_NUM_CHN]; 193 + u32 gain32; 207 194 208 - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 195 + if (id->driver_data >= ARRAY_SIZE(cap11xx_devices)) { 196 + dev_err(dev, "Invalid device ID %lu\n", id->driver_data); 197 + return -EINVAL; 198 + } 199 + 200 + cap = &cap11xx_devices[id->driver_data]; 201 + if (!cap || !cap->num_channels) { 202 + dev_err(dev, "Invalid device configuration\n"); 203 + return -EINVAL; 204 + } 205 + 206 + priv = devm_kzalloc(dev, 207 + sizeof(*priv) + 208 + cap->num_channels * sizeof(priv->keycodes[0]), 209 + GFP_KERNEL); 209 210 if (!priv) 210 211 return -ENOMEM; 211 212 ··· 232 203 if (error) 233 204 return error; 234 205 235 - if (val != CAP11XX_PRODUCT_ID) { 206 + if (val != cap->product_id) { 236 207 dev_err(dev, "Product ID: Got 0x%02x, expected 0x%02x\n", 237 - val, CAP11XX_PRODUCT_ID); 238 - return -ENODEV; 208 + val, cap->product_id); 209 + return -ENXIO; 239 210 } 240 211 241 212 error = regmap_read(priv->regmap, CAP11XX_REG_MANUFACTURER_ID, &val); ··· 245 216 if (val != CAP11XX_MANUFACTURER_ID) { 246 217 dev_err(dev, "Manufacturer ID: Got 0x%02x, expected 0x%02x\n", 247 218 val, CAP11XX_MANUFACTURER_ID); 248 - return -ENODEV; 219 + return -ENXIO; 249 220 } 250 221 251 222 error = regmap_read(priv->regmap, CAP11XX_REG_REVISION, &rev); ··· 263 234 dev_err(dev, "Invalid sensor-gain value %d\n", gain32); 264 235 } 265 236 266 - BUILD_BUG_ON(ARRAY_SIZE(keycodes) != ARRAY_SIZE(priv->keycodes)); 267 - 268 237 /* Provide some useful defaults */ 269 - for (i = 0; i < ARRAY_SIZE(keycodes); i++) 270 - keycodes[i] = KEY_A + i; 238 + for (i = 0; i < cap->num_channels; i++) 239 + priv->keycodes[i] = KEY_A + i; 271 240 272 241 of_property_read_u32_array(node, "linux,keycodes", 273 - keycodes, ARRAY_SIZE(keycodes)); 274 - 275 - for (i = 0; i < ARRAY_SIZE(keycodes); i++) 276 - priv->keycodes[i] = keycodes[i]; 242 + priv->keycodes, cap->num_channels); 277 243 278 244 error = regmap_update_bits(priv->regmap, CAP11XX_REG_MAIN_CONTROL, 279 245 CAP11XX_REG_MAIN_CONTROL_GAIN_MASK, ··· 292 268 if (of_property_read_bool(node, "autorepeat")) 293 269 __set_bit(EV_REP, priv->idev->evbit); 294 270 295 - for (i = 0; i < CAP11XX_NUM_CHN; i++) 271 + for (i = 0; i < cap->num_channels; i++) 296 272 __set_bit(priv->keycodes[i], priv->idev->keybit); 297 273 298 274 __clear_bit(KEY_RESERVED, priv->idev->keybit); 299 275 300 276 priv->idev->keycode = priv->keycodes; 301 277 priv->idev->keycodesize = sizeof(priv->keycodes[0]); 302 - priv->idev->keycodemax = ARRAY_SIZE(priv->keycodes); 278 + priv->idev->keycodemax = cap->num_channels; 303 279 304 280 priv->idev->id.vendor = CAP11XX_MANUFACTURER_ID; 305 - priv->idev->id.product = CAP11XX_PRODUCT_ID; 281 + priv->idev->id.product = cap->product_id; 306 282 priv->idev->id.version = rev; 307 283 308 284 priv->idev->open = cap11xx_input_open; ··· 336 312 337 313 static const struct of_device_id cap11xx_dt_ids[] = { 338 314 { .compatible = "microchip,cap1106", }, 315 + { .compatible = "microchip,cap1126", }, 316 + { .compatible = "microchip,cap1188", }, 339 317 {} 340 318 }; 341 319 MODULE_DEVICE_TABLE(of, cap11xx_dt_ids); 342 320 343 321 static const struct i2c_device_id cap11xx_i2c_ids[] = { 344 - { "cap1106", 0 }, 322 + { "cap1106", CAP1106 }, 323 + { "cap1126", CAP1126 }, 324 + { "cap1188", CAP1188 }, 345 325 {} 346 326 }; 347 327 MODULE_DEVICE_TABLE(i2c, cap11xx_i2c_ids);