diff options
| -rw-r--r-- | drivers/char/keyboard.c | 38 | ||||
| -rw-r--r-- | drivers/input/evdev.c | 21 | ||||
| -rw-r--r-- | drivers/input/input.c | 11 | ||||
| -rw-r--r-- | drivers/input/keyboard/spitzkbd.c | 4 | ||||
| -rw-r--r-- | drivers/input/misc/wistron_btns.c | 30 | ||||
| -rw-r--r-- | drivers/input/mouse/psmouse-base.c | 4 | ||||
| -rw-r--r-- | drivers/input/touchscreen/ads7846.c | 414 | ||||
| -rw-r--r-- | include/linux/input.h | 109 | ||||
| -rw-r--r-- | include/linux/mod_devicetable.h | 48 | ||||
| -rw-r--r-- | include/linux/spi/ads7846.h | 7 | ||||
| -rw-r--r-- | scripts/mod/file2alias.c | 36 |
11 files changed, 555 insertions, 167 deletions
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 935670a3cd98..5755b7e5f187 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
| @@ -860,9 +860,32 @@ static void k_slock(struct vc_data *vc, unsigned char value, char up_flag, struc | |||
| 860 | } | 860 | } |
| 861 | 861 | ||
| 862 | /* by default, 300ms interval for combination release */ | 862 | /* by default, 300ms interval for combination release */ |
| 863 | static long brl_timeout = 300; | 863 | static unsigned brl_timeout = 300; |
| 864 | MODULE_PARM_DESC(brl_timeout, "Braille keys release delay in ms (0 for combination on first release, < 0 for dead characters)"); | 864 | MODULE_PARM_DESC(brl_timeout, "Braille keys release delay in ms (0 for commit on first key release)"); |
| 865 | module_param(brl_timeout, long, 0644); | 865 | module_param(brl_timeout, uint, 0644); |
| 866 | |||
| 867 | static unsigned brl_nbchords = 1; | ||
| 868 | MODULE_PARM_DESC(brl_nbchords, "Number of chords that produce a braille pattern (0 for dead chords)"); | ||
| 869 | module_param(brl_nbchords, uint, 0644); | ||
| 870 | |||
| 871 | static void k_brlcommit(struct vc_data *vc, unsigned int pattern, char up_flag, struct pt_regs *regs) | ||
| 872 | { | ||
| 873 | static unsigned long chords; | ||
| 874 | static unsigned committed; | ||
| 875 | |||
| 876 | if (!brl_nbchords) | ||
| 877 | k_deadunicode(vc, BRL_UC_ROW | pattern, up_flag, regs); | ||
| 878 | else { | ||
| 879 | committed |= pattern; | ||
| 880 | chords++; | ||
| 881 | if (chords == brl_nbchords) { | ||
| 882 | k_unicode(vc, BRL_UC_ROW | committed, up_flag, regs); | ||
| 883 | chords = 0; | ||
| 884 | committed = 0; | ||
| 885 | } | ||
| 886 | } | ||
| 887 | } | ||
| 888 | |||
| 866 | static void k_brl(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) | 889 | static void k_brl(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) |
| 867 | { | 890 | { |
| 868 | static unsigned pressed,committing; | 891 | static unsigned pressed,committing; |
| @@ -882,11 +905,6 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag, struct | |||
| 882 | if (value > 8) | 905 | if (value > 8) |
| 883 | return; | 906 | return; |
| 884 | 907 | ||
| 885 | if (brl_timeout < 0) { | ||
| 886 | k_deadunicode(vc, BRL_UC_ROW | (1 << (value - 1)), up_flag, regs); | ||
| 887 | return; | ||
| 888 | } | ||
| 889 | |||
| 890 | if (up_flag) { | 908 | if (up_flag) { |
| 891 | if (brl_timeout) { | 909 | if (brl_timeout) { |
| 892 | if (!committing || | 910 | if (!committing || |
| @@ -897,13 +915,13 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag, struct | |||
| 897 | pressed &= ~(1 << (value - 1)); | 915 | pressed &= ~(1 << (value - 1)); |
| 898 | if (!pressed) { | 916 | if (!pressed) { |
| 899 | if (committing) { | 917 | if (committing) { |
| 900 | k_unicode(vc, BRL_UC_ROW | committing, 0, regs); | 918 | k_brlcommit(vc, committing, 0, regs); |
| 901 | committing = 0; | 919 | committing = 0; |
| 902 | } | 920 | } |
| 903 | } | 921 | } |
| 904 | } else { | 922 | } else { |
| 905 | if (committing) { | 923 | if (committing) { |
| 906 | k_unicode(vc, BRL_UC_ROW | committing, 0, regs); | 924 | k_brlcommit(vc, committing, 0, regs); |
| 907 | committing = 0; | 925 | committing = 0; |
| 908 | } | 926 | } |
| 909 | pressed &= ~(1 << (value - 1)); | 927 | pressed &= ~(1 << (value - 1)); |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index a34e3d91d9ed..ba325f16d077 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
| @@ -403,6 +403,27 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd, | |||
| 403 | case EVIOCGID: | 403 | case EVIOCGID: |
| 404 | if (copy_to_user(p, &dev->id, sizeof(struct input_id))) | 404 | if (copy_to_user(p, &dev->id, sizeof(struct input_id))) |
| 405 | return -EFAULT; | 405 | return -EFAULT; |
| 406 | return 0; | ||
| 407 | |||
| 408 | case EVIOCGREP: | ||
| 409 | if (!test_bit(EV_REP, dev->evbit)) | ||
| 410 | return -ENOSYS; | ||
| 411 | if (put_user(dev->rep[REP_DELAY], ip)) | ||
| 412 | return -EFAULT; | ||
| 413 | if (put_user(dev->rep[REP_PERIOD], ip + 1)) | ||
| 414 | return -EFAULT; | ||
| 415 | return 0; | ||
| 416 | |||
| 417 | case EVIOCSREP: | ||
| 418 | if (!test_bit(EV_REP, dev->evbit)) | ||
| 419 | return -ENOSYS; | ||
| 420 | if (get_user(u, ip)) | ||
| 421 | return -EFAULT; | ||
| 422 | if (get_user(v, ip + 1)) | ||
| 423 | return -EFAULT; | ||
| 424 | |||
| 425 | input_event(dev, EV_REP, REP_DELAY, u); | ||
| 426 | input_event(dev, EV_REP, REP_PERIOD, v); | ||
| 406 | 427 | ||
| 407 | return 0; | 428 | return 0; |
| 408 | 429 | ||
diff --git a/drivers/input/input.c b/drivers/input/input.c index a935abeffffc..3038c268917d 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
| @@ -155,6 +155,9 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in | |||
| 155 | if (code > SND_MAX || !test_bit(code, dev->sndbit)) | 155 | if (code > SND_MAX || !test_bit(code, dev->sndbit)) |
| 156 | return; | 156 | return; |
| 157 | 157 | ||
| 158 | if (!!test_bit(code, dev->snd) != !!value) | ||
| 159 | change_bit(code, dev->snd); | ||
| 160 | |||
| 158 | if (dev->event) dev->event(dev, type, code, value); | 161 | if (dev->event) dev->event(dev, type, code, value); |
| 159 | 162 | ||
| 160 | break; | 163 | break; |
| @@ -286,19 +289,19 @@ static struct input_device_id *input_match_device(struct input_device_id *id, st | |||
| 286 | for (; id->flags || id->driver_info; id++) { | 289 | for (; id->flags || id->driver_info; id++) { |
| 287 | 290 | ||
| 288 | if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) | 291 | if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) |
| 289 | if (id->id.bustype != dev->id.bustype) | 292 | if (id->bustype != dev->id.bustype) |
| 290 | continue; | 293 | continue; |
| 291 | 294 | ||
| 292 | if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR) | 295 | if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR) |
| 293 | if (id->id.vendor != dev->id.vendor) | 296 | if (id->vendor != dev->id.vendor) |
| 294 | continue; | 297 | continue; |
| 295 | 298 | ||
| 296 | if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT) | 299 | if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT) |
| 297 | if (id->id.product != dev->id.product) | 300 | if (id->product != dev->id.product) |
| 298 | continue; | 301 | continue; |
| 299 | 302 | ||
| 300 | if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION) | 303 | if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION) |
| 301 | if (id->id.version != dev->id.version) | 304 | if (id->version != dev->id.version) |
| 302 | continue; | 305 | continue; |
| 303 | 306 | ||
| 304 | MATCH_BIT(evbit, EV_MAX); | 307 | MATCH_BIT(evbit, EV_MAX); |
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index bc61cf8cfc65..1d238a9d52d6 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c | |||
| @@ -53,8 +53,8 @@ static unsigned char spitzkbd_keycode[NR_SCANCODES] = { | |||
| 53 | KEY_LEFTCTRL, KEY_1, KEY_3, KEY_5, KEY_6, KEY_7, KEY_9, KEY_0, KEY_BACKSPACE, SPITZ_KEY_EXOK, SPITZ_KEY_EXCANCEL, 0, 0, 0, 0, 0, /* 1-16 */ | 53 | KEY_LEFTCTRL, KEY_1, KEY_3, KEY_5, KEY_6, KEY_7, KEY_9, KEY_0, KEY_BACKSPACE, SPITZ_KEY_EXOK, SPITZ_KEY_EXCANCEL, 0, 0, 0, 0, 0, /* 1-16 */ |
| 54 | 0, KEY_2, KEY_4, KEY_R, KEY_Y, KEY_8, KEY_I, KEY_O, KEY_P, SPITZ_KEY_EXJOGDOWN, SPITZ_KEY_EXJOGUP, 0, 0, 0, 0, 0, /* 17-32 */ | 54 | 0, KEY_2, KEY_4, KEY_R, KEY_Y, KEY_8, KEY_I, KEY_O, KEY_P, SPITZ_KEY_EXJOGDOWN, SPITZ_KEY_EXJOGUP, 0, 0, 0, 0, 0, /* 17-32 */ |
| 55 | KEY_TAB, KEY_Q, KEY_E, KEY_T, KEY_G, KEY_U, KEY_J, KEY_K, 0, 0, 0, 0, 0, 0, 0, 0, /* 33-48 */ | 55 | KEY_TAB, KEY_Q, KEY_E, KEY_T, KEY_G, KEY_U, KEY_J, KEY_K, 0, 0, 0, 0, 0, 0, 0, 0, /* 33-48 */ |
| 56 | SPITZ_KEY_CALENDER, KEY_W, KEY_S, KEY_F, KEY_V, KEY_H, KEY_M, KEY_L, 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0, /* 49-64 */ | 56 | SPITZ_KEY_ADDRESS, KEY_W, KEY_S, KEY_F, KEY_V, KEY_H, KEY_M, KEY_L, 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0, /* 49-64 */ |
| 57 | SPITZ_KEY_ADDRESS, KEY_A, KEY_D, KEY_C, KEY_B, KEY_N, KEY_DOT, 0, KEY_ENTER, KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0, /* 65-80 */ | 57 | SPITZ_KEY_CALENDER, KEY_A, KEY_D, KEY_C, KEY_B, KEY_N, KEY_DOT, 0, KEY_ENTER, KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0, /* 65-80 */ |
| 58 | SPITZ_KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, SPITZ_KEY_FN, 0, 0, 0, 0, 0, /* 81-96 */ | 58 | SPITZ_KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, SPITZ_KEY_FN, 0, 0, 0, 0, 0, /* 81-96 */ |
| 59 | KEY_SYSRQ, SPITZ_KEY_JAP1, SPITZ_KEY_JAP2, SPITZ_KEY_CANCEL, SPITZ_KEY_OK, SPITZ_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0 /* 97-112 */ | 59 | KEY_SYSRQ, SPITZ_KEY_JAP1, SPITZ_KEY_JAP2, SPITZ_KEY_CANCEL, SPITZ_KEY_OK, SPITZ_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0 /* 97-112 */ |
| 60 | }; | 60 | }; |
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 4b415d9b0123..36cd2e07fce8 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
| @@ -273,6 +273,18 @@ static struct key_entry keymap_fs_amilo_pro_v2000[] = { | |||
| 273 | { KE_END, 0 } | 273 | { KE_END, 0 } |
| 274 | }; | 274 | }; |
| 275 | 275 | ||
| 276 | static struct key_entry keymap_fujitsu_n3510[] = { | ||
| 277 | { KE_KEY, 0x11, KEY_PROG1 }, | ||
| 278 | { KE_KEY, 0x12, KEY_PROG2 }, | ||
| 279 | { KE_KEY, 0x36, KEY_WWW }, | ||
| 280 | { KE_KEY, 0x31, KEY_MAIL }, | ||
| 281 | { KE_KEY, 0x71, KEY_STOPCD }, | ||
| 282 | { KE_KEY, 0x72, KEY_PLAYPAUSE }, | ||
| 283 | { KE_KEY, 0x74, KEY_REWIND }, | ||
| 284 | { KE_KEY, 0x78, KEY_FORWARD }, | ||
| 285 | { KE_END, 0 } | ||
| 286 | }; | ||
| 287 | |||
| 276 | static struct key_entry keymap_wistron_ms2141[] = { | 288 | static struct key_entry keymap_wistron_ms2141[] = { |
| 277 | { KE_KEY, 0x11, KEY_PROG1 }, | 289 | { KE_KEY, 0x11, KEY_PROG1 }, |
| 278 | { KE_KEY, 0x12, KEY_PROG2 }, | 290 | { KE_KEY, 0x12, KEY_PROG2 }, |
| @@ -323,6 +335,24 @@ static struct dmi_system_id dmi_ids[] = { | |||
| 323 | }, | 335 | }, |
| 324 | { | 336 | { |
| 325 | .callback = dmi_matched, | 337 | .callback = dmi_matched, |
| 338 | .ident = "Fujitsu-Siemens Amilo M7400", | ||
| 339 | .matches = { | ||
| 340 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
| 341 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO M "), | ||
| 342 | }, | ||
| 343 | .driver_data = keymap_fs_amilo_pro_v2000 | ||
| 344 | }, | ||
| 345 | { | ||
| 346 | .callback = dmi_matched, | ||
| 347 | .ident = "Fujitsu N3510", | ||
| 348 | .matches = { | ||
| 349 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | ||
| 350 | DMI_MATCH(DMI_PRODUCT_NAME, "N3510"), | ||
| 351 | }, | ||
| 352 | .driver_data = keymap_fujitsu_n3510 | ||
| 353 | }, | ||
| 354 | { | ||
| 355 | .callback = dmi_matched, | ||
| 326 | .ident = "Acer Aspire 1500", | 356 | .ident = "Acer Aspire 1500", |
| 327 | .matches = { | 357 | .matches = { |
| 328 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 358 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 32d70ed8f41d..136321a2cfdb 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
| @@ -302,8 +302,10 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, | |||
| 302 | * Check if this is a new device announcement (0xAA 0x00) | 302 | * Check if this is a new device announcement (0xAA 0x00) |
| 303 | */ | 303 | */ |
| 304 | if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) { | 304 | if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) { |
| 305 | if (psmouse->pktcnt == 1) | 305 | if (psmouse->pktcnt == 1) { |
| 306 | psmouse->last = jiffies; | ||
| 306 | goto out; | 307 | goto out; |
| 308 | } | ||
| 307 | 309 | ||
| 308 | if (psmouse->packet[1] == PSMOUSE_RET_ID) { | 310 | if (psmouse->packet[1] == PSMOUSE_RET_ID) { |
| 309 | __psmouse_set_state(psmouse, PSMOUSE_IGNORE); | 311 | __psmouse_set_state(psmouse, PSMOUSE_IGNORE); |
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 46d1fec2cfd8..1494175ac6fe 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | * ADS7846 based touchscreen and sensor driver | 2 | * ADS7846 based touchscreen and sensor driver |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2005 David Brownell | 4 | * Copyright (c) 2005 David Brownell |
| 5 | * Copyright (c) 2006 Nokia Corporation | ||
| 6 | * Various changes: Imre Deak <imre.deak@nokia.com> | ||
| 5 | * | 7 | * |
| 6 | * Using code from: | 8 | * Using code from: |
| 7 | * - corgi_ts.c | 9 | * - corgi_ts.c |
| @@ -34,17 +36,25 @@ | |||
| 34 | 36 | ||
| 35 | 37 | ||
| 36 | /* | 38 | /* |
| 37 | * This code has been lightly tested on an ads7846. | 39 | * This code has been tested on an ads7846 / N770 device. |
| 38 | * Support for ads7843 and ads7845 has only been stubbed in. | 40 | * Support for ads7843 and ads7845 has only been stubbed in. |
| 39 | * | 41 | * |
| 40 | * Not yet done: investigate the values reported. Are x/y/pressure | 42 | * Not yet done: How accurate are the temperature and voltage |
| 41 | * event values sane enough for X11? How accurate are the temperature | 43 | * readings? (System-specific calibration should support |
| 42 | * and voltage readings? (System-specific calibration should support | ||
| 43 | * accuracy of 0.3 degrees C; otherwise it's 2.0 degrees.) | 44 | * accuracy of 0.3 degrees C; otherwise it's 2.0 degrees.) |
| 44 | * | 45 | * |
| 46 | * IRQ handling needs a workaround because of a shortcoming in handling | ||
| 47 | * edge triggered IRQs on some platforms like the OMAP1/2. These | ||
| 48 | * platforms don't handle the ARM lazy IRQ disabling properly, thus we | ||
| 49 | * have to maintain our own SW IRQ disabled status. This should be | ||
| 50 | * removed as soon as the affected platform's IRQ handling is fixed. | ||
| 51 | * | ||
| 45 | * app note sbaa036 talks in more detail about accurate sampling... | 52 | * app note sbaa036 talks in more detail about accurate sampling... |
| 46 | * that ought to help in situations like LCDs inducing noise (which | 53 | * that ought to help in situations like LCDs inducing noise (which |
| 47 | * can also be helped by using synch signals) and more generally. | 54 | * can also be helped by using synch signals) and more generally. |
| 55 | * This driver tries to utilize the measures described in the app | ||
| 56 | * note. The strength of filtering can be set in the board-* specific | ||
| 57 | * files. | ||
| 48 | */ | 58 | */ |
| 49 | 59 | ||
| 50 | #define TS_POLL_PERIOD msecs_to_jiffies(10) | 60 | #define TS_POLL_PERIOD msecs_to_jiffies(10) |
| @@ -61,6 +71,7 @@ struct ts_event { | |||
| 61 | __be16 x; | 71 | __be16 x; |
| 62 | __be16 y; | 72 | __be16 y; |
| 63 | __be16 z1, z2; | 73 | __be16 z1, z2; |
| 74 | int ignore; | ||
| 64 | }; | 75 | }; |
| 65 | 76 | ||
| 66 | struct ads7846 { | 77 | struct ads7846 { |
| @@ -71,12 +82,23 @@ struct ads7846 { | |||
| 71 | u16 model; | 82 | u16 model; |
| 72 | u16 vref_delay_usecs; | 83 | u16 vref_delay_usecs; |
| 73 | u16 x_plate_ohms; | 84 | u16 x_plate_ohms; |
| 85 | u16 pressure_max; | ||
| 74 | 86 | ||
| 75 | u8 read_x, read_y, read_z1, read_z2; | 87 | u8 read_x, read_y, read_z1, read_z2, pwrdown; |
| 88 | u16 dummy; /* for the pwrdown read */ | ||
| 76 | struct ts_event tc; | 89 | struct ts_event tc; |
| 77 | 90 | ||
| 78 | struct spi_transfer xfer[8]; | 91 | struct spi_transfer xfer[10]; |
| 79 | struct spi_message msg; | 92 | struct spi_message msg[5]; |
| 93 | struct spi_message *last_msg; | ||
| 94 | int msg_idx; | ||
| 95 | int read_cnt; | ||
| 96 | int read_rep; | ||
| 97 | int last_read; | ||
| 98 | |||
| 99 | u16 debounce_max; | ||
| 100 | u16 debounce_tol; | ||
| 101 | u16 debounce_rep; | ||
| 80 | 102 | ||
| 81 | spinlock_t lock; | 103 | spinlock_t lock; |
| 82 | struct timer_list timer; /* P: lock */ | 104 | struct timer_list timer; /* P: lock */ |
| @@ -84,6 +106,9 @@ struct ads7846 { | |||
| 84 | unsigned pending:1; /* P: lock */ | 106 | unsigned pending:1; /* P: lock */ |
| 85 | // FIXME remove "irq_disabled" | 107 | // FIXME remove "irq_disabled" |
| 86 | unsigned irq_disabled:1; /* P: lock */ | 108 | unsigned irq_disabled:1; /* P: lock */ |
| 109 | unsigned disabled:1; | ||
| 110 | |||
| 111 | int (*get_pendown_state)(void); | ||
| 87 | }; | 112 | }; |
| 88 | 113 | ||
| 89 | /* leave chip selected when we're done, for quicker re-select? */ | 114 | /* leave chip selected when we're done, for quicker re-select? */ |
| @@ -125,7 +150,9 @@ struct ads7846 { | |||
| 125 | #define READ_Y (READ_12BIT_DFR(y) | ADS_PD10_ADC_ON) | 150 | #define READ_Y (READ_12BIT_DFR(y) | ADS_PD10_ADC_ON) |
| 126 | #define READ_Z1 (READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON) | 151 | #define READ_Z1 (READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON) |
| 127 | #define READ_Z2 (READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON) | 152 | #define READ_Z2 (READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON) |
| 128 | #define READ_X (READ_12BIT_DFR(x) | ADS_PD10_PDOWN) /* LAST */ | 153 | |
| 154 | #define READ_X (READ_12BIT_DFR(x) | ADS_PD10_ADC_ON) | ||
| 155 | #define PWRDOWN (READ_12BIT_DFR(y) | ADS_PD10_PDOWN) /* LAST */ | ||
| 129 | 156 | ||
| 130 | /* single-ended samples need to first power up reference voltage; | 157 | /* single-ended samples need to first power up reference voltage; |
| 131 | * we leave both ADC and VREF powered | 158 | * we leave both ADC and VREF powered |
| @@ -152,6 +179,15 @@ struct ser_req { | |||
| 152 | struct spi_transfer xfer[6]; | 179 | struct spi_transfer xfer[6]; |
| 153 | }; | 180 | }; |
| 154 | 181 | ||
| 182 | static void ads7846_enable(struct ads7846 *ts); | ||
| 183 | static void ads7846_disable(struct ads7846 *ts); | ||
| 184 | |||
| 185 | static int device_suspended(struct device *dev) | ||
| 186 | { | ||
| 187 | struct ads7846 *ts = dev_get_drvdata(dev); | ||
| 188 | return dev->power.power_state.event != PM_EVENT_ON || ts->disabled; | ||
| 189 | } | ||
| 190 | |||
| 155 | static int ads7846_read12_ser(struct device *dev, unsigned command) | 191 | static int ads7846_read12_ser(struct device *dev, unsigned command) |
| 156 | { | 192 | { |
| 157 | struct spi_device *spi = to_spi_device(dev); | 193 | struct spi_device *spi = to_spi_device(dev); |
| @@ -164,7 +200,7 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
| 164 | if (!req) | 200 | if (!req) |
| 165 | return -ENOMEM; | 201 | return -ENOMEM; |
| 166 | 202 | ||
| 167 | INIT_LIST_HEAD(&req->msg.transfers); | 203 | spi_message_init(&req->msg); |
| 168 | 204 | ||
| 169 | /* activate reference, so it has time to settle; */ | 205 | /* activate reference, so it has time to settle; */ |
| 170 | req->ref_on = REF_ON; | 206 | req->ref_on = REF_ON; |
| @@ -204,8 +240,10 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
| 204 | for (i = 0; i < 6; i++) | 240 | for (i = 0; i < 6; i++) |
| 205 | spi_message_add_tail(&req->xfer[i], &req->msg); | 241 | spi_message_add_tail(&req->xfer[i], &req->msg); |
| 206 | 242 | ||
| 243 | ts->irq_disabled = 1; | ||
| 207 | disable_irq(spi->irq); | 244 | disable_irq(spi->irq); |
| 208 | status = spi_sync(spi, &req->msg); | 245 | status = spi_sync(spi, &req->msg); |
| 246 | ts->irq_disabled = 0; | ||
| 209 | enable_irq(spi->irq); | 247 | enable_irq(spi->irq); |
| 210 | 248 | ||
| 211 | if (req->msg.status) | 249 | if (req->msg.status) |
| @@ -233,6 +271,52 @@ SHOW(temp1) | |||
| 233 | SHOW(vaux) | 271 | SHOW(vaux) |
| 234 | SHOW(vbatt) | 272 | SHOW(vbatt) |
| 235 | 273 | ||
| 274 | static int is_pen_down(struct device *dev) | ||
| 275 | { | ||
| 276 | struct ads7846 *ts = dev_get_drvdata(dev); | ||
| 277 | |||
| 278 | return ts->pendown; | ||
| 279 | } | ||
| 280 | |||
| 281 | static ssize_t ads7846_pen_down_show(struct device *dev, | ||
| 282 | struct device_attribute *attr, char *buf) | ||
| 283 | { | ||
| 284 | return sprintf(buf, "%u\n", is_pen_down(dev)); | ||
| 285 | } | ||
| 286 | |||
| 287 | static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL); | ||
| 288 | |||
| 289 | static ssize_t ads7846_disable_show(struct device *dev, | ||
| 290 | struct device_attribute *attr, char *buf) | ||
| 291 | { | ||
| 292 | struct ads7846 *ts = dev_get_drvdata(dev); | ||
| 293 | |||
| 294 | return sprintf(buf, "%u\n", ts->disabled); | ||
| 295 | } | ||
| 296 | |||
| 297 | static ssize_t ads7846_disable_store(struct device *dev, | ||
| 298 | struct device_attribute *attr, | ||
| 299 | const char *buf, size_t count) | ||
| 300 | { | ||
| 301 | struct ads7846 *ts = dev_get_drvdata(dev); | ||
| 302 | char *endp; | ||
| 303 | int i; | ||
| 304 | |||
| 305 | i = simple_strtoul(buf, &endp, 10); | ||
| 306 | spin_lock_irq(&ts->lock); | ||
| 307 | |||
| 308 | if (i) | ||
| 309 | ads7846_disable(ts); | ||
| 310 | else | ||
| 311 | ads7846_enable(ts); | ||
| 312 | |||
| 313 | spin_unlock_irq(&ts->lock); | ||
| 314 | |||
| 315 | return count; | ||
| 316 | } | ||
| 317 | |||
| 318 | static DEVICE_ATTR(disable, 0664, ads7846_disable_show, ads7846_disable_store); | ||
| 319 | |||
| 236 | /*--------------------------------------------------------------------------*/ | 320 | /*--------------------------------------------------------------------------*/ |
| 237 | 321 | ||
| 238 | /* | 322 | /* |
| @@ -264,7 +348,7 @@ static void ads7846_rx(void *ads) | |||
| 264 | if (x == MAX_12BIT) | 348 | if (x == MAX_12BIT) |
| 265 | x = 0; | 349 | x = 0; |
| 266 | 350 | ||
| 267 | if (x && z1 && ts->spi->dev.power.power_state.event == PM_EVENT_ON) { | 351 | if (likely(x && z1 && !device_suspended(&ts->spi->dev))) { |
| 268 | /* compute touch pressure resistance using equation #2 */ | 352 | /* compute touch pressure resistance using equation #2 */ |
| 269 | Rt = z2; | 353 | Rt = z2; |
| 270 | Rt -= z1; | 354 | Rt -= z1; |
| @@ -275,6 +359,14 @@ static void ads7846_rx(void *ads) | |||
| 275 | } else | 359 | } else |
| 276 | Rt = 0; | 360 | Rt = 0; |
| 277 | 361 | ||
| 362 | /* Sample found inconsistent by debouncing or pressure is beyond | ||
| 363 | * the maximum. Don't report it to user space, repeat at least | ||
| 364 | * once more the measurement */ | ||
| 365 | if (ts->tc.ignore || Rt > ts->pressure_max) { | ||
| 366 | mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD); | ||
| 367 | return; | ||
| 368 | } | ||
| 369 | |||
| 278 | /* NOTE: "pendown" is inferred from pressure; we don't rely on | 370 | /* NOTE: "pendown" is inferred from pressure; we don't rely on |
| 279 | * being able to check nPENIRQ status, or "friendly" trigger modes | 371 | * being able to check nPENIRQ status, or "friendly" trigger modes |
| 280 | * (both-edges is much better than just-falling or low-level). | 372 | * (both-edges is much better than just-falling or low-level). |
| @@ -296,11 +388,13 @@ static void ads7846_rx(void *ads) | |||
| 296 | if (Rt) { | 388 | if (Rt) { |
| 297 | input_report_abs(input_dev, ABS_X, x); | 389 | input_report_abs(input_dev, ABS_X, x); |
| 298 | input_report_abs(input_dev, ABS_Y, y); | 390 | input_report_abs(input_dev, ABS_Y, y); |
| 299 | input_report_abs(input_dev, ABS_PRESSURE, Rt); | ||
| 300 | sync = 1; | 391 | sync = 1; |
| 301 | } | 392 | } |
| 302 | if (sync) | 393 | |
| 394 | if (sync) { | ||
| 395 | input_report_abs(input_dev, ABS_PRESSURE, Rt); | ||
| 303 | input_sync(input_dev); | 396 | input_sync(input_dev); |
| 397 | } | ||
| 304 | 398 | ||
| 305 | #ifdef VERBOSE | 399 | #ifdef VERBOSE |
| 306 | if (Rt || ts->pendown) | 400 | if (Rt || ts->pendown) |
| @@ -308,80 +402,138 @@ static void ads7846_rx(void *ads) | |||
| 308 | x, y, Rt, Rt ? "" : " UP"); | 402 | x, y, Rt, Rt ? "" : " UP"); |
| 309 | #endif | 403 | #endif |
| 310 | 404 | ||
| 311 | /* don't retrigger while we're suspended */ | ||
| 312 | spin_lock_irqsave(&ts->lock, flags); | 405 | spin_lock_irqsave(&ts->lock, flags); |
| 313 | 406 | ||
| 314 | ts->pendown = (Rt != 0); | 407 | ts->pendown = (Rt != 0); |
| 315 | ts->pending = 0; | 408 | mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD); |
| 316 | 409 | ||
| 317 | if (ts->spi->dev.power.power_state.event == PM_EVENT_ON) { | 410 | spin_unlock_irqrestore(&ts->lock, flags); |
| 318 | if (ts->pendown) | 411 | } |
| 319 | mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD); | 412 | |
| 320 | else if (ts->irq_disabled) { | 413 | static void ads7846_debounce(void *ads) |
| 321 | ts->irq_disabled = 0; | 414 | { |
| 322 | enable_irq(ts->spi->irq); | 415 | struct ads7846 *ts = ads; |
| 416 | struct spi_message *m; | ||
| 417 | struct spi_transfer *t; | ||
| 418 | int val; | ||
| 419 | int status; | ||
| 420 | |||
| 421 | m = &ts->msg[ts->msg_idx]; | ||
| 422 | t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list); | ||
| 423 | val = (*(u16 *)t->rx_buf) >> 3; | ||
| 424 | if (!ts->read_cnt || (abs(ts->last_read - val) > ts->debounce_tol)) { | ||
| 425 | /* Repeat it, if this was the first read or the read | ||
| 426 | * wasn't consistent enough. */ | ||
| 427 | if (ts->read_cnt < ts->debounce_max) { | ||
| 428 | ts->last_read = val; | ||
| 429 | ts->read_cnt++; | ||
| 430 | } else { | ||
| 431 | /* Maximum number of debouncing reached and still | ||
| 432 | * not enough number of consistent readings. Abort | ||
| 433 | * the whole sample, repeat it in the next sampling | ||
| 434 | * period. | ||
| 435 | */ | ||
| 436 | ts->tc.ignore = 1; | ||
| 437 | ts->read_cnt = 0; | ||
| 438 | /* Last message will contain ads7846_rx() as the | ||
| 439 | * completion function. | ||
| 440 | */ | ||
| 441 | m = ts->last_msg; | ||
| 323 | } | 442 | } |
| 443 | /* Start over collecting consistent readings. */ | ||
| 444 | ts->read_rep = 0; | ||
| 445 | } else { | ||
| 446 | if (++ts->read_rep > ts->debounce_rep) { | ||
| 447 | /* Got a good reading for this coordinate, | ||
| 448 | * go for the next one. */ | ||
| 449 | ts->tc.ignore = 0; | ||
| 450 | ts->msg_idx++; | ||
| 451 | ts->read_cnt = 0; | ||
| 452 | ts->read_rep = 0; | ||
| 453 | m++; | ||
| 454 | } else | ||
| 455 | /* Read more values that are consistent. */ | ||
| 456 | ts->read_cnt++; | ||
| 324 | } | 457 | } |
| 325 | 458 | status = spi_async(ts->spi, m); | |
| 326 | spin_unlock_irqrestore(&ts->lock, flags); | 459 | if (status) |
| 460 | dev_err(&ts->spi->dev, "spi_async --> %d\n", | ||
| 461 | status); | ||
| 327 | } | 462 | } |
| 328 | 463 | ||
| 329 | static void ads7846_timer(unsigned long handle) | 464 | static void ads7846_timer(unsigned long handle) |
| 330 | { | 465 | { |
| 331 | struct ads7846 *ts = (void *)handle; | 466 | struct ads7846 *ts = (void *)handle; |
| 332 | int status = 0; | 467 | int status = 0; |
| 333 | unsigned long flags; | 468 | |
| 469 | spin_lock_irq(&ts->lock); | ||
| 470 | |||
| 471 | if (unlikely(ts->msg_idx && !ts->pendown)) { | ||
| 472 | /* measurment cycle ended */ | ||
| 473 | if (!device_suspended(&ts->spi->dev)) { | ||
| 474 | ts->irq_disabled = 0; | ||
| 475 | enable_irq(ts->spi->irq); | ||
| 476 | } | ||
| 477 | ts->pending = 0; | ||
| 478 | ts->msg_idx = 0; | ||
| 479 | } else { | ||
| 480 | /* pen is still down, continue with the measurement */ | ||
| 481 | ts->msg_idx = 0; | ||
| 482 | status = spi_async(ts->spi, &ts->msg[0]); | ||
| 483 | if (status) | ||
| 484 | dev_err(&ts->spi->dev, "spi_async --> %d\n", status); | ||
| 485 | } | ||
| 486 | |||
| 487 | spin_unlock_irq(&ts->lock); | ||
| 488 | } | ||
| 489 | |||
| 490 | static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs) | ||
| 491 | { | ||
| 492 | struct ads7846 *ts = handle; | ||
| 493 | unsigned long flags; | ||
| 334 | 494 | ||
| 335 | spin_lock_irqsave(&ts->lock, flags); | 495 | spin_lock_irqsave(&ts->lock, flags); |
| 336 | if (!ts->pending) { | 496 | if (likely(ts->get_pendown_state())) { |
| 337 | ts->pending = 1; | ||
| 338 | if (!ts->irq_disabled) { | 497 | if (!ts->irq_disabled) { |
| 498 | /* REVISIT irq logic for many ARM chips has cloned a | ||
| 499 | * bug wherein disabling an irq in its handler won't | ||
| 500 | * work;(it's disabled lazily, and too late to work. | ||
| 501 | * until all their irq logic is fixed, we must shadow | ||
| 502 | * that state here. | ||
| 503 | */ | ||
| 339 | ts->irq_disabled = 1; | 504 | ts->irq_disabled = 1; |
| 340 | disable_irq(ts->spi->irq); | 505 | disable_irq(ts->spi->irq); |
| 506 | ts->pending = 1; | ||
| 507 | mod_timer(&ts->timer, jiffies); | ||
| 341 | } | 508 | } |
| 342 | status = spi_async(ts->spi, &ts->msg); | ||
| 343 | if (status) | ||
| 344 | dev_err(&ts->spi->dev, "spi_async --> %d\n", | ||
| 345 | status); | ||
| 346 | } | 509 | } |
| 347 | spin_unlock_irqrestore(&ts->lock, flags); | 510 | spin_unlock_irqrestore(&ts->lock, flags); |
| 348 | } | ||
| 349 | 511 | ||
| 350 | static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs) | ||
| 351 | { | ||
| 352 | ads7846_timer((unsigned long) handle); | ||
| 353 | return IRQ_HANDLED; | 512 | return IRQ_HANDLED; |
| 354 | } | 513 | } |
| 355 | 514 | ||
| 356 | /*--------------------------------------------------------------------------*/ | 515 | /*--------------------------------------------------------------------------*/ |
| 357 | 516 | ||
| 358 | static int | 517 | /* Must be called with ts->lock held */ |
| 359 | ads7846_suspend(struct spi_device *spi, pm_message_t message) | 518 | static void ads7846_disable(struct ads7846 *ts) |
| 360 | { | 519 | { |
| 361 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | 520 | if (ts->disabled) |
| 362 | unsigned long flags; | 521 | return; |
| 363 | 522 | ||
| 364 | spin_lock_irqsave(&ts->lock, flags); | 523 | ts->disabled = 1; |
| 365 | |||
| 366 | spi->dev.power.power_state = message; | ||
| 367 | 524 | ||
| 368 | /* are we waiting for IRQ, or polling? */ | 525 | /* are we waiting for IRQ, or polling? */ |
| 369 | if (!ts->pendown) { | 526 | if (!ts->pending) { |
| 370 | if (!ts->irq_disabled) { | 527 | ts->irq_disabled = 1; |
| 371 | ts->irq_disabled = 1; | 528 | disable_irq(ts->spi->irq); |
| 372 | disable_irq(ts->spi->irq); | ||
| 373 | } | ||
| 374 | } else { | 529 | } else { |
| 375 | /* polling; force a final SPI completion; | 530 | /* the timer will run at least once more, and |
| 376 | * that will clean things up neatly | 531 | * leave everything in a clean state, IRQ disabled |
| 377 | */ | 532 | */ |
| 378 | if (!ts->pending) | 533 | while (ts->pending) { |
| 379 | mod_timer(&ts->timer, jiffies); | 534 | spin_unlock_irq(&ts->lock); |
| 380 | 535 | msleep(1); | |
| 381 | while (ts->pendown || ts->pending) { | 536 | spin_lock_irq(&ts->lock); |
| 382 | spin_unlock_irqrestore(&ts->lock, flags); | ||
| 383 | udelay(10); | ||
| 384 | spin_lock_irqsave(&ts->lock, flags); | ||
| 385 | } | 537 | } |
| 386 | } | 538 | } |
| 387 | 539 | ||
| @@ -389,17 +541,45 @@ ads7846_suspend(struct spi_device *spi, pm_message_t message) | |||
| 389 | * leave it that way after every request | 541 | * leave it that way after every request |
| 390 | */ | 542 | */ |
| 391 | 543 | ||
| 392 | spin_unlock_irqrestore(&ts->lock, flags); | 544 | } |
| 545 | |||
| 546 | /* Must be called with ts->lock held */ | ||
| 547 | static void ads7846_enable(struct ads7846 *ts) | ||
| 548 | { | ||
| 549 | if (!ts->disabled) | ||
| 550 | return; | ||
| 551 | |||
| 552 | ts->disabled = 0; | ||
| 553 | ts->irq_disabled = 0; | ||
| 554 | enable_irq(ts->spi->irq); | ||
| 555 | } | ||
| 556 | |||
| 557 | static int ads7846_suspend(struct spi_device *spi, pm_message_t message) | ||
| 558 | { | ||
| 559 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | ||
| 560 | |||
| 561 | spin_lock_irq(&ts->lock); | ||
| 562 | |||
| 563 | spi->dev.power.power_state = message; | ||
| 564 | ads7846_disable(ts); | ||
| 565 | |||
| 566 | spin_unlock_irq(&ts->lock); | ||
| 567 | |||
| 393 | return 0; | 568 | return 0; |
| 569 | |||
| 394 | } | 570 | } |
| 395 | 571 | ||
| 396 | static int ads7846_resume(struct spi_device *spi) | 572 | static int ads7846_resume(struct spi_device *spi) |
| 397 | { | 573 | { |
| 398 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | 574 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); |
| 399 | 575 | ||
| 400 | ts->irq_disabled = 0; | 576 | spin_lock_irq(&ts->lock); |
| 401 | enable_irq(ts->spi->irq); | 577 | |
| 402 | spi->dev.power.power_state = PMSG_ON; | 578 | spi->dev.power.power_state = PMSG_ON; |
| 579 | ads7846_enable(ts); | ||
| 580 | |||
| 581 | spin_unlock_irq(&ts->lock); | ||
| 582 | |||
| 403 | return 0; | 583 | return 0; |
| 404 | } | 584 | } |
| 405 | 585 | ||
| @@ -408,6 +588,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 408 | struct ads7846 *ts; | 588 | struct ads7846 *ts; |
| 409 | struct input_dev *input_dev; | 589 | struct input_dev *input_dev; |
| 410 | struct ads7846_platform_data *pdata = spi->dev.platform_data; | 590 | struct ads7846_platform_data *pdata = spi->dev.platform_data; |
| 591 | struct spi_message *m; | ||
| 411 | struct spi_transfer *x; | 592 | struct spi_transfer *x; |
| 412 | int err; | 593 | int err; |
| 413 | 594 | ||
| @@ -428,6 +609,11 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 428 | return -EINVAL; | 609 | return -EINVAL; |
| 429 | } | 610 | } |
| 430 | 611 | ||
| 612 | if (pdata->get_pendown_state == NULL) { | ||
| 613 | dev_dbg(&spi->dev, "no get_pendown_state function?\n"); | ||
| 614 | return -EINVAL; | ||
| 615 | } | ||
| 616 | |||
| 431 | /* We'd set the wordsize to 12 bits ... except that some controllers | 617 | /* We'd set the wordsize to 12 bits ... except that some controllers |
| 432 | * will then treat the 8 bit command words as 12 bits (and drop the | 618 | * will then treat the 8 bit command words as 12 bits (and drop the |
| 433 | * four MSBs of the 12 bit result). Result: inputs must be shifted | 619 | * four MSBs of the 12 bit result). Result: inputs must be shifted |
| @@ -451,9 +637,21 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 451 | ts->timer.data = (unsigned long) ts; | 637 | ts->timer.data = (unsigned long) ts; |
| 452 | ts->timer.function = ads7846_timer; | 638 | ts->timer.function = ads7846_timer; |
| 453 | 639 | ||
| 640 | spin_lock_init(&ts->lock); | ||
| 641 | |||
| 454 | ts->model = pdata->model ? : 7846; | 642 | ts->model = pdata->model ? : 7846; |
| 455 | ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; | 643 | ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; |
| 456 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; | 644 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; |
| 645 | ts->pressure_max = pdata->pressure_max ? : ~0; | ||
| 646 | if (pdata->debounce_max) { | ||
| 647 | ts->debounce_max = pdata->debounce_max; | ||
| 648 | ts->debounce_tol = pdata->debounce_tol; | ||
| 649 | ts->debounce_rep = pdata->debounce_rep; | ||
| 650 | if (ts->debounce_rep > ts->debounce_max + 1) | ||
| 651 | ts->debounce_rep = ts->debounce_max - 1; | ||
| 652 | } else | ||
| 653 | ts->debounce_tol = ~0; | ||
| 654 | ts->get_pendown_state = pdata->get_pendown_state; | ||
| 457 | 655 | ||
| 458 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id); | 656 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id); |
| 459 | 657 | ||
| @@ -477,60 +675,100 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 477 | /* set up the transfers to read touchscreen state; this assumes we | 675 | /* set up the transfers to read touchscreen state; this assumes we |
| 478 | * use formula #2 for pressure, not #3. | 676 | * use formula #2 for pressure, not #3. |
| 479 | */ | 677 | */ |
| 480 | INIT_LIST_HEAD(&ts->msg.transfers); | 678 | m = &ts->msg[0]; |
| 481 | x = ts->xfer; | 679 | x = ts->xfer; |
| 482 | 680 | ||
| 681 | spi_message_init(m); | ||
| 682 | |||
| 483 | /* y- still on; turn on only y+ (and ADC) */ | 683 | /* y- still on; turn on only y+ (and ADC) */ |
| 484 | ts->read_y = READ_Y; | 684 | ts->read_y = READ_Y; |
| 485 | x->tx_buf = &ts->read_y; | 685 | x->tx_buf = &ts->read_y; |
| 486 | x->len = 1; | 686 | x->len = 1; |
| 487 | spi_message_add_tail(x, &ts->msg); | 687 | spi_message_add_tail(x, m); |
| 488 | 688 | ||
| 489 | x++; | 689 | x++; |
| 490 | x->rx_buf = &ts->tc.y; | 690 | x->rx_buf = &ts->tc.y; |
| 491 | x->len = 2; | 691 | x->len = 2; |
| 492 | spi_message_add_tail(x, &ts->msg); | 692 | spi_message_add_tail(x, m); |
| 693 | |||
| 694 | m->complete = ads7846_debounce; | ||
| 695 | m->context = ts; | ||
| 696 | |||
| 697 | m++; | ||
| 698 | spi_message_init(m); | ||
| 699 | |||
| 700 | /* turn y- off, x+ on, then leave in lowpower */ | ||
| 701 | x++; | ||
| 702 | ts->read_x = READ_X; | ||
| 703 | x->tx_buf = &ts->read_x; | ||
| 704 | x->len = 1; | ||
| 705 | spi_message_add_tail(x, m); | ||
| 706 | |||
| 707 | x++; | ||
| 708 | x->rx_buf = &ts->tc.x; | ||
| 709 | x->len = 2; | ||
| 710 | spi_message_add_tail(x, m); | ||
| 711 | |||
| 712 | m->complete = ads7846_debounce; | ||
| 713 | m->context = ts; | ||
| 493 | 714 | ||
| 494 | /* turn y+ off, x- on; we'll use formula #2 */ | 715 | /* turn y+ off, x- on; we'll use formula #2 */ |
| 495 | if (ts->model == 7846) { | 716 | if (ts->model == 7846) { |
| 717 | m++; | ||
| 718 | spi_message_init(m); | ||
| 719 | |||
| 496 | x++; | 720 | x++; |
| 497 | ts->read_z1 = READ_Z1; | 721 | ts->read_z1 = READ_Z1; |
| 498 | x->tx_buf = &ts->read_z1; | 722 | x->tx_buf = &ts->read_z1; |
| 499 | x->len = 1; | 723 | x->len = 1; |
| 500 | spi_message_add_tail(x, &ts->msg); | 724 | spi_message_add_tail(x, m); |
| 501 | 725 | ||
| 502 | x++; | 726 | x++; |
| 503 | x->rx_buf = &ts->tc.z1; | 727 | x->rx_buf = &ts->tc.z1; |
| 504 | x->len = 2; | 728 | x->len = 2; |
| 505 | spi_message_add_tail(x, &ts->msg); | 729 | spi_message_add_tail(x, m); |
| 730 | |||
| 731 | m->complete = ads7846_debounce; | ||
| 732 | m->context = ts; | ||
| 733 | |||
| 734 | m++; | ||
| 735 | spi_message_init(m); | ||
| 506 | 736 | ||
| 507 | x++; | 737 | x++; |
| 508 | ts->read_z2 = READ_Z2; | 738 | ts->read_z2 = READ_Z2; |
| 509 | x->tx_buf = &ts->read_z2; | 739 | x->tx_buf = &ts->read_z2; |
| 510 | x->len = 1; | 740 | x->len = 1; |
| 511 | spi_message_add_tail(x, &ts->msg); | 741 | spi_message_add_tail(x, m); |
| 512 | 742 | ||
| 513 | x++; | 743 | x++; |
| 514 | x->rx_buf = &ts->tc.z2; | 744 | x->rx_buf = &ts->tc.z2; |
| 515 | x->len = 2; | 745 | x->len = 2; |
| 516 | spi_message_add_tail(x, &ts->msg); | 746 | spi_message_add_tail(x, m); |
| 747 | |||
| 748 | m->complete = ads7846_debounce; | ||
| 749 | m->context = ts; | ||
| 517 | } | 750 | } |
| 518 | 751 | ||
| 519 | /* turn y- off, x+ on, then leave in lowpower */ | 752 | /* power down */ |
| 753 | m++; | ||
| 754 | spi_message_init(m); | ||
| 755 | |||
| 520 | x++; | 756 | x++; |
| 521 | ts->read_x = READ_X; | 757 | ts->pwrdown = PWRDOWN; |
| 522 | x->tx_buf = &ts->read_x; | 758 | x->tx_buf = &ts->pwrdown; |
| 523 | x->len = 1; | 759 | x->len = 1; |
| 524 | spi_message_add_tail(x, &ts->msg); | 760 | spi_message_add_tail(x, m); |
| 525 | 761 | ||
| 526 | x++; | 762 | x++; |
| 527 | x->rx_buf = &ts->tc.x; | 763 | x->rx_buf = &ts->dummy; |
| 528 | x->len = 2; | 764 | x->len = 2; |
| 529 | CS_CHANGE(*x); | 765 | CS_CHANGE(*x); |
| 530 | spi_message_add_tail(x, &ts->msg); | 766 | spi_message_add_tail(x, m); |
| 531 | 767 | ||
| 532 | ts->msg.complete = ads7846_rx; | 768 | m->complete = ads7846_rx; |
| 533 | ts->msg.context = ts; | 769 | m->context = ts; |
| 770 | |||
| 771 | ts->last_msg = m; | ||
| 534 | 772 | ||
| 535 | if (request_irq(spi->irq, ads7846_irq, | 773 | if (request_irq(spi->irq, ads7846_irq, |
| 536 | SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING, | 774 | SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING, |
| @@ -559,13 +797,27 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 559 | device_create_file(&spi->dev, &dev_attr_vbatt); | 797 | device_create_file(&spi->dev, &dev_attr_vbatt); |
| 560 | device_create_file(&spi->dev, &dev_attr_vaux); | 798 | device_create_file(&spi->dev, &dev_attr_vaux); |
| 561 | 799 | ||
| 800 | device_create_file(&spi->dev, &dev_attr_pen_down); | ||
| 801 | |||
| 802 | device_create_file(&spi->dev, &dev_attr_disable); | ||
| 803 | |||
| 562 | err = input_register_device(input_dev); | 804 | err = input_register_device(input_dev); |
| 563 | if (err) | 805 | if (err) |
| 564 | goto err_free_irq; | 806 | goto err_remove_attr; |
| 565 | 807 | ||
| 566 | return 0; | 808 | return 0; |
| 567 | 809 | ||
| 568 | err_free_irq: | 810 | err_remove_attr: |
| 811 | device_remove_file(&spi->dev, &dev_attr_disable); | ||
| 812 | device_remove_file(&spi->dev, &dev_attr_pen_down); | ||
| 813 | if (ts->model == 7846) { | ||
| 814 | device_remove_file(&spi->dev, &dev_attr_temp1); | ||
| 815 | device_remove_file(&spi->dev, &dev_attr_temp0); | ||
| 816 | } | ||
| 817 | if (ts->model != 7845) | ||
| 818 | device_remove_file(&spi->dev, &dev_attr_vbatt); | ||
| 819 | device_remove_file(&spi->dev, &dev_attr_vaux); | ||
| 820 | |||
| 569 | free_irq(spi->irq, ts); | 821 | free_irq(spi->irq, ts); |
| 570 | err_free_mem: | 822 | err_free_mem: |
| 571 | input_free_device(input_dev); | 823 | input_free_device(input_dev); |
| @@ -577,20 +829,24 @@ static int __devexit ads7846_remove(struct spi_device *spi) | |||
| 577 | { | 829 | { |
| 578 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | 830 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); |
| 579 | 831 | ||
| 832 | input_unregister_device(ts->input); | ||
| 833 | |||
| 580 | ads7846_suspend(spi, PMSG_SUSPEND); | 834 | ads7846_suspend(spi, PMSG_SUSPEND); |
| 581 | free_irq(ts->spi->irq, ts); | ||
| 582 | if (ts->irq_disabled) | ||
| 583 | enable_irq(ts->spi->irq); | ||
| 584 | 835 | ||
| 836 | device_remove_file(&spi->dev, &dev_attr_disable); | ||
| 837 | device_remove_file(&spi->dev, &dev_attr_pen_down); | ||
| 585 | if (ts->model == 7846) { | 838 | if (ts->model == 7846) { |
| 586 | device_remove_file(&spi->dev, &dev_attr_temp0); | ||
| 587 | device_remove_file(&spi->dev, &dev_attr_temp1); | 839 | device_remove_file(&spi->dev, &dev_attr_temp1); |
| 840 | device_remove_file(&spi->dev, &dev_attr_temp0); | ||
| 588 | } | 841 | } |
| 589 | if (ts->model != 7845) | 842 | if (ts->model != 7845) |
| 590 | device_remove_file(&spi->dev, &dev_attr_vbatt); | 843 | device_remove_file(&spi->dev, &dev_attr_vbatt); |
| 591 | device_remove_file(&spi->dev, &dev_attr_vaux); | 844 | device_remove_file(&spi->dev, &dev_attr_vaux); |
| 592 | 845 | ||
| 593 | input_unregister_device(ts->input); | 846 | free_irq(ts->spi->irq, ts); |
| 847 | /* suspend left the IRQ disabled */ | ||
| 848 | enable_irq(ts->spi->irq); | ||
| 849 | |||
| 594 | kfree(ts); | 850 | kfree(ts); |
| 595 | 851 | ||
| 596 | dev_dbg(&spi->dev, "unregistered touchscreen\n"); | 852 | dev_dbg(&spi->dev, "unregistered touchscreen\n"); |
diff --git a/include/linux/input.h b/include/linux/input.h index b0e612dda0cf..50e338d2ffda 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
| @@ -12,8 +12,6 @@ | |||
| 12 | #ifdef __KERNEL__ | 12 | #ifdef __KERNEL__ |
| 13 | #include <linux/time.h> | 13 | #include <linux/time.h> |
| 14 | #include <linux/list.h> | 14 | #include <linux/list.h> |
| 15 | #include <linux/device.h> | ||
| 16 | #include <linux/mod_devicetable.h> | ||
| 17 | #else | 15 | #else |
| 18 | #include <sys/time.h> | 16 | #include <sys/time.h> |
| 19 | #include <sys/ioctl.h> | 17 | #include <sys/ioctl.h> |
| @@ -58,6 +56,8 @@ struct input_absinfo { | |||
| 58 | 56 | ||
| 59 | #define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */ | 57 | #define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */ |
| 60 | #define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */ | 58 | #define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */ |
| 59 | #define EVIOCGREP _IOR('E', 0x03, int[2]) /* get repeat settings */ | ||
| 60 | #define EVIOCSREP _IOW('E', 0x03, int[2]) /* set repeat settings */ | ||
| 61 | #define EVIOCGKEYCODE _IOR('E', 0x04, int[2]) /* get keycode */ | 61 | #define EVIOCGKEYCODE _IOR('E', 0x04, int[2]) /* get keycode */ |
| 62 | #define EVIOCSKEYCODE _IOW('E', 0x04, int[2]) /* set keycode */ | 62 | #define EVIOCSKEYCODE _IOW('E', 0x04, int[2]) /* set keycode */ |
| 63 | 63 | ||
| @@ -577,15 +577,15 @@ struct input_absinfo { | |||
| 577 | * Switch events | 577 | * Switch events |
| 578 | */ | 578 | */ |
| 579 | 579 | ||
| 580 | #define SW_0 0x00 | 580 | #define SW_0 0x00 |
| 581 | #define SW_1 0x01 | 581 | #define SW_1 0x01 |
| 582 | #define SW_2 0x02 | 582 | #define SW_2 0x02 |
| 583 | #define SW_3 0x03 | 583 | #define SW_3 0x03 |
| 584 | #define SW_4 0x04 | 584 | #define SW_4 0x04 |
| 585 | #define SW_5 0x05 | 585 | #define SW_5 0x05 |
| 586 | #define SW_6 0x06 | 586 | #define SW_6 0x06 |
| 587 | #define SW_7 0x07 | 587 | #define SW_7 0x07 |
| 588 | #define SW_MAX 0x0f | 588 | #define SW_MAX 0x0f |
| 589 | 589 | ||
| 590 | /* | 590 | /* |
| 591 | * Misc events | 591 | * Misc events |
| @@ -805,52 +805,16 @@ struct ff_effect { | |||
| 805 | 805 | ||
| 806 | #define FF_MAX 0x7f | 806 | #define FF_MAX 0x7f |
| 807 | 807 | ||
| 808 | struct input_device_id { | ||
| 809 | |||
| 810 | kernel_ulong_t flags; | ||
| 811 | |||
| 812 | struct input_id id; | ||
| 813 | |||
| 814 | kernel_ulong_t evbit[EV_MAX/BITS_PER_LONG+1]; | ||
| 815 | kernel_ulong_t keybit[KEY_MAX/BITS_PER_LONG+1]; | ||
| 816 | kernel_ulong_t relbit[REL_MAX/BITS_PER_LONG+1]; | ||
| 817 | kernel_ulong_t absbit[ABS_MAX/BITS_PER_LONG+1]; | ||
| 818 | kernel_ulong_t mscbit[MSC_MAX/BITS_PER_LONG+1]; | ||
| 819 | kernel_ulong_t ledbit[LED_MAX/BITS_PER_LONG+1]; | ||
| 820 | kernel_ulong_t sndbit[SND_MAX/BITS_PER_LONG+1]; | ||
| 821 | kernel_ulong_t ffbit[FF_MAX/BITS_PER_LONG+1]; | ||
| 822 | kernel_ulong_t swbit[SW_MAX/BITS_PER_LONG+1]; | ||
| 823 | |||
| 824 | kernel_ulong_t driver_info; | ||
| 825 | }; | ||
| 826 | |||
| 827 | /* | ||
| 828 | * Structure for hotplug & device<->driver matching. | ||
| 829 | */ | ||
| 830 | |||
| 831 | #define INPUT_DEVICE_ID_MATCH_BUS 1 | ||
| 832 | #define INPUT_DEVICE_ID_MATCH_VENDOR 2 | ||
| 833 | #define INPUT_DEVICE_ID_MATCH_PRODUCT 4 | ||
| 834 | #define INPUT_DEVICE_ID_MATCH_VERSION 8 | ||
| 835 | |||
| 836 | #define INPUT_DEVICE_ID_MATCH_EVBIT 0x010 | ||
| 837 | #define INPUT_DEVICE_ID_MATCH_KEYBIT 0x020 | ||
| 838 | #define INPUT_DEVICE_ID_MATCH_RELBIT 0x040 | ||
| 839 | #define INPUT_DEVICE_ID_MATCH_ABSBIT 0x080 | ||
| 840 | #define INPUT_DEVICE_ID_MATCH_MSCIT 0x100 | ||
| 841 | #define INPUT_DEVICE_ID_MATCH_LEDBIT 0x200 | ||
| 842 | #define INPUT_DEVICE_ID_MATCH_SNDBIT 0x400 | ||
| 843 | #define INPUT_DEVICE_ID_MATCH_FFBIT 0x800 | ||
| 844 | #define INPUT_DEVICE_ID_MATCH_SWBIT 0x1000 | ||
| 845 | |||
| 846 | #ifdef __KERNEL__ | 808 | #ifdef __KERNEL__ |
| 847 | 809 | ||
| 848 | /* | 810 | /* |
| 849 | * In-kernel definitions. | 811 | * In-kernel definitions. |
| 850 | */ | 812 | */ |
| 851 | 813 | ||
| 814 | #include <linux/device.h> | ||
| 852 | #include <linux/fs.h> | 815 | #include <linux/fs.h> |
| 853 | #include <linux/timer.h> | 816 | #include <linux/timer.h> |
| 817 | #include <linux/mod_devicetable.h> | ||
| 854 | 818 | ||
| 855 | #define NBITS(x) (((x)/BITS_PER_LONG)+1) | 819 | #define NBITS(x) (((x)/BITS_PER_LONG)+1) |
| 856 | #define BIT(x) (1UL<<((x)%BITS_PER_LONG)) | 820 | #define BIT(x) (1UL<<((x)%BITS_PER_LONG)) |
| @@ -951,9 +915,49 @@ struct input_dev { | |||
| 951 | }; | 915 | }; |
| 952 | #define to_input_dev(d) container_of(d, struct input_dev, cdev) | 916 | #define to_input_dev(d) container_of(d, struct input_dev, cdev) |
| 953 | 917 | ||
| 954 | #define INPUT_DEVICE_ID_MATCH_DEVICE\ | 918 | /* |
| 919 | * Verify that we are in sync with input_device_id mod_devicetable.h #defines | ||
| 920 | */ | ||
| 921 | |||
| 922 | #if EV_MAX != INPUT_DEVICE_ID_EV_MAX | ||
| 923 | #error "EV_MAX and INPUT_DEVICE_ID_EV_MAX do not match" | ||
| 924 | #endif | ||
| 925 | |||
| 926 | #if KEY_MAX != INPUT_DEVICE_ID_KEY_MAX | ||
| 927 | #error "KEY_MAX and INPUT_DEVICE_ID_KEY_MAX do not match" | ||
| 928 | #endif | ||
| 929 | |||
| 930 | #if REL_MAX != INPUT_DEVICE_ID_REL_MAX | ||
| 931 | #error "REL_MAX and INPUT_DEVICE_ID_REL_MAX do not match" | ||
| 932 | #endif | ||
| 933 | |||
| 934 | #if ABS_MAX != INPUT_DEVICE_ID_ABS_MAX | ||
| 935 | #error "ABS_MAX and INPUT_DEVICE_ID_ABS_MAX do not match" | ||
| 936 | #endif | ||
| 937 | |||
| 938 | #if MSC_MAX != INPUT_DEVICE_ID_MSC_MAX | ||
| 939 | #error "MSC_MAX and INPUT_DEVICE_ID_MSC_MAX do not match" | ||
| 940 | #endif | ||
| 941 | |||
| 942 | #if LED_MAX != INPUT_DEVICE_ID_LED_MAX | ||
| 943 | #error "LED_MAX and INPUT_DEVICE_ID_LED_MAX do not match" | ||
| 944 | #endif | ||
| 945 | |||
| 946 | #if SND_MAX != INPUT_DEVICE_ID_SND_MAX | ||
| 947 | #error "SND_MAX and INPUT_DEVICE_ID_SND_MAX do not match" | ||
| 948 | #endif | ||
| 949 | |||
| 950 | #if FF_MAX != INPUT_DEVICE_ID_FF_MAX | ||
| 951 | #error "FF_MAX and INPUT_DEVICE_ID_FF_MAX do not match" | ||
| 952 | #endif | ||
| 953 | |||
| 954 | #if SW_MAX != INPUT_DEVICE_ID_SW_MAX | ||
| 955 | #error "SW_MAX and INPUT_DEVICE_ID_SW_MAX do not match" | ||
| 956 | #endif | ||
| 957 | |||
| 958 | #define INPUT_DEVICE_ID_MATCH_DEVICE \ | ||
| 955 | (INPUT_DEVICE_ID_MATCH_BUS | INPUT_DEVICE_ID_MATCH_VENDOR | INPUT_DEVICE_ID_MATCH_PRODUCT) | 959 | (INPUT_DEVICE_ID_MATCH_BUS | INPUT_DEVICE_ID_MATCH_VENDOR | INPUT_DEVICE_ID_MATCH_PRODUCT) |
| 956 | #define INPUT_DEVICE_ID_MATCH_DEVICE_AND_VERSION\ | 960 | #define INPUT_DEVICE_ID_MATCH_DEVICE_AND_VERSION \ |
| 957 | (INPUT_DEVICE_ID_MATCH_DEVICE | INPUT_DEVICE_ID_MATCH_VERSION) | 961 | (INPUT_DEVICE_ID_MATCH_DEVICE | INPUT_DEVICE_ID_MATCH_VERSION) |
| 958 | 962 | ||
| 959 | struct input_handle; | 963 | struct input_handle; |
| @@ -1016,7 +1020,8 @@ static inline void input_put_device(struct input_dev *dev) | |||
| 1016 | 1020 | ||
| 1017 | static inline void input_free_device(struct input_dev *dev) | 1021 | static inline void input_free_device(struct input_dev *dev) |
| 1018 | { | 1022 | { |
| 1019 | input_put_device(dev); | 1023 | if (dev) |
| 1024 | input_put_device(dev); | ||
| 1020 | } | 1025 | } |
| 1021 | 1026 | ||
| 1022 | int input_register_device(struct input_dev *); | 1027 | int input_register_device(struct input_dev *); |
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 7b08c11ec4cc..f6977708585c 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h | |||
| @@ -249,4 +249,52 @@ struct i2c_device_id { | |||
| 249 | __u16 id; | 249 | __u16 id; |
| 250 | }; | 250 | }; |
| 251 | 251 | ||
| 252 | /* Input */ | ||
| 253 | #define INPUT_DEVICE_ID_EV_MAX 0x1f | ||
| 254 | #define INPUT_DEVICE_ID_KEY_MAX 0x1ff | ||
| 255 | #define INPUT_DEVICE_ID_REL_MAX 0x0f | ||
| 256 | #define INPUT_DEVICE_ID_ABS_MAX 0x3f | ||
| 257 | #define INPUT_DEVICE_ID_MSC_MAX 0x07 | ||
| 258 | #define INPUT_DEVICE_ID_LED_MAX 0x0f | ||
| 259 | #define INPUT_DEVICE_ID_SND_MAX 0x07 | ||
| 260 | #define INPUT_DEVICE_ID_FF_MAX 0x7f | ||
| 261 | #define INPUT_DEVICE_ID_SW_MAX 0x0f | ||
| 262 | |||
| 263 | #define INPUT_DEVICE_ID_MATCH_BUS 1 | ||
| 264 | #define INPUT_DEVICE_ID_MATCH_VENDOR 2 | ||
| 265 | #define INPUT_DEVICE_ID_MATCH_PRODUCT 4 | ||
| 266 | #define INPUT_DEVICE_ID_MATCH_VERSION 8 | ||
| 267 | |||
| 268 | #define INPUT_DEVICE_ID_MATCH_EVBIT 0x0010 | ||
| 269 | #define INPUT_DEVICE_ID_MATCH_KEYBIT 0x0020 | ||
| 270 | #define INPUT_DEVICE_ID_MATCH_RELBIT 0x0040 | ||
| 271 | #define INPUT_DEVICE_ID_MATCH_ABSBIT 0x0080 | ||
| 272 | #define INPUT_DEVICE_ID_MATCH_MSCIT 0x0100 | ||
| 273 | #define INPUT_DEVICE_ID_MATCH_LEDBIT 0x0200 | ||
| 274 | #define INPUT_DEVICE_ID_MATCH_SNDBIT 0x0400 | ||
| 275 | #define INPUT_DEVICE_ID_MATCH_FFBIT 0x0800 | ||
| 276 | #define INPUT_DEVICE_ID_MATCH_SWBIT 0x1000 | ||
| 277 | |||
| 278 | struct input_device_id { | ||
| 279 | |||
| 280 | kernel_ulong_t flags; | ||
| 281 | |||
| 282 | __u16 bustype; | ||
| 283 | __u16 vendor; | ||
| 284 | __u16 product; | ||
| 285 | __u16 version; | ||
| 286 | |||
| 287 | kernel_ulong_t evbit[INPUT_DEVICE_ID_EV_MAX / BITS_PER_LONG + 1]; | ||
| 288 | kernel_ulong_t keybit[INPUT_DEVICE_ID_KEY_MAX / BITS_PER_LONG + 1]; | ||
| 289 | kernel_ulong_t relbit[INPUT_DEVICE_ID_REL_MAX / BITS_PER_LONG + 1]; | ||
| 290 | kernel_ulong_t absbit[INPUT_DEVICE_ID_ABS_MAX / BITS_PER_LONG + 1]; | ||
| 291 | kernel_ulong_t mscbit[INPUT_DEVICE_ID_MSC_MAX / BITS_PER_LONG + 1]; | ||
| 292 | kernel_ulong_t ledbit[INPUT_DEVICE_ID_LED_MAX / BITS_PER_LONG + 1]; | ||
| 293 | kernel_ulong_t sndbit[INPUT_DEVICE_ID_SND_MAX / BITS_PER_LONG + 1]; | ||
| 294 | kernel_ulong_t ffbit[INPUT_DEVICE_ID_FF_MAX / BITS_PER_LONG + 1]; | ||
| 295 | kernel_ulong_t swbit[INPUT_DEVICE_ID_SW_MAX / BITS_PER_LONG + 1]; | ||
| 296 | |||
| 297 | kernel_ulong_t driver_info; | ||
| 298 | }; | ||
| 299 | |||
| 252 | #endif /* LINUX_MOD_DEVICETABLE_H */ | 300 | #endif /* LINUX_MOD_DEVICETABLE_H */ |
diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index 72261e0f2ac1..adb3dafd33e9 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h | |||
| @@ -14,5 +14,12 @@ struct ads7846_platform_data { | |||
| 14 | u16 x_min, x_max; | 14 | u16 x_min, x_max; |
| 15 | u16 y_min, y_max; | 15 | u16 y_min, y_max; |
| 16 | u16 pressure_min, pressure_max; | 16 | u16 pressure_min, pressure_max; |
| 17 | |||
| 18 | u16 debounce_max; /* max number of additional readings | ||
| 19 | * per sample */ | ||
| 20 | u16 debounce_tol; /* tolerance used for filtering */ | ||
| 21 | u16 debounce_rep; /* additional consecutive good readings | ||
| 22 | * required after the first two */ | ||
| 23 | int (*get_pendown_state)(void); | ||
| 17 | }; | 24 | }; |
| 18 | 25 | ||
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 84e21201f3c0..37f67c23e11b 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c | |||
| @@ -374,10 +374,10 @@ static void do_input(char *alias, | |||
| 374 | kernel_ulong_t *arr, unsigned int min, unsigned int max) | 374 | kernel_ulong_t *arr, unsigned int min, unsigned int max) |
| 375 | { | 375 | { |
| 376 | unsigned int i; | 376 | unsigned int i; |
| 377 | for (i = min; i < max; i++) { | 377 | |
| 378 | if (arr[i/BITS_PER_LONG] & (1 << (i%BITS_PER_LONG))) | 378 | for (i = min; i < max; i++) |
| 379 | sprintf(alias+strlen(alias), "%X,*", i); | 379 | if (arr[i / BITS_PER_LONG] & (1 << (i%BITS_PER_LONG))) |
| 380 | } | 380 | sprintf(alias + strlen(alias), "%X,*", i); |
| 381 | } | 381 | } |
| 382 | 382 | ||
| 383 | /* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */ | 383 | /* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */ |
| @@ -386,39 +386,37 @@ static int do_input_entry(const char *filename, struct input_device_id *id, | |||
| 386 | { | 386 | { |
| 387 | sprintf(alias, "input:"); | 387 | sprintf(alias, "input:"); |
| 388 | 388 | ||
| 389 | ADD(alias, "b", id->flags&INPUT_DEVICE_ID_MATCH_BUS, id->id.bustype); | 389 | ADD(alias, "b", id->flags & INPUT_DEVICE_ID_MATCH_BUS, id->bustype); |
| 390 | ADD(alias, "v", id->flags&INPUT_DEVICE_ID_MATCH_VENDOR, id->id.vendor); | 390 | ADD(alias, "v", id->flags & INPUT_DEVICE_ID_MATCH_VENDOR, id->vendor); |
| 391 | ADD(alias, "p", id->flags&INPUT_DEVICE_ID_MATCH_PRODUCT, | 391 | ADD(alias, "p", id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT, id->product); |
| 392 | id->id.product); | 392 | ADD(alias, "e", id->flags & INPUT_DEVICE_ID_MATCH_VERSION, id->version); |
| 393 | ADD(alias, "e", id->flags&INPUT_DEVICE_ID_MATCH_VERSION, | ||
| 394 | id->id.version); | ||
| 395 | 393 | ||
| 396 | sprintf(alias + strlen(alias), "-e*"); | 394 | sprintf(alias + strlen(alias), "-e*"); |
| 397 | if (id->flags&INPUT_DEVICE_ID_MATCH_EVBIT) | 395 | if (id->flags & INPUT_DEVICE_ID_MATCH_EVBIT) |
| 398 | do_input(alias, id->evbit, 0, EV_MAX); | 396 | do_input(alias, id->evbit, 0, EV_MAX); |
| 399 | sprintf(alias + strlen(alias), "k*"); | 397 | sprintf(alias + strlen(alias), "k*"); |
| 400 | if (id->flags&INPUT_DEVICE_ID_MATCH_KEYBIT) | 398 | if (id->flags & INPUT_DEVICE_ID_MATCH_KEYBIT) |
| 401 | do_input(alias, id->keybit, KEY_MIN_INTERESTING, KEY_MAX); | 399 | do_input(alias, id->keybit, KEY_MIN_INTERESTING, KEY_MAX); |
| 402 | sprintf(alias + strlen(alias), "r*"); | 400 | sprintf(alias + strlen(alias), "r*"); |
| 403 | if (id->flags&INPUT_DEVICE_ID_MATCH_RELBIT) | 401 | if (id->flags & INPUT_DEVICE_ID_MATCH_RELBIT) |
| 404 | do_input(alias, id->relbit, 0, REL_MAX); | 402 | do_input(alias, id->relbit, 0, REL_MAX); |
| 405 | sprintf(alias + strlen(alias), "a*"); | 403 | sprintf(alias + strlen(alias), "a*"); |
| 406 | if (id->flags&INPUT_DEVICE_ID_MATCH_ABSBIT) | 404 | if (id->flags & INPUT_DEVICE_ID_MATCH_ABSBIT) |
| 407 | do_input(alias, id->absbit, 0, ABS_MAX); | 405 | do_input(alias, id->absbit, 0, ABS_MAX); |
| 408 | sprintf(alias + strlen(alias), "m*"); | 406 | sprintf(alias + strlen(alias), "m*"); |
| 409 | if (id->flags&INPUT_DEVICE_ID_MATCH_MSCIT) | 407 | if (id->flags & INPUT_DEVICE_ID_MATCH_MSCIT) |
| 410 | do_input(alias, id->mscbit, 0, MSC_MAX); | 408 | do_input(alias, id->mscbit, 0, MSC_MAX); |
| 411 | sprintf(alias + strlen(alias), "l*"); | 409 | sprintf(alias + strlen(alias), "l*"); |
| 412 | if (id->flags&INPUT_DEVICE_ID_MATCH_LEDBIT) | 410 | if (id->flags & INPUT_DEVICE_ID_MATCH_LEDBIT) |
| 413 | do_input(alias, id->ledbit, 0, LED_MAX); | 411 | do_input(alias, id->ledbit, 0, LED_MAX); |
| 414 | sprintf(alias + strlen(alias), "s*"); | 412 | sprintf(alias + strlen(alias), "s*"); |
| 415 | if (id->flags&INPUT_DEVICE_ID_MATCH_SNDBIT) | 413 | if (id->flags & INPUT_DEVICE_ID_MATCH_SNDBIT) |
| 416 | do_input(alias, id->sndbit, 0, SND_MAX); | 414 | do_input(alias, id->sndbit, 0, SND_MAX); |
| 417 | sprintf(alias + strlen(alias), "f*"); | 415 | sprintf(alias + strlen(alias), "f*"); |
| 418 | if (id->flags&INPUT_DEVICE_ID_MATCH_FFBIT) | 416 | if (id->flags & INPUT_DEVICE_ID_MATCH_FFBIT) |
| 419 | do_input(alias, id->ffbit, 0, FF_MAX); | 417 | do_input(alias, id->ffbit, 0, FF_MAX); |
| 420 | sprintf(alias + strlen(alias), "w*"); | 418 | sprintf(alias + strlen(alias), "w*"); |
| 421 | if (id->flags&INPUT_DEVICE_ID_MATCH_SWBIT) | 419 | if (id->flags & INPUT_DEVICE_ID_MATCH_SWBIT) |
| 422 | do_input(alias, id->swbit, 0, SW_MAX); | 420 | do_input(alias, id->swbit, 0, SW_MAX); |
| 423 | return 1; | 421 | return 1; |
| 424 | } | 422 | } |
