diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-13 21:05:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-13 21:05:13 -0400 |
commit | 18fb38e2f58ff7a66e30cbb71af81425edf1c9a1 (patch) | |
tree | 8ff2cc5b0d1a11c87a0e2576d6fe863b87faf69a | |
parent | be9c6d9169705504296bdb42ffec8f406691d99f (diff) | |
parent | 88ce3c3ca3df754e8a2a63b01c38bd1667fcae70 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull second round of input updates from Dmitry Torokhov:
"An update to Elantech driver to support hardware v7, fix to the new
cyttsp4 driver to use proper addressing, ads7846 device tree support
and nspire-keypad got a small cleanup."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
Input: nspire-keypad - replace magic offset with define
Input: elantech - fix for newer hardware versions (v7)
Input: cyttsp4 - use 16bit address for I2C/SPI communication
Input: ads7846 - add device tree bindings
Input: ads7846 - make sure we do not change platform data
-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 | ||||
-rw-r--r-- | drivers/input/touchscreen/cyttsp4_core.h | 12 | ||||
-rw-r--r-- | drivers/input/touchscreen/cyttsp4_spi.c | 20 | ||||
-rw-r--r-- | drivers/input/touchscreen/cyttsp_core.h | 8 | ||||
-rw-r--r-- | drivers/input/touchscreen/cyttsp_i2c_common.c | 30 | ||||
-rw-r--r-- | drivers/input/touchscreen/cyttsp_spi.c | 6 |
9 files changed, 253 insertions, 56 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, |
diff --git a/drivers/input/touchscreen/cyttsp4_core.h b/drivers/input/touchscreen/cyttsp4_core.h index 86a254354136..8e0d4d490b20 100644 --- a/drivers/input/touchscreen/cyttsp4_core.h +++ b/drivers/input/touchscreen/cyttsp4_core.h | |||
@@ -369,9 +369,9 @@ struct cyttsp4 { | |||
369 | 369 | ||
370 | struct cyttsp4_bus_ops { | 370 | struct cyttsp4_bus_ops { |
371 | u16 bustype; | 371 | u16 bustype; |
372 | int (*write)(struct device *dev, u8 *xfer_buf, u8 addr, u8 length, | 372 | int (*write)(struct device *dev, u8 *xfer_buf, u16 addr, u8 length, |
373 | const void *values); | 373 | const void *values); |
374 | int (*read)(struct device *dev, u8 *xfer_buf, u8 addr, u8 length, | 374 | int (*read)(struct device *dev, u8 *xfer_buf, u16 addr, u8 length, |
375 | void *values); | 375 | void *values); |
376 | }; | 376 | }; |
377 | 377 | ||
@@ -448,13 +448,13 @@ enum cyttsp4_event_id { | |||
448 | /* y-axis, 0:origin is on top side of panel, 1: bottom */ | 448 | /* y-axis, 0:origin is on top side of panel, 1: bottom */ |
449 | #define CY_PCFG_ORIGIN_Y_MASK 0x80 | 449 | #define CY_PCFG_ORIGIN_Y_MASK 0x80 |
450 | 450 | ||
451 | static inline int cyttsp4_adap_read(struct cyttsp4 *ts, u8 addr, int size, | 451 | static inline int cyttsp4_adap_read(struct cyttsp4 *ts, u16 addr, int size, |
452 | void *buf) | 452 | void *buf) |
453 | { | 453 | { |
454 | return ts->bus_ops->read(ts->dev, ts->xfer_buf, addr, size, buf); | 454 | return ts->bus_ops->read(ts->dev, ts->xfer_buf, addr, size, buf); |
455 | } | 455 | } |
456 | 456 | ||
457 | static inline int cyttsp4_adap_write(struct cyttsp4 *ts, u8 addr, int size, | 457 | static inline int cyttsp4_adap_write(struct cyttsp4 *ts, u16 addr, int size, |
458 | const void *buf) | 458 | const void *buf) |
459 | { | 459 | { |
460 | return ts->bus_ops->write(ts->dev, ts->xfer_buf, addr, size, buf); | 460 | return ts->bus_ops->write(ts->dev, ts->xfer_buf, addr, size, buf); |
@@ -463,9 +463,9 @@ static inline int cyttsp4_adap_write(struct cyttsp4 *ts, u8 addr, int size, | |||
463 | extern struct cyttsp4 *cyttsp4_probe(const struct cyttsp4_bus_ops *ops, | 463 | extern struct cyttsp4 *cyttsp4_probe(const struct cyttsp4_bus_ops *ops, |
464 | struct device *dev, u16 irq, size_t xfer_buf_size); | 464 | struct device *dev, u16 irq, size_t xfer_buf_size); |
465 | extern int cyttsp4_remove(struct cyttsp4 *ts); | 465 | extern int cyttsp4_remove(struct cyttsp4 *ts); |
466 | int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, u8 addr, | 466 | int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, u16 addr, |
467 | u8 length, const void *values); | 467 | u8 length, const void *values); |
468 | int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, u8 addr, | 468 | int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, u16 addr, |
469 | u8 length, void *values); | 469 | u8 length, void *values); |
470 | extern const struct dev_pm_ops cyttsp4_pm_ops; | 470 | extern const struct dev_pm_ops cyttsp4_pm_ops; |
471 | 471 | ||
diff --git a/drivers/input/touchscreen/cyttsp4_spi.c b/drivers/input/touchscreen/cyttsp4_spi.c index f8f891bead34..a71e1141d638 100644 --- a/drivers/input/touchscreen/cyttsp4_spi.c +++ b/drivers/input/touchscreen/cyttsp4_spi.c | |||
@@ -44,7 +44,7 @@ | |||
44 | #define CY_SPI_DATA_BUF_SIZE (CY_SPI_CMD_BYTES + CY_SPI_DATA_SIZE) | 44 | #define CY_SPI_DATA_BUF_SIZE (CY_SPI_CMD_BYTES + CY_SPI_DATA_SIZE) |
45 | 45 | ||
46 | static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf, | 46 | static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf, |
47 | u8 op, u8 reg, u8 *buf, int length) | 47 | u8 op, u16 reg, u8 *buf, int length) |
48 | { | 48 | { |
49 | struct spi_device *spi = to_spi_device(dev); | 49 | struct spi_device *spi = to_spi_device(dev); |
50 | struct spi_message msg; | 50 | struct spi_message msg; |
@@ -63,14 +63,12 @@ static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf, | |||
63 | memset(wr_buf, 0, CY_SPI_DATA_BUF_SIZE); | 63 | memset(wr_buf, 0, CY_SPI_DATA_BUF_SIZE); |
64 | memset(rd_buf, 0, CY_SPI_CMD_BYTES); | 64 | memset(rd_buf, 0, CY_SPI_CMD_BYTES); |
65 | 65 | ||
66 | if (reg > 255) | 66 | wr_buf[0] = op + (((reg >> 8) & 0x1) ? CY_SPI_A8_BIT : 0); |
67 | wr_buf[0] = op + CY_SPI_A8_BIT; | 67 | if (op == CY_SPI_WR_OP) { |
68 | else | 68 | wr_buf[1] = reg & 0xFF; |
69 | wr_buf[0] = op; | 69 | if (length > 0) |
70 | if (op == CY_SPI_WR_OP) | 70 | memcpy(wr_buf + CY_SPI_CMD_BYTES, buf, length); |
71 | wr_buf[1] = reg % 256; | 71 | } |
72 | if (op == CY_SPI_WR_OP && length > 0) | ||
73 | memcpy(wr_buf + CY_SPI_CMD_BYTES, buf, length); | ||
74 | 72 | ||
75 | memset(xfer, 0, sizeof(xfer)); | 73 | memset(xfer, 0, sizeof(xfer)); |
76 | spi_message_init(&msg); | 74 | spi_message_init(&msg); |
@@ -130,7 +128,7 @@ static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf, | |||
130 | } | 128 | } |
131 | 129 | ||
132 | static int cyttsp_spi_read_block_data(struct device *dev, u8 *xfer_buf, | 130 | static int cyttsp_spi_read_block_data(struct device *dev, u8 *xfer_buf, |
133 | u8 addr, u8 length, void *data) | 131 | u16 addr, u8 length, void *data) |
134 | { | 132 | { |
135 | int rc; | 133 | int rc; |
136 | 134 | ||
@@ -143,7 +141,7 @@ static int cyttsp_spi_read_block_data(struct device *dev, u8 *xfer_buf, | |||
143 | } | 141 | } |
144 | 142 | ||
145 | static int cyttsp_spi_write_block_data(struct device *dev, u8 *xfer_buf, | 143 | static int cyttsp_spi_write_block_data(struct device *dev, u8 *xfer_buf, |
146 | u8 addr, u8 length, const void *data) | 144 | u16 addr, u8 length, const void *data) |
147 | { | 145 | { |
148 | return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_WR_OP, addr, (void *)data, | 146 | return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_WR_OP, addr, (void *)data, |
149 | length); | 147 | length); |
diff --git a/drivers/input/touchscreen/cyttsp_core.h b/drivers/input/touchscreen/cyttsp_core.h index 0cf564a79fb5..07074110a902 100644 --- a/drivers/input/touchscreen/cyttsp_core.h +++ b/drivers/input/touchscreen/cyttsp_core.h | |||
@@ -112,9 +112,9 @@ struct cyttsp; | |||
112 | 112 | ||
113 | struct cyttsp_bus_ops { | 113 | struct cyttsp_bus_ops { |
114 | u16 bustype; | 114 | u16 bustype; |
115 | int (*write)(struct device *dev, u8 *xfer_buf, u8 addr, u8 length, | 115 | int (*write)(struct device *dev, u8 *xfer_buf, u16 addr, u8 length, |
116 | const void *values); | 116 | const void *values); |
117 | int (*read)(struct device *dev, u8 *xfer_buf, u8 addr, u8 length, | 117 | int (*read)(struct device *dev, u8 *xfer_buf, u16 addr, u8 length, |
118 | void *values); | 118 | void *values); |
119 | }; | 119 | }; |
120 | 120 | ||
@@ -145,9 +145,9 @@ struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops, | |||
145 | struct device *dev, int irq, size_t xfer_buf_size); | 145 | struct device *dev, int irq, size_t xfer_buf_size); |
146 | void cyttsp_remove(struct cyttsp *ts); | 146 | void cyttsp_remove(struct cyttsp *ts); |
147 | 147 | ||
148 | int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, u8 addr, | 148 | int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, u16 addr, |
149 | u8 length, const void *values); | 149 | u8 length, const void *values); |
150 | int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, u8 addr, | 150 | int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, u16 addr, |
151 | u8 length, void *values); | 151 | u8 length, void *values); |
152 | extern const struct dev_pm_ops cyttsp_pm_ops; | 152 | extern const struct dev_pm_ops cyttsp_pm_ops; |
153 | 153 | ||
diff --git a/drivers/input/touchscreen/cyttsp_i2c_common.c b/drivers/input/touchscreen/cyttsp_i2c_common.c index 07c553fbcef2..1d7b6f154168 100644 --- a/drivers/input/touchscreen/cyttsp_i2c_common.c +++ b/drivers/input/touchscreen/cyttsp_i2c_common.c | |||
@@ -32,18 +32,20 @@ | |||
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | 33 | ||
34 | int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, | 34 | int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, |
35 | u8 addr, u8 length, void *values) | 35 | u16 addr, u8 length, void *values) |
36 | { | 36 | { |
37 | struct i2c_client *client = to_i2c_client(dev); | 37 | struct i2c_client *client = to_i2c_client(dev); |
38 | u8 client_addr = client->addr | ((addr >> 8) & 0x1); | ||
39 | u8 addr_lo = addr & 0xFF; | ||
38 | struct i2c_msg msgs[] = { | 40 | struct i2c_msg msgs[] = { |
39 | { | 41 | { |
40 | .addr = client->addr, | 42 | .addr = client_addr, |
41 | .flags = 0, | 43 | .flags = 0, |
42 | .len = 1, | 44 | .len = 1, |
43 | .buf = &addr, | 45 | .buf = &addr_lo, |
44 | }, | 46 | }, |
45 | { | 47 | { |
46 | .addr = client->addr, | 48 | .addr = client_addr, |
47 | .flags = I2C_M_RD, | 49 | .flags = I2C_M_RD, |
48 | .len = length, | 50 | .len = length, |
49 | .buf = values, | 51 | .buf = values, |
@@ -60,17 +62,29 @@ int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, | |||
60 | EXPORT_SYMBOL_GPL(cyttsp_i2c_read_block_data); | 62 | EXPORT_SYMBOL_GPL(cyttsp_i2c_read_block_data); |
61 | 63 | ||
62 | int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, | 64 | int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, |
63 | u8 addr, u8 length, const void *values) | 65 | u16 addr, u8 length, const void *values) |
64 | { | 66 | { |
65 | struct i2c_client *client = to_i2c_client(dev); | 67 | struct i2c_client *client = to_i2c_client(dev); |
68 | u8 client_addr = client->addr | ((addr >> 8) & 0x1); | ||
69 | u8 addr_lo = addr & 0xFF; | ||
70 | struct i2c_msg msgs[] = { | ||
71 | { | ||
72 | .addr = client_addr, | ||
73 | .flags = 0, | ||
74 | .len = length + 1, | ||
75 | .buf = xfer_buf, | ||
76 | }, | ||
77 | }; | ||
66 | int retval; | 78 | int retval; |
67 | 79 | ||
68 | xfer_buf[0] = addr; | 80 | xfer_buf[0] = addr_lo; |
69 | memcpy(&xfer_buf[1], values, length); | 81 | memcpy(&xfer_buf[1], values, length); |
70 | 82 | ||
71 | retval = i2c_master_send(client, xfer_buf, length + 1); | 83 | retval = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); |
84 | if (retval < 0) | ||
85 | return retval; | ||
72 | 86 | ||
73 | return retval < 0 ? retval : 0; | 87 | return retval != ARRAY_SIZE(msgs) ? -EIO : 0; |
74 | } | 88 | } |
75 | EXPORT_SYMBOL_GPL(cyttsp_i2c_write_block_data); | 89 | EXPORT_SYMBOL_GPL(cyttsp_i2c_write_block_data); |
76 | 90 | ||
diff --git a/drivers/input/touchscreen/cyttsp_spi.c b/drivers/input/touchscreen/cyttsp_spi.c index 1df625337b84..4728bcb1916c 100644 --- a/drivers/input/touchscreen/cyttsp_spi.c +++ b/drivers/input/touchscreen/cyttsp_spi.c | |||
@@ -41,7 +41,7 @@ | |||
41 | #define CY_SPI_BITS_PER_WORD 8 | 41 | #define CY_SPI_BITS_PER_WORD 8 |
42 | 42 | ||
43 | static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf, | 43 | static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf, |
44 | u8 op, u8 reg, u8 *buf, int length) | 44 | u8 op, u16 reg, u8 *buf, int length) |
45 | { | 45 | { |
46 | struct spi_device *spi = to_spi_device(dev); | 46 | struct spi_device *spi = to_spi_device(dev); |
47 | struct spi_message msg; | 47 | struct spi_message msg; |
@@ -126,14 +126,14 @@ static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf, | |||
126 | } | 126 | } |
127 | 127 | ||
128 | static int cyttsp_spi_read_block_data(struct device *dev, u8 *xfer_buf, | 128 | static int cyttsp_spi_read_block_data(struct device *dev, u8 *xfer_buf, |
129 | u8 addr, u8 length, void *data) | 129 | u16 addr, u8 length, void *data) |
130 | { | 130 | { |
131 | return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_RD_OP, addr, data, | 131 | return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_RD_OP, addr, data, |
132 | length); | 132 | length); |
133 | } | 133 | } |
134 | 134 | ||
135 | static int cyttsp_spi_write_block_data(struct device *dev, u8 *xfer_buf, | 135 | static int cyttsp_spi_write_block_data(struct device *dev, u8 *xfer_buf, |
136 | u8 addr, u8 length, const void *data) | 136 | u16 addr, u8 length, const void *data) |
137 | { | 137 | { |
138 | return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_WR_OP, addr, (void *)data, | 138 | return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_WR_OP, addr, (void *)data, |
139 | length); | 139 | length); |