diff options
| -rw-r--r-- | Documentation/devicetree/bindings/input/ads7846.txt | 91 | ||||
| -rw-r--r-- | drivers/input/keyboard/nspire-keypad.c | 2 | ||||
| -rw-r--r-- | drivers/input/mouse/elantech.c | 17 | ||||
| -rw-r--r-- | drivers/input/touchscreen/ads7846.c | 123 |
4 files changed, 209 insertions, 24 deletions
diff --git a/Documentation/devicetree/bindings/input/ads7846.txt b/Documentation/devicetree/bindings/input/ads7846.txt new file mode 100644 index 000000000000..5f7619c22743 --- /dev/null +++ b/Documentation/devicetree/bindings/input/ads7846.txt | |||
| @@ -0,0 +1,91 @@ | |||
| 1 | Device tree bindings for TI's ADS7843, ADS7845, ADS7846, ADS7873, TSC2046 | ||
| 2 | SPI driven touch screen controllers. | ||
| 3 | |||
| 4 | The node for this driver must be a child node of a SPI controller, hence | ||
| 5 | all mandatory properties described in | ||
| 6 | |||
| 7 | Documentation/devicetree/bindings/spi/spi-bus.txt | ||
| 8 | |||
| 9 | must be specified. | ||
| 10 | |||
| 11 | Additional required properties: | ||
| 12 | |||
| 13 | compatible Must be one of the following, depending on the | ||
| 14 | model: | ||
| 15 | "ti,tsc2046" | ||
| 16 | "ti,ads7843" | ||
| 17 | "ti,ads7845" | ||
| 18 | "ti,ads7846" | ||
| 19 | "ti,ads7873" | ||
| 20 | |||
| 21 | interrupt-parent | ||
| 22 | interrupts An interrupt node describing the IRQ line the chip's | ||
| 23 | !PENIRQ pin is connected to. | ||
| 24 | vcc-supply A regulator node for the supply voltage. | ||
| 25 | |||
| 26 | |||
| 27 | Optional properties: | ||
| 28 | |||
| 29 | ti,vref-delay-usecs vref supply delay in usecs, 0 for | ||
| 30 | external vref (u16). | ||
| 31 | ti,vref-mv The VREF voltage, in millivolts (u16). | ||
| 32 | ti,keep-vref-on set to keep vref on for differential | ||
| 33 | measurements as well | ||
| 34 | ti,swap-xy swap x and y axis | ||
| 35 | ti,settle-delay-usec Settling time of the analog signals; | ||
| 36 | a function of Vcc and the capacitance | ||
| 37 | on the X/Y drivers. If set to non-zero, | ||
| 38 | two samples are taken with settle_delay | ||
| 39 | us apart, and the second one is used. | ||
| 40 | ~150 uSec with 0.01uF caps (u16). | ||
| 41 | ti,penirq-recheck-delay-usecs If set to non-zero, after samples are | ||
| 42 | taken this delay is applied and penirq | ||
| 43 | is rechecked, to help avoid false | ||
| 44 | events. This value is affected by the | ||
| 45 | material used to build the touch layer | ||
| 46 | (u16). | ||
| 47 | ti,x-plate-ohms Resistance of the X-plate, | ||
| 48 | in Ohms (u16). | ||
| 49 | ti,y-plate-ohms Resistance of the Y-plate, | ||
| 50 | in Ohms (u16). | ||
| 51 | ti,x-min Minimum value on the X axis (u16). | ||
| 52 | ti,y-min Minimum value on the Y axis (u16). | ||
| 53 | ti,x-max Maximum value on the X axis (u16). | ||
| 54 | ti,y-max Minimum value on the Y axis (u16). | ||
| 55 | ti,pressure-min Minimum reported pressure value | ||
| 56 | (threshold) - u16. | ||
| 57 | ti,pressure-max Maximum reported pressure value (u16). | ||
| 58 | ti,debounce-max Max number of additional readings per | ||
| 59 | sample (u16). | ||
| 60 | ti,debounce-tol Tolerance used for filtering (u16). | ||
| 61 | ti,debounce-rep Additional consecutive good readings | ||
| 62 | required after the first two (u16). | ||
| 63 | ti,pendown-gpio-debounce Platform specific debounce time for the | ||
| 64 | pendown-gpio (u32). | ||
| 65 | pendown-gpio GPIO handle describing the pin the !PENIRQ | ||
| 66 | line is connected to. | ||
| 67 | linux,wakeup use any event on touchscreen as wakeup event. | ||
| 68 | |||
| 69 | |||
| 70 | Example for a TSC2046 chip connected to an McSPI controller of an OMAP SoC:: | ||
| 71 | |||
| 72 | spi_controller { | ||
| 73 | tsc2046@0 { | ||
| 74 | reg = <0>; /* CS0 */ | ||
| 75 | compatible = "ti,tsc2046"; | ||
| 76 | interrupt-parent = <&gpio1>; | ||
| 77 | interrupts = <8 0>; /* BOOT6 / GPIO 8 */ | ||
| 78 | spi-max-frequency = <1000000>; | ||
| 79 | pendown-gpio = <&gpio1 8 0>; | ||
| 80 | vcc-supply = <®_vcc3>; | ||
| 81 | |||
| 82 | ti,x-min = /bits/ 16 <0>; | ||
| 83 | ti,x-max = /bits/ 16 <8000>; | ||
| 84 | ti,y-min = /bits/ 16 <0>; | ||
| 85 | ti,y-max = /bits/ 16 <4800>; | ||
| 86 | ti,x-plate-ohms = /bits/ 16 <40>; | ||
| 87 | ti,pressure-max = /bits/ 16 <255>; | ||
| 88 | |||
| 89 | linux,wakeup; | ||
| 90 | }; | ||
| 91 | }; | ||
diff --git a/drivers/input/keyboard/nspire-keypad.c b/drivers/input/keyboard/nspire-keypad.c index e0a1339e40e6..20d872d6f603 100644 --- a/drivers/input/keyboard/nspire-keypad.c +++ b/drivers/input/keyboard/nspire-keypad.c | |||
| @@ -122,7 +122,7 @@ static int nspire_keypad_chip_init(struct nspire_keypad *keypad) | |||
| 122 | 122 | ||
| 123 | /* Enable interrupts */ | 123 | /* Enable interrupts */ |
| 124 | keypad->int_mask = 1 << 1; | 124 | keypad->int_mask = 1 << 1; |
| 125 | writel(keypad->int_mask, keypad->reg_base + 0xc); | 125 | writel(keypad->int_mask, keypad->reg_base + KEYPAD_INTMSK); |
| 126 | 126 | ||
| 127 | /* Disable GPIO interrupts to prevent hanging on touchpad */ | 127 | /* Disable GPIO interrupts to prevent hanging on touchpad */ |
| 128 | /* Possibly used to detect touchpad events */ | 128 | /* Possibly used to detect touchpad events */ |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 1e8e42fb03a4..57b2637e153a 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
| @@ -694,18 +694,18 @@ static int elantech_packet_check_v3(struct psmouse *psmouse) | |||
| 694 | static int elantech_packet_check_v4(struct psmouse *psmouse) | 694 | static int elantech_packet_check_v4(struct psmouse *psmouse) |
| 695 | { | 695 | { |
| 696 | unsigned char *packet = psmouse->packet; | 696 | unsigned char *packet = psmouse->packet; |
| 697 | unsigned char packet_type = packet[3] & 0x03; | ||
| 697 | 698 | ||
| 698 | if ((packet[0] & 0x0c) == 0x04 && | 699 | switch (packet_type) { |
| 699 | (packet[3] & 0x1f) == 0x11) | 700 | case 0: |
| 701 | return PACKET_V4_STATUS; | ||
| 702 | |||
| 703 | case 1: | ||
| 700 | return PACKET_V4_HEAD; | 704 | return PACKET_V4_HEAD; |
| 701 | 705 | ||
| 702 | if ((packet[0] & 0x0c) == 0x04 && | 706 | case 2: |
| 703 | (packet[3] & 0x1f) == 0x12) | ||
| 704 | return PACKET_V4_MOTION; | 707 | return PACKET_V4_MOTION; |
| 705 | 708 | } | |
| 706 | if ((packet[0] & 0x0c) == 0x04 && | ||
| 707 | (packet[3] & 0x1f) == 0x10) | ||
| 708 | return PACKET_V4_STATUS; | ||
| 709 | 709 | ||
| 710 | return PACKET_UNKNOWN; | 710 | return PACKET_UNKNOWN; |
| 711 | } | 711 | } |
| @@ -1282,6 +1282,7 @@ static int elantech_set_properties(struct elantech_data *etd) | |||
| 1282 | etd->hw_version = 3; | 1282 | etd->hw_version = 3; |
| 1283 | break; | 1283 | break; |
| 1284 | case 6: | 1284 | case 6: |
| 1285 | case 7: | ||
| 1285 | etd->hw_version = 4; | 1286 | etd->hw_version = 4; |
| 1286 | break; | 1287 | break; |
| 1287 | default: | 1288 | default: |
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 84ccf140c1bb..ea195360747e 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
| @@ -27,6 +27,9 @@ | |||
| 27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
| 28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
| 29 | #include <linux/pm.h> | 29 | #include <linux/pm.h> |
| 30 | #include <linux/of.h> | ||
| 31 | #include <linux/of_gpio.h> | ||
| 32 | #include <linux/of_device.h> | ||
| 30 | #include <linux/gpio.h> | 33 | #include <linux/gpio.h> |
| 31 | #include <linux/spi/spi.h> | 34 | #include <linux/spi/spi.h> |
| 32 | #include <linux/spi/ads7846.h> | 35 | #include <linux/spi/ads7846.h> |
| @@ -961,9 +964,9 @@ static int ads7846_resume(struct device *dev) | |||
| 961 | static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume); | 964 | static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume); |
| 962 | 965 | ||
| 963 | static int ads7846_setup_pendown(struct spi_device *spi, | 966 | static int ads7846_setup_pendown(struct spi_device *spi, |
| 964 | struct ads7846 *ts) | 967 | struct ads7846 *ts, |
| 968 | const struct ads7846_platform_data *pdata) | ||
| 965 | { | 969 | { |
| 966 | struct ads7846_platform_data *pdata = spi->dev.platform_data; | ||
| 967 | int err; | 970 | int err; |
| 968 | 971 | ||
| 969 | /* | 972 | /* |
| @@ -1003,7 +1006,7 @@ static int ads7846_setup_pendown(struct spi_device *spi, | |||
| 1003 | * use formula #2 for pressure, not #3. | 1006 | * use formula #2 for pressure, not #3. |
| 1004 | */ | 1007 | */ |
| 1005 | static void ads7846_setup_spi_msg(struct ads7846 *ts, | 1008 | static void ads7846_setup_spi_msg(struct ads7846 *ts, |
| 1006 | const struct ads7846_platform_data *pdata) | 1009 | const struct ads7846_platform_data *pdata) |
| 1007 | { | 1010 | { |
| 1008 | struct spi_message *m = &ts->msg[0]; | 1011 | struct spi_message *m = &ts->msg[0]; |
| 1009 | struct spi_transfer *x = ts->xfer; | 1012 | struct spi_transfer *x = ts->xfer; |
| @@ -1201,33 +1204,107 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts, | |||
| 1201 | spi_message_add_tail(x, m); | 1204 | spi_message_add_tail(x, m); |
| 1202 | } | 1205 | } |
| 1203 | 1206 | ||
| 1207 | #ifdef CONFIG_OF | ||
| 1208 | static const struct of_device_id ads7846_dt_ids[] = { | ||
| 1209 | { .compatible = "ti,tsc2046", .data = (void *) 7846 }, | ||
| 1210 | { .compatible = "ti,ads7843", .data = (void *) 7843 }, | ||
| 1211 | { .compatible = "ti,ads7845", .data = (void *) 7845 }, | ||
| 1212 | { .compatible = "ti,ads7846", .data = (void *) 7846 }, | ||
| 1213 | { .compatible = "ti,ads7873", .data = (void *) 7873 }, | ||
| 1214 | { } | ||
| 1215 | }; | ||
| 1216 | MODULE_DEVICE_TABLE(of, ads7846_dt_ids); | ||
| 1217 | |||
| 1218 | static const struct ads7846_platform_data *ads7846_probe_dt(struct device *dev) | ||
| 1219 | { | ||
| 1220 | struct ads7846_platform_data *pdata; | ||
| 1221 | struct device_node *node = dev->of_node; | ||
| 1222 | const struct of_device_id *match; | ||
| 1223 | |||
| 1224 | if (!node) { | ||
| 1225 | dev_err(dev, "Device does not have associated DT data\n"); | ||
| 1226 | return ERR_PTR(-EINVAL); | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | match = of_match_device(ads7846_dt_ids, dev); | ||
| 1230 | if (!match) { | ||
| 1231 | dev_err(dev, "Unknown device model\n"); | ||
| 1232 | return ERR_PTR(-EINVAL); | ||
| 1233 | } | ||
| 1234 | |||
| 1235 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | ||
| 1236 | if (!pdata) | ||
| 1237 | return ERR_PTR(-ENOMEM); | ||
| 1238 | |||
| 1239 | pdata->model = (unsigned long)match->data; | ||
| 1240 | |||
| 1241 | of_property_read_u16(node, "ti,vref-delay-usecs", | ||
| 1242 | &pdata->vref_delay_usecs); | ||
| 1243 | of_property_read_u16(node, "ti,vref-mv", &pdata->vref_mv); | ||
| 1244 | pdata->keep_vref_on = of_property_read_bool(node, "ti,keep-vref-on"); | ||
| 1245 | |||
| 1246 | pdata->swap_xy = of_property_read_bool(node, "ti,swap-xy"); | ||
| 1247 | |||
| 1248 | of_property_read_u16(node, "ti,settle-delay-usec", | ||
| 1249 | &pdata->settle_delay_usecs); | ||
| 1250 | of_property_read_u16(node, "ti,penirq-recheck-delay-usecs", | ||
| 1251 | &pdata->penirq_recheck_delay_usecs); | ||
| 1252 | |||
| 1253 | of_property_read_u16(node, "ti,x-plate-ohms", &pdata->x_plate_ohms); | ||
| 1254 | of_property_read_u16(node, "ti,y-plate-ohms", &pdata->y_plate_ohms); | ||
| 1255 | |||
| 1256 | of_property_read_u16(node, "ti,x-min", &pdata->x_min); | ||
| 1257 | of_property_read_u16(node, "ti,y-min", &pdata->y_min); | ||
| 1258 | of_property_read_u16(node, "ti,x-max", &pdata->x_max); | ||
| 1259 | of_property_read_u16(node, "ti,y-max", &pdata->y_max); | ||
| 1260 | |||
| 1261 | of_property_read_u16(node, "ti,pressure-min", &pdata->pressure_min); | ||
| 1262 | of_property_read_u16(node, "ti,pressure-max", &pdata->pressure_max); | ||
| 1263 | |||
| 1264 | of_property_read_u16(node, "ti,debounce-max", &pdata->debounce_max); | ||
| 1265 | of_property_read_u16(node, "ti,debounce-tol", &pdata->debounce_tol); | ||
| 1266 | of_property_read_u16(node, "ti,debounce-rep", &pdata->debounce_rep); | ||
| 1267 | |||
| 1268 | of_property_read_u32(node, "ti,pendown-gpio-debounce", | ||
| 1269 | &pdata->gpio_pendown_debounce); | ||
| 1270 | |||
| 1271 | pdata->wakeup = of_property_read_bool(node, "linux,wakeup"); | ||
| 1272 | |||
| 1273 | pdata->gpio_pendown = of_get_named_gpio(dev->of_node, "pendown-gpio", 0); | ||
| 1274 | |||
| 1275 | return pdata; | ||
| 1276 | } | ||
| 1277 | #else | ||
| 1278 | static const struct ads7846_platform_data *ads7846_probe_dt(struct device *dev) | ||
| 1279 | { | ||
| 1280 | dev_err(dev, "no platform data defined\n"); | ||
| 1281 | return ERR_PTR(-EINVAL); | ||
| 1282 | } | ||
| 1283 | #endif | ||
| 1284 | |||
| 1204 | static int ads7846_probe(struct spi_device *spi) | 1285 | static int ads7846_probe(struct spi_device *spi) |
| 1205 | { | 1286 | { |
| 1287 | const struct ads7846_platform_data *pdata; | ||
| 1206 | struct ads7846 *ts; | 1288 | struct ads7846 *ts; |
| 1207 | struct ads7846_packet *packet; | 1289 | struct ads7846_packet *packet; |
| 1208 | struct input_dev *input_dev; | 1290 | struct input_dev *input_dev; |
| 1209 | struct ads7846_platform_data *pdata = spi->dev.platform_data; | ||
| 1210 | unsigned long irq_flags; | 1291 | unsigned long irq_flags; |
| 1211 | int err; | 1292 | int err; |
| 1212 | 1293 | ||
| 1213 | if (!spi->irq) { | 1294 | if (!spi->irq) { |
| 1214 | dev_dbg(&spi->dev, "no IRQ?\n"); | 1295 | dev_dbg(&spi->dev, "no IRQ?\n"); |
| 1215 | return -ENODEV; | 1296 | return -EINVAL; |
| 1216 | } | ||
| 1217 | |||
| 1218 | if (!pdata) { | ||
| 1219 | dev_dbg(&spi->dev, "no platform data?\n"); | ||
| 1220 | return -ENODEV; | ||
| 1221 | } | 1297 | } |
| 1222 | 1298 | ||
| 1223 | /* don't exceed max specified sample rate */ | 1299 | /* don't exceed max specified sample rate */ |
| 1224 | if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) { | 1300 | if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) { |
| 1225 | dev_dbg(&spi->dev, "f(sample) %d KHz?\n", | 1301 | dev_err(&spi->dev, "f(sample) %d KHz?\n", |
| 1226 | (spi->max_speed_hz/SAMPLE_BITS)/1000); | 1302 | (spi->max_speed_hz/SAMPLE_BITS)/1000); |
| 1227 | return -EINVAL; | 1303 | return -EINVAL; |
| 1228 | } | 1304 | } |
| 1229 | 1305 | ||
| 1230 | /* We'd set TX word size 8 bits and RX word size to 13 bits ... except | 1306 | /* |
| 1307 | * We'd set TX word size 8 bits and RX word size to 13 bits ... except | ||
| 1231 | * that even if the hardware can do that, the SPI controller driver | 1308 | * that even if the hardware can do that, the SPI controller driver |
| 1232 | * may not. So we stick to very-portable 8 bit words, both RX and TX. | 1309 | * may not. So we stick to very-portable 8 bit words, both RX and TX. |
| 1233 | */ | 1310 | */ |
| @@ -1250,17 +1327,25 @@ static int ads7846_probe(struct spi_device *spi) | |||
| 1250 | ts->packet = packet; | 1327 | ts->packet = packet; |
| 1251 | ts->spi = spi; | 1328 | ts->spi = spi; |
| 1252 | ts->input = input_dev; | 1329 | ts->input = input_dev; |
| 1253 | ts->vref_mv = pdata->vref_mv; | ||
| 1254 | ts->swap_xy = pdata->swap_xy; | ||
| 1255 | 1330 | ||
| 1256 | mutex_init(&ts->lock); | 1331 | mutex_init(&ts->lock); |
| 1257 | init_waitqueue_head(&ts->wait); | 1332 | init_waitqueue_head(&ts->wait); |
| 1258 | 1333 | ||
| 1334 | pdata = dev_get_platdata(&spi->dev); | ||
| 1335 | if (!pdata) { | ||
| 1336 | pdata = ads7846_probe_dt(&spi->dev); | ||
| 1337 | if (IS_ERR(pdata)) | ||
| 1338 | return PTR_ERR(pdata); | ||
| 1339 | } | ||
| 1340 | |||
| 1259 | ts->model = pdata->model ? : 7846; | 1341 | ts->model = pdata->model ? : 7846; |
| 1260 | ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; | 1342 | ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; |
| 1261 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; | 1343 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; |
| 1262 | ts->pressure_max = pdata->pressure_max ? : ~0; | 1344 | ts->pressure_max = pdata->pressure_max ? : ~0; |
| 1263 | 1345 | ||
| 1346 | ts->vref_mv = pdata->vref_mv; | ||
| 1347 | ts->swap_xy = pdata->swap_xy; | ||
| 1348 | |||
| 1264 | if (pdata->filter != NULL) { | 1349 | if (pdata->filter != NULL) { |
| 1265 | if (pdata->filter_init != NULL) { | 1350 | if (pdata->filter_init != NULL) { |
| 1266 | err = pdata->filter_init(pdata, &ts->filter_data); | 1351 | err = pdata->filter_init(pdata, &ts->filter_data); |
| @@ -1281,7 +1366,7 @@ static int ads7846_probe(struct spi_device *spi) | |||
| 1281 | ts->filter = ads7846_no_filter; | 1366 | ts->filter = ads7846_no_filter; |
| 1282 | } | 1367 | } |
| 1283 | 1368 | ||
| 1284 | err = ads7846_setup_pendown(spi, ts); | 1369 | err = ads7846_setup_pendown(spi, ts, pdata); |
| 1285 | if (err) | 1370 | if (err) |
| 1286 | goto err_cleanup_filter; | 1371 | goto err_cleanup_filter; |
| 1287 | 1372 | ||
| @@ -1370,6 +1455,13 @@ static int ads7846_probe(struct spi_device *spi) | |||
| 1370 | 1455 | ||
| 1371 | device_init_wakeup(&spi->dev, pdata->wakeup); | 1456 | device_init_wakeup(&spi->dev, pdata->wakeup); |
| 1372 | 1457 | ||
| 1458 | /* | ||
| 1459 | * If device does not carry platform data we must have allocated it | ||
| 1460 | * when parsing DT data. | ||
| 1461 | */ | ||
| 1462 | if (!dev_get_platdata(&spi->dev)) | ||
| 1463 | devm_kfree(&spi->dev, (void *)pdata); | ||
| 1464 | |||
| 1373 | return 0; | 1465 | return 0; |
| 1374 | 1466 | ||
| 1375 | err_remove_attr_group: | 1467 | err_remove_attr_group: |
| @@ -1437,6 +1529,7 @@ static struct spi_driver ads7846_driver = { | |||
| 1437 | .name = "ads7846", | 1529 | .name = "ads7846", |
| 1438 | .owner = THIS_MODULE, | 1530 | .owner = THIS_MODULE, |
| 1439 | .pm = &ads7846_pm, | 1531 | .pm = &ads7846_pm, |
| 1532 | .of_match_table = of_match_ptr(ads7846_dt_ids), | ||
| 1440 | }, | 1533 | }, |
| 1441 | .probe = ads7846_probe, | 1534 | .probe = ads7846_probe, |
| 1442 | .remove = ads7846_remove, | 1535 | .remove = ads7846_remove, |
