diff options
Diffstat (limited to 'drivers/input/touchscreen/ads7846.c')
-rw-r--r-- | drivers/input/touchscreen/ads7846.c | 208 |
1 files changed, 156 insertions, 52 deletions
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 634f6f6b9b13..16031933a8f6 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -68,6 +68,8 @@ struct ts_event { | |||
68 | u16 y; | 68 | u16 y; |
69 | u16 z1, z2; | 69 | u16 z1, z2; |
70 | int ignore; | 70 | int ignore; |
71 | u8 x_buf[3]; | ||
72 | u8 y_buf[3]; | ||
71 | }; | 73 | }; |
72 | 74 | ||
73 | /* | 75 | /* |
@@ -79,6 +81,8 @@ struct ads7846_packet { | |||
79 | u8 read_x, read_y, read_z1, read_z2, pwrdown; | 81 | u8 read_x, read_y, read_z1, read_z2, pwrdown; |
80 | u16 dummy; /* for the pwrdown read */ | 82 | u16 dummy; /* for the pwrdown read */ |
81 | struct ts_event tc; | 83 | struct ts_event tc; |
84 | /* for ads7845 with mpc5121 psc spi we use 3-byte buffers */ | ||
85 | u8 read_x_cmd[3], read_y_cmd[3], pwrdown_cmd[3]; | ||
82 | }; | 86 | }; |
83 | 87 | ||
84 | struct ads7846 { | 88 | struct ads7846 { |
@@ -207,6 +211,14 @@ struct ser_req { | |||
207 | struct spi_transfer xfer[6]; | 211 | struct spi_transfer xfer[6]; |
208 | }; | 212 | }; |
209 | 213 | ||
214 | struct ads7845_ser_req { | ||
215 | u8 command[3]; | ||
216 | u8 pwrdown[3]; | ||
217 | u8 sample[3]; | ||
218 | struct spi_message msg; | ||
219 | struct spi_transfer xfer[2]; | ||
220 | }; | ||
221 | |||
210 | static void ads7846_enable(struct ads7846 *ts); | 222 | static void ads7846_enable(struct ads7846 *ts); |
211 | static void ads7846_disable(struct ads7846 *ts); | 223 | static void ads7846_disable(struct ads7846 *ts); |
212 | 224 | ||
@@ -287,6 +299,41 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
287 | return status; | 299 | return status; |
288 | } | 300 | } |
289 | 301 | ||
302 | static int ads7845_read12_ser(struct device *dev, unsigned command) | ||
303 | { | ||
304 | struct spi_device *spi = to_spi_device(dev); | ||
305 | struct ads7846 *ts = dev_get_drvdata(dev); | ||
306 | struct ads7845_ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); | ||
307 | int status; | ||
308 | |||
309 | if (!req) | ||
310 | return -ENOMEM; | ||
311 | |||
312 | spi_message_init(&req->msg); | ||
313 | |||
314 | req->command[0] = (u8) command; | ||
315 | req->xfer[0].tx_buf = req->command; | ||
316 | req->xfer[0].rx_buf = req->sample; | ||
317 | req->xfer[0].len = 3; | ||
318 | spi_message_add_tail(&req->xfer[0], &req->msg); | ||
319 | |||
320 | ts->irq_disabled = 1; | ||
321 | disable_irq(spi->irq); | ||
322 | status = spi_sync(spi, &req->msg); | ||
323 | ts->irq_disabled = 0; | ||
324 | enable_irq(spi->irq); | ||
325 | |||
326 | if (status == 0) { | ||
327 | /* BE12 value, then padding */ | ||
328 | status = be16_to_cpu(*((u16 *)&req->sample[1])); | ||
329 | status = status >> 3; | ||
330 | status &= 0x0fff; | ||
331 | } | ||
332 | |||
333 | kfree(req); | ||
334 | return status; | ||
335 | } | ||
336 | |||
290 | #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) | 337 | #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) |
291 | 338 | ||
292 | #define SHOW(name, var, adjust) static ssize_t \ | 339 | #define SHOW(name, var, adjust) static ssize_t \ |
@@ -540,10 +587,17 @@ static void ads7846_rx(void *ads) | |||
540 | /* ads7846_rx_val() did in-place conversion (including byteswap) from | 587 | /* ads7846_rx_val() did in-place conversion (including byteswap) from |
541 | * on-the-wire format as part of debouncing to get stable readings. | 588 | * on-the-wire format as part of debouncing to get stable readings. |
542 | */ | 589 | */ |
543 | x = packet->tc.x; | 590 | if (ts->model == 7845) { |
544 | y = packet->tc.y; | 591 | x = *(u16 *)packet->tc.x_buf; |
545 | z1 = packet->tc.z1; | 592 | y = *(u16 *)packet->tc.y_buf; |
546 | z2 = packet->tc.z2; | 593 | z1 = 0; |
594 | z2 = 0; | ||
595 | } else { | ||
596 | x = packet->tc.x; | ||
597 | y = packet->tc.y; | ||
598 | z1 = packet->tc.z1; | ||
599 | z2 = packet->tc.z2; | ||
600 | } | ||
547 | 601 | ||
548 | /* range filtering */ | 602 | /* range filtering */ |
549 | if (x == MAX_12BIT) | 603 | if (x == MAX_12BIT) |
@@ -551,6 +605,12 @@ static void ads7846_rx(void *ads) | |||
551 | 605 | ||
552 | if (ts->model == 7843) { | 606 | if (ts->model == 7843) { |
553 | Rt = ts->pressure_max / 2; | 607 | Rt = ts->pressure_max / 2; |
608 | } else if (ts->model == 7845) { | ||
609 | if (get_pendown_state(ts)) | ||
610 | Rt = ts->pressure_max / 2; | ||
611 | else | ||
612 | Rt = 0; | ||
613 | dev_vdbg(&ts->spi->dev, "x/y: %d/%d, PD %d\n", x, y, Rt); | ||
554 | } else if (likely(x && z1)) { | 614 | } else if (likely(x && z1)) { |
555 | /* compute touch pressure resistance using equation #2 */ | 615 | /* compute touch pressure resistance using equation #2 */ |
556 | Rt = z2; | 616 | Rt = z2; |
@@ -671,10 +731,14 @@ static void ads7846_rx_val(void *ads) | |||
671 | m = &ts->msg[ts->msg_idx]; | 731 | m = &ts->msg[ts->msg_idx]; |
672 | t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list); | 732 | t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list); |
673 | 733 | ||
674 | /* adjust: on-wire is a must-ignore bit, a BE12 value, then padding; | 734 | if (ts->model == 7845) { |
675 | * built from two 8 bit values written msb-first. | 735 | val = be16_to_cpup((__be16 *)&(((char*)t->rx_buf)[1])) >> 3; |
676 | */ | 736 | } else { |
677 | val = be16_to_cpup((__be16 *)t->rx_buf) >> 3; | 737 | /* adjust: on-wire is a must-ignore bit, a BE12 value, then |
738 | * padding; built from two 8 bit values written msb-first. | ||
739 | */ | ||
740 | val = be16_to_cpup((__be16 *)t->rx_buf) >> 3; | ||
741 | } | ||
678 | 742 | ||
679 | action = ts->filter(ts->filter_data, ts->msg_idx, &val); | 743 | action = ts->filter(ts->filter_data, ts->msg_idx, &val); |
680 | switch (action) { | 744 | switch (action) { |
@@ -878,14 +942,15 @@ static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts) | |||
878 | 942 | ||
879 | static int __devinit ads7846_probe(struct spi_device *spi) | 943 | static int __devinit ads7846_probe(struct spi_device *spi) |
880 | { | 944 | { |
881 | struct ads7846 *ts; | 945 | struct ads7846 *ts; |
882 | struct ads7846_packet *packet; | 946 | struct ads7846_packet *packet; |
883 | struct input_dev *input_dev; | 947 | struct input_dev *input_dev; |
884 | struct ads7846_platform_data *pdata = spi->dev.platform_data; | 948 | const struct ads7846_platform_data *pdata = spi->dev.platform_data; |
885 | struct spi_message *m; | 949 | struct spi_message *m; |
886 | struct spi_transfer *x; | 950 | struct spi_transfer *x; |
887 | int vref; | 951 | unsigned long irq_flags; |
888 | int err; | 952 | int vref; |
953 | int err; | ||
889 | 954 | ||
890 | if (!spi->irq) { | 955 | if (!spi->irq) { |
891 | dev_dbg(&spi->dev, "no IRQ?\n"); | 956 | dev_dbg(&spi->dev, "no IRQ?\n"); |
@@ -1008,16 +1073,26 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1008 | 1073 | ||
1009 | spi_message_init(m); | 1074 | spi_message_init(m); |
1010 | 1075 | ||
1011 | /* y- still on; turn on only y+ (and ADC) */ | 1076 | if (ts->model == 7845) { |
1012 | packet->read_y = READ_Y(vref); | 1077 | packet->read_y_cmd[0] = READ_Y(vref); |
1013 | x->tx_buf = &packet->read_y; | 1078 | packet->read_y_cmd[1] = 0; |
1014 | x->len = 1; | 1079 | packet->read_y_cmd[2] = 0; |
1015 | spi_message_add_tail(x, m); | 1080 | x->tx_buf = &packet->read_y_cmd[0]; |
1081 | x->rx_buf = &packet->tc.y_buf[0]; | ||
1082 | x->len = 3; | ||
1083 | spi_message_add_tail(x, m); | ||
1084 | } else { | ||
1085 | /* y- still on; turn on only y+ (and ADC) */ | ||
1086 | packet->read_y = READ_Y(vref); | ||
1087 | x->tx_buf = &packet->read_y; | ||
1088 | x->len = 1; | ||
1089 | spi_message_add_tail(x, m); | ||
1016 | 1090 | ||
1017 | x++; | 1091 | x++; |
1018 | x->rx_buf = &packet->tc.y; | 1092 | x->rx_buf = &packet->tc.y; |
1019 | x->len = 2; | 1093 | x->len = 2; |
1020 | spi_message_add_tail(x, m); | 1094 | spi_message_add_tail(x, m); |
1095 | } | ||
1021 | 1096 | ||
1022 | /* the first sample after switching drivers can be low quality; | 1097 | /* the first sample after switching drivers can be low quality; |
1023 | * optionally discard it, using a second one after the signals | 1098 | * optionally discard it, using a second one after the signals |
@@ -1043,17 +1118,28 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1043 | m++; | 1118 | m++; |
1044 | spi_message_init(m); | 1119 | spi_message_init(m); |
1045 | 1120 | ||
1046 | /* turn y- off, x+ on, then leave in lowpower */ | 1121 | if (ts->model == 7845) { |
1047 | x++; | 1122 | x++; |
1048 | packet->read_x = READ_X(vref); | 1123 | packet->read_x_cmd[0] = READ_X(vref); |
1049 | x->tx_buf = &packet->read_x; | 1124 | packet->read_x_cmd[1] = 0; |
1050 | x->len = 1; | 1125 | packet->read_x_cmd[2] = 0; |
1051 | spi_message_add_tail(x, m); | 1126 | x->tx_buf = &packet->read_x_cmd[0]; |
1127 | x->rx_buf = &packet->tc.x_buf[0]; | ||
1128 | x->len = 3; | ||
1129 | spi_message_add_tail(x, m); | ||
1130 | } else { | ||
1131 | /* turn y- off, x+ on, then leave in lowpower */ | ||
1132 | x++; | ||
1133 | packet->read_x = READ_X(vref); | ||
1134 | x->tx_buf = &packet->read_x; | ||
1135 | x->len = 1; | ||
1136 | spi_message_add_tail(x, m); | ||
1052 | 1137 | ||
1053 | x++; | 1138 | x++; |
1054 | x->rx_buf = &packet->tc.x; | 1139 | x->rx_buf = &packet->tc.x; |
1055 | x->len = 2; | 1140 | x->len = 2; |
1056 | spi_message_add_tail(x, m); | 1141 | spi_message_add_tail(x, m); |
1142 | } | ||
1057 | 1143 | ||
1058 | /* ... maybe discard first sample ... */ | 1144 | /* ... maybe discard first sample ... */ |
1059 | if (pdata->settle_delay_usecs) { | 1145 | if (pdata->settle_delay_usecs) { |
@@ -1144,15 +1230,25 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1144 | m++; | 1230 | m++; |
1145 | spi_message_init(m); | 1231 | spi_message_init(m); |
1146 | 1232 | ||
1147 | x++; | 1233 | if (ts->model == 7845) { |
1148 | packet->pwrdown = PWRDOWN; | 1234 | x++; |
1149 | x->tx_buf = &packet->pwrdown; | 1235 | packet->pwrdown_cmd[0] = PWRDOWN; |
1150 | x->len = 1; | 1236 | packet->pwrdown_cmd[1] = 0; |
1151 | spi_message_add_tail(x, m); | 1237 | packet->pwrdown_cmd[2] = 0; |
1238 | x->tx_buf = &packet->pwrdown_cmd[0]; | ||
1239 | x->len = 3; | ||
1240 | } else { | ||
1241 | x++; | ||
1242 | packet->pwrdown = PWRDOWN; | ||
1243 | x->tx_buf = &packet->pwrdown; | ||
1244 | x->len = 1; | ||
1245 | spi_message_add_tail(x, m); | ||
1246 | |||
1247 | x++; | ||
1248 | x->rx_buf = &packet->dummy; | ||
1249 | x->len = 2; | ||
1250 | } | ||
1152 | 1251 | ||
1153 | x++; | ||
1154 | x->rx_buf = &packet->dummy; | ||
1155 | x->len = 2; | ||
1156 | CS_CHANGE(*x); | 1252 | CS_CHANGE(*x); |
1157 | spi_message_add_tail(x, m); | 1253 | spi_message_add_tail(x, m); |
1158 | 1254 | ||
@@ -1164,7 +1260,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1164 | ts->reg = regulator_get(&spi->dev, "vcc"); | 1260 | ts->reg = regulator_get(&spi->dev, "vcc"); |
1165 | if (IS_ERR(ts->reg)) { | 1261 | if (IS_ERR(ts->reg)) { |
1166 | err = PTR_ERR(ts->reg); | 1262 | err = PTR_ERR(ts->reg); |
1167 | dev_err(&spi->dev, "unable to get regulator: %ld\n", err); | 1263 | dev_err(&spi->dev, "unable to get regulator: %d\n", err); |
1168 | goto err_free_gpio; | 1264 | goto err_free_gpio; |
1169 | } | 1265 | } |
1170 | 1266 | ||
@@ -1174,17 +1270,22 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1174 | goto err_put_regulator; | 1270 | goto err_put_regulator; |
1175 | } | 1271 | } |
1176 | 1272 | ||
1177 | if (request_irq(spi->irq, ads7846_irq, IRQF_TRIGGER_FALLING, | 1273 | irq_flags = pdata->irq_flags ? : IRQF_TRIGGER_FALLING; |
1178 | spi->dev.driver->name, ts)) { | 1274 | |
1275 | err = request_irq(spi->irq, ads7846_irq, irq_flags, | ||
1276 | spi->dev.driver->name, ts); | ||
1277 | |||
1278 | if (err && !pdata->irq_flags) { | ||
1179 | dev_info(&spi->dev, | 1279 | dev_info(&spi->dev, |
1180 | "trying pin change workaround on irq %d\n", spi->irq); | 1280 | "trying pin change workaround on irq %d\n", spi->irq); |
1181 | err = request_irq(spi->irq, ads7846_irq, | 1281 | err = request_irq(spi->irq, ads7846_irq, |
1182 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | 1282 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, |
1183 | spi->dev.driver->name, ts); | 1283 | spi->dev.driver->name, ts); |
1184 | if (err) { | 1284 | } |
1185 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); | 1285 | |
1186 | goto err_disable_regulator; | 1286 | if (err) { |
1187 | } | 1287 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); |
1288 | goto err_disable_regulator; | ||
1188 | } | 1289 | } |
1189 | 1290 | ||
1190 | err = ads784x_hwmon_register(spi, ts); | 1291 | err = ads784x_hwmon_register(spi, ts); |
@@ -1196,8 +1297,11 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1196 | /* take a first sample, leaving nPENIRQ active and vREF off; avoid | 1297 | /* take a first sample, leaving nPENIRQ active and vREF off; avoid |
1197 | * the touchscreen, in case it's not connected. | 1298 | * the touchscreen, in case it's not connected. |
1198 | */ | 1299 | */ |
1199 | (void) ads7846_read12_ser(&spi->dev, | 1300 | if (ts->model == 7845) |
1200 | READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); | 1301 | ads7845_read12_ser(&spi->dev, PWRDOWN); |
1302 | else | ||
1303 | (void) ads7846_read12_ser(&spi->dev, | ||
1304 | READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); | ||
1201 | 1305 | ||
1202 | err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group); | 1306 | err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group); |
1203 | if (err) | 1307 | if (err) |