diff options
Diffstat (limited to 'drivers')
63 files changed, 5453 insertions, 1809 deletions
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index a7ca75212bfe..e95d7876ca6b 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -175,8 +175,7 @@ EXPORT_SYMBOL_GPL(unregister_keyboard_notifier); | |||
175 | */ | 175 | */ |
176 | 176 | ||
177 | struct getset_keycode_data { | 177 | struct getset_keycode_data { |
178 | unsigned int scancode; | 178 | struct input_keymap_entry ke; |
179 | unsigned int keycode; | ||
180 | int error; | 179 | int error; |
181 | }; | 180 | }; |
182 | 181 | ||
@@ -184,32 +183,50 @@ static int getkeycode_helper(struct input_handle *handle, void *data) | |||
184 | { | 183 | { |
185 | struct getset_keycode_data *d = data; | 184 | struct getset_keycode_data *d = data; |
186 | 185 | ||
187 | d->error = input_get_keycode(handle->dev, d->scancode, &d->keycode); | 186 | d->error = input_get_keycode(handle->dev, &d->ke); |
188 | 187 | ||
189 | return d->error == 0; /* stop as soon as we successfully get one */ | 188 | return d->error == 0; /* stop as soon as we successfully get one */ |
190 | } | 189 | } |
191 | 190 | ||
192 | int getkeycode(unsigned int scancode) | 191 | int getkeycode(unsigned int scancode) |
193 | { | 192 | { |
194 | struct getset_keycode_data d = { scancode, 0, -ENODEV }; | 193 | struct getset_keycode_data d = { |
194 | .ke = { | ||
195 | .flags = 0, | ||
196 | .len = sizeof(scancode), | ||
197 | .keycode = 0, | ||
198 | }, | ||
199 | .error = -ENODEV, | ||
200 | }; | ||
201 | |||
202 | memcpy(d.ke.scancode, &scancode, sizeof(scancode)); | ||
195 | 203 | ||
196 | input_handler_for_each_handle(&kbd_handler, &d, getkeycode_helper); | 204 | input_handler_for_each_handle(&kbd_handler, &d, getkeycode_helper); |
197 | 205 | ||
198 | return d.error ?: d.keycode; | 206 | return d.error ?: d.ke.keycode; |
199 | } | 207 | } |
200 | 208 | ||
201 | static int setkeycode_helper(struct input_handle *handle, void *data) | 209 | static int setkeycode_helper(struct input_handle *handle, void *data) |
202 | { | 210 | { |
203 | struct getset_keycode_data *d = data; | 211 | struct getset_keycode_data *d = data; |
204 | 212 | ||
205 | d->error = input_set_keycode(handle->dev, d->scancode, d->keycode); | 213 | d->error = input_set_keycode(handle->dev, &d->ke); |
206 | 214 | ||
207 | return d->error == 0; /* stop as soon as we successfully set one */ | 215 | return d->error == 0; /* stop as soon as we successfully set one */ |
208 | } | 216 | } |
209 | 217 | ||
210 | int setkeycode(unsigned int scancode, unsigned int keycode) | 218 | int setkeycode(unsigned int scancode, unsigned int keycode) |
211 | { | 219 | { |
212 | struct getset_keycode_data d = { scancode, keycode, -ENODEV }; | 220 | struct getset_keycode_data d = { |
221 | .ke = { | ||
222 | .flags = 0, | ||
223 | .len = sizeof(scancode), | ||
224 | .keycode = keycode, | ||
225 | }, | ||
226 | .error = -ENODEV, | ||
227 | }; | ||
228 | |||
229 | memcpy(d.ke.scancode, &scancode, sizeof(scancode)); | ||
213 | 230 | ||
214 | input_handler_for_each_handle(&kbd_handler, &d, setkeycode_helper); | 231 | input_handler_for_each_handle(&kbd_handler, &d, setkeycode_helper); |
215 | 232 | ||
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index f3019f53e875..eaa5d3efa79d 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -566,10 +566,16 @@ static const unsigned char sysrq_xlate[KEY_MAX + 1] = | |||
566 | static bool sysrq_down; | 566 | static bool sysrq_down; |
567 | static int sysrq_alt_use; | 567 | static int sysrq_alt_use; |
568 | static int sysrq_alt; | 568 | static int sysrq_alt; |
569 | static DEFINE_SPINLOCK(sysrq_event_lock); | ||
569 | 570 | ||
570 | static bool sysrq_filter(struct input_handle *handle, unsigned int type, | 571 | static bool sysrq_filter(struct input_handle *handle, unsigned int type, |
571 | unsigned int code, int value) | 572 | unsigned int code, int value) |
572 | { | 573 | { |
574 | bool suppress; | ||
575 | |||
576 | /* We are called with interrupts disabled, just take the lock */ | ||
577 | spin_lock(&sysrq_event_lock); | ||
578 | |||
573 | if (type != EV_KEY) | 579 | if (type != EV_KEY) |
574 | goto out; | 580 | goto out; |
575 | 581 | ||
@@ -601,7 +607,10 @@ static bool sysrq_filter(struct input_handle *handle, unsigned int type, | |||
601 | } | 607 | } |
602 | 608 | ||
603 | out: | 609 | out: |
604 | return sysrq_down; | 610 | suppress = sysrq_down; |
611 | spin_unlock(&sysrq_event_lock); | ||
612 | |||
613 | return suppress; | ||
605 | } | 614 | } |
606 | 615 | ||
607 | static int sysrq_connect(struct input_handler *handler, | 616 | static int sysrq_connect(struct input_handler *handler, |
@@ -652,8 +661,8 @@ static void sysrq_disconnect(struct input_handle *handle) | |||
652 | } | 661 | } |
653 | 662 | ||
654 | /* | 663 | /* |
655 | * We are matching on KEY_LEFTALT insteard of KEY_SYSRQ because not all | 664 | * We are matching on KEY_LEFTALT instead of KEY_SYSRQ because not all |
656 | * keyboards have SysRq ikey predefined and so user may add it to keymap | 665 | * keyboards have SysRq key predefined and so user may add it to keymap |
657 | * later, but we expect all such keyboards to have left alt. | 666 | * later, but we expect all such keyboards to have left alt. |
658 | */ | 667 | */ |
659 | static const struct input_device_id sysrq_ids[] = { | 668 | static const struct input_device_id sysrq_ids[] = { |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 7832b6e2478b..515345b11ac9 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1780,6 +1780,11 @@ static bool hid_ignore(struct hid_device *hdev) | |||
1780 | hdev->product <= USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST) | 1780 | hdev->product <= USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST) |
1781 | return true; | 1781 | return true; |
1782 | break; | 1782 | break; |
1783 | case USB_VENDOR_ID_HANWANG: | ||
1784 | if (hdev->product >= USB_DEVICE_ID_HANWANG_TABLET_FIRST && | ||
1785 | hdev->product <= USB_DEVICE_ID_HANWANG_TABLET_LAST) | ||
1786 | return true; | ||
1787 | break; | ||
1783 | } | 1788 | } |
1784 | 1789 | ||
1785 | if (hdev->type == HID_TYPE_USBMOUSE && | 1790 | if (hdev->type == HID_TYPE_USBMOUSE && |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 3ee999d33004..3341baa86a30 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -299,6 +299,10 @@ | |||
299 | #define USB_DEVICE_ID_GYRATION_REMOTE_2 0x0003 | 299 | #define USB_DEVICE_ID_GYRATION_REMOTE_2 0x0003 |
300 | #define USB_DEVICE_ID_GYRATION_REMOTE_3 0x0008 | 300 | #define USB_DEVICE_ID_GYRATION_REMOTE_3 0x0008 |
301 | 301 | ||
302 | #define USB_VENDOR_ID_HANWANG 0x0b57 | ||
303 | #define USB_DEVICE_ID_HANWANG_TABLET_FIRST 0x5000 | ||
304 | #define USB_DEVICE_ID_HANWANG_TABLET_LAST 0x8fff | ||
305 | |||
302 | #define USB_VENDOR_ID_HAPP 0x078b | 306 | #define USB_VENDOR_ID_HAPP 0x078b |
303 | #define USB_DEVICE_ID_UGCI_DRIVING 0x0010 | 307 | #define USB_DEVICE_ID_UGCI_DRIVING 0x0010 |
304 | #define USB_DEVICE_ID_UGCI_FLYING 0x0020 | 308 | #define USB_DEVICE_ID_UGCI_FLYING 0x0020 |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 834ef47b76d6..bb0b3659437b 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -68,39 +68,52 @@ static const struct { | |||
68 | #define map_key_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \ | 68 | #define map_key_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \ |
69 | &max, EV_KEY, (c)) | 69 | &max, EV_KEY, (c)) |
70 | 70 | ||
71 | static inline int match_scancode(unsigned int code, unsigned int scancode) | 71 | static bool match_scancode(struct hid_usage *usage, |
72 | unsigned int cur_idx, unsigned int scancode) | ||
72 | { | 73 | { |
73 | if (scancode == 0) | 74 | return (usage->hid & (HID_USAGE_PAGE | HID_USAGE)) == scancode; |
74 | return 1; | ||
75 | |||
76 | return (code & (HID_USAGE_PAGE | HID_USAGE)) == scancode; | ||
77 | } | 75 | } |
78 | 76 | ||
79 | static inline int match_keycode(unsigned int code, unsigned int keycode) | 77 | static bool match_keycode(struct hid_usage *usage, |
78 | unsigned int cur_idx, unsigned int keycode) | ||
80 | { | 79 | { |
81 | if (keycode == 0) | 80 | /* |
82 | return 1; | 81 | * We should exclude unmapped usages when doing lookup by keycode. |
82 | */ | ||
83 | return (usage->type == EV_KEY && usage->code == keycode); | ||
84 | } | ||
83 | 85 | ||
84 | return code == keycode; | 86 | static bool match_index(struct hid_usage *usage, |
87 | unsigned int cur_idx, unsigned int idx) | ||
88 | { | ||
89 | return cur_idx == idx; | ||
85 | } | 90 | } |
86 | 91 | ||
92 | typedef bool (*hid_usage_cmp_t)(struct hid_usage *usage, | ||
93 | unsigned int cur_idx, unsigned int val); | ||
94 | |||
87 | static struct hid_usage *hidinput_find_key(struct hid_device *hid, | 95 | static struct hid_usage *hidinput_find_key(struct hid_device *hid, |
88 | unsigned int scancode, | 96 | hid_usage_cmp_t match, |
89 | unsigned int keycode) | 97 | unsigned int value, |
98 | unsigned int *usage_idx) | ||
90 | { | 99 | { |
91 | int i, j, k; | 100 | unsigned int i, j, k, cur_idx = 0; |
92 | struct hid_report *report; | 101 | struct hid_report *report; |
93 | struct hid_usage *usage; | 102 | struct hid_usage *usage; |
94 | 103 | ||
95 | for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) { | 104 | for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) { |
96 | list_for_each_entry(report, &hid->report_enum[k].report_list, list) { | 105 | list_for_each_entry(report, &hid->report_enum[k].report_list, list) { |
97 | for (i = 0; i < report->maxfield; i++) { | 106 | for (i = 0; i < report->maxfield; i++) { |
98 | for ( j = 0; j < report->field[i]->maxusage; j++) { | 107 | for (j = 0; j < report->field[i]->maxusage; j++) { |
99 | usage = report->field[i]->usage + j; | 108 | usage = report->field[i]->usage + j; |
100 | if (usage->type == EV_KEY && | 109 | if (usage->type == EV_KEY || usage->type == 0) { |
101 | match_scancode(usage->hid, scancode) && | 110 | if (match(usage, cur_idx, value)) { |
102 | match_keycode(usage->code, keycode)) | 111 | if (usage_idx) |
103 | return usage; | 112 | *usage_idx = cur_idx; |
113 | return usage; | ||
114 | } | ||
115 | cur_idx++; | ||
116 | } | ||
104 | } | 117 | } |
105 | } | 118 | } |
106 | } | 119 | } |
@@ -108,39 +121,68 @@ static struct hid_usage *hidinput_find_key(struct hid_device *hid, | |||
108 | return NULL; | 121 | return NULL; |
109 | } | 122 | } |
110 | 123 | ||
124 | static struct hid_usage *hidinput_locate_usage(struct hid_device *hid, | ||
125 | const struct input_keymap_entry *ke, | ||
126 | unsigned int *index) | ||
127 | { | ||
128 | struct hid_usage *usage; | ||
129 | unsigned int scancode; | ||
130 | |||
131 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) | ||
132 | usage = hidinput_find_key(hid, match_index, ke->index, index); | ||
133 | else if (input_scancode_to_scalar(ke, &scancode) == 0) | ||
134 | usage = hidinput_find_key(hid, match_scancode, scancode, index); | ||
135 | else | ||
136 | usage = NULL; | ||
137 | |||
138 | return usage; | ||
139 | } | ||
140 | |||
111 | static int hidinput_getkeycode(struct input_dev *dev, | 141 | static int hidinput_getkeycode(struct input_dev *dev, |
112 | unsigned int scancode, unsigned int *keycode) | 142 | struct input_keymap_entry *ke) |
113 | { | 143 | { |
114 | struct hid_device *hid = input_get_drvdata(dev); | 144 | struct hid_device *hid = input_get_drvdata(dev); |
115 | struct hid_usage *usage; | 145 | struct hid_usage *usage; |
146 | unsigned int scancode, index; | ||
116 | 147 | ||
117 | usage = hidinput_find_key(hid, scancode, 0); | 148 | usage = hidinput_locate_usage(hid, ke, &index); |
118 | if (usage) { | 149 | if (usage) { |
119 | *keycode = usage->code; | 150 | ke->keycode = usage->type == EV_KEY ? |
151 | usage->code : KEY_RESERVED; | ||
152 | ke->index = index; | ||
153 | scancode = usage->hid & (HID_USAGE_PAGE | HID_USAGE); | ||
154 | ke->len = sizeof(scancode); | ||
155 | memcpy(ke->scancode, &scancode, sizeof(scancode)); | ||
120 | return 0; | 156 | return 0; |
121 | } | 157 | } |
158 | |||
122 | return -EINVAL; | 159 | return -EINVAL; |
123 | } | 160 | } |
124 | 161 | ||
125 | static int hidinput_setkeycode(struct input_dev *dev, | 162 | static int hidinput_setkeycode(struct input_dev *dev, |
126 | unsigned int scancode, unsigned int keycode) | 163 | const struct input_keymap_entry *ke, |
164 | unsigned int *old_keycode) | ||
127 | { | 165 | { |
128 | struct hid_device *hid = input_get_drvdata(dev); | 166 | struct hid_device *hid = input_get_drvdata(dev); |
129 | struct hid_usage *usage; | 167 | struct hid_usage *usage; |
130 | int old_keycode; | ||
131 | 168 | ||
132 | usage = hidinput_find_key(hid, scancode, 0); | 169 | usage = hidinput_locate_usage(hid, ke, NULL); |
133 | if (usage) { | 170 | if (usage) { |
134 | old_keycode = usage->code; | 171 | *old_keycode = usage->type == EV_KEY ? |
135 | usage->code = keycode; | 172 | usage->code : KEY_RESERVED; |
173 | usage->code = ke->keycode; | ||
136 | 174 | ||
137 | clear_bit(old_keycode, dev->keybit); | 175 | clear_bit(*old_keycode, dev->keybit); |
138 | set_bit(usage->code, dev->keybit); | 176 | set_bit(usage->code, dev->keybit); |
139 | dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode); | 177 | dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", |
140 | /* Set the keybit for the old keycode if the old keycode is used | 178 | usage->code, usage->hid); |
141 | * by another key */ | 179 | |
142 | if (hidinput_find_key (hid, 0, old_keycode)) | 180 | /* |
143 | set_bit(old_keycode, dev->keybit); | 181 | * Set the keybit for the old keycode if the old keycode is used |
182 | * by another key | ||
183 | */ | ||
184 | if (hidinput_find_key(hid, match_keycode, *old_keycode, NULL)) | ||
185 | set_bit(*old_keycode, dev->keybit); | ||
144 | 186 | ||
145 | return 0; | 187 | return 0; |
146 | } | 188 | } |
@@ -835,8 +877,8 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) | |||
835 | hid->ll_driver->hidinput_input_event; | 877 | hid->ll_driver->hidinput_input_event; |
836 | input_dev->open = hidinput_open; | 878 | input_dev->open = hidinput_open; |
837 | input_dev->close = hidinput_close; | 879 | input_dev->close = hidinput_close; |
838 | input_dev->setkeycode = hidinput_setkeycode; | 880 | input_dev->setkeycode_new = hidinput_setkeycode; |
839 | input_dev->getkeycode = hidinput_getkeycode; | 881 | input_dev->getkeycode_new = hidinput_getkeycode; |
840 | 882 | ||
841 | input_dev->name = hid->name; | 883 | input_dev->name = hid->name; |
842 | input_dev->phys = hid->phys; | 884 | input_dev->phys = hid->phys; |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 535fea4fe67f..e3f7fc6f9565 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -534,6 +534,80 @@ static int handle_eviocgbit(struct input_dev *dev, | |||
534 | } | 534 | } |
535 | #undef OLD_KEY_MAX | 535 | #undef OLD_KEY_MAX |
536 | 536 | ||
537 | static int evdev_handle_get_keycode(struct input_dev *dev, | ||
538 | void __user *p, size_t size) | ||
539 | { | ||
540 | struct input_keymap_entry ke; | ||
541 | int error; | ||
542 | |||
543 | memset(&ke, 0, sizeof(ke)); | ||
544 | |||
545 | if (size == sizeof(unsigned int[2])) { | ||
546 | /* legacy case */ | ||
547 | int __user *ip = (int __user *)p; | ||
548 | |||
549 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | ||
550 | return -EFAULT; | ||
551 | |||
552 | ke.len = sizeof(unsigned int); | ||
553 | ke.flags = 0; | ||
554 | |||
555 | error = input_get_keycode(dev, &ke); | ||
556 | if (error) | ||
557 | return error; | ||
558 | |||
559 | if (put_user(ke.keycode, ip + 1)) | ||
560 | return -EFAULT; | ||
561 | |||
562 | } else { | ||
563 | size = min(size, sizeof(ke)); | ||
564 | |||
565 | if (copy_from_user(&ke, p, size)) | ||
566 | return -EFAULT; | ||
567 | |||
568 | error = input_get_keycode(dev, &ke); | ||
569 | if (error) | ||
570 | return error; | ||
571 | |||
572 | if (copy_to_user(p, &ke, size)) | ||
573 | return -EFAULT; | ||
574 | } | ||
575 | return 0; | ||
576 | } | ||
577 | |||
578 | static int evdev_handle_set_keycode(struct input_dev *dev, | ||
579 | void __user *p, size_t size) | ||
580 | { | ||
581 | struct input_keymap_entry ke; | ||
582 | |||
583 | memset(&ke, 0, sizeof(ke)); | ||
584 | |||
585 | if (size == sizeof(unsigned int[2])) { | ||
586 | /* legacy case */ | ||
587 | int __user *ip = (int __user *)p; | ||
588 | |||
589 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | ||
590 | return -EFAULT; | ||
591 | |||
592 | if (get_user(ke.keycode, ip + 1)) | ||
593 | return -EFAULT; | ||
594 | |||
595 | ke.len = sizeof(unsigned int); | ||
596 | ke.flags = 0; | ||
597 | |||
598 | } else { | ||
599 | size = min(size, sizeof(ke)); | ||
600 | |||
601 | if (copy_from_user(&ke, p, size)) | ||
602 | return -EFAULT; | ||
603 | |||
604 | if (ke.len > sizeof(ke.scancode)) | ||
605 | return -EINVAL; | ||
606 | } | ||
607 | |||
608 | return input_set_keycode(dev, &ke); | ||
609 | } | ||
610 | |||
537 | static long evdev_do_ioctl(struct file *file, unsigned int cmd, | 611 | static long evdev_do_ioctl(struct file *file, unsigned int cmd, |
538 | void __user *p, int compat_mode) | 612 | void __user *p, int compat_mode) |
539 | { | 613 | { |
@@ -580,25 +654,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
580 | 654 | ||
581 | return 0; | 655 | return 0; |
582 | 656 | ||
583 | case EVIOCGKEYCODE: | ||
584 | if (get_user(t, ip)) | ||
585 | return -EFAULT; | ||
586 | |||
587 | error = input_get_keycode(dev, t, &v); | ||
588 | if (error) | ||
589 | return error; | ||
590 | |||
591 | if (put_user(v, ip + 1)) | ||
592 | return -EFAULT; | ||
593 | |||
594 | return 0; | ||
595 | |||
596 | case EVIOCSKEYCODE: | ||
597 | if (get_user(t, ip) || get_user(v, ip + 1)) | ||
598 | return -EFAULT; | ||
599 | |||
600 | return input_set_keycode(dev, t, v); | ||
601 | |||
602 | case EVIOCRMFF: | 657 | case EVIOCRMFF: |
603 | return input_ff_erase(dev, (int)(unsigned long) p, file); | 658 | return input_ff_erase(dev, (int)(unsigned long) p, file); |
604 | 659 | ||
@@ -620,7 +675,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
620 | 675 | ||
621 | /* Now check variable-length commands */ | 676 | /* Now check variable-length commands */ |
622 | #define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) | 677 | #define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) |
623 | |||
624 | switch (EVIOC_MASK_SIZE(cmd)) { | 678 | switch (EVIOC_MASK_SIZE(cmd)) { |
625 | 679 | ||
626 | case EVIOCGKEY(0): | 680 | case EVIOCGKEY(0): |
@@ -654,6 +708,12 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
654 | return -EFAULT; | 708 | return -EFAULT; |
655 | 709 | ||
656 | return error; | 710 | return error; |
711 | |||
712 | case EVIOC_MASK_SIZE(EVIOCGKEYCODE): | ||
713 | return evdev_handle_get_keycode(dev, p, size); | ||
714 | |||
715 | case EVIOC_MASK_SIZE(EVIOCSKEYCODE): | ||
716 | return evdev_handle_set_keycode(dev, p, size); | ||
657 | } | 717 | } |
658 | 718 | ||
659 | /* Multi-number variable-length handlers */ | 719 | /* Multi-number variable-length handlers */ |
diff --git a/drivers/input/gameport/emu10k1-gp.c b/drivers/input/gameport/emu10k1-gp.c index 7392992da424..422aa0a6b77f 100644 --- a/drivers/input/gameport/emu10k1-gp.c +++ b/drivers/input/gameport/emu10k1-gp.c | |||
@@ -59,44 +59,52 @@ MODULE_DEVICE_TABLE(pci, emu_tbl); | |||
59 | 59 | ||
60 | static int __devinit emu_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 60 | static int __devinit emu_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
61 | { | 61 | { |
62 | int ioport, iolen; | ||
63 | struct emu *emu; | 62 | struct emu *emu; |
64 | struct gameport *port; | 63 | struct gameport *port; |
65 | 64 | int error; | |
66 | if (pci_enable_device(pdev)) | ||
67 | return -EBUSY; | ||
68 | |||
69 | ioport = pci_resource_start(pdev, 0); | ||
70 | iolen = pci_resource_len(pdev, 0); | ||
71 | |||
72 | if (!request_region(ioport, iolen, "emu10k1-gp")) | ||
73 | return -EBUSY; | ||
74 | 65 | ||
75 | emu = kzalloc(sizeof(struct emu), GFP_KERNEL); | 66 | emu = kzalloc(sizeof(struct emu), GFP_KERNEL); |
76 | port = gameport_allocate_port(); | 67 | port = gameport_allocate_port(); |
77 | if (!emu || !port) { | 68 | if (!emu || !port) { |
78 | printk(KERN_ERR "emu10k1-gp: Memory allocation failed\n"); | 69 | printk(KERN_ERR "emu10k1-gp: Memory allocation failed\n"); |
79 | release_region(ioport, iolen); | 70 | error = -ENOMEM; |
80 | kfree(emu); | 71 | goto err_out_free; |
81 | gameport_free_port(port); | ||
82 | return -ENOMEM; | ||
83 | } | 72 | } |
84 | 73 | ||
85 | emu->io = ioport; | 74 | error = pci_enable_device(pdev); |
86 | emu->size = iolen; | 75 | if (error) |
76 | goto err_out_free; | ||
77 | |||
78 | emu->io = pci_resource_start(pdev, 0); | ||
79 | emu->size = pci_resource_len(pdev, 0); | ||
80 | |||
87 | emu->dev = pdev; | 81 | emu->dev = pdev; |
88 | emu->gameport = port; | 82 | emu->gameport = port; |
89 | 83 | ||
90 | gameport_set_name(port, "EMU10K1"); | 84 | gameport_set_name(port, "EMU10K1"); |
91 | gameport_set_phys(port, "pci%s/gameport0", pci_name(pdev)); | 85 | gameport_set_phys(port, "pci%s/gameport0", pci_name(pdev)); |
92 | port->dev.parent = &pdev->dev; | 86 | port->dev.parent = &pdev->dev; |
93 | port->io = ioport; | 87 | port->io = emu->io; |
88 | |||
89 | if (!request_region(emu->io, emu->size, "emu10k1-gp")) { | ||
90 | printk(KERN_ERR "emu10k1-gp: unable to grab region 0x%x-0x%x\n", | ||
91 | emu->io, emu->io + emu->size - 1); | ||
92 | error = -EBUSY; | ||
93 | goto err_out_disable_dev; | ||
94 | } | ||
94 | 95 | ||
95 | pci_set_drvdata(pdev, emu); | 96 | pci_set_drvdata(pdev, emu); |
96 | 97 | ||
97 | gameport_register_port(port); | 98 | gameport_register_port(port); |
98 | 99 | ||
99 | return 0; | 100 | return 0; |
101 | |||
102 | err_out_disable_dev: | ||
103 | pci_disable_device(pdev); | ||
104 | err_out_free: | ||
105 | gameport_free_port(port); | ||
106 | kfree(emu); | ||
107 | return error; | ||
100 | } | 108 | } |
101 | 109 | ||
102 | static void __devexit emu_remove(struct pci_dev *pdev) | 110 | static void __devexit emu_remove(struct pci_dev *pdev) |
@@ -106,6 +114,8 @@ static void __devexit emu_remove(struct pci_dev *pdev) | |||
106 | gameport_unregister_port(emu->gameport); | 114 | gameport_unregister_port(emu->gameport); |
107 | release_region(emu->io, emu->size); | 115 | release_region(emu->io, emu->size); |
108 | kfree(emu); | 116 | kfree(emu); |
117 | |||
118 | pci_disable_device(pdev); | ||
109 | } | 119 | } |
110 | 120 | ||
111 | static struct pci_driver emu_driver = { | 121 | static struct pci_driver emu_driver = { |
diff --git a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c index 14d3f3e208a2..a3b70ff21018 100644 --- a/drivers/input/gameport/fm801-gp.c +++ b/drivers/input/gameport/fm801-gp.c | |||
@@ -133,11 +133,11 @@ static void __devexit fm801_gp_remove(struct pci_dev *pci) | |||
133 | { | 133 | { |
134 | struct fm801_gp *gp = pci_get_drvdata(pci); | 134 | struct fm801_gp *gp = pci_get_drvdata(pci); |
135 | 135 | ||
136 | if (gp) { | 136 | gameport_unregister_port(gp->gameport); |
137 | gameport_unregister_port(gp->gameport); | 137 | release_resource(gp->res_port); |
138 | release_resource(gp->res_port); | 138 | kfree(gp); |
139 | kfree(gp); | 139 | |
140 | } | 140 | pci_disable_device(pci); |
141 | } | 141 | } |
142 | 142 | ||
143 | static const struct pci_device_id fm801_gp_id_table[] = { | 143 | static const struct pci_device_id fm801_gp_id_table[] = { |
diff --git a/drivers/input/input.c b/drivers/input/input.c index 7919c2537225..d092ef9291da 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -171,7 +171,7 @@ static int input_handle_abs_event(struct input_dev *dev, | |||
171 | if (code == ABS_MT_SLOT) { | 171 | if (code == ABS_MT_SLOT) { |
172 | /* | 172 | /* |
173 | * "Stage" the event; we'll flush it later, when we | 173 | * "Stage" the event; we'll flush it later, when we |
174 | * get actiual touch data. | 174 | * get actual touch data. |
175 | */ | 175 | */ |
176 | if (*pval >= 0 && *pval < dev->mtsize) | 176 | if (*pval >= 0 && *pval < dev->mtsize) |
177 | dev->slot = *pval; | 177 | dev->slot = *pval; |
@@ -188,7 +188,7 @@ static int input_handle_abs_event(struct input_dev *dev, | |||
188 | pold = &mtslot->abs[code - ABS_MT_FIRST]; | 188 | pold = &mtslot->abs[code - ABS_MT_FIRST]; |
189 | } else { | 189 | } else { |
190 | /* | 190 | /* |
191 | * Bypass filtering for multitouch events when | 191 | * Bypass filtering for multi-touch events when |
192 | * not employing slots. | 192 | * not employing slots. |
193 | */ | 193 | */ |
194 | pold = NULL; | 194 | pold = NULL; |
@@ -634,78 +634,141 @@ static void input_disconnect_device(struct input_dev *dev) | |||
634 | spin_unlock_irq(&dev->event_lock); | 634 | spin_unlock_irq(&dev->event_lock); |
635 | } | 635 | } |
636 | 636 | ||
637 | static int input_fetch_keycode(struct input_dev *dev, int scancode) | 637 | /** |
638 | * input_scancode_to_scalar() - converts scancode in &struct input_keymap_entry | ||
639 | * @ke: keymap entry containing scancode to be converted. | ||
640 | * @scancode: pointer to the location where converted scancode should | ||
641 | * be stored. | ||
642 | * | ||
643 | * This function is used to convert scancode stored in &struct keymap_entry | ||
644 | * into scalar form understood by legacy keymap handling methods. These | ||
645 | * methods expect scancodes to be represented as 'unsigned int'. | ||
646 | */ | ||
647 | int input_scancode_to_scalar(const struct input_keymap_entry *ke, | ||
648 | unsigned int *scancode) | ||
649 | { | ||
650 | switch (ke->len) { | ||
651 | case 1: | ||
652 | *scancode = *((u8 *)ke->scancode); | ||
653 | break; | ||
654 | |||
655 | case 2: | ||
656 | *scancode = *((u16 *)ke->scancode); | ||
657 | break; | ||
658 | |||
659 | case 4: | ||
660 | *scancode = *((u32 *)ke->scancode); | ||
661 | break; | ||
662 | |||
663 | default: | ||
664 | return -EINVAL; | ||
665 | } | ||
666 | |||
667 | return 0; | ||
668 | } | ||
669 | EXPORT_SYMBOL(input_scancode_to_scalar); | ||
670 | |||
671 | /* | ||
672 | * Those routines handle the default case where no [gs]etkeycode() is | ||
673 | * defined. In this case, an array indexed by the scancode is used. | ||
674 | */ | ||
675 | |||
676 | static unsigned int input_fetch_keycode(struct input_dev *dev, | ||
677 | unsigned int index) | ||
638 | { | 678 | { |
639 | switch (dev->keycodesize) { | 679 | switch (dev->keycodesize) { |
640 | case 1: | 680 | case 1: |
641 | return ((u8 *)dev->keycode)[scancode]; | 681 | return ((u8 *)dev->keycode)[index]; |
642 | 682 | ||
643 | case 2: | 683 | case 2: |
644 | return ((u16 *)dev->keycode)[scancode]; | 684 | return ((u16 *)dev->keycode)[index]; |
645 | 685 | ||
646 | default: | 686 | default: |
647 | return ((u32 *)dev->keycode)[scancode]; | 687 | return ((u32 *)dev->keycode)[index]; |
648 | } | 688 | } |
649 | } | 689 | } |
650 | 690 | ||
651 | static int input_default_getkeycode(struct input_dev *dev, | 691 | static int input_default_getkeycode(struct input_dev *dev, |
652 | unsigned int scancode, | 692 | struct input_keymap_entry *ke) |
653 | unsigned int *keycode) | ||
654 | { | 693 | { |
694 | unsigned int index; | ||
695 | int error; | ||
696 | |||
655 | if (!dev->keycodesize) | 697 | if (!dev->keycodesize) |
656 | return -EINVAL; | 698 | return -EINVAL; |
657 | 699 | ||
658 | if (scancode >= dev->keycodemax) | 700 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) |
701 | index = ke->index; | ||
702 | else { | ||
703 | error = input_scancode_to_scalar(ke, &index); | ||
704 | if (error) | ||
705 | return error; | ||
706 | } | ||
707 | |||
708 | if (index >= dev->keycodemax) | ||
659 | return -EINVAL; | 709 | return -EINVAL; |
660 | 710 | ||
661 | *keycode = input_fetch_keycode(dev, scancode); | 711 | ke->keycode = input_fetch_keycode(dev, index); |
712 | ke->index = index; | ||
713 | ke->len = sizeof(index); | ||
714 | memcpy(ke->scancode, &index, sizeof(index)); | ||
662 | 715 | ||
663 | return 0; | 716 | return 0; |
664 | } | 717 | } |
665 | 718 | ||
666 | static int input_default_setkeycode(struct input_dev *dev, | 719 | static int input_default_setkeycode(struct input_dev *dev, |
667 | unsigned int scancode, | 720 | const struct input_keymap_entry *ke, |
668 | unsigned int keycode) | 721 | unsigned int *old_keycode) |
669 | { | 722 | { |
670 | int old_keycode; | 723 | unsigned int index; |
724 | int error; | ||
671 | int i; | 725 | int i; |
672 | 726 | ||
673 | if (scancode >= dev->keycodemax) | 727 | if (!dev->keycodesize) |
674 | return -EINVAL; | 728 | return -EINVAL; |
675 | 729 | ||
676 | if (!dev->keycodesize) | 730 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) { |
731 | index = ke->index; | ||
732 | } else { | ||
733 | error = input_scancode_to_scalar(ke, &index); | ||
734 | if (error) | ||
735 | return error; | ||
736 | } | ||
737 | |||
738 | if (index >= dev->keycodemax) | ||
677 | return -EINVAL; | 739 | return -EINVAL; |
678 | 740 | ||
679 | if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8))) | 741 | if (dev->keycodesize < sizeof(dev->keycode) && |
742 | (ke->keycode >> (dev->keycodesize * 8))) | ||
680 | return -EINVAL; | 743 | return -EINVAL; |
681 | 744 | ||
682 | switch (dev->keycodesize) { | 745 | switch (dev->keycodesize) { |
683 | case 1: { | 746 | case 1: { |
684 | u8 *k = (u8 *)dev->keycode; | 747 | u8 *k = (u8 *)dev->keycode; |
685 | old_keycode = k[scancode]; | 748 | *old_keycode = k[index]; |
686 | k[scancode] = keycode; | 749 | k[index] = ke->keycode; |
687 | break; | 750 | break; |
688 | } | 751 | } |
689 | case 2: { | 752 | case 2: { |
690 | u16 *k = (u16 *)dev->keycode; | 753 | u16 *k = (u16 *)dev->keycode; |
691 | old_keycode = k[scancode]; | 754 | *old_keycode = k[index]; |
692 | k[scancode] = keycode; | 755 | k[index] = ke->keycode; |
693 | break; | 756 | break; |
694 | } | 757 | } |
695 | default: { | 758 | default: { |
696 | u32 *k = (u32 *)dev->keycode; | 759 | u32 *k = (u32 *)dev->keycode; |
697 | old_keycode = k[scancode]; | 760 | *old_keycode = k[index]; |
698 | k[scancode] = keycode; | 761 | k[index] = ke->keycode; |
699 | break; | 762 | break; |
700 | } | 763 | } |
701 | } | 764 | } |
702 | 765 | ||
703 | __clear_bit(old_keycode, dev->keybit); | 766 | __clear_bit(*old_keycode, dev->keybit); |
704 | __set_bit(keycode, dev->keybit); | 767 | __set_bit(ke->keycode, dev->keybit); |
705 | 768 | ||
706 | for (i = 0; i < dev->keycodemax; i++) { | 769 | for (i = 0; i < dev->keycodemax; i++) { |
707 | if (input_fetch_keycode(dev, i) == old_keycode) { | 770 | if (input_fetch_keycode(dev, i) == *old_keycode) { |
708 | __set_bit(old_keycode, dev->keybit); | 771 | __set_bit(*old_keycode, dev->keybit); |
709 | break; /* Setting the bit twice is useless, so break */ | 772 | break; /* Setting the bit twice is useless, so break */ |
710 | } | 773 | } |
711 | } | 774 | } |
@@ -716,53 +779,86 @@ static int input_default_setkeycode(struct input_dev *dev, | |||
716 | /** | 779 | /** |
717 | * input_get_keycode - retrieve keycode currently mapped to a given scancode | 780 | * input_get_keycode - retrieve keycode currently mapped to a given scancode |
718 | * @dev: input device which keymap is being queried | 781 | * @dev: input device which keymap is being queried |
719 | * @scancode: scancode (or its equivalent for device in question) for which | 782 | * @ke: keymap entry |
720 | * keycode is needed | ||
721 | * @keycode: result | ||
722 | * | 783 | * |
723 | * This function should be called by anyone interested in retrieving current | 784 | * This function should be called by anyone interested in retrieving current |
724 | * keymap. Presently keyboard and evdev handlers use it. | 785 | * keymap. Presently evdev handlers use it. |
725 | */ | 786 | */ |
726 | int input_get_keycode(struct input_dev *dev, | 787 | int input_get_keycode(struct input_dev *dev, struct input_keymap_entry *ke) |
727 | unsigned int scancode, unsigned int *keycode) | ||
728 | { | 788 | { |
729 | unsigned long flags; | 789 | unsigned long flags; |
730 | int retval; | 790 | int retval; |
731 | 791 | ||
732 | spin_lock_irqsave(&dev->event_lock, flags); | 792 | spin_lock_irqsave(&dev->event_lock, flags); |
733 | retval = dev->getkeycode(dev, scancode, keycode); | ||
734 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
735 | 793 | ||
794 | if (dev->getkeycode) { | ||
795 | /* | ||
796 | * Support for legacy drivers, that don't implement the new | ||
797 | * ioctls | ||
798 | */ | ||
799 | u32 scancode = ke->index; | ||
800 | |||
801 | memcpy(ke->scancode, &scancode, sizeof(scancode)); | ||
802 | ke->len = sizeof(scancode); | ||
803 | retval = dev->getkeycode(dev, scancode, &ke->keycode); | ||
804 | } else { | ||
805 | retval = dev->getkeycode_new(dev, ke); | ||
806 | } | ||
807 | |||
808 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
736 | return retval; | 809 | return retval; |
737 | } | 810 | } |
738 | EXPORT_SYMBOL(input_get_keycode); | 811 | EXPORT_SYMBOL(input_get_keycode); |
739 | 812 | ||
740 | /** | 813 | /** |
741 | * input_get_keycode - assign new keycode to a given scancode | 814 | * input_set_keycode - attribute a keycode to a given scancode |
742 | * @dev: input device which keymap is being updated | 815 | * @dev: input device which keymap is being updated |
743 | * @scancode: scancode (or its equivalent for device in question) | 816 | * @ke: new keymap entry |
744 | * @keycode: new keycode to be assigned to the scancode | ||
745 | * | 817 | * |
746 | * This function should be called by anyone needing to update current | 818 | * This function should be called by anyone needing to update current |
747 | * keymap. Presently keyboard and evdev handlers use it. | 819 | * keymap. Presently keyboard and evdev handlers use it. |
748 | */ | 820 | */ |
749 | int input_set_keycode(struct input_dev *dev, | 821 | int input_set_keycode(struct input_dev *dev, |
750 | unsigned int scancode, unsigned int keycode) | 822 | const struct input_keymap_entry *ke) |
751 | { | 823 | { |
752 | unsigned long flags; | 824 | unsigned long flags; |
753 | unsigned int old_keycode; | 825 | unsigned int old_keycode; |
754 | int retval; | 826 | int retval; |
755 | 827 | ||
756 | if (keycode > KEY_MAX) | 828 | if (ke->keycode > KEY_MAX) |
757 | return -EINVAL; | 829 | return -EINVAL; |
758 | 830 | ||
759 | spin_lock_irqsave(&dev->event_lock, flags); | 831 | spin_lock_irqsave(&dev->event_lock, flags); |
760 | 832 | ||
761 | retval = dev->getkeycode(dev, scancode, &old_keycode); | 833 | if (dev->setkeycode) { |
762 | if (retval) | 834 | /* |
763 | goto out; | 835 | * Support for legacy drivers, that don't implement the new |
836 | * ioctls | ||
837 | */ | ||
838 | unsigned int scancode; | ||
839 | |||
840 | retval = input_scancode_to_scalar(ke, &scancode); | ||
841 | if (retval) | ||
842 | goto out; | ||
843 | |||
844 | /* | ||
845 | * We need to know the old scancode, in order to generate a | ||
846 | * keyup effect, if the set operation happens successfully | ||
847 | */ | ||
848 | if (!dev->getkeycode) { | ||
849 | retval = -EINVAL; | ||
850 | goto out; | ||
851 | } | ||
852 | |||
853 | retval = dev->getkeycode(dev, scancode, &old_keycode); | ||
854 | if (retval) | ||
855 | goto out; | ||
856 | |||
857 | retval = dev->setkeycode(dev, scancode, ke->keycode); | ||
858 | } else { | ||
859 | retval = dev->setkeycode_new(dev, ke, &old_keycode); | ||
860 | } | ||
764 | 861 | ||
765 | retval = dev->setkeycode(dev, scancode, keycode); | ||
766 | if (retval) | 862 | if (retval) |
767 | goto out; | 863 | goto out; |
768 | 864 | ||
@@ -1601,7 +1697,7 @@ EXPORT_SYMBOL(input_free_device); | |||
1601 | * | 1697 | * |
1602 | * This function allocates all necessary memory for MT slot handling in the | 1698 | * This function allocates all necessary memory for MT slot handling in the |
1603 | * input device, and adds ABS_MT_SLOT to the device capabilities. All slots | 1699 | * input device, and adds ABS_MT_SLOT to the device capabilities. All slots |
1604 | * are initially marked as unused iby setting ABS_MT_TRACKING_ID to -1. | 1700 | * are initially marked as unused by setting ABS_MT_TRACKING_ID to -1. |
1605 | */ | 1701 | */ |
1606 | int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots) | 1702 | int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots) |
1607 | { | 1703 | { |
@@ -1759,11 +1855,11 @@ int input_register_device(struct input_dev *dev) | |||
1759 | dev->rep[REP_PERIOD] = 33; | 1855 | dev->rep[REP_PERIOD] = 33; |
1760 | } | 1856 | } |
1761 | 1857 | ||
1762 | if (!dev->getkeycode) | 1858 | if (!dev->getkeycode && !dev->getkeycode_new) |
1763 | dev->getkeycode = input_default_getkeycode; | 1859 | dev->getkeycode_new = input_default_getkeycode; |
1764 | 1860 | ||
1765 | if (!dev->setkeycode) | 1861 | if (!dev->setkeycode && !dev->setkeycode_new) |
1766 | dev->setkeycode = input_default_setkeycode; | 1862 | dev->setkeycode_new = input_default_setkeycode; |
1767 | 1863 | ||
1768 | dev_set_name(&dev->dev, "input%ld", | 1864 | dev_set_name(&dev->dev, "input%ld", |
1769 | (unsigned long) atomic_inc_return(&input_no) - 1); | 1865 | (unsigned long) atomic_inc_return(&input_no) - 1); |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index aa037fec2f86..0426630f0e98 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -327,6 +327,16 @@ config KEYBOARD_NEWTON | |||
327 | To compile this driver as a module, choose M here: the | 327 | To compile this driver as a module, choose M here: the |
328 | module will be called newtonkbd. | 328 | module will be called newtonkbd. |
329 | 329 | ||
330 | config KEYBOARD_NOMADIK | ||
331 | tristate "ST-Ericsson Nomadik SKE keyboard" | ||
332 | depends on PLAT_NOMADIK | ||
333 | help | ||
334 | Say Y here if you want to use a keypad provided on the SKE controller | ||
335 | used on the Ux500 and Nomadik platforms | ||
336 | |||
337 | To compile this driver as a module, choose M here: the | ||
338 | module will be called nmk-ske-keypad. | ||
339 | |||
330 | config KEYBOARD_OPENCORES | 340 | config KEYBOARD_OPENCORES |
331 | tristate "OpenCores Keyboard Controller" | 341 | tristate "OpenCores Keyboard Controller" |
332 | help | 342 | help |
@@ -424,6 +434,15 @@ config KEYBOARD_OMAP | |||
424 | To compile this driver as a module, choose M here: the | 434 | To compile this driver as a module, choose M here: the |
425 | module will be called omap-keypad. | 435 | module will be called omap-keypad. |
426 | 436 | ||
437 | config KEYBOARD_OMAP4 | ||
438 | tristate "TI OMAP4 keypad support" | ||
439 | depends on ARCH_OMAP4 | ||
440 | help | ||
441 | Say Y here if you want to use the OMAP4 keypad. | ||
442 | |||
443 | To compile this driver as a module, choose M here: the | ||
444 | module will be called omap4-keypad. | ||
445 | |||
427 | config KEYBOARD_TWL4030 | 446 | config KEYBOARD_TWL4030 |
428 | tristate "TI TWL4030/TWL5030/TPS659x0 keypad support" | 447 | tristate "TI TWL4030/TWL5030/TPS659x0 keypad support" |
429 | depends on TWL4030_CORE | 448 | depends on TWL4030_CORE |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 504b591be0cd..c13809c5c3a7 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -28,7 +28,9 @@ obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o | |||
28 | obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o | 28 | obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o |
29 | obj-$(CONFIG_KEYBOARD_MCS) += mcs_touchkey.o | 29 | obj-$(CONFIG_KEYBOARD_MCS) += mcs_touchkey.o |
30 | obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o | 30 | obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o |
31 | obj-$(CONFIG_KEYBOARD_NOMADIK) += nomadik-ske-keypad.o | ||
31 | obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o | 32 | obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o |
33 | obj-$(CONFIG_KEYBOARD_OMAP4) += omap4-keypad.o | ||
32 | obj-$(CONFIG_KEYBOARD_OPENCORES) += opencores-kbd.o | 34 | obj-$(CONFIG_KEYBOARD_OPENCORES) += opencores-kbd.o |
33 | obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o | 35 | obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o |
34 | obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o | 36 | obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o |
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index d6918cb966c0..b92d1cd5cba1 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c | |||
@@ -660,7 +660,7 @@ static const struct dev_pm_ops adp5588_dev_pm_ops = { | |||
660 | #endif | 660 | #endif |
661 | 661 | ||
662 | static const struct i2c_device_id adp5588_id[] = { | 662 | static const struct i2c_device_id adp5588_id[] = { |
663 | { KBUILD_MODNAME, 0 }, | 663 | { "adp5588-keys", 0 }, |
664 | { "adp5587-keys", 0 }, | 664 | { "adp5587-keys", 0 }, |
665 | { } | 665 | { } |
666 | }; | 666 | }; |
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index 19fa94af207a..fed31e0947a1 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c | |||
@@ -570,6 +570,8 @@ static struct serio_device_id hil_dev_ids[] = { | |||
570 | { 0 } | 570 | { 0 } |
571 | }; | 571 | }; |
572 | 572 | ||
573 | MODULE_DEVICE_TABLE(serio, hil_dev_ids); | ||
574 | |||
573 | static struct serio_driver hil_serio_drv = { | 575 | static struct serio_driver hil_serio_drv = { |
574 | .driver = { | 576 | .driver = { |
575 | .name = "hil_dev", | 577 | .name = "hil_dev", |
diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c new file mode 100644 index 000000000000..6e0f23091360 --- /dev/null +++ b/drivers/input/keyboard/nomadik-ske-keypad.c | |||
@@ -0,0 +1,408 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Naveen Kumar G <naveen.gaddipati@stericsson.com> for ST-Ericsson | ||
5 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson | ||
6 | * | ||
7 | * License terms:GNU General Public License (GPL) version 2 | ||
8 | * | ||
9 | * Keypad controller driver for the SKE (Scroll Key Encoder) module used in | ||
10 | * the Nomadik 8815 and Ux500 platforms. | ||
11 | */ | ||
12 | |||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/spinlock.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/input.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/clk.h> | ||
21 | |||
22 | #include <plat/ske.h> | ||
23 | |||
24 | /* SKE_CR bits */ | ||
25 | #define SKE_KPMLT (0x1 << 6) | ||
26 | #define SKE_KPCN (0x7 << 3) | ||
27 | #define SKE_KPASEN (0x1 << 2) | ||
28 | #define SKE_KPASON (0x1 << 7) | ||
29 | |||
30 | /* SKE_IMSC bits */ | ||
31 | #define SKE_KPIMA (0x1 << 2) | ||
32 | |||
33 | /* SKE_ICR bits */ | ||
34 | #define SKE_KPICS (0x1 << 3) | ||
35 | #define SKE_KPICA (0x1 << 2) | ||
36 | |||
37 | /* SKE_RIS bits */ | ||
38 | #define SKE_KPRISA (0x1 << 2) | ||
39 | |||
40 | #define SKE_KEYPAD_ROW_SHIFT 3 | ||
41 | #define SKE_KPD_KEYMAP_SIZE (8 * 8) | ||
42 | |||
43 | /* keypad auto scan registers */ | ||
44 | #define SKE_ASR0 0x20 | ||
45 | #define SKE_ASR1 0x24 | ||
46 | #define SKE_ASR2 0x28 | ||
47 | #define SKE_ASR3 0x2C | ||
48 | |||
49 | #define SKE_NUM_ASRX_REGISTERS (4) | ||
50 | |||
51 | /** | ||
52 | * struct ske_keypad - data structure used by keypad driver | ||
53 | * @irq: irq no | ||
54 | * @reg_base: ske regsiters base address | ||
55 | * @input: pointer to input device object | ||
56 | * @board: keypad platform device | ||
57 | * @keymap: matrix scan code table for keycodes | ||
58 | * @clk: clock structure pointer | ||
59 | */ | ||
60 | struct ske_keypad { | ||
61 | int irq; | ||
62 | void __iomem *reg_base; | ||
63 | struct input_dev *input; | ||
64 | const struct ske_keypad_platform_data *board; | ||
65 | unsigned short keymap[SKE_KPD_KEYMAP_SIZE]; | ||
66 | struct clk *clk; | ||
67 | spinlock_t ske_keypad_lock; | ||
68 | }; | ||
69 | |||
70 | static void ske_keypad_set_bits(struct ske_keypad *keypad, u16 addr, | ||
71 | u8 mask, u8 data) | ||
72 | { | ||
73 | u32 ret; | ||
74 | |||
75 | spin_lock(&keypad->ske_keypad_lock); | ||
76 | |||
77 | ret = readl(keypad->reg_base + addr); | ||
78 | ret &= ~mask; | ||
79 | ret |= data; | ||
80 | writel(ret, keypad->reg_base + addr); | ||
81 | |||
82 | spin_unlock(&keypad->ske_keypad_lock); | ||
83 | } | ||
84 | |||
85 | /* | ||
86 | * ske_keypad_chip_init: init keypad controller configuration | ||
87 | * | ||
88 | * Enable Multi key press detection, auto scan mode | ||
89 | */ | ||
90 | static int __devinit ske_keypad_chip_init(struct ske_keypad *keypad) | ||
91 | { | ||
92 | u32 value; | ||
93 | int timeout = 50; | ||
94 | |||
95 | /* check SKE_RIS to be 0 */ | ||
96 | while ((readl(keypad->reg_base + SKE_RIS) != 0x00000000) && timeout--) | ||
97 | cpu_relax(); | ||
98 | |||
99 | if (!timeout) | ||
100 | return -EINVAL; | ||
101 | |||
102 | /* | ||
103 | * set debounce value | ||
104 | * keypad dbounce is configured in DBCR[15:8] | ||
105 | * dbounce value in steps of 32/32.768 ms | ||
106 | */ | ||
107 | spin_lock(&keypad->ske_keypad_lock); | ||
108 | value = readl(keypad->reg_base + SKE_DBCR); | ||
109 | value = value & 0xff; | ||
110 | value |= ((keypad->board->debounce_ms * 32000)/32768) << 8; | ||
111 | writel(value, keypad->reg_base + SKE_DBCR); | ||
112 | spin_unlock(&keypad->ske_keypad_lock); | ||
113 | |||
114 | /* enable multi key detection */ | ||
115 | ske_keypad_set_bits(keypad, SKE_CR, 0x0, SKE_KPMLT); | ||
116 | |||
117 | /* | ||
118 | * set up the number of columns | ||
119 | * KPCN[5:3] defines no. of keypad columns to be auto scanned | ||
120 | */ | ||
121 | value = (keypad->board->kcol - 1) << 3; | ||
122 | ske_keypad_set_bits(keypad, SKE_CR, SKE_KPCN, value); | ||
123 | |||
124 | /* clear keypad interrupt for auto(and pending SW) scans */ | ||
125 | ske_keypad_set_bits(keypad, SKE_ICR, 0x0, SKE_KPICA | SKE_KPICS); | ||
126 | |||
127 | /* un-mask keypad interrupts */ | ||
128 | ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA); | ||
129 | |||
130 | /* enable automatic scan */ | ||
131 | ske_keypad_set_bits(keypad, SKE_CR, 0x0, SKE_KPASEN); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static void ske_keypad_read_data(struct ske_keypad *keypad) | ||
137 | { | ||
138 | struct input_dev *input = keypad->input; | ||
139 | u16 status; | ||
140 | int col = 0, row = 0, code; | ||
141 | int ske_asr, ske_ris, key_pressed, i; | ||
142 | |||
143 | /* | ||
144 | * Read the auto scan registers | ||
145 | * | ||
146 | * Each SKE_ASRx (x=0 to x=3) contains two row values. | ||
147 | * lower byte contains row value for column 2*x, | ||
148 | * upper byte contains row value for column 2*x + 1 | ||
149 | */ | ||
150 | for (i = 0; i < SKE_NUM_ASRX_REGISTERS; i++) { | ||
151 | ske_asr = readl(keypad->reg_base + SKE_ASR0 + (4 * i)); | ||
152 | if (!ske_asr) | ||
153 | continue; | ||
154 | |||
155 | /* now that ASRx is zero, find out the column x and row y*/ | ||
156 | if (ske_asr & 0xff) { | ||
157 | col = i * 2; | ||
158 | status = ske_asr & 0xff; | ||
159 | } else { | ||
160 | col = (i * 2) + 1; | ||
161 | status = (ske_asr & 0xff00) >> 8; | ||
162 | } | ||
163 | |||
164 | /* find out the row */ | ||
165 | row = __ffs(status); | ||
166 | |||
167 | code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT); | ||
168 | ske_ris = readl(keypad->reg_base + SKE_RIS); | ||
169 | key_pressed = ske_ris & SKE_KPRISA; | ||
170 | |||
171 | input_event(input, EV_MSC, MSC_SCAN, code); | ||
172 | input_report_key(input, keypad->keymap[code], key_pressed); | ||
173 | input_sync(input); | ||
174 | } | ||
175 | } | ||
176 | |||
177 | static irqreturn_t ske_keypad_irq(int irq, void *dev_id) | ||
178 | { | ||
179 | struct ske_keypad *keypad = dev_id; | ||
180 | int retries = 20; | ||
181 | |||
182 | /* disable auto scan interrupt; mask the interrupt generated */ | ||
183 | ske_keypad_set_bits(keypad, SKE_IMSC, ~SKE_KPIMA, 0x0); | ||
184 | ske_keypad_set_bits(keypad, SKE_ICR, 0x0, SKE_KPICA); | ||
185 | |||
186 | while ((readl(keypad->reg_base + SKE_CR) & SKE_KPASON) && --retries) | ||
187 | msleep(5); | ||
188 | |||
189 | if (retries) { | ||
190 | /* SKEx registers are stable and can be read */ | ||
191 | ske_keypad_read_data(keypad); | ||
192 | } | ||
193 | |||
194 | /* enable auto scan interrupts */ | ||
195 | ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA); | ||
196 | |||
197 | return IRQ_HANDLED; | ||
198 | } | ||
199 | |||
200 | static int __devinit ske_keypad_probe(struct platform_device *pdev) | ||
201 | { | ||
202 | const struct ske_keypad_platform_data *plat = pdev->dev.platform_data; | ||
203 | struct ske_keypad *keypad; | ||
204 | struct input_dev *input; | ||
205 | struct resource *res; | ||
206 | int irq; | ||
207 | int error; | ||
208 | |||
209 | if (!plat) { | ||
210 | dev_err(&pdev->dev, "invalid keypad platform data\n"); | ||
211 | return -EINVAL; | ||
212 | } | ||
213 | |||
214 | irq = platform_get_irq(pdev, 0); | ||
215 | if (irq < 0) { | ||
216 | dev_err(&pdev->dev, "failed to get keypad irq\n"); | ||
217 | return -EINVAL; | ||
218 | } | ||
219 | |||
220 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
221 | if (!res) { | ||
222 | dev_err(&pdev->dev, "missing platform resources\n"); | ||
223 | return -EINVAL; | ||
224 | } | ||
225 | |||
226 | keypad = kzalloc(sizeof(struct ske_keypad), GFP_KERNEL); | ||
227 | input = input_allocate_device(); | ||
228 | if (!keypad || !input) { | ||
229 | dev_err(&pdev->dev, "failed to allocate keypad memory\n"); | ||
230 | error = -ENOMEM; | ||
231 | goto err_free_mem; | ||
232 | } | ||
233 | |||
234 | keypad->irq = irq; | ||
235 | keypad->board = plat; | ||
236 | keypad->input = input; | ||
237 | spin_lock_init(&keypad->ske_keypad_lock); | ||
238 | |||
239 | if (!request_mem_region(res->start, resource_size(res), pdev->name)) { | ||
240 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
241 | error = -EBUSY; | ||
242 | goto err_free_mem; | ||
243 | } | ||
244 | |||
245 | keypad->reg_base = ioremap(res->start, resource_size(res)); | ||
246 | if (!keypad->reg_base) { | ||
247 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
248 | error = -ENXIO; | ||
249 | goto err_free_mem_region; | ||
250 | } | ||
251 | |||
252 | keypad->clk = clk_get(&pdev->dev, NULL); | ||
253 | if (IS_ERR(keypad->clk)) { | ||
254 | dev_err(&pdev->dev, "failed to get clk\n"); | ||
255 | error = PTR_ERR(keypad->clk); | ||
256 | goto err_iounmap; | ||
257 | } | ||
258 | |||
259 | input->id.bustype = BUS_HOST; | ||
260 | input->name = "ux500-ske-keypad"; | ||
261 | input->dev.parent = &pdev->dev; | ||
262 | |||
263 | input->keycode = keypad->keymap; | ||
264 | input->keycodesize = sizeof(keypad->keymap[0]); | ||
265 | input->keycodemax = ARRAY_SIZE(keypad->keymap); | ||
266 | |||
267 | input_set_capability(input, EV_MSC, MSC_SCAN); | ||
268 | |||
269 | __set_bit(EV_KEY, input->evbit); | ||
270 | if (!plat->no_autorepeat) | ||
271 | __set_bit(EV_REP, input->evbit); | ||
272 | |||
273 | matrix_keypad_build_keymap(plat->keymap_data, SKE_KEYPAD_ROW_SHIFT, | ||
274 | input->keycode, input->keybit); | ||
275 | |||
276 | clk_enable(keypad->clk); | ||
277 | |||
278 | /* go through board initialization helpers */ | ||
279 | if (keypad->board->init) | ||
280 | keypad->board->init(); | ||
281 | |||
282 | error = ske_keypad_chip_init(keypad); | ||
283 | if (error) { | ||
284 | dev_err(&pdev->dev, "unable to init keypad hardware\n"); | ||
285 | goto err_clk_disable; | ||
286 | } | ||
287 | |||
288 | error = request_threaded_irq(keypad->irq, NULL, ske_keypad_irq, | ||
289 | IRQF_ONESHOT, "ske-keypad", keypad); | ||
290 | if (error) { | ||
291 | dev_err(&pdev->dev, "allocate irq %d failed\n", keypad->irq); | ||
292 | goto err_clk_disable; | ||
293 | } | ||
294 | |||
295 | error = input_register_device(input); | ||
296 | if (error) { | ||
297 | dev_err(&pdev->dev, | ||
298 | "unable to register input device: %d\n", error); | ||
299 | goto err_free_irq; | ||
300 | } | ||
301 | |||
302 | if (plat->wakeup_enable) | ||
303 | device_init_wakeup(&pdev->dev, true); | ||
304 | |||
305 | platform_set_drvdata(pdev, keypad); | ||
306 | |||
307 | return 0; | ||
308 | |||
309 | err_free_irq: | ||
310 | free_irq(keypad->irq, keypad); | ||
311 | err_clk_disable: | ||
312 | clk_disable(keypad->clk); | ||
313 | clk_put(keypad->clk); | ||
314 | err_iounmap: | ||
315 | iounmap(keypad->reg_base); | ||
316 | err_free_mem_region: | ||
317 | release_mem_region(res->start, resource_size(res)); | ||
318 | err_free_mem: | ||
319 | input_free_device(input); | ||
320 | kfree(keypad); | ||
321 | return error; | ||
322 | } | ||
323 | |||
324 | static int __devexit ske_keypad_remove(struct platform_device *pdev) | ||
325 | { | ||
326 | struct ske_keypad *keypad = platform_get_drvdata(pdev); | ||
327 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
328 | |||
329 | free_irq(keypad->irq, keypad); | ||
330 | |||
331 | input_unregister_device(keypad->input); | ||
332 | |||
333 | clk_disable(keypad->clk); | ||
334 | clk_put(keypad->clk); | ||
335 | |||
336 | if (keypad->board->exit) | ||
337 | keypad->board->exit(); | ||
338 | |||
339 | iounmap(keypad->reg_base); | ||
340 | release_mem_region(res->start, resource_size(res)); | ||
341 | kfree(keypad); | ||
342 | |||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | #ifdef CONFIG_PM | ||
347 | static int ske_keypad_suspend(struct device *dev) | ||
348 | { | ||
349 | struct platform_device *pdev = to_platform_device(dev); | ||
350 | struct ske_keypad *keypad = platform_get_drvdata(pdev); | ||
351 | int irq = platform_get_irq(pdev, 0); | ||
352 | |||
353 | if (device_may_wakeup(dev)) | ||
354 | enable_irq_wake(irq); | ||
355 | else | ||
356 | ske_keypad_set_bits(keypad, SKE_IMSC, ~SKE_KPIMA, 0x0); | ||
357 | |||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | static int ske_keypad_resume(struct device *dev) | ||
362 | { | ||
363 | struct platform_device *pdev = to_platform_device(dev); | ||
364 | struct ske_keypad *keypad = platform_get_drvdata(pdev); | ||
365 | int irq = platform_get_irq(pdev, 0); | ||
366 | |||
367 | if (device_may_wakeup(dev)) | ||
368 | disable_irq_wake(irq); | ||
369 | else | ||
370 | ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA); | ||
371 | |||
372 | return 0; | ||
373 | } | ||
374 | |||
375 | static const struct dev_pm_ops ske_keypad_dev_pm_ops = { | ||
376 | .suspend = ske_keypad_suspend, | ||
377 | .resume = ske_keypad_resume, | ||
378 | }; | ||
379 | #endif | ||
380 | |||
381 | struct platform_driver ske_keypad_driver = { | ||
382 | .driver = { | ||
383 | .name = "nmk-ske-keypad", | ||
384 | .owner = THIS_MODULE, | ||
385 | #ifdef CONFIG_PM | ||
386 | .pm = &ske_keypad_dev_pm_ops, | ||
387 | #endif | ||
388 | }, | ||
389 | .probe = ske_keypad_probe, | ||
390 | .remove = __devexit_p(ske_keypad_remove), | ||
391 | }; | ||
392 | |||
393 | static int __init ske_keypad_init(void) | ||
394 | { | ||
395 | return platform_driver_probe(&ske_keypad_driver, ske_keypad_probe); | ||
396 | } | ||
397 | module_init(ske_keypad_init); | ||
398 | |||
399 | static void __exit ske_keypad_exit(void) | ||
400 | { | ||
401 | platform_driver_unregister(&ske_keypad_driver); | ||
402 | } | ||
403 | module_exit(ske_keypad_exit); | ||
404 | |||
405 | MODULE_LICENSE("GPL v2"); | ||
406 | MODULE_AUTHOR("Naveen Kumar <naveen.gaddipati@stericsson.com> / Sundar Iyer <sundar.iyer@stericsson.com>"); | ||
407 | MODULE_DESCRIPTION("Nomadik Scroll-Key-Encoder Keypad Driver"); | ||
408 | MODULE_ALIAS("platform:nomadik-ske-keypad"); | ||
diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c new file mode 100644 index 000000000000..45bd0977d006 --- /dev/null +++ b/drivers/input/keyboard/omap4-keypad.c | |||
@@ -0,0 +1,318 @@ | |||
1 | /* | ||
2 | * OMAP4 Keypad Driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments | ||
5 | * | ||
6 | * Author: Abraham Arce <x0066660@ti.com> | ||
7 | * Initial Code: Syed Rafiuddin <rafiuddin.syed@ti.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/io.h> | ||
30 | #include <linux/input.h> | ||
31 | #include <linux/slab.h> | ||
32 | |||
33 | #include <plat/omap4-keypad.h> | ||
34 | |||
35 | /* OMAP4 registers */ | ||
36 | #define OMAP4_KBD_REVISION 0x00 | ||
37 | #define OMAP4_KBD_SYSCONFIG 0x10 | ||
38 | #define OMAP4_KBD_SYSSTATUS 0x14 | ||
39 | #define OMAP4_KBD_IRQSTATUS 0x18 | ||
40 | #define OMAP4_KBD_IRQENABLE 0x1C | ||
41 | #define OMAP4_KBD_WAKEUPENABLE 0x20 | ||
42 | #define OMAP4_KBD_PENDING 0x24 | ||
43 | #define OMAP4_KBD_CTRL 0x28 | ||
44 | #define OMAP4_KBD_DEBOUNCINGTIME 0x2C | ||
45 | #define OMAP4_KBD_LONGKEYTIME 0x30 | ||
46 | #define OMAP4_KBD_TIMEOUT 0x34 | ||
47 | #define OMAP4_KBD_STATEMACHINE 0x38 | ||
48 | #define OMAP4_KBD_ROWINPUTS 0x3C | ||
49 | #define OMAP4_KBD_COLUMNOUTPUTS 0x40 | ||
50 | #define OMAP4_KBD_FULLCODE31_0 0x44 | ||
51 | #define OMAP4_KBD_FULLCODE63_32 0x48 | ||
52 | |||
53 | /* OMAP4 bit definitions */ | ||
54 | #define OMAP4_DEF_IRQENABLE_EVENTEN (1 << 0) | ||
55 | #define OMAP4_DEF_IRQENABLE_LONGKEY (1 << 1) | ||
56 | #define OMAP4_DEF_IRQENABLE_TIMEOUTEN (1 << 2) | ||
57 | #define OMAP4_DEF_WUP_EVENT_ENA (1 << 0) | ||
58 | #define OMAP4_DEF_WUP_LONG_KEY_ENA (1 << 1) | ||
59 | #define OMAP4_DEF_CTRL_NOSOFTMODE (1 << 1) | ||
60 | #define OMAP4_DEF_CTRLPTVVALUE (1 << 2) | ||
61 | #define OMAP4_DEF_CTRLPTV (1 << 1) | ||
62 | |||
63 | /* OMAP4 values */ | ||
64 | #define OMAP4_VAL_IRQDISABLE 0x00 | ||
65 | #define OMAP4_VAL_DEBOUNCINGTIME 0x07 | ||
66 | #define OMAP4_VAL_FUNCTIONALCFG 0x1E | ||
67 | |||
68 | #define OMAP4_MASK_IRQSTATUSDISABLE 0xFFFF | ||
69 | |||
70 | struct omap4_keypad { | ||
71 | struct input_dev *input; | ||
72 | |||
73 | void __iomem *base; | ||
74 | int irq; | ||
75 | |||
76 | unsigned int rows; | ||
77 | unsigned int cols; | ||
78 | unsigned int row_shift; | ||
79 | unsigned char key_state[8]; | ||
80 | unsigned short keymap[]; | ||
81 | }; | ||
82 | |||
83 | static void __devinit omap4_keypad_config(struct omap4_keypad *keypad_data) | ||
84 | { | ||
85 | __raw_writel(OMAP4_VAL_FUNCTIONALCFG, | ||
86 | keypad_data->base + OMAP4_KBD_CTRL); | ||
87 | __raw_writel(OMAP4_VAL_DEBOUNCINGTIME, | ||
88 | keypad_data->base + OMAP4_KBD_DEBOUNCINGTIME); | ||
89 | __raw_writel(OMAP4_VAL_IRQDISABLE, | ||
90 | keypad_data->base + OMAP4_KBD_IRQSTATUS); | ||
91 | __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY, | ||
92 | keypad_data->base + OMAP4_KBD_IRQENABLE); | ||
93 | __raw_writel(OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA, | ||
94 | keypad_data->base + OMAP4_KBD_WAKEUPENABLE); | ||
95 | } | ||
96 | |||
97 | /* Interrupt handler */ | ||
98 | static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id) | ||
99 | { | ||
100 | struct omap4_keypad *keypad_data = dev_id; | ||
101 | struct input_dev *input_dev = keypad_data->input; | ||
102 | unsigned char key_state[ARRAY_SIZE(keypad_data->key_state)]; | ||
103 | unsigned int col, row, code, changed; | ||
104 | u32 *new_state = (u32 *) key_state; | ||
105 | |||
106 | /* Disable interrupts */ | ||
107 | __raw_writel(OMAP4_VAL_IRQDISABLE, | ||
108 | keypad_data->base + OMAP4_KBD_IRQENABLE); | ||
109 | |||
110 | *new_state = __raw_readl(keypad_data->base + OMAP4_KBD_FULLCODE31_0); | ||
111 | *(new_state + 1) = __raw_readl(keypad_data->base | ||
112 | + OMAP4_KBD_FULLCODE63_32); | ||
113 | |||
114 | for (row = 0; row < keypad_data->rows; row++) { | ||
115 | changed = key_state[row] ^ keypad_data->key_state[row]; | ||
116 | if (!changed) | ||
117 | continue; | ||
118 | |||
119 | for (col = 0; col < keypad_data->cols; col++) { | ||
120 | if (changed & (1 << col)) { | ||
121 | code = MATRIX_SCAN_CODE(row, col, | ||
122 | keypad_data->row_shift); | ||
123 | input_event(input_dev, EV_MSC, MSC_SCAN, code); | ||
124 | input_report_key(input_dev, | ||
125 | keypad_data->keymap[code], | ||
126 | key_state[row] & (1 << col)); | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | |||
131 | input_sync(input_dev); | ||
132 | |||
133 | memcpy(keypad_data->key_state, key_state, | ||
134 | sizeof(keypad_data->key_state)); | ||
135 | |||
136 | /* clear pending interrupts */ | ||
137 | __raw_writel(__raw_readl(keypad_data->base + OMAP4_KBD_IRQSTATUS), | ||
138 | keypad_data->base + OMAP4_KBD_IRQSTATUS); | ||
139 | |||
140 | /* enable interrupts */ | ||
141 | __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY, | ||
142 | keypad_data->base + OMAP4_KBD_IRQENABLE); | ||
143 | |||
144 | return IRQ_HANDLED; | ||
145 | } | ||
146 | |||
147 | static int __devinit omap4_keypad_probe(struct platform_device *pdev) | ||
148 | { | ||
149 | const struct omap4_keypad_platform_data *pdata; | ||
150 | struct omap4_keypad *keypad_data; | ||
151 | struct input_dev *input_dev; | ||
152 | struct resource *res; | ||
153 | resource_size_t size; | ||
154 | unsigned int row_shift, max_keys; | ||
155 | int irq; | ||
156 | int error; | ||
157 | |||
158 | /* platform data */ | ||
159 | pdata = pdev->dev.platform_data; | ||
160 | if (!pdata) { | ||
161 | dev_err(&pdev->dev, "no platform data defined\n"); | ||
162 | return -EINVAL; | ||
163 | } | ||
164 | |||
165 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
166 | if (!res) { | ||
167 | dev_err(&pdev->dev, "no base address specified\n"); | ||
168 | return -EINVAL; | ||
169 | } | ||
170 | |||
171 | irq = platform_get_irq(pdev, 0); | ||
172 | if (!irq) { | ||
173 | dev_err(&pdev->dev, "no keyboard irq assigned\n"); | ||
174 | return -EINVAL; | ||
175 | } | ||
176 | |||
177 | if (!pdata->keymap_data) { | ||
178 | dev_err(&pdev->dev, "no keymap data defined\n"); | ||
179 | return -EINVAL; | ||
180 | } | ||
181 | |||
182 | row_shift = get_count_order(pdata->cols); | ||
183 | max_keys = pdata->rows << row_shift; | ||
184 | |||
185 | keypad_data = kzalloc(sizeof(struct omap4_keypad) + | ||
186 | max_keys * sizeof(keypad_data->keymap[0]), | ||
187 | GFP_KERNEL); | ||
188 | if (!keypad_data) { | ||
189 | dev_err(&pdev->dev, "keypad_data memory allocation failed\n"); | ||
190 | return -ENOMEM; | ||
191 | } | ||
192 | |||
193 | size = resource_size(res); | ||
194 | |||
195 | res = request_mem_region(res->start, size, pdev->name); | ||
196 | if (!res) { | ||
197 | dev_err(&pdev->dev, "can't request mem region\n"); | ||
198 | error = -EBUSY; | ||
199 | goto err_free_keypad; | ||
200 | } | ||
201 | |||
202 | keypad_data->base = ioremap(res->start, resource_size(res)); | ||
203 | if (!keypad_data->base) { | ||
204 | dev_err(&pdev->dev, "can't ioremap mem resource\n"); | ||
205 | error = -ENOMEM; | ||
206 | goto err_release_mem; | ||
207 | } | ||
208 | |||
209 | keypad_data->irq = irq; | ||
210 | keypad_data->row_shift = row_shift; | ||
211 | keypad_data->rows = pdata->rows; | ||
212 | keypad_data->cols = pdata->cols; | ||
213 | |||
214 | /* input device allocation */ | ||
215 | keypad_data->input = input_dev = input_allocate_device(); | ||
216 | if (!input_dev) { | ||
217 | error = -ENOMEM; | ||
218 | goto err_unmap; | ||
219 | } | ||
220 | |||
221 | input_dev->name = pdev->name; | ||
222 | input_dev->dev.parent = &pdev->dev; | ||
223 | input_dev->id.bustype = BUS_HOST; | ||
224 | input_dev->id.vendor = 0x0001; | ||
225 | input_dev->id.product = 0x0001; | ||
226 | input_dev->id.version = 0x0001; | ||
227 | |||
228 | input_dev->keycode = keypad_data->keymap; | ||
229 | input_dev->keycodesize = sizeof(keypad_data->keymap[0]); | ||
230 | input_dev->keycodemax = max_keys; | ||
231 | |||
232 | __set_bit(EV_KEY, input_dev->evbit); | ||
233 | __set_bit(EV_REP, input_dev->evbit); | ||
234 | |||
235 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | ||
236 | |||
237 | input_set_drvdata(input_dev, keypad_data); | ||
238 | |||
239 | matrix_keypad_build_keymap(pdata->keymap_data, row_shift, | ||
240 | input_dev->keycode, input_dev->keybit); | ||
241 | |||
242 | omap4_keypad_config(keypad_data); | ||
243 | |||
244 | error = request_irq(keypad_data->irq, omap4_keypad_interrupt, | ||
245 | IRQF_TRIGGER_RISING, | ||
246 | "omap4-keypad", keypad_data); | ||
247 | if (error) { | ||
248 | dev_err(&pdev->dev, "failed to register interrupt\n"); | ||
249 | goto err_free_input; | ||
250 | } | ||
251 | |||
252 | error = input_register_device(keypad_data->input); | ||
253 | if (error < 0) { | ||
254 | dev_err(&pdev->dev, "failed to register input device\n"); | ||
255 | goto err_free_irq; | ||
256 | } | ||
257 | |||
258 | |||
259 | platform_set_drvdata(pdev, keypad_data); | ||
260 | return 0; | ||
261 | |||
262 | err_free_irq: | ||
263 | free_irq(keypad_data->irq, keypad_data); | ||
264 | err_free_input: | ||
265 | input_free_device(input_dev); | ||
266 | err_unmap: | ||
267 | iounmap(keypad_data->base); | ||
268 | err_release_mem: | ||
269 | release_mem_region(res->start, size); | ||
270 | err_free_keypad: | ||
271 | kfree(keypad_data); | ||
272 | return error; | ||
273 | } | ||
274 | |||
275 | static int __devexit omap4_keypad_remove(struct platform_device *pdev) | ||
276 | { | ||
277 | struct omap4_keypad *keypad_data = platform_get_drvdata(pdev); | ||
278 | struct resource *res; | ||
279 | |||
280 | free_irq(keypad_data->irq, keypad_data); | ||
281 | input_unregister_device(keypad_data->input); | ||
282 | |||
283 | iounmap(keypad_data->base); | ||
284 | |||
285 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
286 | release_mem_region(res->start, resource_size(res)); | ||
287 | |||
288 | kfree(keypad_data); | ||
289 | platform_set_drvdata(pdev, NULL); | ||
290 | |||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | static struct platform_driver omap4_keypad_driver = { | ||
295 | .probe = omap4_keypad_probe, | ||
296 | .remove = __devexit_p(omap4_keypad_remove), | ||
297 | .driver = { | ||
298 | .name = "omap4-keypad", | ||
299 | .owner = THIS_MODULE, | ||
300 | }, | ||
301 | }; | ||
302 | |||
303 | static int __init omap4_keypad_init(void) | ||
304 | { | ||
305 | return platform_driver_register(&omap4_keypad_driver); | ||
306 | } | ||
307 | module_init(omap4_keypad_init); | ||
308 | |||
309 | static void __exit omap4_keypad_exit(void) | ||
310 | { | ||
311 | platform_driver_unregister(&omap4_keypad_driver); | ||
312 | } | ||
313 | module_exit(omap4_keypad_exit); | ||
314 | |||
315 | MODULE_AUTHOR("Texas Instruments"); | ||
316 | MODULE_DESCRIPTION("OMAP4 Keypad Driver"); | ||
317 | MODULE_LICENSE("GPL"); | ||
318 | MODULE_ALIAS("platform:omap4-keypad"); | ||
diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index fb16b5e5ea13..09bef79d9da1 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c | |||
@@ -406,23 +406,22 @@ static int __devinit twl4030_kp_probe(struct platform_device *pdev) | |||
406 | if (error) { | 406 | if (error) { |
407 | dev_info(kp->dbg_dev, "request_irq failed for irq no=%d\n", | 407 | dev_info(kp->dbg_dev, "request_irq failed for irq no=%d\n", |
408 | kp->irq); | 408 | kp->irq); |
409 | goto err3; | 409 | goto err2; |
410 | } | 410 | } |
411 | 411 | ||
412 | /* Enable KP and TO interrupts now. */ | 412 | /* Enable KP and TO interrupts now. */ |
413 | reg = (u8) ~(KEYP_IMR1_KP | KEYP_IMR1_TO); | 413 | reg = (u8) ~(KEYP_IMR1_KP | KEYP_IMR1_TO); |
414 | if (twl4030_kpwrite_u8(kp, reg, KEYP_IMR1)) { | 414 | if (twl4030_kpwrite_u8(kp, reg, KEYP_IMR1)) { |
415 | error = -EIO; | 415 | error = -EIO; |
416 | goto err4; | 416 | goto err3; |
417 | } | 417 | } |
418 | 418 | ||
419 | platform_set_drvdata(pdev, kp); | 419 | platform_set_drvdata(pdev, kp); |
420 | return 0; | 420 | return 0; |
421 | 421 | ||
422 | err4: | 422 | err3: |
423 | /* mask all events - we don't care about the result */ | 423 | /* mask all events - we don't care about the result */ |
424 | (void) twl4030_kpwrite_u8(kp, 0xff, KEYP_IMR1); | 424 | (void) twl4030_kpwrite_u8(kp, 0xff, KEYP_IMR1); |
425 | err3: | ||
426 | free_irq(kp->irq, NULL); | 425 | free_irq(kp->irq, NULL); |
427 | err2: | 426 | err2: |
428 | input_unregister_device(input); | 427 | input_unregister_device(input); |
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index b49e23379723..b99b8cbde02f 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -22,6 +22,16 @@ config INPUT_88PM860X_ONKEY | |||
22 | To compile this driver as a module, choose M here: the module | 22 | To compile this driver as a module, choose M here: the module |
23 | will be called 88pm860x_onkey. | 23 | will be called 88pm860x_onkey. |
24 | 24 | ||
25 | config INPUT_AB8500_PONKEY | ||
26 | tristate "AB8500 Pon (PowerOn) Key" | ||
27 | depends on AB8500_CORE | ||
28 | help | ||
29 | Say Y here to use the PowerOn Key for ST-Ericsson's AB8500 | ||
30 | Mix-Sig PMIC. | ||
31 | |||
32 | To compile this driver as a module, choose M here: the module | ||
33 | will be called ab8500-ponkey. | ||
34 | |||
25 | config INPUT_AD714X | 35 | config INPUT_AD714X |
26 | tristate "Analog Devices AD714x Capacitance Touch Sensor" | 36 | tristate "Analog Devices AD714x Capacitance Touch Sensor" |
27 | help | 37 | help |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 19ccca78fa76..1fe1f6c8b737 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
@@ -5,6 +5,7 @@ | |||
5 | # Each configuration option enables a list of files. | 5 | # Each configuration option enables a list of files. |
6 | 6 | ||
7 | obj-$(CONFIG_INPUT_88PM860X_ONKEY) += 88pm860x_onkey.o | 7 | obj-$(CONFIG_INPUT_88PM860X_ONKEY) += 88pm860x_onkey.o |
8 | obj-$(CONFIG_INPUT_AB8500_PONKEY) += ab8500-ponkey.o | ||
8 | obj-$(CONFIG_INPUT_AD714X) += ad714x.o | 9 | obj-$(CONFIG_INPUT_AD714X) += ad714x.o |
9 | obj-$(CONFIG_INPUT_AD714X_I2C) += ad714x-i2c.o | 10 | obj-$(CONFIG_INPUT_AD714X_I2C) += ad714x-i2c.o |
10 | obj-$(CONFIG_INPUT_AD714X_SPI) += ad714x-spi.o | 11 | obj-$(CONFIG_INPUT_AD714X_SPI) += ad714x-spi.o |
diff --git a/drivers/input/misc/ab8500-ponkey.c b/drivers/input/misc/ab8500-ponkey.c new file mode 100644 index 000000000000..3d3288a78fdc --- /dev/null +++ b/drivers/input/misc/ab8500-ponkey.c | |||
@@ -0,0 +1,157 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License Terms: GNU General Public License v2 | ||
5 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson | ||
6 | * | ||
7 | * AB8500 Power-On Key handler | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/input.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/mfd/ab8500.h> | ||
16 | #include <linux/slab.h> | ||
17 | |||
18 | /** | ||
19 | * struct ab8500_ponkey - ab8500 ponkey information | ||
20 | * @input_dev: pointer to input device | ||
21 | * @ab8500: ab8500 parent | ||
22 | * @irq_dbf: irq number for falling transition | ||
23 | * @irq_dbr: irq number for rising transition | ||
24 | */ | ||
25 | struct ab8500_ponkey { | ||
26 | struct input_dev *idev; | ||
27 | struct ab8500 *ab8500; | ||
28 | int irq_dbf; | ||
29 | int irq_dbr; | ||
30 | }; | ||
31 | |||
32 | /* AB8500 gives us an interrupt when ONKEY is held */ | ||
33 | static irqreturn_t ab8500_ponkey_handler(int irq, void *data) | ||
34 | { | ||
35 | struct ab8500_ponkey *ponkey = data; | ||
36 | |||
37 | if (irq == ponkey->irq_dbf) | ||
38 | input_report_key(ponkey->idev, KEY_POWER, true); | ||
39 | else if (irq == ponkey->irq_dbr) | ||
40 | input_report_key(ponkey->idev, KEY_POWER, false); | ||
41 | |||
42 | input_sync(ponkey->idev); | ||
43 | |||
44 | return IRQ_HANDLED; | ||
45 | } | ||
46 | |||
47 | static int __devinit ab8500_ponkey_probe(struct platform_device *pdev) | ||
48 | { | ||
49 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); | ||
50 | struct ab8500_ponkey *ponkey; | ||
51 | struct input_dev *input; | ||
52 | int irq_dbf, irq_dbr; | ||
53 | int error; | ||
54 | |||
55 | irq_dbf = platform_get_irq_byname(pdev, "ONKEY_DBF"); | ||
56 | if (irq_dbf < 0) { | ||
57 | dev_err(&pdev->dev, "No IRQ for ONKEY_DBF, error=%d\n", irq_dbf); | ||
58 | return irq_dbf; | ||
59 | } | ||
60 | |||
61 | irq_dbr = platform_get_irq_byname(pdev, "ONKEY_DBR"); | ||
62 | if (irq_dbr < 0) { | ||
63 | dev_err(&pdev->dev, "No IRQ for ONKEY_DBR, error=%d\n", irq_dbr); | ||
64 | return irq_dbr; | ||
65 | } | ||
66 | |||
67 | ponkey = kzalloc(sizeof(struct ab8500_ponkey), GFP_KERNEL); | ||
68 | input = input_allocate_device(); | ||
69 | if (!ponkey || !input) { | ||
70 | error = -ENOMEM; | ||
71 | goto err_free_mem; | ||
72 | } | ||
73 | |||
74 | ponkey->idev = input; | ||
75 | ponkey->ab8500 = ab8500; | ||
76 | ponkey->irq_dbf = irq_dbf; | ||
77 | ponkey->irq_dbr = irq_dbr; | ||
78 | |||
79 | input->name = "AB8500 POn(PowerOn) Key"; | ||
80 | input->dev.parent = &pdev->dev; | ||
81 | |||
82 | input_set_capability(input, EV_KEY, KEY_POWER); | ||
83 | |||
84 | error = request_any_context_irq(ponkey->irq_dbf, ab8500_ponkey_handler, | ||
85 | 0, "ab8500-ponkey-dbf", ponkey); | ||
86 | if (error < 0) { | ||
87 | dev_err(ab8500->dev, "Failed to request dbf IRQ#%d: %d\n", | ||
88 | ponkey->irq_dbf, error); | ||
89 | goto err_free_mem; | ||
90 | } | ||
91 | |||
92 | error = request_any_context_irq(ponkey->irq_dbr, ab8500_ponkey_handler, | ||
93 | 0, "ab8500-ponkey-dbr", ponkey); | ||
94 | if (error < 0) { | ||
95 | dev_err(ab8500->dev, "Failed to request dbr IRQ#%d: %d\n", | ||
96 | ponkey->irq_dbr, error); | ||
97 | goto err_free_dbf_irq; | ||
98 | } | ||
99 | |||
100 | error = input_register_device(ponkey->idev); | ||
101 | if (error) { | ||
102 | dev_err(ab8500->dev, "Can't register input device: %d\n", error); | ||
103 | goto err_free_dbr_irq; | ||
104 | } | ||
105 | |||
106 | platform_set_drvdata(pdev, ponkey); | ||
107 | return 0; | ||
108 | |||
109 | err_free_dbr_irq: | ||
110 | free_irq(ponkey->irq_dbr, ponkey); | ||
111 | err_free_dbf_irq: | ||
112 | free_irq(ponkey->irq_dbf, ponkey); | ||
113 | err_free_mem: | ||
114 | input_free_device(input); | ||
115 | kfree(ponkey); | ||
116 | |||
117 | return error; | ||
118 | } | ||
119 | |||
120 | static int __devexit ab8500_ponkey_remove(struct platform_device *pdev) | ||
121 | { | ||
122 | struct ab8500_ponkey *ponkey = platform_get_drvdata(pdev); | ||
123 | |||
124 | free_irq(ponkey->irq_dbf, ponkey); | ||
125 | free_irq(ponkey->irq_dbr, ponkey); | ||
126 | input_unregister_device(ponkey->idev); | ||
127 | kfree(ponkey); | ||
128 | |||
129 | platform_set_drvdata(pdev, NULL); | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static struct platform_driver ab8500_ponkey_driver = { | ||
135 | .driver = { | ||
136 | .name = "ab8500-poweron-key", | ||
137 | .owner = THIS_MODULE, | ||
138 | }, | ||
139 | .probe = ab8500_ponkey_probe, | ||
140 | .remove = __devexit_p(ab8500_ponkey_remove), | ||
141 | }; | ||
142 | |||
143 | static int __init ab8500_ponkey_init(void) | ||
144 | { | ||
145 | return platform_driver_register(&ab8500_ponkey_driver); | ||
146 | } | ||
147 | module_init(ab8500_ponkey_init); | ||
148 | |||
149 | static void __exit ab8500_ponkey_exit(void) | ||
150 | { | ||
151 | platform_driver_unregister(&ab8500_ponkey_driver); | ||
152 | } | ||
153 | module_exit(ab8500_ponkey_exit); | ||
154 | |||
155 | MODULE_LICENSE("GPL v2"); | ||
156 | MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>"); | ||
157 | MODULE_DESCRIPTION("ST-Ericsson AB8500 Power-ON(Pon) Key driver"); | ||
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index 23257652b8e8..0b0e9be63542 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c | |||
@@ -483,51 +483,88 @@ static void ati_remote2_complete_key(struct urb *urb) | |||
483 | } | 483 | } |
484 | 484 | ||
485 | static int ati_remote2_getkeycode(struct input_dev *idev, | 485 | static int ati_remote2_getkeycode(struct input_dev *idev, |
486 | unsigned int scancode, unsigned int *keycode) | 486 | struct input_keymap_entry *ke) |
487 | { | 487 | { |
488 | struct ati_remote2 *ar2 = input_get_drvdata(idev); | 488 | struct ati_remote2 *ar2 = input_get_drvdata(idev); |
489 | unsigned int mode; | 489 | unsigned int mode; |
490 | int index; | 490 | int offset; |
491 | unsigned int index; | ||
492 | unsigned int scancode; | ||
493 | |||
494 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) { | ||
495 | index = ke->index; | ||
496 | if (index >= ATI_REMOTE2_MODES * | ||
497 | ARRAY_SIZE(ati_remote2_key_table)) | ||
498 | return -EINVAL; | ||
499 | |||
500 | mode = ke->index / ARRAY_SIZE(ati_remote2_key_table); | ||
501 | offset = ke->index % ARRAY_SIZE(ati_remote2_key_table); | ||
502 | scancode = (mode << 8) + ati_remote2_key_table[offset].hw_code; | ||
503 | } else { | ||
504 | if (input_scancode_to_scalar(ke, &scancode)) | ||
505 | return -EINVAL; | ||
506 | |||
507 | mode = scancode >> 8; | ||
508 | if (mode > ATI_REMOTE2_PC) | ||
509 | return -EINVAL; | ||
510 | |||
511 | offset = ati_remote2_lookup(scancode & 0xff); | ||
512 | if (offset < 0) | ||
513 | return -EINVAL; | ||
514 | |||
515 | index = mode * ARRAY_SIZE(ati_remote2_key_table) + offset; | ||
516 | } | ||
491 | 517 | ||
492 | mode = scancode >> 8; | 518 | ke->keycode = ar2->keycode[mode][offset]; |
493 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) | 519 | ke->len = sizeof(scancode); |
494 | return -EINVAL; | 520 | memcpy(&ke->scancode, &scancode, sizeof(scancode)); |
521 | ke->index = index; | ||
495 | 522 | ||
496 | index = ati_remote2_lookup(scancode & 0xFF); | ||
497 | if (index < 0) | ||
498 | return -EINVAL; | ||
499 | |||
500 | *keycode = ar2->keycode[mode][index]; | ||
501 | return 0; | 523 | return 0; |
502 | } | 524 | } |
503 | 525 | ||
504 | static int ati_remote2_setkeycode(struct input_dev *idev, | 526 | static int ati_remote2_setkeycode(struct input_dev *idev, |
505 | unsigned int scancode, unsigned int keycode) | 527 | const struct input_keymap_entry *ke, |
528 | unsigned int *old_keycode) | ||
506 | { | 529 | { |
507 | struct ati_remote2 *ar2 = input_get_drvdata(idev); | 530 | struct ati_remote2 *ar2 = input_get_drvdata(idev); |
508 | unsigned int mode, old_keycode; | 531 | unsigned int mode; |
509 | int index; | 532 | int offset; |
510 | 533 | unsigned int index; | |
511 | mode = scancode >> 8; | 534 | unsigned int scancode; |
512 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) | 535 | |
513 | return -EINVAL; | 536 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) { |
514 | 537 | if (ke->index >= ATI_REMOTE2_MODES * | |
515 | index = ati_remote2_lookup(scancode & 0xFF); | 538 | ARRAY_SIZE(ati_remote2_key_table)) |
516 | if (index < 0) | 539 | return -EINVAL; |
517 | return -EINVAL; | 540 | |
541 | mode = ke->index / ARRAY_SIZE(ati_remote2_key_table); | ||
542 | offset = ke->index % ARRAY_SIZE(ati_remote2_key_table); | ||
543 | } else { | ||
544 | if (input_scancode_to_scalar(ke, &scancode)) | ||
545 | return -EINVAL; | ||
546 | |||
547 | mode = scancode >> 8; | ||
548 | if (mode > ATI_REMOTE2_PC) | ||
549 | return -EINVAL; | ||
550 | |||
551 | offset = ati_remote2_lookup(scancode & 0xff); | ||
552 | if (offset < 0) | ||
553 | return -EINVAL; | ||
554 | } | ||
518 | 555 | ||
519 | old_keycode = ar2->keycode[mode][index]; | 556 | *old_keycode = ar2->keycode[mode][offset]; |
520 | ar2->keycode[mode][index] = keycode; | 557 | ar2->keycode[mode][offset] = ke->keycode; |
521 | __set_bit(keycode, idev->keybit); | 558 | __set_bit(ke->keycode, idev->keybit); |
522 | 559 | ||
523 | for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) { | 560 | for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) { |
524 | for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) { | 561 | for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) { |
525 | if (ar2->keycode[mode][index] == old_keycode) | 562 | if (ar2->keycode[mode][index] == *old_keycode) |
526 | return 0; | 563 | return 0; |
527 | } | 564 | } |
528 | } | 565 | } |
529 | 566 | ||
530 | __clear_bit(old_keycode, idev->keybit); | 567 | __clear_bit(*old_keycode, idev->keybit); |
531 | 568 | ||
532 | return 0; | 569 | return 0; |
533 | } | 570 | } |
@@ -575,8 +612,8 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2) | |||
575 | idev->open = ati_remote2_open; | 612 | idev->open = ati_remote2_open; |
576 | idev->close = ati_remote2_close; | 613 | idev->close = ati_remote2_close; |
577 | 614 | ||
578 | idev->getkeycode = ati_remote2_getkeycode; | 615 | idev->getkeycode_new = ati_remote2_getkeycode; |
579 | idev->setkeycode = ati_remote2_setkeycode; | 616 | idev->setkeycode_new = ati_remote2_setkeycode; |
580 | 617 | ||
581 | idev->name = ar2->name; | 618 | idev->name = ar2->name; |
582 | idev->phys = ar2->phys; | 619 | idev->phys = ar2->phys; |
diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c index bf170f6b4422..f45947190e4f 100644 --- a/drivers/input/misc/powermate.c +++ b/drivers/input/misc/powermate.c | |||
@@ -280,7 +280,7 @@ static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_dev | |||
280 | 280 | ||
281 | pm->configcr = kmalloc(sizeof(*(pm->configcr)), GFP_KERNEL); | 281 | pm->configcr = kmalloc(sizeof(*(pm->configcr)), GFP_KERNEL); |
282 | if (!pm->configcr) | 282 | if (!pm->configcr) |
283 | return -1; | 283 | return -ENOMEM; |
284 | 284 | ||
285 | return 0; | 285 | return 0; |
286 | } | 286 | } |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 48311204ba51..04d9bf320a4f 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -699,7 +699,7 @@ int elantech_init(struct psmouse *psmouse) | |||
699 | 699 | ||
700 | psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL); | 700 | psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL); |
701 | if (!etd) | 701 | if (!etd) |
702 | return -1; | 702 | return -ENOMEM; |
703 | 703 | ||
704 | etd->parity[0] = 1; | 704 | etd->parity[0] = 1; |
705 | for (i = 1; i < 256; i++) | 705 | for (i = 1; i < 256; i++) |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 73a7af2542a8..cd9d0c97e429 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -1584,10 +1584,10 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
1584 | if (!new_dev) | 1584 | if (!new_dev) |
1585 | return -ENOMEM; | 1585 | return -ENOMEM; |
1586 | 1586 | ||
1587 | while (serio->child) { | 1587 | while (!list_empty(&serio->children)) { |
1588 | if (++retry > 3) { | 1588 | if (++retry > 3) { |
1589 | printk(KERN_WARNING | 1589 | printk(KERN_WARNING |
1590 | "psmouse: failed to destroy child port, " | 1590 | "psmouse: failed to destroy children ports, " |
1591 | "protocol change aborted.\n"); | 1591 | "protocol change aborted.\n"); |
1592 | input_free_device(new_dev); | 1592 | input_free_device(new_dev); |
1593 | return -EIO; | 1593 | return -EIO; |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 96b70a43515f..2e300a460556 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -294,7 +294,29 @@ static int synaptics_pt_write(struct serio *serio, unsigned char c) | |||
294 | return 0; | 294 | return 0; |
295 | } | 295 | } |
296 | 296 | ||
297 | static inline int synaptics_is_pt_packet(unsigned char *buf) | 297 | static int synaptics_pt_start(struct serio *serio) |
298 | { | ||
299 | struct psmouse *parent = serio_get_drvdata(serio->parent); | ||
300 | struct synaptics_data *priv = parent->private; | ||
301 | |||
302 | serio_pause_rx(parent->ps2dev.serio); | ||
303 | priv->pt_port = serio; | ||
304 | serio_continue_rx(parent->ps2dev.serio); | ||
305 | |||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | static void synaptics_pt_stop(struct serio *serio) | ||
310 | { | ||
311 | struct psmouse *parent = serio_get_drvdata(serio->parent); | ||
312 | struct synaptics_data *priv = parent->private; | ||
313 | |||
314 | serio_pause_rx(parent->ps2dev.serio); | ||
315 | priv->pt_port = NULL; | ||
316 | serio_continue_rx(parent->ps2dev.serio); | ||
317 | } | ||
318 | |||
319 | static int synaptics_is_pt_packet(unsigned char *buf) | ||
298 | { | 320 | { |
299 | return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4; | 321 | return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4; |
300 | } | 322 | } |
@@ -315,9 +337,8 @@ static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet | |||
315 | 337 | ||
316 | static void synaptics_pt_activate(struct psmouse *psmouse) | 338 | static void synaptics_pt_activate(struct psmouse *psmouse) |
317 | { | 339 | { |
318 | struct serio *ptport = psmouse->ps2dev.serio->child; | ||
319 | struct psmouse *child = serio_get_drvdata(ptport); | ||
320 | struct synaptics_data *priv = psmouse->private; | 340 | struct synaptics_data *priv = psmouse->private; |
341 | struct psmouse *child = serio_get_drvdata(priv->pt_port); | ||
321 | 342 | ||
322 | /* adjust the touchpad to child's choice of protocol */ | 343 | /* adjust the touchpad to child's choice of protocol */ |
323 | if (child) { | 344 | if (child) { |
@@ -345,6 +366,8 @@ static void synaptics_pt_create(struct psmouse *psmouse) | |||
345 | strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name)); | 366 | strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name)); |
346 | strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->name)); | 367 | strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->name)); |
347 | serio->write = synaptics_pt_write; | 368 | serio->write = synaptics_pt_write; |
369 | serio->start = synaptics_pt_start; | ||
370 | serio->stop = synaptics_pt_stop; | ||
348 | serio->parent = psmouse->ps2dev.serio; | 371 | serio->parent = psmouse->ps2dev.serio; |
349 | 372 | ||
350 | psmouse->pt_activate = synaptics_pt_activate; | 373 | psmouse->pt_activate = synaptics_pt_activate; |
@@ -578,9 +601,10 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse) | |||
578 | if (unlikely(priv->pkt_type == SYN_NEWABS)) | 601 | if (unlikely(priv->pkt_type == SYN_NEWABS)) |
579 | priv->pkt_type = synaptics_detect_pkt_type(psmouse); | 602 | priv->pkt_type = synaptics_detect_pkt_type(psmouse); |
580 | 603 | ||
581 | if (SYN_CAP_PASS_THROUGH(priv->capabilities) && synaptics_is_pt_packet(psmouse->packet)) { | 604 | if (SYN_CAP_PASS_THROUGH(priv->capabilities) && |
582 | if (psmouse->ps2dev.serio->child) | 605 | synaptics_is_pt_packet(psmouse->packet)) { |
583 | synaptics_pass_pt_packet(psmouse->ps2dev.serio->child, psmouse->packet); | 606 | if (priv->pt_port) |
607 | synaptics_pass_pt_packet(priv->pt_port, psmouse->packet); | ||
584 | } else | 608 | } else |
585 | synaptics_process_packet(psmouse); | 609 | synaptics_process_packet(psmouse); |
586 | 610 | ||
@@ -731,7 +755,7 @@ int synaptics_init(struct psmouse *psmouse) | |||
731 | 755 | ||
732 | psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL); | 756 | psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL); |
733 | if (!priv) | 757 | if (!priv) |
734 | return -1; | 758 | return -ENOMEM; |
735 | 759 | ||
736 | psmouse_reset(psmouse); | 760 | psmouse_reset(psmouse); |
737 | 761 | ||
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index b6aa7d20d8a3..613a3652f98f 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
@@ -110,6 +110,8 @@ struct synaptics_data { | |||
110 | unsigned char pkt_type; /* packet type - old, new, etc */ | 110 | unsigned char pkt_type; /* packet type - old, new, etc */ |
111 | unsigned char mode; /* current mode byte */ | 111 | unsigned char mode; /* current mode byte */ |
112 | int scroll; | 112 | int scroll; |
113 | |||
114 | struct serio *pt_port; /* Pass-through serio port */ | ||
113 | }; | 115 | }; |
114 | 116 | ||
115 | void synaptics_module_init(void); | 117 | void synaptics_module_init(void); |
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index 0643e49ca603..54b2fa892e19 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c | |||
@@ -303,7 +303,7 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) | |||
303 | 303 | ||
304 | psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL); | 304 | psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL); |
305 | if (!psmouse->private) | 305 | if (!psmouse->private) |
306 | return -1; | 306 | return -ENOMEM; |
307 | 307 | ||
308 | psmouse->vendor = "IBM"; | 308 | psmouse->vendor = "IBM"; |
309 | psmouse->name = "TrackPoint"; | 309 | psmouse->name = "TrackPoint"; |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 31ec7265aac6..2a00ddf4f23a 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
@@ -867,7 +867,7 @@ static struct mousedev *mousedev_create(struct input_dev *dev, | |||
867 | spin_lock_init(&mousedev->client_lock); | 867 | spin_lock_init(&mousedev->client_lock); |
868 | mutex_init(&mousedev->mutex); | 868 | mutex_init(&mousedev->mutex); |
869 | lockdep_set_subclass(&mousedev->mutex, | 869 | lockdep_set_subclass(&mousedev->mutex, |
870 | minor == MOUSEDEV_MIX ? MOUSEDEV_MIX : 0); | 870 | minor == MOUSEDEV_MIX ? SINGLE_DEPTH_NESTING : 0); |
871 | init_waitqueue_head(&mousedev->wait); | 871 | init_waitqueue_head(&mousedev->wait); |
872 | 872 | ||
873 | if (minor == MOUSEDEV_MIX) | 873 | if (minor == MOUSEDEV_MIX) |
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index 3bfe8fafc6ad..6256233d2bfb 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig | |||
@@ -226,4 +226,13 @@ config SERIO_AMS_DELTA | |||
226 | To compile this driver as a module, choose M here; | 226 | To compile this driver as a module, choose M here; |
227 | the module will be called ams_delta_serio. | 227 | the module will be called ams_delta_serio. |
228 | 228 | ||
229 | config SERIO_PS2MULT | ||
230 | tristate "TQC PS/2 multiplexer" | ||
231 | help | ||
232 | Say Y here if you have the PS/2 line multiplexer like the one | ||
233 | present on TQC boads. | ||
234 | |||
235 | To compile this driver as a module, choose M here: the | ||
236 | module will be called ps2mult. | ||
237 | |||
229 | endif | 238 | endif |
diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile index 84c80bf7185e..dbbe37616c92 100644 --- a/drivers/input/serio/Makefile +++ b/drivers/input/serio/Makefile | |||
@@ -18,6 +18,7 @@ obj-$(CONFIG_SERIO_GSCPS2) += gscps2.o | |||
18 | obj-$(CONFIG_HP_SDC) += hp_sdc.o | 18 | obj-$(CONFIG_HP_SDC) += hp_sdc.o |
19 | obj-$(CONFIG_HIL_MLC) += hp_sdc_mlc.o hil_mlc.o | 19 | obj-$(CONFIG_HIL_MLC) += hp_sdc_mlc.o hil_mlc.o |
20 | obj-$(CONFIG_SERIO_PCIPS2) += pcips2.o | 20 | obj-$(CONFIG_SERIO_PCIPS2) += pcips2.o |
21 | obj-$(CONFIG_SERIO_PS2MULT) += ps2mult.o | ||
21 | obj-$(CONFIG_SERIO_MACEPS2) += maceps2.o | 22 | obj-$(CONFIG_SERIO_MACEPS2) += maceps2.o |
22 | obj-$(CONFIG_SERIO_LIBPS2) += libps2.o | 23 | obj-$(CONFIG_SERIO_LIBPS2) += libps2.o |
23 | obj-$(CONFIG_SERIO_RAW) += serio_raw.o | 24 | obj-$(CONFIG_SERIO_RAW) += serio_raw.o |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index f58513160480..18db5a8c7478 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -1063,7 +1063,7 @@ static long i8042_panic_blink(int state) | |||
1063 | #ifdef CONFIG_X86 | 1063 | #ifdef CONFIG_X86 |
1064 | static void i8042_dritek_enable(void) | 1064 | static void i8042_dritek_enable(void) |
1065 | { | 1065 | { |
1066 | char param = 0x90; | 1066 | unsigned char param = 0x90; |
1067 | int error; | 1067 | int error; |
1068 | 1068 | ||
1069 | error = i8042_command(¶m, 0x1059); | 1069 | error = i8042_command(¶m, 0x1059); |
diff --git a/drivers/input/serio/ps2mult.c b/drivers/input/serio/ps2mult.c new file mode 100644 index 000000000000..6bce22e4e495 --- /dev/null +++ b/drivers/input/serio/ps2mult.c | |||
@@ -0,0 +1,318 @@ | |||
1 | /* | ||
2 | * TQC PS/2 Multiplexer driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Dmitry Eremin-Solenikov | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published by | ||
8 | * the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/serio.h> | ||
16 | |||
17 | MODULE_AUTHOR("Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>"); | ||
18 | MODULE_DESCRIPTION("TQC PS/2 Multiplexer driver"); | ||
19 | MODULE_LICENSE("GPL"); | ||
20 | |||
21 | #define PS2MULT_KB_SELECTOR 0xA0 | ||
22 | #define PS2MULT_MS_SELECTOR 0xA1 | ||
23 | #define PS2MULT_ESCAPE 0x7D | ||
24 | #define PS2MULT_BSYNC 0x7E | ||
25 | #define PS2MULT_SESSION_START 0x55 | ||
26 | #define PS2MULT_SESSION_END 0x56 | ||
27 | |||
28 | struct ps2mult_port { | ||
29 | struct serio *serio; | ||
30 | unsigned char sel; | ||
31 | bool registered; | ||
32 | }; | ||
33 | |||
34 | #define PS2MULT_NUM_PORTS 2 | ||
35 | #define PS2MULT_KBD_PORT 0 | ||
36 | #define PS2MULT_MOUSE_PORT 1 | ||
37 | |||
38 | struct ps2mult { | ||
39 | struct serio *mx_serio; | ||
40 | struct ps2mult_port ports[PS2MULT_NUM_PORTS]; | ||
41 | |||
42 | spinlock_t lock; | ||
43 | struct ps2mult_port *in_port; | ||
44 | struct ps2mult_port *out_port; | ||
45 | bool escape; | ||
46 | }; | ||
47 | |||
48 | /* First MUST come PS2MULT_NUM_PORTS selectors */ | ||
49 | static const unsigned char ps2mult_controls[] = { | ||
50 | PS2MULT_KB_SELECTOR, PS2MULT_MS_SELECTOR, | ||
51 | PS2MULT_ESCAPE, PS2MULT_BSYNC, | ||
52 | PS2MULT_SESSION_START, PS2MULT_SESSION_END, | ||
53 | }; | ||
54 | |||
55 | static const struct serio_device_id ps2mult_serio_ids[] = { | ||
56 | { | ||
57 | .type = SERIO_RS232, | ||
58 | .proto = SERIO_PS2MULT, | ||
59 | .id = SERIO_ANY, | ||
60 | .extra = SERIO_ANY, | ||
61 | }, | ||
62 | { 0 } | ||
63 | }; | ||
64 | |||
65 | MODULE_DEVICE_TABLE(serio, ps2mult_serio_ids); | ||
66 | |||
67 | static void ps2mult_select_port(struct ps2mult *psm, struct ps2mult_port *port) | ||
68 | { | ||
69 | struct serio *mx_serio = psm->mx_serio; | ||
70 | |||
71 | serio_write(mx_serio, port->sel); | ||
72 | psm->out_port = port; | ||
73 | dev_dbg(&mx_serio->dev, "switched to sel %02x\n", port->sel); | ||
74 | } | ||
75 | |||
76 | static int ps2mult_serio_write(struct serio *serio, unsigned char data) | ||
77 | { | ||
78 | struct serio *mx_port = serio->parent; | ||
79 | struct ps2mult *psm = serio_get_drvdata(mx_port); | ||
80 | struct ps2mult_port *port = serio->port_data; | ||
81 | bool need_escape; | ||
82 | unsigned long flags; | ||
83 | |||
84 | spin_lock_irqsave(&psm->lock, flags); | ||
85 | |||
86 | if (psm->out_port != port) | ||
87 | ps2mult_select_port(psm, port); | ||
88 | |||
89 | need_escape = memchr(ps2mult_controls, data, sizeof(ps2mult_controls)); | ||
90 | |||
91 | dev_dbg(&serio->dev, | ||
92 | "write: %s%02x\n", need_escape ? "ESC " : "", data); | ||
93 | |||
94 | if (need_escape) | ||
95 | serio_write(mx_port, PS2MULT_ESCAPE); | ||
96 | |||
97 | serio_write(mx_port, data); | ||
98 | |||
99 | spin_unlock_irqrestore(&psm->lock, flags); | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static int ps2mult_serio_start(struct serio *serio) | ||
105 | { | ||
106 | struct ps2mult *psm = serio_get_drvdata(serio->parent); | ||
107 | struct ps2mult_port *port = serio->port_data; | ||
108 | unsigned long flags; | ||
109 | |||
110 | spin_lock_irqsave(&psm->lock, flags); | ||
111 | port->registered = true; | ||
112 | spin_unlock_irqrestore(&psm->lock, flags); | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static void ps2mult_serio_stop(struct serio *serio) | ||
118 | { | ||
119 | struct ps2mult *psm = serio_get_drvdata(serio->parent); | ||
120 | struct ps2mult_port *port = serio->port_data; | ||
121 | unsigned long flags; | ||
122 | |||
123 | spin_lock_irqsave(&psm->lock, flags); | ||
124 | port->registered = false; | ||
125 | spin_unlock_irqrestore(&psm->lock, flags); | ||
126 | } | ||
127 | |||
128 | static int ps2mult_create_port(struct ps2mult *psm, int i) | ||
129 | { | ||
130 | struct serio *mx_serio = psm->mx_serio; | ||
131 | struct serio *serio; | ||
132 | |||
133 | serio = kzalloc(sizeof(struct serio), GFP_KERNEL); | ||
134 | if (!serio) | ||
135 | return -ENOMEM; | ||
136 | |||
137 | strlcpy(serio->name, "TQC PS/2 Multiplexer", sizeof(serio->name)); | ||
138 | snprintf(serio->phys, sizeof(serio->phys), | ||
139 | "%s/port%d", mx_serio->phys, i); | ||
140 | serio->id.type = SERIO_8042; | ||
141 | serio->write = ps2mult_serio_write; | ||
142 | serio->start = ps2mult_serio_start; | ||
143 | serio->stop = ps2mult_serio_stop; | ||
144 | serio->parent = psm->mx_serio; | ||
145 | serio->port_data = &psm->ports[i]; | ||
146 | |||
147 | psm->ports[i].serio = serio; | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static void ps2mult_reset(struct ps2mult *psm) | ||
153 | { | ||
154 | unsigned long flags; | ||
155 | |||
156 | spin_lock_irqsave(&psm->lock, flags); | ||
157 | |||
158 | serio_write(psm->mx_serio, PS2MULT_SESSION_END); | ||
159 | serio_write(psm->mx_serio, PS2MULT_SESSION_START); | ||
160 | |||
161 | ps2mult_select_port(psm, &psm->ports[PS2MULT_KBD_PORT]); | ||
162 | |||
163 | spin_unlock_irqrestore(&psm->lock, flags); | ||
164 | } | ||
165 | |||
166 | static int ps2mult_connect(struct serio *serio, struct serio_driver *drv) | ||
167 | { | ||
168 | struct ps2mult *psm; | ||
169 | int i; | ||
170 | int error; | ||
171 | |||
172 | if (!serio->write) | ||
173 | return -EINVAL; | ||
174 | |||
175 | psm = kzalloc(sizeof(*psm), GFP_KERNEL); | ||
176 | if (!psm) | ||
177 | return -ENOMEM; | ||
178 | |||
179 | spin_lock_init(&psm->lock); | ||
180 | psm->mx_serio = serio; | ||
181 | |||
182 | for (i = 0; i < PS2MULT_NUM_PORTS; i++) { | ||
183 | psm->ports[i].sel = ps2mult_controls[i]; | ||
184 | error = ps2mult_create_port(psm, i); | ||
185 | if (error) | ||
186 | goto err_out; | ||
187 | } | ||
188 | |||
189 | psm->in_port = psm->out_port = &psm->ports[PS2MULT_KBD_PORT]; | ||
190 | |||
191 | serio_set_drvdata(serio, psm); | ||
192 | error = serio_open(serio, drv); | ||
193 | if (error) | ||
194 | goto err_out; | ||
195 | |||
196 | ps2mult_reset(psm); | ||
197 | |||
198 | for (i = 0; i < PS2MULT_NUM_PORTS; i++) { | ||
199 | struct serio *s = psm->ports[i].serio; | ||
200 | |||
201 | dev_info(&serio->dev, "%s port at %s\n", s->name, serio->phys); | ||
202 | serio_register_port(s); | ||
203 | } | ||
204 | |||
205 | return 0; | ||
206 | |||
207 | err_out: | ||
208 | while (--i >= 0) | ||
209 | kfree(psm->ports[i].serio); | ||
210 | kfree(serio); | ||
211 | return error; | ||
212 | } | ||
213 | |||
214 | static void ps2mult_disconnect(struct serio *serio) | ||
215 | { | ||
216 | struct ps2mult *psm = serio_get_drvdata(serio); | ||
217 | |||
218 | /* Note that serio core already take care of children ports */ | ||
219 | serio_write(serio, PS2MULT_SESSION_END); | ||
220 | serio_close(serio); | ||
221 | kfree(psm); | ||
222 | |||
223 | serio_set_drvdata(serio, NULL); | ||
224 | } | ||
225 | |||
226 | static int ps2mult_reconnect(struct serio *serio) | ||
227 | { | ||
228 | struct ps2mult *psm = serio_get_drvdata(serio); | ||
229 | |||
230 | ps2mult_reset(psm); | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static irqreturn_t ps2mult_interrupt(struct serio *serio, | ||
236 | unsigned char data, unsigned int dfl) | ||
237 | { | ||
238 | struct ps2mult *psm = serio_get_drvdata(serio); | ||
239 | struct ps2mult_port *in_port; | ||
240 | unsigned long flags; | ||
241 | |||
242 | dev_dbg(&serio->dev, "Received %02x flags %02x\n", data, dfl); | ||
243 | |||
244 | spin_lock_irqsave(&psm->lock, flags); | ||
245 | |||
246 | if (psm->escape) { | ||
247 | psm->escape = false; | ||
248 | in_port = psm->in_port; | ||
249 | if (in_port->registered) | ||
250 | serio_interrupt(in_port->serio, data, dfl); | ||
251 | goto out; | ||
252 | } | ||
253 | |||
254 | switch (data) { | ||
255 | case PS2MULT_ESCAPE: | ||
256 | dev_dbg(&serio->dev, "ESCAPE\n"); | ||
257 | psm->escape = true; | ||
258 | break; | ||
259 | |||
260 | case PS2MULT_BSYNC: | ||
261 | dev_dbg(&serio->dev, "BSYNC\n"); | ||
262 | psm->in_port = psm->out_port; | ||
263 | break; | ||
264 | |||
265 | case PS2MULT_SESSION_START: | ||
266 | dev_dbg(&serio->dev, "SS\n"); | ||
267 | break; | ||
268 | |||
269 | case PS2MULT_SESSION_END: | ||
270 | dev_dbg(&serio->dev, "SE\n"); | ||
271 | break; | ||
272 | |||
273 | case PS2MULT_KB_SELECTOR: | ||
274 | dev_dbg(&serio->dev, "KB\n"); | ||
275 | psm->in_port = &psm->ports[PS2MULT_KBD_PORT]; | ||
276 | break; | ||
277 | |||
278 | case PS2MULT_MS_SELECTOR: | ||
279 | dev_dbg(&serio->dev, "MS\n"); | ||
280 | psm->in_port = &psm->ports[PS2MULT_MOUSE_PORT]; | ||
281 | break; | ||
282 | |||
283 | default: | ||
284 | in_port = psm->in_port; | ||
285 | if (in_port->registered) | ||
286 | serio_interrupt(in_port->serio, data, dfl); | ||
287 | break; | ||
288 | } | ||
289 | |||
290 | out: | ||
291 | spin_unlock_irqrestore(&psm->lock, flags); | ||
292 | return IRQ_HANDLED; | ||
293 | } | ||
294 | |||
295 | static struct serio_driver ps2mult_drv = { | ||
296 | .driver = { | ||
297 | .name = "ps2mult", | ||
298 | }, | ||
299 | .description = "TQC PS/2 Multiplexer driver", | ||
300 | .id_table = ps2mult_serio_ids, | ||
301 | .interrupt = ps2mult_interrupt, | ||
302 | .connect = ps2mult_connect, | ||
303 | .disconnect = ps2mult_disconnect, | ||
304 | .reconnect = ps2mult_reconnect, | ||
305 | }; | ||
306 | |||
307 | static int __init ps2mult_init(void) | ||
308 | { | ||
309 | return serio_register_driver(&ps2mult_drv); | ||
310 | } | ||
311 | |||
312 | static void __exit ps2mult_exit(void) | ||
313 | { | ||
314 | serio_unregister_driver(&ps2mult_drv); | ||
315 | } | ||
316 | |||
317 | module_init(ps2mult_init); | ||
318 | module_exit(ps2mult_exit); | ||
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index c3b626e9eae7..405bf214527c 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | #include <linux/kthread.h> | 38 | #include <linux/kthread.h> |
39 | #include <linux/mutex.h> | 39 | #include <linux/mutex.h> |
40 | #include <linux/freezer.h> | ||
41 | 40 | ||
42 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 41 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
43 | MODULE_DESCRIPTION("Serio abstraction core"); | 42 | MODULE_DESCRIPTION("Serio abstraction core"); |
@@ -56,7 +55,7 @@ static struct bus_type serio_bus; | |||
56 | static void serio_add_port(struct serio *serio); | 55 | static void serio_add_port(struct serio *serio); |
57 | static int serio_reconnect_port(struct serio *serio); | 56 | static int serio_reconnect_port(struct serio *serio); |
58 | static void serio_disconnect_port(struct serio *serio); | 57 | static void serio_disconnect_port(struct serio *serio); |
59 | static void serio_reconnect_chain(struct serio *serio); | 58 | static void serio_reconnect_subtree(struct serio *serio); |
60 | static void serio_attach_driver(struct serio_driver *drv); | 59 | static void serio_attach_driver(struct serio_driver *drv); |
61 | 60 | ||
62 | static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) | 61 | static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) |
@@ -152,7 +151,7 @@ static void serio_find_driver(struct serio *serio) | |||
152 | enum serio_event_type { | 151 | enum serio_event_type { |
153 | SERIO_RESCAN_PORT, | 152 | SERIO_RESCAN_PORT, |
154 | SERIO_RECONNECT_PORT, | 153 | SERIO_RECONNECT_PORT, |
155 | SERIO_RECONNECT_CHAIN, | 154 | SERIO_RECONNECT_SUBTREE, |
156 | SERIO_REGISTER_PORT, | 155 | SERIO_REGISTER_PORT, |
157 | SERIO_ATTACH_DRIVER, | 156 | SERIO_ATTACH_DRIVER, |
158 | }; | 157 | }; |
@@ -292,8 +291,8 @@ static void serio_handle_event(void) | |||
292 | serio_find_driver(event->object); | 291 | serio_find_driver(event->object); |
293 | break; | 292 | break; |
294 | 293 | ||
295 | case SERIO_RECONNECT_CHAIN: | 294 | case SERIO_RECONNECT_SUBTREE: |
296 | serio_reconnect_chain(event->object); | 295 | serio_reconnect_subtree(event->object); |
297 | break; | 296 | break; |
298 | 297 | ||
299 | case SERIO_ATTACH_DRIVER: | 298 | case SERIO_ATTACH_DRIVER: |
@@ -330,12 +329,10 @@ static void serio_remove_pending_events(void *object) | |||
330 | } | 329 | } |
331 | 330 | ||
332 | /* | 331 | /* |
333 | * Destroy child serio port (if any) that has not been fully registered yet. | 332 | * Locate child serio port (if any) that has not been fully registered yet. |
334 | * | 333 | * |
335 | * Note that we rely on the fact that port can have only one child and therefore | 334 | * Children are registered by driver's connect() handler so there can't be a |
336 | * only one child registration request can be pending. Additionally, children | 335 | * grandchild pending registration together with a child. |
337 | * are registered by driver's connect() handler so there can't be a grandchild | ||
338 | * pending registration together with a child. | ||
339 | */ | 336 | */ |
340 | static struct serio *serio_get_pending_child(struct serio *parent) | 337 | static struct serio *serio_get_pending_child(struct serio *parent) |
341 | { | 338 | { |
@@ -449,7 +446,7 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute * | |||
449 | if (!strncmp(buf, "none", count)) { | 446 | if (!strncmp(buf, "none", count)) { |
450 | serio_disconnect_port(serio); | 447 | serio_disconnect_port(serio); |
451 | } else if (!strncmp(buf, "reconnect", count)) { | 448 | } else if (!strncmp(buf, "reconnect", count)) { |
452 | serio_reconnect_chain(serio); | 449 | serio_reconnect_subtree(serio); |
453 | } else if (!strncmp(buf, "rescan", count)) { | 450 | } else if (!strncmp(buf, "rescan", count)) { |
454 | serio_disconnect_port(serio); | 451 | serio_disconnect_port(serio); |
455 | serio_find_driver(serio); | 452 | serio_find_driver(serio); |
@@ -516,6 +513,8 @@ static void serio_init_port(struct serio *serio) | |||
516 | __module_get(THIS_MODULE); | 513 | __module_get(THIS_MODULE); |
517 | 514 | ||
518 | INIT_LIST_HEAD(&serio->node); | 515 | INIT_LIST_HEAD(&serio->node); |
516 | INIT_LIST_HEAD(&serio->child_node); | ||
517 | INIT_LIST_HEAD(&serio->children); | ||
519 | spin_lock_init(&serio->lock); | 518 | spin_lock_init(&serio->lock); |
520 | mutex_init(&serio->drv_mutex); | 519 | mutex_init(&serio->drv_mutex); |
521 | device_initialize(&serio->dev); | 520 | device_initialize(&serio->dev); |
@@ -538,12 +537,13 @@ static void serio_init_port(struct serio *serio) | |||
538 | */ | 537 | */ |
539 | static void serio_add_port(struct serio *serio) | 538 | static void serio_add_port(struct serio *serio) |
540 | { | 539 | { |
540 | struct serio *parent = serio->parent; | ||
541 | int error; | 541 | int error; |
542 | 542 | ||
543 | if (serio->parent) { | 543 | if (parent) { |
544 | serio_pause_rx(serio->parent); | 544 | serio_pause_rx(parent); |
545 | serio->parent->child = serio; | 545 | list_add_tail(&serio->child_node, &parent->children); |
546 | serio_continue_rx(serio->parent); | 546 | serio_continue_rx(parent); |
547 | } | 547 | } |
548 | 548 | ||
549 | list_add_tail(&serio->node, &serio_list); | 549 | list_add_tail(&serio->node, &serio_list); |
@@ -559,15 +559,14 @@ static void serio_add_port(struct serio *serio) | |||
559 | } | 559 | } |
560 | 560 | ||
561 | /* | 561 | /* |
562 | * serio_destroy_port() completes deregistration process and removes | 562 | * serio_destroy_port() completes unregistration process and removes |
563 | * port from the system | 563 | * port from the system |
564 | */ | 564 | */ |
565 | static void serio_destroy_port(struct serio *serio) | 565 | static void serio_destroy_port(struct serio *serio) |
566 | { | 566 | { |
567 | struct serio *child; | 567 | struct serio *child; |
568 | 568 | ||
569 | child = serio_get_pending_child(serio); | 569 | while ((child = serio_get_pending_child(serio)) != NULL) { |
570 | if (child) { | ||
571 | serio_remove_pending_events(child); | 570 | serio_remove_pending_events(child); |
572 | put_device(&child->dev); | 571 | put_device(&child->dev); |
573 | } | 572 | } |
@@ -577,7 +576,7 @@ static void serio_destroy_port(struct serio *serio) | |||
577 | 576 | ||
578 | if (serio->parent) { | 577 | if (serio->parent) { |
579 | serio_pause_rx(serio->parent); | 578 | serio_pause_rx(serio->parent); |
580 | serio->parent->child = NULL; | 579 | list_del_init(&serio->child_node); |
581 | serio_continue_rx(serio->parent); | 580 | serio_continue_rx(serio->parent); |
582 | serio->parent = NULL; | 581 | serio->parent = NULL; |
583 | } | 582 | } |
@@ -609,46 +608,82 @@ static int serio_reconnect_port(struct serio *serio) | |||
609 | } | 608 | } |
610 | 609 | ||
611 | /* | 610 | /* |
612 | * Reconnect serio port and all its children (re-initialize attached devices) | 611 | * Reconnect serio port and all its children (re-initialize attached |
612 | * devices). | ||
613 | */ | 613 | */ |
614 | static void serio_reconnect_chain(struct serio *serio) | 614 | static void serio_reconnect_subtree(struct serio *root) |
615 | { | 615 | { |
616 | struct serio *s = root; | ||
617 | int error; | ||
618 | |||
616 | do { | 619 | do { |
617 | if (serio_reconnect_port(serio)) { | 620 | error = serio_reconnect_port(s); |
618 | /* Ok, old children are now gone, we are done */ | 621 | if (!error) { |
619 | break; | 622 | /* |
623 | * Reconnect was successful, move on to do the | ||
624 | * first child. | ||
625 | */ | ||
626 | if (!list_empty(&s->children)) { | ||
627 | s = list_first_entry(&s->children, | ||
628 | struct serio, child_node); | ||
629 | continue; | ||
630 | } | ||
620 | } | 631 | } |
621 | serio = serio->child; | 632 | |
622 | } while (serio); | 633 | /* |
634 | * Either it was a leaf node or reconnect failed and it | ||
635 | * became a leaf node. Continue reconnecting starting with | ||
636 | * the next sibling of the parent node. | ||
637 | */ | ||
638 | while (s != root) { | ||
639 | struct serio *parent = s->parent; | ||
640 | |||
641 | if (!list_is_last(&s->child_node, &parent->children)) { | ||
642 | s = list_entry(s->child_node.next, | ||
643 | struct serio, child_node); | ||
644 | break; | ||
645 | } | ||
646 | |||
647 | s = parent; | ||
648 | } | ||
649 | } while (s != root); | ||
623 | } | 650 | } |
624 | 651 | ||
625 | /* | 652 | /* |
626 | * serio_disconnect_port() unbinds a port from its driver. As a side effect | 653 | * serio_disconnect_port() unbinds a port from its driver. As a side effect |
627 | * all child ports are unbound and destroyed. | 654 | * all children ports are unbound and destroyed. |
628 | */ | 655 | */ |
629 | static void serio_disconnect_port(struct serio *serio) | 656 | static void serio_disconnect_port(struct serio *serio) |
630 | { | 657 | { |
631 | struct serio *s, *parent; | 658 | struct serio *s = serio; |
659 | |||
660 | /* | ||
661 | * Children ports should be disconnected and destroyed | ||
662 | * first; we travel the tree in depth-first order. | ||
663 | */ | ||
664 | while (!list_empty(&serio->children)) { | ||
665 | |||
666 | /* Locate a leaf */ | ||
667 | while (!list_empty(&s->children)) | ||
668 | s = list_first_entry(&s->children, | ||
669 | struct serio, child_node); | ||
632 | 670 | ||
633 | if (serio->child) { | ||
634 | /* | 671 | /* |
635 | * Children ports should be disconnected and destroyed | 672 | * Prune this leaf node unless it is the one we |
636 | * first, staring with the leaf one, since we don't want | 673 | * started with. |
637 | * to do recursion | ||
638 | */ | 674 | */ |
639 | for (s = serio; s->child; s = s->child) | 675 | if (s != serio) { |
640 | /* empty */; | 676 | struct serio *parent = s->parent; |
641 | |||
642 | do { | ||
643 | parent = s->parent; | ||
644 | 677 | ||
645 | device_release_driver(&s->dev); | 678 | device_release_driver(&s->dev); |
646 | serio_destroy_port(s); | 679 | serio_destroy_port(s); |
647 | } while ((s = parent) != serio); | 680 | |
681 | s = parent; | ||
682 | } | ||
648 | } | 683 | } |
649 | 684 | ||
650 | /* | 685 | /* |
651 | * Ok, no children left, now disconnect this port | 686 | * OK, no children left, now disconnect this port. |
652 | */ | 687 | */ |
653 | device_release_driver(&serio->dev); | 688 | device_release_driver(&serio->dev); |
654 | } | 689 | } |
@@ -661,7 +696,7 @@ EXPORT_SYMBOL(serio_rescan); | |||
661 | 696 | ||
662 | void serio_reconnect(struct serio *serio) | 697 | void serio_reconnect(struct serio *serio) |
663 | { | 698 | { |
664 | serio_queue_event(serio, NULL, SERIO_RECONNECT_CHAIN); | 699 | serio_queue_event(serio, NULL, SERIO_RECONNECT_SUBTREE); |
665 | } | 700 | } |
666 | EXPORT_SYMBOL(serio_reconnect); | 701 | EXPORT_SYMBOL(serio_reconnect); |
667 | 702 | ||
@@ -689,14 +724,16 @@ void serio_unregister_port(struct serio *serio) | |||
689 | EXPORT_SYMBOL(serio_unregister_port); | 724 | EXPORT_SYMBOL(serio_unregister_port); |
690 | 725 | ||
691 | /* | 726 | /* |
692 | * Safely unregisters child port if one is present. | 727 | * Safely unregisters children ports if they are present. |
693 | */ | 728 | */ |
694 | void serio_unregister_child_port(struct serio *serio) | 729 | void serio_unregister_child_port(struct serio *serio) |
695 | { | 730 | { |
731 | struct serio *s, *next; | ||
732 | |||
696 | mutex_lock(&serio_mutex); | 733 | mutex_lock(&serio_mutex); |
697 | if (serio->child) { | 734 | list_for_each_entry_safe(s, next, &serio->children, child_node) { |
698 | serio_disconnect_port(serio->child); | 735 | serio_disconnect_port(s); |
699 | serio_destroy_port(serio->child); | 736 | serio_destroy_port(s); |
700 | } | 737 | } |
701 | mutex_unlock(&serio_mutex); | 738 | mutex_unlock(&serio_mutex); |
702 | } | 739 | } |
diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c index 014248344763..a29a7812bd46 100644 --- a/drivers/input/sparse-keymap.c +++ b/drivers/input/sparse-keymap.c | |||
@@ -22,6 +22,37 @@ MODULE_DESCRIPTION("Generic support for sparse keymaps"); | |||
22 | MODULE_LICENSE("GPL v2"); | 22 | MODULE_LICENSE("GPL v2"); |
23 | MODULE_VERSION("0.1"); | 23 | MODULE_VERSION("0.1"); |
24 | 24 | ||
25 | static unsigned int sparse_keymap_get_key_index(struct input_dev *dev, | ||
26 | const struct key_entry *k) | ||
27 | { | ||
28 | struct key_entry *key; | ||
29 | unsigned int idx = 0; | ||
30 | |||
31 | for (key = dev->keycode; key->type != KE_END; key++) { | ||
32 | if (key->type == KE_KEY) { | ||
33 | if (key == k) | ||
34 | break; | ||
35 | idx++; | ||
36 | } | ||
37 | } | ||
38 | |||
39 | return idx; | ||
40 | } | ||
41 | |||
42 | static struct key_entry *sparse_keymap_entry_by_index(struct input_dev *dev, | ||
43 | unsigned int index) | ||
44 | { | ||
45 | struct key_entry *key; | ||
46 | unsigned int key_cnt = 0; | ||
47 | |||
48 | for (key = dev->keycode; key->type != KE_END; key++) | ||
49 | if (key->type == KE_KEY) | ||
50 | if (key_cnt++ == index) | ||
51 | return key; | ||
52 | |||
53 | return NULL; | ||
54 | } | ||
55 | |||
25 | /** | 56 | /** |
26 | * sparse_keymap_entry_from_scancode - perform sparse keymap lookup | 57 | * sparse_keymap_entry_from_scancode - perform sparse keymap lookup |
27 | * @dev: Input device using sparse keymap | 58 | * @dev: Input device using sparse keymap |
@@ -64,16 +95,36 @@ struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev, | |||
64 | } | 95 | } |
65 | EXPORT_SYMBOL(sparse_keymap_entry_from_keycode); | 96 | EXPORT_SYMBOL(sparse_keymap_entry_from_keycode); |
66 | 97 | ||
98 | static struct key_entry *sparse_keymap_locate(struct input_dev *dev, | ||
99 | const struct input_keymap_entry *ke) | ||
100 | { | ||
101 | struct key_entry *key; | ||
102 | unsigned int scancode; | ||
103 | |||
104 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) | ||
105 | key = sparse_keymap_entry_by_index(dev, ke->index); | ||
106 | else if (input_scancode_to_scalar(ke, &scancode) == 0) | ||
107 | key = sparse_keymap_entry_from_scancode(dev, scancode); | ||
108 | else | ||
109 | key = NULL; | ||
110 | |||
111 | return key; | ||
112 | } | ||
113 | |||
67 | static int sparse_keymap_getkeycode(struct input_dev *dev, | 114 | static int sparse_keymap_getkeycode(struct input_dev *dev, |
68 | unsigned int scancode, | 115 | struct input_keymap_entry *ke) |
69 | unsigned int *keycode) | ||
70 | { | 116 | { |
71 | const struct key_entry *key; | 117 | const struct key_entry *key; |
72 | 118 | ||
73 | if (dev->keycode) { | 119 | if (dev->keycode) { |
74 | key = sparse_keymap_entry_from_scancode(dev, scancode); | 120 | key = sparse_keymap_locate(dev, ke); |
75 | if (key && key->type == KE_KEY) { | 121 | if (key && key->type == KE_KEY) { |
76 | *keycode = key->keycode; | 122 | ke->keycode = key->keycode; |
123 | if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) | ||
124 | ke->index = | ||
125 | sparse_keymap_get_key_index(dev, key); | ||
126 | ke->len = sizeof(key->code); | ||
127 | memcpy(ke->scancode, &key->code, sizeof(key->code)); | ||
77 | return 0; | 128 | return 0; |
78 | } | 129 | } |
79 | } | 130 | } |
@@ -82,20 +133,19 @@ static int sparse_keymap_getkeycode(struct input_dev *dev, | |||
82 | } | 133 | } |
83 | 134 | ||
84 | static int sparse_keymap_setkeycode(struct input_dev *dev, | 135 | static int sparse_keymap_setkeycode(struct input_dev *dev, |
85 | unsigned int scancode, | 136 | const struct input_keymap_entry *ke, |
86 | unsigned int keycode) | 137 | unsigned int *old_keycode) |
87 | { | 138 | { |
88 | struct key_entry *key; | 139 | struct key_entry *key; |
89 | int old_keycode; | ||
90 | 140 | ||
91 | if (dev->keycode) { | 141 | if (dev->keycode) { |
92 | key = sparse_keymap_entry_from_scancode(dev, scancode); | 142 | key = sparse_keymap_locate(dev, ke); |
93 | if (key && key->type == KE_KEY) { | 143 | if (key && key->type == KE_KEY) { |
94 | old_keycode = key->keycode; | 144 | *old_keycode = key->keycode; |
95 | key->keycode = keycode; | 145 | key->keycode = ke->keycode; |
96 | set_bit(keycode, dev->keybit); | 146 | set_bit(ke->keycode, dev->keybit); |
97 | if (!sparse_keymap_entry_from_keycode(dev, old_keycode)) | 147 | if (!sparse_keymap_entry_from_keycode(dev, *old_keycode)) |
98 | clear_bit(old_keycode, dev->keybit); | 148 | clear_bit(*old_keycode, dev->keybit); |
99 | return 0; | 149 | return 0; |
100 | } | 150 | } |
101 | } | 151 | } |
@@ -159,15 +209,14 @@ int sparse_keymap_setup(struct input_dev *dev, | |||
159 | 209 | ||
160 | dev->keycode = map; | 210 | dev->keycode = map; |
161 | dev->keycodemax = map_size; | 211 | dev->keycodemax = map_size; |
162 | dev->getkeycode = sparse_keymap_getkeycode; | 212 | dev->getkeycode_new = sparse_keymap_getkeycode; |
163 | dev->setkeycode = sparse_keymap_setkeycode; | 213 | dev->setkeycode_new = sparse_keymap_setkeycode; |
164 | 214 | ||
165 | return 0; | 215 | return 0; |
166 | 216 | ||
167 | err_out: | 217 | err_out: |
168 | kfree(map); | 218 | kfree(map); |
169 | return error; | 219 | return error; |
170 | |||
171 | } | 220 | } |
172 | EXPORT_SYMBOL(sparse_keymap_setup); | 221 | EXPORT_SYMBOL(sparse_keymap_setup); |
173 | 222 | ||
diff --git a/drivers/input/tablet/Kconfig b/drivers/input/tablet/Kconfig index effb49ea24aa..58a87755b936 100644 --- a/drivers/input/tablet/Kconfig +++ b/drivers/input/tablet/Kconfig | |||
@@ -49,6 +49,17 @@ config TABLET_USB_GTCO | |||
49 | To compile this driver as a module, choose M here: the | 49 | To compile this driver as a module, choose M here: the |
50 | module will be called gtco. | 50 | module will be called gtco. |
51 | 51 | ||
52 | config TABLET_USB_HANWANG | ||
53 | tristate "Hanwang Art Master III tablet support (USB)" | ||
54 | depends on USB_ARCH_HAS_HCD | ||
55 | select USB | ||
56 | help | ||
57 | Say Y here if you want to use the USB version of the Hanwang Art | ||
58 | Master III tablet. | ||
59 | |||
60 | To compile this driver as a module, choose M here: the | ||
61 | module will be called hanwang. | ||
62 | |||
52 | config TABLET_USB_KBTAB | 63 | config TABLET_USB_KBTAB |
53 | tristate "KB Gear JamStudio tablet support (USB)" | 64 | tristate "KB Gear JamStudio tablet support (USB)" |
54 | depends on USB_ARCH_HAS_HCD | 65 | depends on USB_ARCH_HAS_HCD |
diff --git a/drivers/input/tablet/Makefile b/drivers/input/tablet/Makefile index ce8b9a9cfa40..3f6c25220638 100644 --- a/drivers/input/tablet/Makefile +++ b/drivers/input/tablet/Makefile | |||
@@ -8,5 +8,6 @@ wacom-objs := wacom_wac.o wacom_sys.o | |||
8 | obj-$(CONFIG_TABLET_USB_ACECAD) += acecad.o | 8 | obj-$(CONFIG_TABLET_USB_ACECAD) += acecad.o |
9 | obj-$(CONFIG_TABLET_USB_AIPTEK) += aiptek.o | 9 | obj-$(CONFIG_TABLET_USB_AIPTEK) += aiptek.o |
10 | obj-$(CONFIG_TABLET_USB_GTCO) += gtco.o | 10 | obj-$(CONFIG_TABLET_USB_GTCO) += gtco.o |
11 | obj-$(CONFIG_TABLET_USB_HANWANG) += hanwang.o | ||
11 | obj-$(CONFIG_TABLET_USB_KBTAB) += kbtab.o | 12 | obj-$(CONFIG_TABLET_USB_KBTAB) += kbtab.o |
12 | obj-$(CONFIG_TABLET_USB_WACOM) += wacom.o | 13 | obj-$(CONFIG_TABLET_USB_WACOM) += wacom.o |
diff --git a/drivers/input/tablet/hanwang.c b/drivers/input/tablet/hanwang.c new file mode 100644 index 000000000000..6504b627b234 --- /dev/null +++ b/drivers/input/tablet/hanwang.c | |||
@@ -0,0 +1,446 @@ | |||
1 | /* | ||
2 | * USB Hanwang tablet support | ||
3 | * | ||
4 | * Copyright (c) 2010 Xing Wei <weixing@hanwang.com.cn> | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | /* | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #include <linux/types.h> | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/usb/input.h> | ||
31 | |||
32 | #define DRIVER_AUTHOR "Xing Wei <weixing@hanwang.com.cn>" | ||
33 | #define DRIVER_DESC "USB Hanwang tablet driver" | ||
34 | #define DRIVER_LICENSE "GPL" | ||
35 | |||
36 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
37 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
38 | MODULE_LICENSE(DRIVER_LICENSE); | ||
39 | |||
40 | #define USB_VENDOR_ID_HANWANG 0x0b57 | ||
41 | #define HANWANG_TABLET_INT_CLASS 0x0003 | ||
42 | #define HANWANG_TABLET_INT_SUB_CLASS 0x0001 | ||
43 | #define HANWANG_TABLET_INT_PROTOCOL 0x0002 | ||
44 | |||
45 | #define ART_MASTER_PKGLEN_MAX 10 | ||
46 | |||
47 | /* device IDs */ | ||
48 | #define STYLUS_DEVICE_ID 0x02 | ||
49 | #define TOUCH_DEVICE_ID 0x03 | ||
50 | #define CURSOR_DEVICE_ID 0x06 | ||
51 | #define ERASER_DEVICE_ID 0x0A | ||
52 | #define PAD_DEVICE_ID 0x0F | ||
53 | |||
54 | /* match vendor and interface info */ | ||
55 | #define HANWANG_TABLET_DEVICE(vend, cl, sc, pr) \ | ||
56 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR \ | ||
57 | | USB_DEVICE_ID_MATCH_INT_INFO, \ | ||
58 | .idVendor = (vend), \ | ||
59 | .bInterfaceClass = (cl), \ | ||
60 | .bInterfaceSubClass = (sc), \ | ||
61 | .bInterfaceProtocol = (pr) | ||
62 | |||
63 | enum hanwang_tablet_type { | ||
64 | HANWANG_ART_MASTER_III, | ||
65 | HANWANG_ART_MASTER_HD, | ||
66 | }; | ||
67 | |||
68 | struct hanwang { | ||
69 | unsigned char *data; | ||
70 | dma_addr_t data_dma; | ||
71 | struct input_dev *dev; | ||
72 | struct usb_device *usbdev; | ||
73 | struct urb *irq; | ||
74 | const struct hanwang_features *features; | ||
75 | unsigned int current_tool; | ||
76 | unsigned int current_id; | ||
77 | char name[64]; | ||
78 | char phys[32]; | ||
79 | }; | ||
80 | |||
81 | struct hanwang_features { | ||
82 | unsigned short pid; | ||
83 | char *name; | ||
84 | enum hanwang_tablet_type type; | ||
85 | int pkg_len; | ||
86 | int max_x; | ||
87 | int max_y; | ||
88 | int max_tilt_x; | ||
89 | int max_tilt_y; | ||
90 | int max_pressure; | ||
91 | }; | ||
92 | |||
93 | static const struct hanwang_features features_array[] = { | ||
94 | { 0x8528, "Hanwang Art Master III 0906", HANWANG_ART_MASTER_III, | ||
95 | ART_MASTER_PKGLEN_MAX, 0x5757, 0x3692, 0x3f, 0x7f, 2048 }, | ||
96 | { 0x8529, "Hanwang Art Master III 0604", HANWANG_ART_MASTER_III, | ||
97 | ART_MASTER_PKGLEN_MAX, 0x3d84, 0x2672, 0x3f, 0x7f, 2048 }, | ||
98 | { 0x852a, "Hanwang Art Master III 1308", HANWANG_ART_MASTER_III, | ||
99 | ART_MASTER_PKGLEN_MAX, 0x7f00, 0x4f60, 0x3f, 0x7f, 2048 }, | ||
100 | { 0x8401, "Hanwang Art Master HD 5012", HANWANG_ART_MASTER_HD, | ||
101 | ART_MASTER_PKGLEN_MAX, 0x678e, 0x4150, 0x3f, 0x7f, 1024 }, | ||
102 | }; | ||
103 | |||
104 | static const int hw_eventtypes[] = { | ||
105 | EV_KEY, EV_ABS, EV_MSC, | ||
106 | }; | ||
107 | |||
108 | static const int hw_absevents[] = { | ||
109 | ABS_X, ABS_Y, ABS_TILT_X, ABS_TILT_Y, ABS_WHEEL, | ||
110 | ABS_RX, ABS_RY, ABS_PRESSURE, ABS_MISC, | ||
111 | }; | ||
112 | |||
113 | static const int hw_btnevents[] = { | ||
114 | BTN_STYLUS, BTN_STYLUS2, BTN_TOOL_PEN, BTN_TOOL_RUBBER, | ||
115 | BTN_TOOL_MOUSE, BTN_TOOL_FINGER, | ||
116 | BTN_0, BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7, BTN_8, | ||
117 | }; | ||
118 | |||
119 | static const int hw_mscevents[] = { | ||
120 | MSC_SERIAL, | ||
121 | }; | ||
122 | |||
123 | static void hanwang_parse_packet(struct hanwang *hanwang) | ||
124 | { | ||
125 | unsigned char *data = hanwang->data; | ||
126 | struct input_dev *input_dev = hanwang->dev; | ||
127 | struct usb_device *dev = hanwang->usbdev; | ||
128 | enum hanwang_tablet_type type = hanwang->features->type; | ||
129 | int i; | ||
130 | u16 x, y, p; | ||
131 | |||
132 | switch (data[0]) { | ||
133 | case 0x02: /* data packet */ | ||
134 | switch (data[1]) { | ||
135 | case 0x80: /* tool prox out */ | ||
136 | hanwang->current_id = 0; | ||
137 | input_report_key(input_dev, hanwang->current_tool, 0); | ||
138 | break; | ||
139 | |||
140 | case 0xc2: /* first time tool prox in */ | ||
141 | switch (data[3] & 0xf0) { | ||
142 | case 0x20: /* art_master III */ | ||
143 | case 0x30: /* art_master_HD */ | ||
144 | hanwang->current_id = STYLUS_DEVICE_ID; | ||
145 | hanwang->current_tool = BTN_TOOL_PEN; | ||
146 | input_report_key(input_dev, BTN_TOOL_PEN, 1); | ||
147 | break; | ||
148 | case 0xa0: /* art_master III */ | ||
149 | case 0xb0: /* art_master_HD */ | ||
150 | hanwang->current_id = ERASER_DEVICE_ID; | ||
151 | hanwang->current_tool = BTN_TOOL_RUBBER; | ||
152 | input_report_key(input_dev, BTN_TOOL_RUBBER, 1); | ||
153 | break; | ||
154 | default: | ||
155 | hanwang->current_id = 0; | ||
156 | dev_dbg(&dev->dev, | ||
157 | "unknown tablet tool %02x ", data[0]); | ||
158 | break; | ||
159 | } | ||
160 | break; | ||
161 | |||
162 | default: /* tool data packet */ | ||
163 | x = (data[2] << 8) | data[3]; | ||
164 | y = (data[4] << 8) | data[5]; | ||
165 | |||
166 | switch (type) { | ||
167 | case HANWANG_ART_MASTER_III: | ||
168 | p = (data[6] << 3) | | ||
169 | ((data[7] & 0xc0) >> 5) | | ||
170 | (data[1] & 0x01); | ||
171 | break; | ||
172 | |||
173 | case HANWANG_ART_MASTER_HD: | ||
174 | p = (data[7] >> 6) | (data[6] << 2); | ||
175 | break; | ||
176 | |||
177 | default: | ||
178 | p = 0; | ||
179 | break; | ||
180 | } | ||
181 | |||
182 | input_report_abs(input_dev, ABS_X, | ||
183 | le16_to_cpup((__le16 *)&x)); | ||
184 | input_report_abs(input_dev, ABS_Y, | ||
185 | le16_to_cpup((__le16 *)&y)); | ||
186 | input_report_abs(input_dev, ABS_PRESSURE, | ||
187 | le16_to_cpup((__le16 *)&p)); | ||
188 | input_report_abs(input_dev, ABS_TILT_X, data[7] & 0x3f); | ||
189 | input_report_abs(input_dev, ABS_TILT_Y, data[8] & 0x7f); | ||
190 | input_report_key(input_dev, BTN_STYLUS, data[1] & 0x02); | ||
191 | input_report_key(input_dev, BTN_STYLUS2, data[1] & 0x04); | ||
192 | break; | ||
193 | } | ||
194 | input_report_abs(input_dev, ABS_MISC, hanwang->current_id); | ||
195 | input_event(input_dev, EV_MSC, MSC_SERIAL, | ||
196 | hanwang->features->pid); | ||
197 | break; | ||
198 | |||
199 | case 0x0c: | ||
200 | /* roll wheel */ | ||
201 | hanwang->current_id = PAD_DEVICE_ID; | ||
202 | |||
203 | switch (type) { | ||
204 | case HANWANG_ART_MASTER_III: | ||
205 | input_report_key(input_dev, BTN_TOOL_FINGER, data[1] || | ||
206 | data[2] || data[3]); | ||
207 | input_report_abs(input_dev, ABS_WHEEL, data[1]); | ||
208 | input_report_key(input_dev, BTN_0, data[2]); | ||
209 | for (i = 0; i < 8; i++) | ||
210 | input_report_key(input_dev, | ||
211 | BTN_1 + i, data[3] & (1 << i)); | ||
212 | break; | ||
213 | |||
214 | case HANWANG_ART_MASTER_HD: | ||
215 | input_report_key(input_dev, BTN_TOOL_FINGER, data[1] || | ||
216 | data[2] || data[3] || data[4] || | ||
217 | data[5] || data[6]); | ||
218 | input_report_abs(input_dev, ABS_RX, | ||
219 | ((data[1] & 0x1f) << 8) | data[2]); | ||
220 | input_report_abs(input_dev, ABS_RY, | ||
221 | ((data[3] & 0x1f) << 8) | data[4]); | ||
222 | input_report_key(input_dev, BTN_0, data[5] & 0x01); | ||
223 | for (i = 0; i < 4; i++) { | ||
224 | input_report_key(input_dev, | ||
225 | BTN_1 + i, data[5] & (1 << i)); | ||
226 | input_report_key(input_dev, | ||
227 | BTN_5 + i, data[6] & (1 << i)); | ||
228 | } | ||
229 | break; | ||
230 | } | ||
231 | |||
232 | input_report_abs(input_dev, ABS_MISC, hanwang->current_id); | ||
233 | input_event(input_dev, EV_MSC, MSC_SERIAL, 0xffffffff); | ||
234 | break; | ||
235 | |||
236 | default: | ||
237 | dev_dbg(&dev->dev, "error packet %02x ", data[0]); | ||
238 | break; | ||
239 | } | ||
240 | |||
241 | input_sync(input_dev); | ||
242 | } | ||
243 | |||
244 | static void hanwang_irq(struct urb *urb) | ||
245 | { | ||
246 | struct hanwang *hanwang = urb->context; | ||
247 | struct usb_device *dev = hanwang->usbdev; | ||
248 | int retval; | ||
249 | |||
250 | switch (urb->status) { | ||
251 | case 0: | ||
252 | /* success */; | ||
253 | hanwang_parse_packet(hanwang); | ||
254 | break; | ||
255 | case -ECONNRESET: | ||
256 | case -ENOENT: | ||
257 | case -ESHUTDOWN: | ||
258 | /* this urb is terminated, clean up */ | ||
259 | dev_err(&dev->dev, "%s - urb shutting down with status: %d", | ||
260 | __func__, urb->status); | ||
261 | return; | ||
262 | default: | ||
263 | dev_err(&dev->dev, "%s - nonzero urb status received: %d", | ||
264 | __func__, urb->status); | ||
265 | break; | ||
266 | } | ||
267 | |||
268 | retval = usb_submit_urb(urb, GFP_ATOMIC); | ||
269 | if (retval) | ||
270 | dev_err(&dev->dev, "%s - usb_submit_urb failed with result %d", | ||
271 | __func__, retval); | ||
272 | } | ||
273 | |||
274 | static int hanwang_open(struct input_dev *dev) | ||
275 | { | ||
276 | struct hanwang *hanwang = input_get_drvdata(dev); | ||
277 | |||
278 | hanwang->irq->dev = hanwang->usbdev; | ||
279 | if (usb_submit_urb(hanwang->irq, GFP_KERNEL)) | ||
280 | return -EIO; | ||
281 | |||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static void hanwang_close(struct input_dev *dev) | ||
286 | { | ||
287 | struct hanwang *hanwang = input_get_drvdata(dev); | ||
288 | |||
289 | usb_kill_urb(hanwang->irq); | ||
290 | } | ||
291 | |||
292 | static bool get_features(struct usb_device *dev, struct hanwang *hanwang) | ||
293 | { | ||
294 | int i; | ||
295 | |||
296 | for (i = 0; i < ARRAY_SIZE(features_array); i++) { | ||
297 | if (le16_to_cpu(dev->descriptor.idProduct) == | ||
298 | features_array[i].pid) { | ||
299 | hanwang->features = &features_array[i]; | ||
300 | return true; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | return false; | ||
305 | } | ||
306 | |||
307 | |||
308 | static int hanwang_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
309 | { | ||
310 | struct usb_device *dev = interface_to_usbdev(intf); | ||
311 | struct usb_endpoint_descriptor *endpoint; | ||
312 | struct hanwang *hanwang; | ||
313 | struct input_dev *input_dev; | ||
314 | int error; | ||
315 | int i; | ||
316 | |||
317 | hanwang = kzalloc(sizeof(struct hanwang), GFP_KERNEL); | ||
318 | input_dev = input_allocate_device(); | ||
319 | if (!hanwang || !input_dev) { | ||
320 | error = -ENOMEM; | ||
321 | goto fail1; | ||
322 | } | ||
323 | |||
324 | if (!get_features(dev, hanwang)) { | ||
325 | error = -ENXIO; | ||
326 | goto fail1; | ||
327 | } | ||
328 | |||
329 | hanwang->data = usb_alloc_coherent(dev, hanwang->features->pkg_len, | ||
330 | GFP_KERNEL, &hanwang->data_dma); | ||
331 | if (!hanwang->data) { | ||
332 | error = -ENOMEM; | ||
333 | goto fail1; | ||
334 | } | ||
335 | |||
336 | hanwang->irq = usb_alloc_urb(0, GFP_KERNEL); | ||
337 | if (!hanwang->irq) { | ||
338 | error = -ENOMEM; | ||
339 | goto fail2; | ||
340 | } | ||
341 | |||
342 | hanwang->usbdev = dev; | ||
343 | hanwang->dev = input_dev; | ||
344 | |||
345 | usb_make_path(dev, hanwang->phys, sizeof(hanwang->phys)); | ||
346 | strlcat(hanwang->phys, "/input0", sizeof(hanwang->phys)); | ||
347 | |||
348 | strlcpy(hanwang->name, hanwang->features->name, sizeof(hanwang->name)); | ||
349 | input_dev->name = hanwang->name; | ||
350 | input_dev->phys = hanwang->phys; | ||
351 | usb_to_input_id(dev, &input_dev->id); | ||
352 | input_dev->dev.parent = &intf->dev; | ||
353 | |||
354 | input_set_drvdata(input_dev, hanwang); | ||
355 | |||
356 | input_dev->open = hanwang_open; | ||
357 | input_dev->close = hanwang_close; | ||
358 | |||
359 | for (i = 0; i < ARRAY_SIZE(hw_eventtypes); ++i) | ||
360 | __set_bit(hw_eventtypes[i], input_dev->evbit); | ||
361 | |||
362 | for (i = 0; i < ARRAY_SIZE(hw_absevents); ++i) | ||
363 | __set_bit(hw_absevents[i], input_dev->absbit); | ||
364 | |||
365 | for (i = 0; i < ARRAY_SIZE(hw_btnevents); ++i) | ||
366 | __set_bit(hw_btnevents[i], input_dev->keybit); | ||
367 | |||
368 | for (i = 0; i < ARRAY_SIZE(hw_mscevents); ++i) | ||
369 | __set_bit(hw_mscevents[i], input_dev->mscbit); | ||
370 | |||
371 | input_set_abs_params(input_dev, ABS_X, | ||
372 | 0, hanwang->features->max_x, 4, 0); | ||
373 | input_set_abs_params(input_dev, ABS_Y, | ||
374 | 0, hanwang->features->max_y, 4, 0); | ||
375 | input_set_abs_params(input_dev, ABS_TILT_X, | ||
376 | 0, hanwang->features->max_tilt_x, 0, 0); | ||
377 | input_set_abs_params(input_dev, ABS_TILT_Y, | ||
378 | 0, hanwang->features->max_tilt_y, 0, 0); | ||
379 | input_set_abs_params(input_dev, ABS_PRESSURE, | ||
380 | 0, hanwang->features->max_pressure, 0, 0); | ||
381 | |||
382 | endpoint = &intf->cur_altsetting->endpoint[0].desc; | ||
383 | usb_fill_int_urb(hanwang->irq, dev, | ||
384 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), | ||
385 | hanwang->data, hanwang->features->pkg_len, | ||
386 | hanwang_irq, hanwang, endpoint->bInterval); | ||
387 | hanwang->irq->transfer_dma = hanwang->data_dma; | ||
388 | hanwang->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
389 | |||
390 | error = input_register_device(hanwang->dev); | ||
391 | if (error) | ||
392 | goto fail3; | ||
393 | |||
394 | usb_set_intfdata(intf, hanwang); | ||
395 | |||
396 | return 0; | ||
397 | |||
398 | fail3: usb_free_urb(hanwang->irq); | ||
399 | fail2: usb_free_coherent(dev, hanwang->features->pkg_len, | ||
400 | hanwang->data, hanwang->data_dma); | ||
401 | fail1: input_free_device(input_dev); | ||
402 | kfree(hanwang); | ||
403 | return error; | ||
404 | |||
405 | } | ||
406 | |||
407 | static void hanwang_disconnect(struct usb_interface *intf) | ||
408 | { | ||
409 | struct hanwang *hanwang = usb_get_intfdata(intf); | ||
410 | |||
411 | input_unregister_device(hanwang->dev); | ||
412 | usb_free_urb(hanwang->irq); | ||
413 | usb_free_coherent(interface_to_usbdev(intf), | ||
414 | hanwang->features->pkg_len, hanwang->data, | ||
415 | hanwang->data_dma); | ||
416 | kfree(hanwang); | ||
417 | usb_set_intfdata(intf, NULL); | ||
418 | } | ||
419 | |||
420 | static const struct usb_device_id hanwang_ids[] = { | ||
421 | { HANWANG_TABLET_DEVICE(USB_VENDOR_ID_HANWANG, HANWANG_TABLET_INT_CLASS, | ||
422 | HANWANG_TABLET_INT_SUB_CLASS, HANWANG_TABLET_INT_PROTOCOL) }, | ||
423 | {} | ||
424 | }; | ||
425 | |||
426 | MODULE_DEVICE_TABLE(usb, hanwang_ids); | ||
427 | |||
428 | static struct usb_driver hanwang_driver = { | ||
429 | .name = "hanwang", | ||
430 | .probe = hanwang_probe, | ||
431 | .disconnect = hanwang_disconnect, | ||
432 | .id_table = hanwang_ids, | ||
433 | }; | ||
434 | |||
435 | static int __init hanwang_init(void) | ||
436 | { | ||
437 | return usb_register(&hanwang_driver); | ||
438 | } | ||
439 | |||
440 | static void __exit hanwang_exit(void) | ||
441 | { | ||
442 | usb_deregister(&hanwang_driver); | ||
443 | } | ||
444 | |||
445 | module_init(hanwang_init); | ||
446 | module_exit(hanwang_exit); | ||
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index 284dfaab6b8c..de5adb109030 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h | |||
@@ -118,6 +118,7 @@ struct wacom { | |||
118 | extern const struct usb_device_id wacom_ids[]; | 118 | extern const struct usb_device_id wacom_ids[]; |
119 | 119 | ||
120 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); | 120 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); |
121 | void wacom_setup_device_quirks(struct wacom_features *features); | ||
121 | void wacom_setup_input_capabilities(struct input_dev *input_dev, | 122 | void wacom_setup_input_capabilities(struct input_dev *input_dev, |
122 | struct wacom_wac *wacom_wac); | 123 | struct wacom_wac *wacom_wac); |
123 | #endif | 124 | #endif |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index b35876ee6908..fc381498b798 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -120,14 +120,16 @@ static int wacom_open(struct input_dev *dev) | |||
120 | 120 | ||
121 | out: | 121 | out: |
122 | mutex_unlock(&wacom->lock); | 122 | mutex_unlock(&wacom->lock); |
123 | if (retval) | 123 | usb_autopm_put_interface(wacom->intf); |
124 | usb_autopm_put_interface(wacom->intf); | ||
125 | return retval; | 124 | return retval; |
126 | } | 125 | } |
127 | 126 | ||
128 | static void wacom_close(struct input_dev *dev) | 127 | static void wacom_close(struct input_dev *dev) |
129 | { | 128 | { |
130 | struct wacom *wacom = input_get_drvdata(dev); | 129 | struct wacom *wacom = input_get_drvdata(dev); |
130 | int autopm_error; | ||
131 | |||
132 | autopm_error = usb_autopm_get_interface(wacom->intf); | ||
131 | 133 | ||
132 | mutex_lock(&wacom->lock); | 134 | mutex_lock(&wacom->lock); |
133 | usb_kill_urb(wacom->irq); | 135 | usb_kill_urb(wacom->irq); |
@@ -135,7 +137,8 @@ static void wacom_close(struct input_dev *dev) | |||
135 | wacom->intf->needs_remote_wakeup = 0; | 137 | wacom->intf->needs_remote_wakeup = 0; |
136 | mutex_unlock(&wacom->lock); | 138 | mutex_unlock(&wacom->lock); |
137 | 139 | ||
138 | usb_autopm_put_interface(wacom->intf); | 140 | if (!autopm_error) |
141 | usb_autopm_put_interface(wacom->intf); | ||
139 | } | 142 | } |
140 | 143 | ||
141 | static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, | 144 | static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, |
@@ -196,17 +199,30 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
196 | features->pktlen = WACOM_PKGLEN_TPC2FG; | 199 | features->pktlen = WACOM_PKGLEN_TPC2FG; |
197 | features->device_type = BTN_TOOL_TRIPLETAP; | 200 | features->device_type = BTN_TOOL_TRIPLETAP; |
198 | } | 201 | } |
199 | features->x_max = | 202 | if (features->type == BAMBOO_PT) { |
200 | get_unaligned_le16(&report[i + 3]); | 203 | /* need to reset back */ |
201 | features->x_phy = | 204 | features->pktlen = WACOM_PKGLEN_BBTOUCH; |
202 | get_unaligned_le16(&report[i + 6]); | 205 | features->device_type = BTN_TOOL_TRIPLETAP; |
203 | features->unit = report[i + 9]; | 206 | features->x_phy = |
204 | features->unitExpo = report[i + 11]; | 207 | get_unaligned_le16(&report[i + 5]); |
205 | i += 12; | 208 | features->x_max = |
209 | get_unaligned_le16(&report[i + 8]); | ||
210 | i += 15; | ||
211 | } else { | ||
212 | features->x_max = | ||
213 | get_unaligned_le16(&report[i + 3]); | ||
214 | features->x_phy = | ||
215 | get_unaligned_le16(&report[i + 6]); | ||
216 | features->unit = report[i + 9]; | ||
217 | features->unitExpo = report[i + 11]; | ||
218 | i += 12; | ||
219 | } | ||
206 | } else if (pen) { | 220 | } else if (pen) { |
207 | /* penabled only accepts exact bytes of data */ | 221 | /* penabled only accepts exact bytes of data */ |
208 | if (features->type == TABLETPC2FG) | 222 | if (features->type == TABLETPC2FG) |
209 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; | 223 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; |
224 | if (features->type == BAMBOO_PT) | ||
225 | features->pktlen = WACOM_PKGLEN_BBFUN; | ||
210 | features->device_type = BTN_TOOL_PEN; | 226 | features->device_type = BTN_TOOL_PEN; |
211 | features->x_max = | 227 | features->x_max = |
212 | get_unaligned_le16(&report[i + 3]); | 228 | get_unaligned_le16(&report[i + 3]); |
@@ -235,6 +251,15 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
235 | features->y_phy = | 251 | features->y_phy = |
236 | get_unaligned_le16(&report[i + 6]); | 252 | get_unaligned_le16(&report[i + 6]); |
237 | i += 7; | 253 | i += 7; |
254 | } else if (features->type == BAMBOO_PT) { | ||
255 | /* need to reset back */ | ||
256 | features->pktlen = WACOM_PKGLEN_BBTOUCH; | ||
257 | features->device_type = BTN_TOOL_TRIPLETAP; | ||
258 | features->y_phy = | ||
259 | get_unaligned_le16(&report[i + 3]); | ||
260 | features->y_max = | ||
261 | get_unaligned_le16(&report[i + 6]); | ||
262 | i += 12; | ||
238 | } else { | 263 | } else { |
239 | features->y_max = | 264 | features->y_max = |
240 | features->x_max; | 265 | features->x_max; |
@@ -246,6 +271,8 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
246 | /* penabled only accepts exact bytes of data */ | 271 | /* penabled only accepts exact bytes of data */ |
247 | if (features->type == TABLETPC2FG) | 272 | if (features->type == TABLETPC2FG) |
248 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; | 273 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; |
274 | if (features->type == BAMBOO_PT) | ||
275 | features->pktlen = WACOM_PKGLEN_BBFUN; | ||
249 | features->device_type = BTN_TOOL_PEN; | 276 | features->device_type = BTN_TOOL_PEN; |
250 | features->y_max = | 277 | features->y_max = |
251 | get_unaligned_le16(&report[i + 3]); | 278 | get_unaligned_le16(&report[i + 3]); |
@@ -296,8 +323,9 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat | |||
296 | if (!rep_data) | 323 | if (!rep_data) |
297 | return error; | 324 | return error; |
298 | 325 | ||
299 | /* ask to report tablet data if it is 2FGT or not a Tablet PC */ | 326 | /* ask to report tablet data if it is 2FGT Tablet PC or |
300 | if (features->device_type == BTN_TOOL_TRIPLETAP) { | 327 | * not a Tablet PC */ |
328 | if (features->type == TABLETPC2FG) { | ||
301 | do { | 329 | do { |
302 | rep_data[0] = 3; | 330 | rep_data[0] = 3; |
303 | rep_data[1] = 4; | 331 | rep_data[1] = 4; |
@@ -309,7 +337,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat | |||
309 | WAC_HID_FEATURE_REPORT, report_id, | 337 | WAC_HID_FEATURE_REPORT, report_id, |
310 | rep_data, 3); | 338 | rep_data, 3); |
311 | } while ((error < 0 || rep_data[1] != 4) && limit++ < 5); | 339 | } while ((error < 0 || rep_data[1] != 4) && limit++ < 5); |
312 | } else if (features->type != TABLETPC && features->type != TABLETPC2FG) { | 340 | } else if (features->type != TABLETPC) { |
313 | do { | 341 | do { |
314 | rep_data[0] = 2; | 342 | rep_data[0] = 2; |
315 | rep_data[1] = 2; | 343 | rep_data[1] = 2; |
@@ -334,11 +362,16 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, | |||
334 | struct usb_host_interface *interface = intf->cur_altsetting; | 362 | struct usb_host_interface *interface = intf->cur_altsetting; |
335 | struct hid_descriptor *hid_desc; | 363 | struct hid_descriptor *hid_desc; |
336 | 364 | ||
337 | /* default device to penabled */ | 365 | /* default features */ |
338 | features->device_type = BTN_TOOL_PEN; | 366 | features->device_type = BTN_TOOL_PEN; |
339 | 367 | features->x_fuzz = 4; | |
340 | /* only Tablet PCs need to retrieve the info */ | 368 | features->y_fuzz = 4; |
341 | if ((features->type != TABLETPC) && (features->type != TABLETPC2FG)) | 369 | features->pressure_fuzz = 0; |
370 | features->distance_fuzz = 0; | ||
371 | |||
372 | /* only Tablet PCs and Bamboo P&T need to retrieve the info */ | ||
373 | if ((features->type != TABLETPC) && (features->type != TABLETPC2FG) && | ||
374 | (features->type != BAMBOO_PT)) | ||
342 | goto out; | 375 | goto out; |
343 | 376 | ||
344 | if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { | 377 | if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { |
@@ -353,12 +386,6 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, | |||
353 | if (error) | 386 | if (error) |
354 | goto out; | 387 | goto out; |
355 | 388 | ||
356 | /* touch device found but size is not defined. use default */ | ||
357 | if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) { | ||
358 | features->x_max = 1023; | ||
359 | features->y_max = 1023; | ||
360 | } | ||
361 | |||
362 | out: | 389 | out: |
363 | return error; | 390 | return error; |
364 | } | 391 | } |
@@ -494,9 +521,11 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
494 | if (error) | 521 | if (error) |
495 | goto fail2; | 522 | goto fail2; |
496 | 523 | ||
524 | wacom_setup_device_quirks(features); | ||
525 | |||
497 | strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); | 526 | strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); |
498 | 527 | ||
499 | if (features->type == TABLETPC || features->type == TABLETPC2FG) { | 528 | if (features->quirks & WACOM_QUIRK_MULTI_INPUT) { |
500 | /* Append the device type to the name */ | 529 | /* Append the device type to the name */ |
501 | strlcat(wacom_wac->name, | 530 | strlcat(wacom_wac->name, |
502 | features->device_type == BTN_TOOL_PEN ? | 531 | features->device_type == BTN_TOOL_PEN ? |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 47fd7a041c52..b3252ef1e279 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -857,6 +857,134 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) | |||
857 | return retval; | 857 | return retval; |
858 | } | 858 | } |
859 | 859 | ||
860 | static int wacom_bpt_touch(struct wacom_wac *wacom) | ||
861 | { | ||
862 | struct wacom_features *features = &wacom->features; | ||
863 | struct input_dev *input = wacom->input; | ||
864 | unsigned char *data = wacom->data; | ||
865 | int sp = 0, sx = 0, sy = 0, count = 0; | ||
866 | int i; | ||
867 | |||
868 | for (i = 0; i < 2; i++) { | ||
869 | int p = data[9 * i + 2]; | ||
870 | input_mt_slot(input, i); | ||
871 | /* | ||
872 | * Touch events need to be disabled while stylus is | ||
873 | * in proximity because user's hand is resting on touchpad | ||
874 | * and sending unwanted events. User expects tablet buttons | ||
875 | * to continue working though. | ||
876 | */ | ||
877 | if (p && !wacom->shared->stylus_in_proximity) { | ||
878 | int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff; | ||
879 | int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff; | ||
880 | if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) { | ||
881 | x <<= 5; | ||
882 | y <<= 5; | ||
883 | } | ||
884 | input_report_abs(input, ABS_MT_PRESSURE, p); | ||
885 | input_report_abs(input, ABS_MT_POSITION_X, x); | ||
886 | input_report_abs(input, ABS_MT_POSITION_Y, y); | ||
887 | if (wacom->id[i] < 0) | ||
888 | wacom->id[i] = wacom->trk_id++ & MAX_TRACKING_ID; | ||
889 | if (!count++) | ||
890 | sp = p, sx = x, sy = y; | ||
891 | } else { | ||
892 | wacom->id[i] = -1; | ||
893 | } | ||
894 | input_report_abs(input, ABS_MT_TRACKING_ID, wacom->id[i]); | ||
895 | } | ||
896 | |||
897 | input_report_key(input, BTN_TOUCH, count > 0); | ||
898 | input_report_key(input, BTN_TOOL_FINGER, count == 1); | ||
899 | input_report_key(input, BTN_TOOL_DOUBLETAP, count == 2); | ||
900 | |||
901 | input_report_abs(input, ABS_PRESSURE, sp); | ||
902 | input_report_abs(input, ABS_X, sx); | ||
903 | input_report_abs(input, ABS_Y, sy); | ||
904 | |||
905 | input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0); | ||
906 | input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0); | ||
907 | input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0); | ||
908 | input_report_key(input, BTN_RIGHT, (data[1] & 0x01) != 0); | ||
909 | |||
910 | input_sync(input); | ||
911 | |||
912 | return 0; | ||
913 | } | ||
914 | |||
915 | static int wacom_bpt_pen(struct wacom_wac *wacom) | ||
916 | { | ||
917 | struct input_dev *input = wacom->input; | ||
918 | unsigned char *data = wacom->data; | ||
919 | int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0; | ||
920 | |||
921 | /* | ||
922 | * Similar to Graphire protocol, data[1] & 0x20 is proximity and | ||
923 | * data[1] & 0x18 is tool ID. 0x30 is safety check to ignore | ||
924 | * 2 unused tool ID's. | ||
925 | */ | ||
926 | prox = (data[1] & 0x30) == 0x30; | ||
927 | |||
928 | /* | ||
929 | * All reports shared between PEN and RUBBER tool must be | ||
930 | * forced to a known starting value (zero) when transitioning to | ||
931 | * out-of-prox. | ||
932 | * | ||
933 | * If not reset then, to userspace, it will look like lost events | ||
934 | * if new tool comes in-prox with same values as previous tool sent. | ||
935 | * | ||
936 | * Hardware does report zero in most out-of-prox cases but not all. | ||
937 | */ | ||
938 | if (prox) { | ||
939 | if (!wacom->shared->stylus_in_proximity) { | ||
940 | if (data[1] & 0x08) { | ||
941 | wacom->tool[0] = BTN_TOOL_RUBBER; | ||
942 | wacom->id[0] = ERASER_DEVICE_ID; | ||
943 | } else { | ||
944 | wacom->tool[0] = BTN_TOOL_PEN; | ||
945 | wacom->id[0] = STYLUS_DEVICE_ID; | ||
946 | } | ||
947 | wacom->shared->stylus_in_proximity = true; | ||
948 | } | ||
949 | x = le16_to_cpup((__le16 *)&data[2]); | ||
950 | y = le16_to_cpup((__le16 *)&data[4]); | ||
951 | p = le16_to_cpup((__le16 *)&data[6]); | ||
952 | d = data[8]; | ||
953 | pen = data[1] & 0x01; | ||
954 | btn1 = data[1] & 0x02; | ||
955 | btn2 = data[1] & 0x04; | ||
956 | } | ||
957 | |||
958 | input_report_key(input, BTN_TOUCH, pen); | ||
959 | input_report_key(input, BTN_STYLUS, btn1); | ||
960 | input_report_key(input, BTN_STYLUS2, btn2); | ||
961 | |||
962 | input_report_abs(input, ABS_X, x); | ||
963 | input_report_abs(input, ABS_Y, y); | ||
964 | input_report_abs(input, ABS_PRESSURE, p); | ||
965 | input_report_abs(input, ABS_DISTANCE, d); | ||
966 | |||
967 | if (!prox) { | ||
968 | wacom->id[0] = 0; | ||
969 | wacom->shared->stylus_in_proximity = false; | ||
970 | } | ||
971 | |||
972 | input_report_key(input, wacom->tool[0], prox); /* PEN or RUBBER */ | ||
973 | input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */ | ||
974 | |||
975 | return 1; | ||
976 | } | ||
977 | |||
978 | static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len) | ||
979 | { | ||
980 | if (len == WACOM_PKGLEN_BBTOUCH) | ||
981 | return wacom_bpt_touch(wacom); | ||
982 | else if (len == WACOM_PKGLEN_BBFUN) | ||
983 | return wacom_bpt_pen(wacom); | ||
984 | |||
985 | return 0; | ||
986 | } | ||
987 | |||
860 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | 988 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) |
861 | { | 989 | { |
862 | bool sync; | 990 | bool sync; |
@@ -902,6 +1030,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
902 | sync = wacom_tpc_irq(wacom_wac, len); | 1030 | sync = wacom_tpc_irq(wacom_wac, len); |
903 | break; | 1031 | break; |
904 | 1032 | ||
1033 | case BAMBOO_PT: | ||
1034 | sync = wacom_bpt_irq(wacom_wac, len); | ||
1035 | break; | ||
1036 | |||
905 | default: | 1037 | default: |
906 | sync = false; | 1038 | sync = false; |
907 | break; | 1039 | break; |
@@ -911,26 +1043,17 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
911 | input_sync(wacom_wac->input); | 1043 | input_sync(wacom_wac->input); |
912 | } | 1044 | } |
913 | 1045 | ||
914 | static void wacom_setup_intuos(struct wacom_wac *wacom_wac) | 1046 | static void wacom_setup_cintiq(struct wacom_wac *wacom_wac) |
915 | { | 1047 | { |
916 | struct input_dev *input_dev = wacom_wac->input; | 1048 | struct input_dev *input_dev = wacom_wac->input; |
917 | 1049 | ||
918 | input_set_capability(input_dev, EV_MSC, MSC_SERIAL); | 1050 | input_set_capability(input_dev, EV_MSC, MSC_SERIAL); |
919 | input_set_capability(input_dev, EV_REL, REL_WHEEL); | ||
920 | |||
921 | __set_bit(BTN_LEFT, input_dev->keybit); | ||
922 | __set_bit(BTN_RIGHT, input_dev->keybit); | ||
923 | __set_bit(BTN_MIDDLE, input_dev->keybit); | ||
924 | __set_bit(BTN_SIDE, input_dev->keybit); | ||
925 | __set_bit(BTN_EXTRA, input_dev->keybit); | ||
926 | 1051 | ||
927 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); | 1052 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); |
928 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); | 1053 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); |
929 | __set_bit(BTN_TOOL_MOUSE, input_dev->keybit); | ||
930 | __set_bit(BTN_TOOL_BRUSH, input_dev->keybit); | 1054 | __set_bit(BTN_TOOL_BRUSH, input_dev->keybit); |
931 | __set_bit(BTN_TOOL_PENCIL, input_dev->keybit); | 1055 | __set_bit(BTN_TOOL_PENCIL, input_dev->keybit); |
932 | __set_bit(BTN_TOOL_AIRBRUSH, input_dev->keybit); | 1056 | __set_bit(BTN_TOOL_AIRBRUSH, input_dev->keybit); |
933 | __set_bit(BTN_TOOL_LENS, input_dev->keybit); | ||
934 | __set_bit(BTN_STYLUS, input_dev->keybit); | 1057 | __set_bit(BTN_STYLUS, input_dev->keybit); |
935 | __set_bit(BTN_STYLUS2, input_dev->keybit); | 1058 | __set_bit(BTN_STYLUS2, input_dev->keybit); |
936 | 1059 | ||
@@ -939,10 +1062,55 @@ static void wacom_setup_intuos(struct wacom_wac *wacom_wac) | |||
939 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); | 1062 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); |
940 | input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); | 1063 | input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); |
941 | input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); | 1064 | input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); |
1065 | } | ||
1066 | |||
1067 | static void wacom_setup_intuos(struct wacom_wac *wacom_wac) | ||
1068 | { | ||
1069 | struct input_dev *input_dev = wacom_wac->input; | ||
1070 | |||
1071 | input_set_capability(input_dev, EV_REL, REL_WHEEL); | ||
1072 | |||
1073 | wacom_setup_cintiq(wacom_wac); | ||
1074 | |||
1075 | __set_bit(BTN_LEFT, input_dev->keybit); | ||
1076 | __set_bit(BTN_RIGHT, input_dev->keybit); | ||
1077 | __set_bit(BTN_MIDDLE, input_dev->keybit); | ||
1078 | __set_bit(BTN_SIDE, input_dev->keybit); | ||
1079 | __set_bit(BTN_EXTRA, input_dev->keybit); | ||
1080 | __set_bit(BTN_TOOL_MOUSE, input_dev->keybit); | ||
1081 | __set_bit(BTN_TOOL_LENS, input_dev->keybit); | ||
1082 | |||
942 | input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); | 1083 | input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); |
943 | input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); | 1084 | input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); |
944 | } | 1085 | } |
945 | 1086 | ||
1087 | void wacom_setup_device_quirks(struct wacom_features *features) | ||
1088 | { | ||
1089 | |||
1090 | /* touch device found but size is not defined. use default */ | ||
1091 | if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) { | ||
1092 | features->x_max = 1023; | ||
1093 | features->y_max = 1023; | ||
1094 | } | ||
1095 | |||
1096 | /* these device have multiple inputs */ | ||
1097 | if (features->type == TABLETPC || features->type == TABLETPC2FG || | ||
1098 | features->type == BAMBOO_PT) | ||
1099 | features->quirks |= WACOM_QUIRK_MULTI_INPUT; | ||
1100 | |||
1101 | /* quirks for bamboo touch */ | ||
1102 | if (features->type == BAMBOO_PT && | ||
1103 | features->device_type == BTN_TOOL_TRIPLETAP) { | ||
1104 | features->x_max <<= 5; | ||
1105 | features->y_max <<= 5; | ||
1106 | features->x_fuzz <<= 5; | ||
1107 | features->y_fuzz <<= 5; | ||
1108 | features->pressure_max = 256; | ||
1109 | features->pressure_fuzz = 16; | ||
1110 | features->quirks |= WACOM_QUIRK_BBTOUCH_LOWRES; | ||
1111 | } | ||
1112 | } | ||
1113 | |||
946 | void wacom_setup_input_capabilities(struct input_dev *input_dev, | 1114 | void wacom_setup_input_capabilities(struct input_dev *input_dev, |
947 | struct wacom_wac *wacom_wac) | 1115 | struct wacom_wac *wacom_wac) |
948 | { | 1116 | { |
@@ -953,9 +1121,12 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
953 | 1121 | ||
954 | __set_bit(BTN_TOUCH, input_dev->keybit); | 1122 | __set_bit(BTN_TOUCH, input_dev->keybit); |
955 | 1123 | ||
956 | input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0); | 1124 | input_set_abs_params(input_dev, ABS_X, 0, features->x_max, |
957 | input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0); | 1125 | features->x_fuzz, 0); |
958 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0); | 1126 | input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, |
1127 | features->y_fuzz, 0); | ||
1128 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, | ||
1129 | features->pressure_fuzz, 0); | ||
959 | 1130 | ||
960 | __set_bit(ABS_MISC, input_dev->absbit); | 1131 | __set_bit(ABS_MISC, input_dev->absbit); |
961 | 1132 | ||
@@ -1005,9 +1176,19 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1005 | __set_bit(BTN_9, input_dev->keybit); | 1176 | __set_bit(BTN_9, input_dev->keybit); |
1006 | /* fall through */ | 1177 | /* fall through */ |
1007 | 1178 | ||
1179 | case CINTIQ: | ||
1180 | for (i = 0; i < 8; i++) | ||
1181 | __set_bit(BTN_0 + i, input_dev->keybit); | ||
1182 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
1183 | |||
1184 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); | ||
1185 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); | ||
1186 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | ||
1187 | wacom_setup_cintiq(wacom_wac); | ||
1188 | break; | ||
1189 | |||
1008 | case INTUOS3: | 1190 | case INTUOS3: |
1009 | case INTUOS3L: | 1191 | case INTUOS3L: |
1010 | case CINTIQ: | ||
1011 | __set_bit(BTN_4, input_dev->keybit); | 1192 | __set_bit(BTN_4, input_dev->keybit); |
1012 | __set_bit(BTN_5, input_dev->keybit); | 1193 | __set_bit(BTN_5, input_dev->keybit); |
1013 | __set_bit(BTN_6, input_dev->keybit); | 1194 | __set_bit(BTN_6, input_dev->keybit); |
@@ -1078,6 +1259,38 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1078 | case PENPARTNER: | 1259 | case PENPARTNER: |
1079 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); | 1260 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); |
1080 | break; | 1261 | break; |
1262 | |||
1263 | case BAMBOO_PT: | ||
1264 | __clear_bit(ABS_MISC, input_dev->absbit); | ||
1265 | |||
1266 | if (features->device_type == BTN_TOOL_TRIPLETAP) { | ||
1267 | __set_bit(BTN_LEFT, input_dev->keybit); | ||
1268 | __set_bit(BTN_FORWARD, input_dev->keybit); | ||
1269 | __set_bit(BTN_BACK, input_dev->keybit); | ||
1270 | __set_bit(BTN_RIGHT, input_dev->keybit); | ||
1271 | |||
1272 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
1273 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | ||
1274 | |||
1275 | input_mt_create_slots(input_dev, 2); | ||
1276 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
1277 | 0, features->x_max, | ||
1278 | features->x_fuzz, 0); | ||
1279 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
1280 | 0, features->y_max, | ||
1281 | features->y_fuzz, 0); | ||
1282 | input_set_abs_params(input_dev, ABS_MT_PRESSURE, | ||
1283 | 0, features->pressure_max, | ||
1284 | features->pressure_fuzz, 0); | ||
1285 | input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, | ||
1286 | MAX_TRACKING_ID, 0, 0); | ||
1287 | } else if (features->device_type == BTN_TOOL_PEN) { | ||
1288 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); | ||
1289 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); | ||
1290 | __set_bit(BTN_STYLUS, input_dev->keybit); | ||
1291 | __set_bit(BTN_STYLUS2, input_dev->keybit); | ||
1292 | } | ||
1293 | break; | ||
1081 | } | 1294 | } |
1082 | } | 1295 | } |
1083 | 1296 | ||
@@ -1215,6 +1428,14 @@ static const struct wacom_features wacom_features_0xE3 = | |||
1215 | { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; | 1428 | { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; |
1216 | static const struct wacom_features wacom_features_0x47 = | 1429 | static const struct wacom_features wacom_features_0x47 = |
1217 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; | 1430 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; |
1431 | static struct wacom_features wacom_features_0xD0 = | ||
1432 | { "Wacom Bamboo 2FG", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; | ||
1433 | static struct wacom_features wacom_features_0xD1 = | ||
1434 | { "Wacom Bamboo 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; | ||
1435 | static struct wacom_features wacom_features_0xD2 = | ||
1436 | { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; | ||
1437 | static struct wacom_features wacom_features_0xD3 = | ||
1438 | { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; | ||
1218 | 1439 | ||
1219 | #define USB_DEVICE_WACOM(prod) \ | 1440 | #define USB_DEVICE_WACOM(prod) \ |
1220 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ | 1441 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ |
@@ -1279,6 +1500,10 @@ const struct usb_device_id wacom_ids[] = { | |||
1279 | { USB_DEVICE_WACOM(0xC6) }, | 1500 | { USB_DEVICE_WACOM(0xC6) }, |
1280 | { USB_DEVICE_WACOM(0xC7) }, | 1501 | { USB_DEVICE_WACOM(0xC7) }, |
1281 | { USB_DEVICE_WACOM(0xCE) }, | 1502 | { USB_DEVICE_WACOM(0xCE) }, |
1503 | { USB_DEVICE_WACOM(0xD0) }, | ||
1504 | { USB_DEVICE_WACOM(0xD1) }, | ||
1505 | { USB_DEVICE_WACOM(0xD2) }, | ||
1506 | { USB_DEVICE_WACOM(0xD3) }, | ||
1282 | { USB_DEVICE_WACOM(0xF0) }, | 1507 | { USB_DEVICE_WACOM(0xF0) }, |
1283 | { USB_DEVICE_WACOM(0xCC) }, | 1508 | { USB_DEVICE_WACOM(0xCC) }, |
1284 | { USB_DEVICE_WACOM(0x90) }, | 1509 | { USB_DEVICE_WACOM(0x90) }, |
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 99e1a54cd305..00ca01541d89 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #define WACOM_PKGLEN_INTUOS 10 | 21 | #define WACOM_PKGLEN_INTUOS 10 |
22 | #define WACOM_PKGLEN_TPC1FG 5 | 22 | #define WACOM_PKGLEN_TPC1FG 5 |
23 | #define WACOM_PKGLEN_TPC2FG 14 | 23 | #define WACOM_PKGLEN_TPC2FG 14 |
24 | #define WACOM_PKGLEN_BBTOUCH 20 | ||
24 | 25 | ||
25 | /* device IDs */ | 26 | /* device IDs */ |
26 | #define STYLUS_DEVICE_ID 0x02 | 27 | #define STYLUS_DEVICE_ID 0x02 |
@@ -37,6 +38,13 @@ | |||
37 | #define WACOM_REPORT_TPC1FG 6 | 38 | #define WACOM_REPORT_TPC1FG 6 |
38 | #define WACOM_REPORT_TPC2FG 13 | 39 | #define WACOM_REPORT_TPC2FG 13 |
39 | 40 | ||
41 | /* device quirks */ | ||
42 | #define WACOM_QUIRK_MULTI_INPUT 0x0001 | ||
43 | #define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002 | ||
44 | |||
45 | /* largest reported tracking id */ | ||
46 | #define MAX_TRACKING_ID 0xfff | ||
47 | |||
40 | enum { | 48 | enum { |
41 | PENPARTNER = 0, | 49 | PENPARTNER = 0, |
42 | GRAPHIRE, | 50 | GRAPHIRE, |
@@ -44,6 +52,7 @@ enum { | |||
44 | PTU, | 52 | PTU, |
45 | PL, | 53 | PL, |
46 | DTU, | 54 | DTU, |
55 | BAMBOO_PT, | ||
47 | INTUOS, | 56 | INTUOS, |
48 | INTUOS3S, | 57 | INTUOS3S, |
49 | INTUOS3, | 58 | INTUOS3, |
@@ -73,6 +82,11 @@ struct wacom_features { | |||
73 | int y_phy; | 82 | int y_phy; |
74 | unsigned char unit; | 83 | unsigned char unit; |
75 | unsigned char unitExpo; | 84 | unsigned char unitExpo; |
85 | int x_fuzz; | ||
86 | int y_fuzz; | ||
87 | int pressure_fuzz; | ||
88 | int distance_fuzz; | ||
89 | unsigned quirks; | ||
76 | }; | 90 | }; |
77 | 91 | ||
78 | struct wacom_shared { | 92 | struct wacom_shared { |
@@ -86,6 +100,7 @@ struct wacom_wac { | |||
86 | int id[3]; | 100 | int id[3]; |
87 | __u32 serial[2]; | 101 | __u32 serial[2]; |
88 | int last_finger; | 102 | int last_finger; |
103 | int trk_id; | ||
89 | struct wacom_features features; | 104 | struct wacom_features features; |
90 | struct wacom_shared *shared; | 105 | struct wacom_shared *shared; |
91 | struct input_dev *input; | 106 | struct input_dev *input; |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 0069d9703fda..0ea361f23fa7 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -98,6 +98,18 @@ config TOUCHSCREEN_BITSY | |||
98 | To compile this driver as a module, choose M here: the | 98 | To compile this driver as a module, choose M here: the |
99 | module will be called h3600_ts_input. | 99 | module will be called h3600_ts_input. |
100 | 100 | ||
101 | config TOUCHSCREEN_BU21013 | ||
102 | tristate "BU21013 based touch panel controllers" | ||
103 | depends on I2C | ||
104 | help | ||
105 | Say Y here if you have a bu21013 touchscreen connected to | ||
106 | your system. | ||
107 | |||
108 | If unsure, say N. | ||
109 | |||
110 | To compile this driver as a module, choose M here: the | ||
111 | module will be called bu21013_ts. | ||
112 | |||
101 | config TOUCHSCREEN_CY8CTMG110 | 113 | config TOUCHSCREEN_CY8CTMG110 |
102 | tristate "cy8ctmg110 touchscreen" | 114 | tristate "cy8ctmg110 touchscreen" |
103 | depends on I2C | 115 | depends on I2C |
@@ -214,6 +226,16 @@ config TOUCHSCREEN_WACOM_W8001 | |||
214 | To compile this driver as a module, choose M here: the | 226 | To compile this driver as a module, choose M here: the |
215 | module will be called wacom_w8001. | 227 | module will be called wacom_w8001. |
216 | 228 | ||
229 | config TOUCHSCREEN_LPC32XX | ||
230 | tristate "LPC32XX touchscreen controller" | ||
231 | depends on ARCH_LPC32XX | ||
232 | help | ||
233 | Say Y here if you have a LPC32XX device and want | ||
234 | to support the built-in touchscreen. | ||
235 | |||
236 | To compile this driver as a module, choose M here: the | ||
237 | module will be called lpc32xx_ts. | ||
238 | |||
217 | config TOUCHSCREEN_MCS5000 | 239 | config TOUCHSCREEN_MCS5000 |
218 | tristate "MELFAS MCS-5000 touchscreen" | 240 | tristate "MELFAS MCS-5000 touchscreen" |
219 | depends on I2C | 241 | depends on I2C |
@@ -250,6 +272,18 @@ config TOUCHSCREEN_INEXIO | |||
250 | To compile this driver as a module, choose M here: the | 272 | To compile this driver as a module, choose M here: the |
251 | module will be called inexio. | 273 | module will be called inexio. |
252 | 274 | ||
275 | config TOUCHSCREEN_INTEL_MID | ||
276 | tristate "Intel MID platform resistive touchscreen" | ||
277 | depends on INTEL_SCU_IPC | ||
278 | help | ||
279 | Say Y here if you have a Intel MID based touchscreen in | ||
280 | your system. | ||
281 | |||
282 | If unsure, say N. | ||
283 | |||
284 | To compile this driver as a module, choose M here: the | ||
285 | module will be called intel_mid_touch. | ||
286 | |||
253 | config TOUCHSCREEN_MK712 | 287 | config TOUCHSCREEN_MK712 |
254 | tristate "ICS MicroClock MK712 touchscreen" | 288 | tristate "ICS MicroClock MK712 touchscreen" |
255 | help | 289 | help |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 28217e1dcafd..99b353c4e9ae 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
@@ -14,6 +14,7 @@ obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o | |||
14 | obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o | 14 | obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o |
15 | obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o | 15 | obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o |
16 | obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o | 16 | obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o |
17 | obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o | ||
17 | obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o | 18 | obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o |
18 | obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o | 19 | obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o |
19 | obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o | 20 | obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o |
@@ -23,6 +24,8 @@ obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o | |||
23 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o | 24 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o |
24 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o | 25 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o |
25 | obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o | 26 | obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o |
27 | obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o | ||
28 | obj-$(CONFIG_TOUCHSCREEN_LPC32XX) += lpc32xx_ts.o | ||
26 | obj-$(CONFIG_TOUCHSCREEN_MC13783) += mc13783_ts.o | 29 | obj-$(CONFIG_TOUCHSCREEN_MC13783) += mc13783_ts.o |
27 | obj-$(CONFIG_TOUCHSCREEN_MCS5000) += mcs5000_ts.o | 30 | obj-$(CONFIG_TOUCHSCREEN_MCS5000) += mcs5000_ts.o |
28 | obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o | 31 | obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o |
diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index 5f0221cffef9..a1952fcc083e 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c | |||
@@ -191,13 +191,12 @@ struct ad7877 { | |||
191 | struct spi_message msg; | 191 | struct spi_message msg; |
192 | 192 | ||
193 | struct mutex mutex; | 193 | struct mutex mutex; |
194 | unsigned disabled:1; /* P: mutex */ | 194 | bool disabled; /* P: mutex */ |
195 | unsigned gpio3:1; /* P: mutex */ | 195 | bool gpio3; /* P: mutex */ |
196 | unsigned gpio4:1; /* P: mutex */ | 196 | bool gpio4; /* P: mutex */ |
197 | 197 | ||
198 | spinlock_t lock; | 198 | spinlock_t lock; |
199 | struct timer_list timer; /* P: lock */ | 199 | struct timer_list timer; /* P: lock */ |
200 | unsigned pending:1; /* P: lock */ | ||
201 | 200 | ||
202 | /* | 201 | /* |
203 | * DMA (thus cache coherency maintenance) requires the | 202 | * DMA (thus cache coherency maintenance) requires the |
@@ -206,8 +205,8 @@ struct ad7877 { | |||
206 | u16 conversion_data[AD7877_NR_SENSE] ____cacheline_aligned; | 205 | u16 conversion_data[AD7877_NR_SENSE] ____cacheline_aligned; |
207 | }; | 206 | }; |
208 | 207 | ||
209 | static int gpio3; | 208 | static bool gpio3; |
210 | module_param(gpio3, int, 0); | 209 | module_param(gpio3, bool, 0); |
211 | MODULE_PARM_DESC(gpio3, "If gpio3 is set to 1 AUX3 acts as GPIO3"); | 210 | MODULE_PARM_DESC(gpio3, "If gpio3 is set to 1 AUX3 acts as GPIO3"); |
212 | 211 | ||
213 | /* | 212 | /* |
@@ -230,6 +229,7 @@ static int ad7877_read(struct spi_device *spi, u16 reg) | |||
230 | AD7877_READADD(reg)); | 229 | AD7877_READADD(reg)); |
231 | req->xfer[0].tx_buf = &req->command; | 230 | req->xfer[0].tx_buf = &req->command; |
232 | req->xfer[0].len = 2; | 231 | req->xfer[0].len = 2; |
232 | req->xfer[0].cs_change = 1; | ||
233 | 233 | ||
234 | req->xfer[1].rx_buf = &req->sample; | 234 | req->xfer[1].rx_buf = &req->sample; |
235 | req->xfer[1].len = 2; | 235 | req->xfer[1].len = 2; |
@@ -295,20 +295,25 @@ static int ad7877_read_adc(struct spi_device *spi, unsigned command) | |||
295 | 295 | ||
296 | req->xfer[0].tx_buf = &req->reset; | 296 | req->xfer[0].tx_buf = &req->reset; |
297 | req->xfer[0].len = 2; | 297 | req->xfer[0].len = 2; |
298 | req->xfer[0].cs_change = 1; | ||
298 | 299 | ||
299 | req->xfer[1].tx_buf = &req->ref_on; | 300 | req->xfer[1].tx_buf = &req->ref_on; |
300 | req->xfer[1].len = 2; | 301 | req->xfer[1].len = 2; |
301 | req->xfer[1].delay_usecs = ts->vref_delay_usecs; | 302 | req->xfer[1].delay_usecs = ts->vref_delay_usecs; |
303 | req->xfer[1].cs_change = 1; | ||
302 | 304 | ||
303 | req->xfer[2].tx_buf = &req->command; | 305 | req->xfer[2].tx_buf = &req->command; |
304 | req->xfer[2].len = 2; | 306 | req->xfer[2].len = 2; |
305 | req->xfer[2].delay_usecs = ts->vref_delay_usecs; | 307 | req->xfer[2].delay_usecs = ts->vref_delay_usecs; |
308 | req->xfer[2].cs_change = 1; | ||
306 | 309 | ||
307 | req->xfer[3].rx_buf = &req->sample; | 310 | req->xfer[3].rx_buf = &req->sample; |
308 | req->xfer[3].len = 2; | 311 | req->xfer[3].len = 2; |
312 | req->xfer[3].cs_change = 1; | ||
309 | 313 | ||
310 | req->xfer[4].tx_buf = &ts->cmd_crtl2; /*REF OFF*/ | 314 | req->xfer[4].tx_buf = &ts->cmd_crtl2; /*REF OFF*/ |
311 | req->xfer[4].len = 2; | 315 | req->xfer[4].len = 2; |
316 | req->xfer[4].cs_change = 1; | ||
312 | 317 | ||
313 | req->xfer[5].tx_buf = &ts->cmd_crtl1; /*DEFAULT*/ | 318 | req->xfer[5].tx_buf = &ts->cmd_crtl1; /*DEFAULT*/ |
314 | req->xfer[5].len = 2; | 319 | req->xfer[5].len = 2; |
@@ -327,7 +332,7 @@ static int ad7877_read_adc(struct spi_device *spi, unsigned command) | |||
327 | return status ? : sample; | 332 | return status ? : sample; |
328 | } | 333 | } |
329 | 334 | ||
330 | static void ad7877_rx(struct ad7877 *ts) | 335 | static int ad7877_process_data(struct ad7877 *ts) |
331 | { | 336 | { |
332 | struct input_dev *input_dev = ts->input; | 337 | struct input_dev *input_dev = ts->input; |
333 | unsigned Rt; | 338 | unsigned Rt; |
@@ -354,11 +359,25 @@ static void ad7877_rx(struct ad7877 *ts) | |||
354 | Rt /= z1; | 359 | Rt /= z1; |
355 | Rt = (Rt + 2047) >> 12; | 360 | Rt = (Rt + 2047) >> 12; |
356 | 361 | ||
362 | /* | ||
363 | * Sample found inconsistent, pressure is beyond | ||
364 | * the maximum. Don't report it to user space. | ||
365 | */ | ||
366 | if (Rt > ts->pressure_max) | ||
367 | return -EINVAL; | ||
368 | |||
369 | if (!timer_pending(&ts->timer)) | ||
370 | input_report_key(input_dev, BTN_TOUCH, 1); | ||
371 | |||
357 | input_report_abs(input_dev, ABS_X, x); | 372 | input_report_abs(input_dev, ABS_X, x); |
358 | input_report_abs(input_dev, ABS_Y, y); | 373 | input_report_abs(input_dev, ABS_Y, y); |
359 | input_report_abs(input_dev, ABS_PRESSURE, Rt); | 374 | input_report_abs(input_dev, ABS_PRESSURE, Rt); |
360 | input_sync(input_dev); | 375 | input_sync(input_dev); |
376 | |||
377 | return 0; | ||
361 | } | 378 | } |
379 | |||
380 | return -EINVAL; | ||
362 | } | 381 | } |
363 | 382 | ||
364 | static inline void ad7877_ts_event_release(struct ad7877 *ts) | 383 | static inline void ad7877_ts_event_release(struct ad7877 *ts) |
@@ -366,72 +385,56 @@ static inline void ad7877_ts_event_release(struct ad7877 *ts) | |||
366 | struct input_dev *input_dev = ts->input; | 385 | struct input_dev *input_dev = ts->input; |
367 | 386 | ||
368 | input_report_abs(input_dev, ABS_PRESSURE, 0); | 387 | input_report_abs(input_dev, ABS_PRESSURE, 0); |
388 | input_report_key(input_dev, BTN_TOUCH, 0); | ||
369 | input_sync(input_dev); | 389 | input_sync(input_dev); |
370 | } | 390 | } |
371 | 391 | ||
372 | static void ad7877_timer(unsigned long handle) | 392 | static void ad7877_timer(unsigned long handle) |
373 | { | 393 | { |
374 | struct ad7877 *ts = (void *)handle; | 394 | struct ad7877 *ts = (void *)handle; |
395 | unsigned long flags; | ||
375 | 396 | ||
397 | spin_lock_irqsave(&ts->lock, flags); | ||
376 | ad7877_ts_event_release(ts); | 398 | ad7877_ts_event_release(ts); |
399 | spin_unlock_irqrestore(&ts->lock, flags); | ||
377 | } | 400 | } |
378 | 401 | ||
379 | static irqreturn_t ad7877_irq(int irq, void *handle) | 402 | static irqreturn_t ad7877_irq(int irq, void *handle) |
380 | { | 403 | { |
381 | struct ad7877 *ts = handle; | 404 | struct ad7877 *ts = handle; |
382 | unsigned long flags; | 405 | unsigned long flags; |
383 | int status; | 406 | int error; |
384 | 407 | ||
385 | /* | 408 | error = spi_sync(ts->spi, &ts->msg); |
386 | * The repeated conversion sequencer controlled by TMR kicked off | 409 | if (error) { |
387 | * too fast. We ignore the last and process the sample sequence | 410 | dev_err(&ts->spi->dev, "spi_sync --> %d\n", error); |
388 | * currently in the queue. It can't be older than 9.4ms, and we | 411 | goto out; |
389 | * need to avoid that ts->msg doesn't get issued twice while in work. | 412 | } |
390 | */ | ||
391 | 413 | ||
392 | spin_lock_irqsave(&ts->lock, flags); | 414 | spin_lock_irqsave(&ts->lock, flags); |
393 | if (!ts->pending) { | 415 | error = ad7877_process_data(ts); |
394 | ts->pending = 1; | 416 | if (!error) |
395 | 417 | mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT); | |
396 | status = spi_async(ts->spi, &ts->msg); | ||
397 | if (status) | ||
398 | dev_err(&ts->spi->dev, "spi_sync --> %d\n", status); | ||
399 | } | ||
400 | spin_unlock_irqrestore(&ts->lock, flags); | 418 | spin_unlock_irqrestore(&ts->lock, flags); |
401 | 419 | ||
420 | out: | ||
402 | return IRQ_HANDLED; | 421 | return IRQ_HANDLED; |
403 | } | 422 | } |
404 | 423 | ||
405 | static void ad7877_callback(void *_ts) | ||
406 | { | ||
407 | struct ad7877 *ts = _ts; | ||
408 | |||
409 | spin_lock_irq(&ts->lock); | ||
410 | |||
411 | ad7877_rx(ts); | ||
412 | ts->pending = 0; | ||
413 | mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT); | ||
414 | |||
415 | spin_unlock_irq(&ts->lock); | ||
416 | } | ||
417 | |||
418 | static void ad7877_disable(struct ad7877 *ts) | 424 | static void ad7877_disable(struct ad7877 *ts) |
419 | { | 425 | { |
420 | mutex_lock(&ts->mutex); | 426 | mutex_lock(&ts->mutex); |
421 | 427 | ||
422 | if (!ts->disabled) { | 428 | if (!ts->disabled) { |
423 | ts->disabled = 1; | 429 | ts->disabled = true; |
424 | disable_irq(ts->spi->irq); | 430 | disable_irq(ts->spi->irq); |
425 | 431 | ||
426 | /* Wait for spi_async callback */ | ||
427 | while (ts->pending) | ||
428 | msleep(1); | ||
429 | |||
430 | if (del_timer_sync(&ts->timer)) | 432 | if (del_timer_sync(&ts->timer)) |
431 | ad7877_ts_event_release(ts); | 433 | ad7877_ts_event_release(ts); |
432 | } | 434 | } |
433 | 435 | ||
434 | /* we know the chip's in lowpower mode since we always | 436 | /* |
437 | * We know the chip's in lowpower mode since we always | ||
435 | * leave it that way after every request | 438 | * leave it that way after every request |
436 | */ | 439 | */ |
437 | 440 | ||
@@ -443,7 +446,7 @@ static void ad7877_enable(struct ad7877 *ts) | |||
443 | mutex_lock(&ts->mutex); | 446 | mutex_lock(&ts->mutex); |
444 | 447 | ||
445 | if (ts->disabled) { | 448 | if (ts->disabled) { |
446 | ts->disabled = 0; | 449 | ts->disabled = false; |
447 | enable_irq(ts->spi->irq); | 450 | enable_irq(ts->spi->irq); |
448 | } | 451 | } |
449 | 452 | ||
@@ -453,7 +456,7 @@ static void ad7877_enable(struct ad7877 *ts) | |||
453 | #define SHOW(name) static ssize_t \ | 456 | #define SHOW(name) static ssize_t \ |
454 | name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ | 457 | name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ |
455 | { \ | 458 | { \ |
456 | struct ad7877 *ts = dev_get_drvdata(dev); \ | 459 | struct ad7877 *ts = dev_get_drvdata(dev); \ |
457 | ssize_t v = ad7877_read_adc(ts->spi, \ | 460 | ssize_t v = ad7877_read_adc(ts->spi, \ |
458 | AD7877_READ_CHAN(name)); \ | 461 | AD7877_READ_CHAN(name)); \ |
459 | if (v < 0) \ | 462 | if (v < 0) \ |
@@ -473,7 +476,7 @@ SHOW(temp2) | |||
473 | static ssize_t ad7877_disable_show(struct device *dev, | 476 | static ssize_t ad7877_disable_show(struct device *dev, |
474 | struct device_attribute *attr, char *buf) | 477 | struct device_attribute *attr, char *buf) |
475 | { | 478 | { |
476 | struct ad7877 *ts = dev_get_drvdata(dev); | 479 | struct ad7877 *ts = dev_get_drvdata(dev); |
477 | 480 | ||
478 | return sprintf(buf, "%u\n", ts->disabled); | 481 | return sprintf(buf, "%u\n", ts->disabled); |
479 | } | 482 | } |
@@ -503,7 +506,7 @@ static DEVICE_ATTR(disable, 0664, ad7877_disable_show, ad7877_disable_store); | |||
503 | static ssize_t ad7877_dac_show(struct device *dev, | 506 | static ssize_t ad7877_dac_show(struct device *dev, |
504 | struct device_attribute *attr, char *buf) | 507 | struct device_attribute *attr, char *buf) |
505 | { | 508 | { |
506 | struct ad7877 *ts = dev_get_drvdata(dev); | 509 | struct ad7877 *ts = dev_get_drvdata(dev); |
507 | 510 | ||
508 | return sprintf(buf, "%u\n", ts->dac); | 511 | return sprintf(buf, "%u\n", ts->dac); |
509 | } | 512 | } |
@@ -533,7 +536,7 @@ static DEVICE_ATTR(dac, 0664, ad7877_dac_show, ad7877_dac_store); | |||
533 | static ssize_t ad7877_gpio3_show(struct device *dev, | 536 | static ssize_t ad7877_gpio3_show(struct device *dev, |
534 | struct device_attribute *attr, char *buf) | 537 | struct device_attribute *attr, char *buf) |
535 | { | 538 | { |
536 | struct ad7877 *ts = dev_get_drvdata(dev); | 539 | struct ad7877 *ts = dev_get_drvdata(dev); |
537 | 540 | ||
538 | return sprintf(buf, "%u\n", ts->gpio3); | 541 | return sprintf(buf, "%u\n", ts->gpio3); |
539 | } | 542 | } |
@@ -564,7 +567,7 @@ static DEVICE_ATTR(gpio3, 0664, ad7877_gpio3_show, ad7877_gpio3_store); | |||
564 | static ssize_t ad7877_gpio4_show(struct device *dev, | 567 | static ssize_t ad7877_gpio4_show(struct device *dev, |
565 | struct device_attribute *attr, char *buf) | 568 | struct device_attribute *attr, char *buf) |
566 | { | 569 | { |
567 | struct ad7877 *ts = dev_get_drvdata(dev); | 570 | struct ad7877 *ts = dev_get_drvdata(dev); |
568 | 571 | ||
569 | return sprintf(buf, "%u\n", ts->gpio4); | 572 | return sprintf(buf, "%u\n", ts->gpio4); |
570 | } | 573 | } |
@@ -597,16 +600,35 @@ static struct attribute *ad7877_attributes[] = { | |||
597 | &dev_attr_temp2.attr, | 600 | &dev_attr_temp2.attr, |
598 | &dev_attr_aux1.attr, | 601 | &dev_attr_aux1.attr, |
599 | &dev_attr_aux2.attr, | 602 | &dev_attr_aux2.attr, |
603 | &dev_attr_aux3.attr, | ||
600 | &dev_attr_bat1.attr, | 604 | &dev_attr_bat1.attr, |
601 | &dev_attr_bat2.attr, | 605 | &dev_attr_bat2.attr, |
602 | &dev_attr_disable.attr, | 606 | &dev_attr_disable.attr, |
603 | &dev_attr_dac.attr, | 607 | &dev_attr_dac.attr, |
608 | &dev_attr_gpio3.attr, | ||
604 | &dev_attr_gpio4.attr, | 609 | &dev_attr_gpio4.attr, |
605 | NULL | 610 | NULL |
606 | }; | 611 | }; |
607 | 612 | ||
613 | static mode_t ad7877_attr_is_visible(struct kobject *kobj, | ||
614 | struct attribute *attr, int n) | ||
615 | { | ||
616 | mode_t mode = attr->mode; | ||
617 | |||
618 | if (attr == &dev_attr_aux3.attr) { | ||
619 | if (gpio3) | ||
620 | mode = 0; | ||
621 | } else if (attr == &dev_attr_gpio3.attr) { | ||
622 | if (!gpio3) | ||
623 | mode = 0; | ||
624 | } | ||
625 | |||
626 | return mode; | ||
627 | } | ||
628 | |||
608 | static const struct attribute_group ad7877_attr_group = { | 629 | static const struct attribute_group ad7877_attr_group = { |
609 | .attrs = ad7877_attributes, | 630 | .is_visible = ad7877_attr_is_visible, |
631 | .attrs = ad7877_attributes, | ||
610 | }; | 632 | }; |
611 | 633 | ||
612 | static void ad7877_setup_ts_def_msg(struct spi_device *spi, struct ad7877 *ts) | 634 | static void ad7877_setup_ts_def_msg(struct spi_device *spi, struct ad7877 *ts) |
@@ -635,22 +657,25 @@ static void ad7877_setup_ts_def_msg(struct spi_device *spi, struct ad7877 *ts) | |||
635 | 657 | ||
636 | spi_message_init(m); | 658 | spi_message_init(m); |
637 | 659 | ||
638 | m->complete = ad7877_callback; | ||
639 | m->context = ts; | 660 | m->context = ts; |
640 | 661 | ||
641 | ts->xfer[0].tx_buf = &ts->cmd_crtl1; | 662 | ts->xfer[0].tx_buf = &ts->cmd_crtl1; |
642 | ts->xfer[0].len = 2; | 663 | ts->xfer[0].len = 2; |
664 | ts->xfer[0].cs_change = 1; | ||
643 | 665 | ||
644 | spi_message_add_tail(&ts->xfer[0], m); | 666 | spi_message_add_tail(&ts->xfer[0], m); |
645 | 667 | ||
646 | ts->xfer[1].tx_buf = &ts->cmd_dummy; /* Send ZERO */ | 668 | ts->xfer[1].tx_buf = &ts->cmd_dummy; /* Send ZERO */ |
647 | ts->xfer[1].len = 2; | 669 | ts->xfer[1].len = 2; |
670 | ts->xfer[1].cs_change = 1; | ||
648 | 671 | ||
649 | spi_message_add_tail(&ts->xfer[1], m); | 672 | spi_message_add_tail(&ts->xfer[1], m); |
650 | 673 | ||
651 | for (i = 0; i < 11; i++) { | 674 | for (i = 0; i < AD7877_NR_SENSE; i++) { |
652 | ts->xfer[i + 2].rx_buf = &ts->conversion_data[AD7877_SEQ_YPOS + i]; | 675 | ts->xfer[i + 2].rx_buf = &ts->conversion_data[AD7877_SEQ_YPOS + i]; |
653 | ts->xfer[i + 2].len = 2; | 676 | ts->xfer[i + 2].len = 2; |
677 | if (i < (AD7877_NR_SENSE - 1)) | ||
678 | ts->xfer[i + 2].cs_change = 1; | ||
654 | spi_message_add_tail(&ts->xfer[i + 2], m); | 679 | spi_message_add_tail(&ts->xfer[i + 2], m); |
655 | } | 680 | } |
656 | } | 681 | } |
@@ -718,6 +743,8 @@ static int __devinit ad7877_probe(struct spi_device *spi) | |||
718 | input_dev->phys = ts->phys; | 743 | input_dev->phys = ts->phys; |
719 | input_dev->dev.parent = &spi->dev; | 744 | input_dev->dev.parent = &spi->dev; |
720 | 745 | ||
746 | __set_bit(EV_KEY, input_dev->evbit); | ||
747 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
721 | __set_bit(EV_ABS, input_dev->evbit); | 748 | __set_bit(EV_ABS, input_dev->evbit); |
722 | __set_bit(ABS_X, input_dev->absbit); | 749 | __set_bit(ABS_X, input_dev->absbit); |
723 | __set_bit(ABS_Y, input_dev->absbit); | 750 | __set_bit(ABS_Y, input_dev->absbit); |
@@ -752,8 +779,9 @@ static int __devinit ad7877_probe(struct spi_device *spi) | |||
752 | 779 | ||
753 | /* Request AD7877 /DAV GPIO interrupt */ | 780 | /* Request AD7877 /DAV GPIO interrupt */ |
754 | 781 | ||
755 | err = request_irq(spi->irq, ad7877_irq, IRQF_TRIGGER_FALLING, | 782 | err = request_threaded_irq(spi->irq, NULL, ad7877_irq, |
756 | spi->dev.driver->name, ts); | 783 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
784 | spi->dev.driver->name, ts); | ||
757 | if (err) { | 785 | if (err) { |
758 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); | 786 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); |
759 | goto err_free_mem; | 787 | goto err_free_mem; |
@@ -763,20 +791,12 @@ static int __devinit ad7877_probe(struct spi_device *spi) | |||
763 | if (err) | 791 | if (err) |
764 | goto err_free_irq; | 792 | goto err_free_irq; |
765 | 793 | ||
766 | err = device_create_file(&spi->dev, | ||
767 | gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3); | ||
768 | if (err) | ||
769 | goto err_remove_attr_group; | ||
770 | |||
771 | err = input_register_device(input_dev); | 794 | err = input_register_device(input_dev); |
772 | if (err) | 795 | if (err) |
773 | goto err_remove_attr; | 796 | goto err_remove_attr_group; |
774 | 797 | ||
775 | return 0; | 798 | return 0; |
776 | 799 | ||
777 | err_remove_attr: | ||
778 | device_remove_file(&spi->dev, | ||
779 | gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3); | ||
780 | err_remove_attr_group: | 800 | err_remove_attr_group: |
781 | sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); | 801 | sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); |
782 | err_free_irq: | 802 | err_free_irq: |
@@ -790,11 +810,9 @@ err_free_mem: | |||
790 | 810 | ||
791 | static int __devexit ad7877_remove(struct spi_device *spi) | 811 | static int __devexit ad7877_remove(struct spi_device *spi) |
792 | { | 812 | { |
793 | struct ad7877 *ts = dev_get_drvdata(&spi->dev); | 813 | struct ad7877 *ts = dev_get_drvdata(&spi->dev); |
794 | 814 | ||
795 | sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); | 815 | sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); |
796 | device_remove_file(&spi->dev, | ||
797 | gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3); | ||
798 | 816 | ||
799 | ad7877_disable(ts); | 817 | ad7877_disable(ts); |
800 | free_irq(ts->spi->irq, ts); | 818 | free_irq(ts->spi->irq, ts); |
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 16031933a8f6..14ea54b78e46 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -17,9 +17,11 @@ | |||
17 | * it under the terms of the GNU General Public License version 2 as | 17 | * it under the terms of the GNU General Public License version 2 as |
18 | * published by the Free Software Foundation. | 18 | * published by the Free Software Foundation. |
19 | */ | 19 | */ |
20 | #include <linux/types.h> | ||
20 | #include <linux/hwmon.h> | 21 | #include <linux/hwmon.h> |
21 | #include <linux/init.h> | 22 | #include <linux/init.h> |
22 | #include <linux/err.h> | 23 | #include <linux/err.h> |
24 | #include <linux/sched.h> | ||
23 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
24 | #include <linux/input.h> | 26 | #include <linux/input.h> |
25 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
@@ -52,22 +54,23 @@ | |||
52 | * files. | 54 | * files. |
53 | */ | 55 | */ |
54 | 56 | ||
55 | #define TS_POLL_DELAY (1 * 1000000) /* ns delay before the first sample */ | 57 | #define TS_POLL_DELAY 1 /* ms delay before the first sample */ |
56 | #define TS_POLL_PERIOD (5 * 1000000) /* ns delay between samples */ | 58 | #define TS_POLL_PERIOD 5 /* ms delay between samples */ |
57 | 59 | ||
58 | /* this driver doesn't aim at the peak continuous sample rate */ | 60 | /* this driver doesn't aim at the peak continuous sample rate */ |
59 | #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */) | 61 | #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */) |
60 | 62 | ||
61 | struct ts_event { | 63 | struct ts_event { |
62 | /* For portability, we can't read 12 bit values using SPI (which | 64 | /* |
63 | * would make the controller deliver them as native byteorder u16 | 65 | * For portability, we can't read 12 bit values using SPI (which |
66 | * would make the controller deliver them as native byte order u16 | ||
64 | * with msbs zeroed). Instead, we read them as two 8-bit values, | 67 | * with msbs zeroed). Instead, we read them as two 8-bit values, |
65 | * *** WHICH NEED BYTESWAPPING *** and range adjustment. | 68 | * *** WHICH NEED BYTESWAPPING *** and range adjustment. |
66 | */ | 69 | */ |
67 | u16 x; | 70 | u16 x; |
68 | u16 y; | 71 | u16 y; |
69 | u16 z1, z2; | 72 | u16 z1, z2; |
70 | int ignore; | 73 | bool ignore; |
71 | u8 x_buf[3]; | 74 | u8 x_buf[3]; |
72 | u8 y_buf[3]; | 75 | u8 y_buf[3]; |
73 | }; | 76 | }; |
@@ -110,8 +113,11 @@ struct ads7846 { | |||
110 | 113 | ||
111 | struct spi_transfer xfer[18]; | 114 | struct spi_transfer xfer[18]; |
112 | struct spi_message msg[5]; | 115 | struct spi_message msg[5]; |
113 | struct spi_message *last_msg; | 116 | int msg_count; |
114 | int msg_idx; | 117 | wait_queue_head_t wait; |
118 | |||
119 | bool pendown; | ||
120 | |||
115 | int read_cnt; | 121 | int read_cnt; |
116 | int read_rep; | 122 | int read_rep; |
117 | int last_read; | 123 | int last_read; |
@@ -122,14 +128,10 @@ struct ads7846 { | |||
122 | 128 | ||
123 | u16 penirq_recheck_delay_usecs; | 129 | u16 penirq_recheck_delay_usecs; |
124 | 130 | ||
125 | spinlock_t lock; | 131 | struct mutex lock; |
126 | struct hrtimer timer; | 132 | bool stopped; /* P: lock */ |
127 | unsigned pendown:1; /* P: lock */ | 133 | bool disabled; /* P: lock */ |
128 | unsigned pending:1; /* P: lock */ | 134 | bool suspended; /* P: lock */ |
129 | // FIXME remove "irq_disabled" | ||
130 | unsigned irq_disabled:1; /* P: lock */ | ||
131 | unsigned disabled:1; | ||
132 | unsigned is_suspended:1; | ||
133 | 135 | ||
134 | int (*filter)(void *data, int data_idx, int *val); | 136 | int (*filter)(void *data, int data_idx, int *val); |
135 | void *filter_data; | 137 | void *filter_data; |
@@ -165,7 +167,7 @@ struct ads7846 { | |||
165 | #define ADS_12_BIT (0 << 3) | 167 | #define ADS_12_BIT (0 << 3) |
166 | #define ADS_SER (1 << 2) /* non-differential */ | 168 | #define ADS_SER (1 << 2) /* non-differential */ |
167 | #define ADS_DFR (0 << 2) /* differential */ | 169 | #define ADS_DFR (0 << 2) /* differential */ |
168 | #define ADS_PD10_PDOWN (0 << 0) /* lowpower mode + penirq */ | 170 | #define ADS_PD10_PDOWN (0 << 0) /* low power mode + penirq */ |
169 | #define ADS_PD10_ADC_ON (1 << 0) /* ADC on */ | 171 | #define ADS_PD10_ADC_ON (1 << 0) /* ADC on */ |
170 | #define ADS_PD10_REF_ON (2 << 0) /* vREF on + penirq */ | 172 | #define ADS_PD10_REF_ON (2 << 0) /* vREF on + penirq */ |
171 | #define ADS_PD10_ALL_ON (3 << 0) /* ADC + vREF on */ | 173 | #define ADS_PD10_ALL_ON (3 << 0) /* ADC + vREF on */ |
@@ -193,6 +195,78 @@ struct ads7846 { | |||
193 | #define REF_ON (READ_12BIT_DFR(x, 1, 1)) | 195 | #define REF_ON (READ_12BIT_DFR(x, 1, 1)) |
194 | #define REF_OFF (READ_12BIT_DFR(y, 0, 0)) | 196 | #define REF_OFF (READ_12BIT_DFR(y, 0, 0)) |
195 | 197 | ||
198 | /* Must be called with ts->lock held */ | ||
199 | static void ads7846_stop(struct ads7846 *ts) | ||
200 | { | ||
201 | if (!ts->disabled && !ts->suspended) { | ||
202 | /* Signal IRQ thread to stop polling and disable the handler. */ | ||
203 | ts->stopped = true; | ||
204 | mb(); | ||
205 | wake_up(&ts->wait); | ||
206 | disable_irq(ts->spi->irq); | ||
207 | } | ||
208 | } | ||
209 | |||
210 | /* Must be called with ts->lock held */ | ||
211 | static void ads7846_restart(struct ads7846 *ts) | ||
212 | { | ||
213 | if (!ts->disabled && !ts->suspended) { | ||
214 | /* Tell IRQ thread that it may poll the device. */ | ||
215 | ts->stopped = false; | ||
216 | mb(); | ||
217 | enable_irq(ts->spi->irq); | ||
218 | } | ||
219 | } | ||
220 | |||
221 | /* Must be called with ts->lock held */ | ||
222 | static void __ads7846_disable(struct ads7846 *ts) | ||
223 | { | ||
224 | ads7846_stop(ts); | ||
225 | regulator_disable(ts->reg); | ||
226 | |||
227 | /* | ||
228 | * We know the chip's in low power mode since we always | ||
229 | * leave it that way after every request | ||
230 | */ | ||
231 | } | ||
232 | |||
233 | /* Must be called with ts->lock held */ | ||
234 | static void __ads7846_enable(struct ads7846 *ts) | ||
235 | { | ||
236 | regulator_enable(ts->reg); | ||
237 | ads7846_restart(ts); | ||
238 | } | ||
239 | |||
240 | static void ads7846_disable(struct ads7846 *ts) | ||
241 | { | ||
242 | mutex_lock(&ts->lock); | ||
243 | |||
244 | if (!ts->disabled) { | ||
245 | |||
246 | if (!ts->suspended) | ||
247 | __ads7846_disable(ts); | ||
248 | |||
249 | ts->disabled = true; | ||
250 | } | ||
251 | |||
252 | mutex_unlock(&ts->lock); | ||
253 | } | ||
254 | |||
255 | static void ads7846_enable(struct ads7846 *ts) | ||
256 | { | ||
257 | mutex_lock(&ts->lock); | ||
258 | |||
259 | if (ts->disabled) { | ||
260 | |||
261 | ts->disabled = false; | ||
262 | |||
263 | if (!ts->suspended) | ||
264 | __ads7846_enable(ts); | ||
265 | } | ||
266 | |||
267 | mutex_unlock(&ts->lock); | ||
268 | } | ||
269 | |||
196 | /*--------------------------------------------------------------------------*/ | 270 | /*--------------------------------------------------------------------------*/ |
197 | 271 | ||
198 | /* | 272 | /* |
@@ -219,23 +293,15 @@ struct ads7845_ser_req { | |||
219 | struct spi_transfer xfer[2]; | 293 | struct spi_transfer xfer[2]; |
220 | }; | 294 | }; |
221 | 295 | ||
222 | static void ads7846_enable(struct ads7846 *ts); | ||
223 | static void ads7846_disable(struct ads7846 *ts); | ||
224 | |||
225 | static int device_suspended(struct device *dev) | ||
226 | { | ||
227 | struct ads7846 *ts = dev_get_drvdata(dev); | ||
228 | return ts->is_suspended || ts->disabled; | ||
229 | } | ||
230 | |||
231 | static int ads7846_read12_ser(struct device *dev, unsigned command) | 296 | static int ads7846_read12_ser(struct device *dev, unsigned command) |
232 | { | 297 | { |
233 | struct spi_device *spi = to_spi_device(dev); | 298 | struct spi_device *spi = to_spi_device(dev); |
234 | struct ads7846 *ts = dev_get_drvdata(dev); | 299 | struct ads7846 *ts = dev_get_drvdata(dev); |
235 | struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); | 300 | struct ser_req *req; |
236 | int status; | 301 | int status; |
237 | int use_internal; | 302 | int use_internal; |
238 | 303 | ||
304 | req = kzalloc(sizeof *req, GFP_KERNEL); | ||
239 | if (!req) | 305 | if (!req) |
240 | return -ENOMEM; | 306 | return -ENOMEM; |
241 | 307 | ||
@@ -282,11 +348,11 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
282 | CS_CHANGE(req->xfer[5]); | 348 | CS_CHANGE(req->xfer[5]); |
283 | spi_message_add_tail(&req->xfer[5], &req->msg); | 349 | spi_message_add_tail(&req->xfer[5], &req->msg); |
284 | 350 | ||
285 | ts->irq_disabled = 1; | 351 | mutex_lock(&ts->lock); |
286 | disable_irq(spi->irq); | 352 | ads7846_stop(ts); |
287 | status = spi_sync(spi, &req->msg); | 353 | status = spi_sync(spi, &req->msg); |
288 | ts->irq_disabled = 0; | 354 | ads7846_restart(ts); |
289 | enable_irq(spi->irq); | 355 | mutex_unlock(&ts->lock); |
290 | 356 | ||
291 | if (status == 0) { | 357 | if (status == 0) { |
292 | /* on-wire is a must-ignore bit, a BE12 value, then padding */ | 358 | /* on-wire is a must-ignore bit, a BE12 value, then padding */ |
@@ -301,11 +367,12 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
301 | 367 | ||
302 | static int ads7845_read12_ser(struct device *dev, unsigned command) | 368 | static int ads7845_read12_ser(struct device *dev, unsigned command) |
303 | { | 369 | { |
304 | struct spi_device *spi = to_spi_device(dev); | 370 | struct spi_device *spi = to_spi_device(dev); |
305 | struct ads7846 *ts = dev_get_drvdata(dev); | 371 | struct ads7846 *ts = dev_get_drvdata(dev); |
306 | struct ads7845_ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); | 372 | struct ads7845_ser_req *req; |
307 | int status; | 373 | int status; |
308 | 374 | ||
375 | req = kzalloc(sizeof *req, GFP_KERNEL); | ||
309 | if (!req) | 376 | if (!req) |
310 | return -ENOMEM; | 377 | return -ENOMEM; |
311 | 378 | ||
@@ -317,11 +384,11 @@ static int ads7845_read12_ser(struct device *dev, unsigned command) | |||
317 | req->xfer[0].len = 3; | 384 | req->xfer[0].len = 3; |
318 | spi_message_add_tail(&req->xfer[0], &req->msg); | 385 | spi_message_add_tail(&req->xfer[0], &req->msg); |
319 | 386 | ||
320 | ts->irq_disabled = 1; | 387 | mutex_lock(&ts->lock); |
321 | disable_irq(spi->irq); | 388 | ads7846_stop(ts); |
322 | status = spi_sync(spi, &req->msg); | 389 | status = spi_sync(spi, &req->msg); |
323 | ts->irq_disabled = 0; | 390 | ads7846_restart(ts); |
324 | enable_irq(spi->irq); | 391 | mutex_unlock(&ts->lock); |
325 | 392 | ||
326 | if (status == 0) { | 393 | if (status == 0) { |
327 | /* BE12 value, then padding */ | 394 | /* BE12 value, then padding */ |
@@ -374,6 +441,7 @@ static inline unsigned vaux_adjust(struct ads7846 *ts, ssize_t v) | |||
374 | /* external resistors may scale vAUX into 0..vREF */ | 441 | /* external resistors may scale vAUX into 0..vREF */ |
375 | retval *= ts->vref_mv; | 442 | retval *= ts->vref_mv; |
376 | retval = retval >> 12; | 443 | retval = retval >> 12; |
444 | |||
377 | return retval; | 445 | return retval; |
378 | } | 446 | } |
379 | 447 | ||
@@ -384,13 +452,13 @@ static inline unsigned vbatt_adjust(struct ads7846 *ts, ssize_t v) | |||
384 | /* ads7846 has a resistor ladder to scale this signal down */ | 452 | /* ads7846 has a resistor ladder to scale this signal down */ |
385 | if (ts->model == 7846) | 453 | if (ts->model == 7846) |
386 | retval *= 4; | 454 | retval *= 4; |
455 | |||
387 | return retval; | 456 | return retval; |
388 | } | 457 | } |
389 | 458 | ||
390 | SHOW(in0_input, vaux, vaux_adjust) | 459 | SHOW(in0_input, vaux, vaux_adjust) |
391 | SHOW(in1_input, vbatt, vbatt_adjust) | 460 | SHOW(in1_input, vbatt, vbatt_adjust) |
392 | 461 | ||
393 | |||
394 | static struct attribute *ads7846_attributes[] = { | 462 | static struct attribute *ads7846_attributes[] = { |
395 | &dev_attr_temp0.attr, | 463 | &dev_attr_temp0.attr, |
396 | &dev_attr_temp1.attr, | 464 | &dev_attr_temp1.attr, |
@@ -498,17 +566,12 @@ static inline void ads784x_hwmon_unregister(struct spi_device *spi, | |||
498 | } | 566 | } |
499 | #endif | 567 | #endif |
500 | 568 | ||
501 | static int is_pen_down(struct device *dev) | ||
502 | { | ||
503 | struct ads7846 *ts = dev_get_drvdata(dev); | ||
504 | |||
505 | return ts->pendown; | ||
506 | } | ||
507 | |||
508 | static ssize_t ads7846_pen_down_show(struct device *dev, | 569 | static ssize_t ads7846_pen_down_show(struct device *dev, |
509 | struct device_attribute *attr, char *buf) | 570 | struct device_attribute *attr, char *buf) |
510 | { | 571 | { |
511 | return sprintf(buf, "%u\n", is_pen_down(dev)); | 572 | struct ads7846 *ts = dev_get_drvdata(dev); |
573 | |||
574 | return sprintf(buf, "%u\n", ts->pendown); | ||
512 | } | 575 | } |
513 | 576 | ||
514 | static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL); | 577 | static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL); |
@@ -516,7 +579,7 @@ static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL); | |||
516 | static ssize_t ads7846_disable_show(struct device *dev, | 579 | static ssize_t ads7846_disable_show(struct device *dev, |
517 | struct device_attribute *attr, char *buf) | 580 | struct device_attribute *attr, char *buf) |
518 | { | 581 | { |
519 | struct ads7846 *ts = dev_get_drvdata(dev); | 582 | struct ads7846 *ts = dev_get_drvdata(dev); |
520 | 583 | ||
521 | return sprintf(buf, "%u\n", ts->disabled); | 584 | return sprintf(buf, "%u\n", ts->disabled); |
522 | } | 585 | } |
@@ -531,15 +594,11 @@ static ssize_t ads7846_disable_store(struct device *dev, | |||
531 | if (strict_strtoul(buf, 10, &i)) | 594 | if (strict_strtoul(buf, 10, &i)) |
532 | return -EINVAL; | 595 | return -EINVAL; |
533 | 596 | ||
534 | spin_lock_irq(&ts->lock); | ||
535 | |||
536 | if (i) | 597 | if (i) |
537 | ads7846_disable(ts); | 598 | ads7846_disable(ts); |
538 | else | 599 | else |
539 | ads7846_enable(ts); | 600 | ads7846_enable(ts); |
540 | 601 | ||
541 | spin_unlock_irq(&ts->lock); | ||
542 | |||
543 | return count; | 602 | return count; |
544 | } | 603 | } |
545 | 604 | ||
@@ -569,23 +628,141 @@ static void null_wait_for_sync(void) | |||
569 | { | 628 | { |
570 | } | 629 | } |
571 | 630 | ||
572 | /* | 631 | static int ads7846_debounce_filter(void *ads, int data_idx, int *val) |
573 | * PENIRQ only kicks the timer. The timer only reissues the SPI transfer, | 632 | { |
574 | * to retrieve touchscreen status. | 633 | struct ads7846 *ts = ads; |
575 | * | 634 | |
576 | * The SPI transfer completion callback does the real work. It reports | 635 | if (!ts->read_cnt || (abs(ts->last_read - *val) > ts->debounce_tol)) { |
577 | * touchscreen events and reactivates the timer (or IRQ) as appropriate. | 636 | /* Start over collecting consistent readings. */ |
578 | */ | 637 | ts->read_rep = 0; |
638 | /* | ||
639 | * Repeat it, if this was the first read or the read | ||
640 | * wasn't consistent enough. | ||
641 | */ | ||
642 | if (ts->read_cnt < ts->debounce_max) { | ||
643 | ts->last_read = *val; | ||
644 | ts->read_cnt++; | ||
645 | return ADS7846_FILTER_REPEAT; | ||
646 | } else { | ||
647 | /* | ||
648 | * Maximum number of debouncing reached and still | ||
649 | * not enough number of consistent readings. Abort | ||
650 | * the whole sample, repeat it in the next sampling | ||
651 | * period. | ||
652 | */ | ||
653 | ts->read_cnt = 0; | ||
654 | return ADS7846_FILTER_IGNORE; | ||
655 | } | ||
656 | } else { | ||
657 | if (++ts->read_rep > ts->debounce_rep) { | ||
658 | /* | ||
659 | * Got a good reading for this coordinate, | ||
660 | * go for the next one. | ||
661 | */ | ||
662 | ts->read_cnt = 0; | ||
663 | ts->read_rep = 0; | ||
664 | return ADS7846_FILTER_OK; | ||
665 | } else { | ||
666 | /* Read more values that are consistent. */ | ||
667 | ts->read_cnt++; | ||
668 | return ADS7846_FILTER_REPEAT; | ||
669 | } | ||
670 | } | ||
671 | } | ||
672 | |||
673 | static int ads7846_no_filter(void *ads, int data_idx, int *val) | ||
674 | { | ||
675 | return ADS7846_FILTER_OK; | ||
676 | } | ||
677 | |||
678 | static int ads7846_get_value(struct ads7846 *ts, struct spi_message *m) | ||
679 | { | ||
680 | struct spi_transfer *t = | ||
681 | list_entry(m->transfers.prev, struct spi_transfer, transfer_list); | ||
682 | |||
683 | if (ts->model == 7845) { | ||
684 | return be16_to_cpup((__be16 *)&(((char*)t->rx_buf)[1])) >> 3; | ||
685 | } else { | ||
686 | /* | ||
687 | * adjust: on-wire is a must-ignore bit, a BE12 value, then | ||
688 | * padding; built from two 8 bit values written msb-first. | ||
689 | */ | ||
690 | return be16_to_cpup((__be16 *)t->rx_buf) >> 3; | ||
691 | } | ||
692 | } | ||
693 | |||
694 | static void ads7846_update_value(struct spi_message *m, int val) | ||
695 | { | ||
696 | struct spi_transfer *t = | ||
697 | list_entry(m->transfers.prev, struct spi_transfer, transfer_list); | ||
698 | |||
699 | *(u16 *)t->rx_buf = val; | ||
700 | } | ||
701 | |||
702 | static void ads7846_read_state(struct ads7846 *ts) | ||
703 | { | ||
704 | struct ads7846_packet *packet = ts->packet; | ||
705 | struct spi_message *m; | ||
706 | int msg_idx = 0; | ||
707 | int val; | ||
708 | int action; | ||
709 | int error; | ||
710 | |||
711 | while (msg_idx < ts->msg_count) { | ||
712 | |||
713 | ts->wait_for_sync(); | ||
714 | |||
715 | m = &ts->msg[msg_idx]; | ||
716 | error = spi_sync(ts->spi, m); | ||
717 | if (error) { | ||
718 | dev_err(&ts->spi->dev, "spi_async --> %d\n", error); | ||
719 | packet->tc.ignore = true; | ||
720 | return; | ||
721 | } | ||
722 | |||
723 | /* | ||
724 | * Last message is power down request, no need to convert | ||
725 | * or filter the value. | ||
726 | */ | ||
727 | if (msg_idx < ts->msg_count - 1) { | ||
579 | 728 | ||
580 | static void ads7846_rx(void *ads) | 729 | val = ads7846_get_value(ts, m); |
730 | |||
731 | action = ts->filter(ts->filter_data, msg_idx, &val); | ||
732 | switch (action) { | ||
733 | case ADS7846_FILTER_REPEAT: | ||
734 | continue; | ||
735 | |||
736 | case ADS7846_FILTER_IGNORE: | ||
737 | packet->tc.ignore = true; | ||
738 | msg_idx = ts->msg_count - 1; | ||
739 | continue; | ||
740 | |||
741 | case ADS7846_FILTER_OK: | ||
742 | ads7846_update_value(m, val); | ||
743 | packet->tc.ignore = false; | ||
744 | msg_idx++; | ||
745 | break; | ||
746 | |||
747 | default: | ||
748 | BUG(); | ||
749 | } | ||
750 | } else { | ||
751 | msg_idx++; | ||
752 | } | ||
753 | } | ||
754 | } | ||
755 | |||
756 | static void ads7846_report_state(struct ads7846 *ts) | ||
581 | { | 757 | { |
582 | struct ads7846 *ts = ads; | 758 | struct ads7846_packet *packet = ts->packet; |
583 | struct ads7846_packet *packet = ts->packet; | 759 | unsigned int Rt; |
584 | unsigned Rt; | 760 | u16 x, y, z1, z2; |
585 | u16 x, y, z1, z2; | ||
586 | 761 | ||
587 | /* ads7846_rx_val() did in-place conversion (including byteswap) from | 762 | /* |
588 | * on-the-wire format as part of debouncing to get stable readings. | 763 | * ads7846_get_value() does in-place conversion (including byte swap) |
764 | * from on-the-wire format as part of debouncing to get stable | ||
765 | * readings. | ||
589 | */ | 766 | */ |
590 | if (ts->model == 7845) { | 767 | if (ts->model == 7845) { |
591 | x = *(u16 *)packet->tc.x_buf; | 768 | x = *(u16 *)packet->tc.x_buf; |
@@ -623,19 +800,19 @@ static void ads7846_rx(void *ads) | |||
623 | Rt = 0; | 800 | Rt = 0; |
624 | } | 801 | } |
625 | 802 | ||
626 | /* Sample found inconsistent by debouncing or pressure is beyond | 803 | /* |
804 | * Sample found inconsistent by debouncing or pressure is beyond | ||
627 | * the maximum. Don't report it to user space, repeat at least | 805 | * the maximum. Don't report it to user space, repeat at least |
628 | * once more the measurement | 806 | * once more the measurement |
629 | */ | 807 | */ |
630 | if (packet->tc.ignore || Rt > ts->pressure_max) { | 808 | if (packet->tc.ignore || Rt > ts->pressure_max) { |
631 | dev_vdbg(&ts->spi->dev, "ignored %d pressure %d\n", | 809 | dev_vdbg(&ts->spi->dev, "ignored %d pressure %d\n", |
632 | packet->tc.ignore, Rt); | 810 | packet->tc.ignore, Rt); |
633 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), | ||
634 | HRTIMER_MODE_REL); | ||
635 | return; | 811 | return; |
636 | } | 812 | } |
637 | 813 | ||
638 | /* Maybe check the pendown state before reporting. This discards | 814 | /* |
815 | * Maybe check the pendown state before reporting. This discards | ||
639 | * false readings when the pen is lifted. | 816 | * false readings when the pen is lifted. |
640 | */ | 817 | */ |
641 | if (ts->penirq_recheck_delay_usecs) { | 818 | if (ts->penirq_recheck_delay_usecs) { |
@@ -644,8 +821,9 @@ static void ads7846_rx(void *ads) | |||
644 | Rt = 0; | 821 | Rt = 0; |
645 | } | 822 | } |
646 | 823 | ||
647 | /* NOTE: We can't rely on the pressure to determine the pen down | 824 | /* |
648 | * state, even this controller has a pressure sensor. The pressure | 825 | * NOTE: We can't rely on the pressure to determine the pen down |
826 | * state, even this controller has a pressure sensor. The pressure | ||
649 | * value can fluctuate for quite a while after lifting the pen and | 827 | * value can fluctuate for quite a while after lifting the pen and |
650 | * in some cases may not even settle at the expected value. | 828 | * in some cases may not even settle at the expected value. |
651 | * | 829 | * |
@@ -655,15 +833,15 @@ static void ads7846_rx(void *ads) | |||
655 | if (Rt) { | 833 | if (Rt) { |
656 | struct input_dev *input = ts->input; | 834 | struct input_dev *input = ts->input; |
657 | 835 | ||
836 | if (ts->swap_xy) | ||
837 | swap(x, y); | ||
838 | |||
658 | if (!ts->pendown) { | 839 | if (!ts->pendown) { |
659 | input_report_key(input, BTN_TOUCH, 1); | 840 | input_report_key(input, BTN_TOUCH, 1); |
660 | ts->pendown = 1; | 841 | ts->pendown = true; |
661 | dev_vdbg(&ts->spi->dev, "DOWN\n"); | 842 | dev_vdbg(&ts->spi->dev, "DOWN\n"); |
662 | } | 843 | } |
663 | 844 | ||
664 | if (ts->swap_xy) | ||
665 | swap(x, y); | ||
666 | |||
667 | input_report_abs(input, ABS_X, x); | 845 | input_report_abs(input, ABS_X, x); |
668 | input_report_abs(input, ABS_Y, y); | 846 | input_report_abs(input, ABS_Y, y); |
669 | input_report_abs(input, ABS_PRESSURE, ts->pressure_max - Rt); | 847 | input_report_abs(input, ABS_PRESSURE, ts->pressure_max - Rt); |
@@ -671,246 +849,94 @@ static void ads7846_rx(void *ads) | |||
671 | input_sync(input); | 849 | input_sync(input); |
672 | dev_vdbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt); | 850 | dev_vdbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt); |
673 | } | 851 | } |
674 | |||
675 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), | ||
676 | HRTIMER_MODE_REL); | ||
677 | } | ||
678 | |||
679 | static int ads7846_debounce(void *ads, int data_idx, int *val) | ||
680 | { | ||
681 | struct ads7846 *ts = ads; | ||
682 | |||
683 | if (!ts->read_cnt || (abs(ts->last_read - *val) > ts->debounce_tol)) { | ||
684 | /* Start over collecting consistent readings. */ | ||
685 | ts->read_rep = 0; | ||
686 | /* Repeat it, if this was the first read or the read | ||
687 | * wasn't consistent enough. */ | ||
688 | if (ts->read_cnt < ts->debounce_max) { | ||
689 | ts->last_read = *val; | ||
690 | ts->read_cnt++; | ||
691 | return ADS7846_FILTER_REPEAT; | ||
692 | } else { | ||
693 | /* Maximum number of debouncing reached and still | ||
694 | * not enough number of consistent readings. Abort | ||
695 | * the whole sample, repeat it in the next sampling | ||
696 | * period. | ||
697 | */ | ||
698 | ts->read_cnt = 0; | ||
699 | return ADS7846_FILTER_IGNORE; | ||
700 | } | ||
701 | } else { | ||
702 | if (++ts->read_rep > ts->debounce_rep) { | ||
703 | /* Got a good reading for this coordinate, | ||
704 | * go for the next one. */ | ||
705 | ts->read_cnt = 0; | ||
706 | ts->read_rep = 0; | ||
707 | return ADS7846_FILTER_OK; | ||
708 | } else { | ||
709 | /* Read more values that are consistent. */ | ||
710 | ts->read_cnt++; | ||
711 | return ADS7846_FILTER_REPEAT; | ||
712 | } | ||
713 | } | ||
714 | } | 852 | } |
715 | 853 | ||
716 | static int ads7846_no_filter(void *ads, int data_idx, int *val) | 854 | static irqreturn_t ads7846_hard_irq(int irq, void *handle) |
717 | { | 855 | { |
718 | return ADS7846_FILTER_OK; | 856 | struct ads7846 *ts = handle; |
719 | } | ||
720 | |||
721 | static void ads7846_rx_val(void *ads) | ||
722 | { | ||
723 | struct ads7846 *ts = ads; | ||
724 | struct ads7846_packet *packet = ts->packet; | ||
725 | struct spi_message *m; | ||
726 | struct spi_transfer *t; | ||
727 | int val; | ||
728 | int action; | ||
729 | int status; | ||
730 | |||
731 | m = &ts->msg[ts->msg_idx]; | ||
732 | t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list); | ||
733 | |||
734 | if (ts->model == 7845) { | ||
735 | val = be16_to_cpup((__be16 *)&(((char*)t->rx_buf)[1])) >> 3; | ||
736 | } else { | ||
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 | } | ||
742 | 857 | ||
743 | action = ts->filter(ts->filter_data, ts->msg_idx, &val); | 858 | return get_pendown_state(ts) ? IRQ_WAKE_THREAD : IRQ_HANDLED; |
744 | switch (action) { | ||
745 | case ADS7846_FILTER_REPEAT: | ||
746 | break; | ||
747 | case ADS7846_FILTER_IGNORE: | ||
748 | packet->tc.ignore = 1; | ||
749 | /* Last message will contain ads7846_rx() as the | ||
750 | * completion function. | ||
751 | */ | ||
752 | m = ts->last_msg; | ||
753 | break; | ||
754 | case ADS7846_FILTER_OK: | ||
755 | *(u16 *)t->rx_buf = val; | ||
756 | packet->tc.ignore = 0; | ||
757 | m = &ts->msg[++ts->msg_idx]; | ||
758 | break; | ||
759 | default: | ||
760 | BUG(); | ||
761 | } | ||
762 | ts->wait_for_sync(); | ||
763 | status = spi_async(ts->spi, m); | ||
764 | if (status) | ||
765 | dev_err(&ts->spi->dev, "spi_async --> %d\n", | ||
766 | status); | ||
767 | } | 859 | } |
768 | 860 | ||
769 | static enum hrtimer_restart ads7846_timer(struct hrtimer *handle) | ||
770 | { | ||
771 | struct ads7846 *ts = container_of(handle, struct ads7846, timer); | ||
772 | int status = 0; | ||
773 | |||
774 | spin_lock(&ts->lock); | ||
775 | |||
776 | if (unlikely(!get_pendown_state(ts) || | ||
777 | device_suspended(&ts->spi->dev))) { | ||
778 | if (ts->pendown) { | ||
779 | struct input_dev *input = ts->input; | ||
780 | |||
781 | input_report_key(input, BTN_TOUCH, 0); | ||
782 | input_report_abs(input, ABS_PRESSURE, 0); | ||
783 | input_sync(input); | ||
784 | |||
785 | ts->pendown = 0; | ||
786 | dev_vdbg(&ts->spi->dev, "UP\n"); | ||
787 | } | ||
788 | |||
789 | /* measurement cycle ended */ | ||
790 | if (!device_suspended(&ts->spi->dev)) { | ||
791 | ts->irq_disabled = 0; | ||
792 | enable_irq(ts->spi->irq); | ||
793 | } | ||
794 | ts->pending = 0; | ||
795 | } else { | ||
796 | /* pen is still down, continue with the measurement */ | ||
797 | ts->msg_idx = 0; | ||
798 | ts->wait_for_sync(); | ||
799 | status = spi_async(ts->spi, &ts->msg[0]); | ||
800 | if (status) | ||
801 | dev_err(&ts->spi->dev, "spi_async --> %d\n", status); | ||
802 | } | ||
803 | |||
804 | spin_unlock(&ts->lock); | ||
805 | return HRTIMER_NORESTART; | ||
806 | } | ||
807 | 861 | ||
808 | static irqreturn_t ads7846_irq(int irq, void *handle) | 862 | static irqreturn_t ads7846_irq(int irq, void *handle) |
809 | { | 863 | { |
810 | struct ads7846 *ts = handle; | 864 | struct ads7846 *ts = handle; |
811 | unsigned long flags; | ||
812 | |||
813 | spin_lock_irqsave(&ts->lock, flags); | ||
814 | if (likely(get_pendown_state(ts))) { | ||
815 | if (!ts->irq_disabled) { | ||
816 | /* The ARM do_simple_IRQ() dispatcher doesn't act | ||
817 | * like the other dispatchers: it will report IRQs | ||
818 | * even after they've been disabled. We work around | ||
819 | * that here. (The "generic irq" framework may help...) | ||
820 | */ | ||
821 | ts->irq_disabled = 1; | ||
822 | disable_irq_nosync(ts->spi->irq); | ||
823 | ts->pending = 1; | ||
824 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY), | ||
825 | HRTIMER_MODE_REL); | ||
826 | } | ||
827 | } | ||
828 | spin_unlock_irqrestore(&ts->lock, flags); | ||
829 | 865 | ||
830 | return IRQ_HANDLED; | 866 | /* Start with a small delay before checking pendown state */ |
831 | } | 867 | msleep(TS_POLL_DELAY); |
832 | 868 | ||
833 | /*--------------------------------------------------------------------------*/ | 869 | while (!ts->stopped && get_pendown_state(ts)) { |
834 | 870 | ||
835 | /* Must be called with ts->lock held */ | 871 | /* pen is down, continue with the measurement */ |
836 | static void ads7846_disable(struct ads7846 *ts) | 872 | ads7846_read_state(ts); |
837 | { | ||
838 | if (ts->disabled) | ||
839 | return; | ||
840 | 873 | ||
841 | ts->disabled = 1; | 874 | if (!ts->stopped) |
875 | ads7846_report_state(ts); | ||
842 | 876 | ||
843 | /* are we waiting for IRQ, or polling? */ | 877 | wait_event_timeout(ts->wait, ts->stopped, |
844 | if (!ts->pending) { | 878 | msecs_to_jiffies(TS_POLL_PERIOD)); |
845 | ts->irq_disabled = 1; | ||
846 | disable_irq(ts->spi->irq); | ||
847 | } else { | ||
848 | /* the timer will run at least once more, and | ||
849 | * leave everything in a clean state, IRQ disabled | ||
850 | */ | ||
851 | while (ts->pending) { | ||
852 | spin_unlock_irq(&ts->lock); | ||
853 | msleep(1); | ||
854 | spin_lock_irq(&ts->lock); | ||
855 | } | ||
856 | } | 879 | } |
857 | 880 | ||
858 | regulator_disable(ts->reg); | 881 | if (ts->pendown) { |
859 | 882 | struct input_dev *input = ts->input; | |
860 | /* we know the chip's in lowpower mode since we always | ||
861 | * leave it that way after every request | ||
862 | */ | ||
863 | } | ||
864 | 883 | ||
865 | /* Must be called with ts->lock held */ | 884 | input_report_key(input, BTN_TOUCH, 0); |
866 | static void ads7846_enable(struct ads7846 *ts) | 885 | input_report_abs(input, ABS_PRESSURE, 0); |
867 | { | 886 | input_sync(input); |
868 | if (!ts->disabled) | ||
869 | return; | ||
870 | 887 | ||
871 | regulator_enable(ts->reg); | 888 | ts->pendown = false; |
889 | dev_vdbg(&ts->spi->dev, "UP\n"); | ||
890 | } | ||
872 | 891 | ||
873 | ts->disabled = 0; | 892 | return IRQ_HANDLED; |
874 | ts->irq_disabled = 0; | ||
875 | enable_irq(ts->spi->irq); | ||
876 | } | 893 | } |
877 | 894 | ||
878 | static int ads7846_suspend(struct spi_device *spi, pm_message_t message) | 895 | static int ads7846_suspend(struct spi_device *spi, pm_message_t message) |
879 | { | 896 | { |
880 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | 897 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); |
881 | 898 | ||
882 | spin_lock_irq(&ts->lock); | 899 | mutex_lock(&ts->lock); |
883 | 900 | ||
884 | ts->is_suspended = 1; | 901 | if (!ts->suspended) { |
885 | ads7846_disable(ts); | ||
886 | 902 | ||
887 | spin_unlock_irq(&ts->lock); | 903 | if (!ts->disabled) |
904 | __ads7846_disable(ts); | ||
888 | 905 | ||
889 | if (device_may_wakeup(&ts->spi->dev)) | 906 | if (device_may_wakeup(&ts->spi->dev)) |
890 | enable_irq_wake(ts->spi->irq); | 907 | enable_irq_wake(ts->spi->irq); |
891 | 908 | ||
892 | return 0; | 909 | ts->suspended = true; |
910 | } | ||
911 | |||
912 | mutex_unlock(&ts->lock); | ||
893 | 913 | ||
914 | return 0; | ||
894 | } | 915 | } |
895 | 916 | ||
896 | static int ads7846_resume(struct spi_device *spi) | 917 | static int ads7846_resume(struct spi_device *spi) |
897 | { | 918 | { |
898 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | 919 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); |
899 | 920 | ||
900 | if (device_may_wakeup(&ts->spi->dev)) | 921 | mutex_lock(&ts->lock); |
901 | disable_irq_wake(ts->spi->irq); | 922 | |
923 | if (ts->suspended) { | ||
902 | 924 | ||
903 | spin_lock_irq(&ts->lock); | 925 | ts->suspended = false; |
904 | 926 | ||
905 | ts->is_suspended = 0; | 927 | if (device_may_wakeup(&ts->spi->dev)) |
906 | ads7846_enable(ts); | 928 | disable_irq_wake(ts->spi->irq); |
907 | 929 | ||
908 | spin_unlock_irq(&ts->lock); | 930 | if (!ts->disabled) |
931 | __ads7846_enable(ts); | ||
932 | } | ||
933 | |||
934 | mutex_unlock(&ts->lock); | ||
909 | 935 | ||
910 | return 0; | 936 | return 0; |
911 | } | 937 | } |
912 | 938 | ||
913 | static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts) | 939 | static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads7846 *ts) |
914 | { | 940 | { |
915 | struct ads7846_platform_data *pdata = spi->dev.platform_data; | 941 | struct ads7846_platform_data *pdata = spi->dev.platform_data; |
916 | int err; | 942 | int err; |
@@ -932,146 +958,40 @@ static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts) | |||
932 | err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); | 958 | err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); |
933 | if (err) { | 959 | if (err) { |
934 | dev_err(&spi->dev, "failed to request pendown GPIO%d\n", | 960 | dev_err(&spi->dev, "failed to request pendown GPIO%d\n", |
935 | pdata->gpio_pendown); | 961 | pdata->gpio_pendown); |
936 | return err; | 962 | return err; |
937 | } | 963 | } |
938 | 964 | ||
939 | ts->gpio_pendown = pdata->gpio_pendown; | 965 | ts->gpio_pendown = pdata->gpio_pendown; |
966 | |||
940 | return 0; | 967 | return 0; |
941 | } | 968 | } |
942 | 969 | ||
943 | static int __devinit ads7846_probe(struct spi_device *spi) | 970 | /* |
971 | * Set up the transfers to read touchscreen state; this assumes we | ||
972 | * use formula #2 for pressure, not #3. | ||
973 | */ | ||
974 | static void __devinit ads7846_setup_spi_msg(struct ads7846 *ts, | ||
975 | const struct ads7846_platform_data *pdata) | ||
944 | { | 976 | { |
945 | struct ads7846 *ts; | 977 | struct spi_message *m = &ts->msg[0]; |
946 | struct ads7846_packet *packet; | 978 | struct spi_transfer *x = ts->xfer; |
947 | struct input_dev *input_dev; | 979 | struct ads7846_packet *packet = ts->packet; |
948 | const struct ads7846_platform_data *pdata = spi->dev.platform_data; | 980 | int vref = pdata->keep_vref_on; |
949 | struct spi_message *m; | ||
950 | struct spi_transfer *x; | ||
951 | unsigned long irq_flags; | ||
952 | int vref; | ||
953 | int err; | ||
954 | |||
955 | if (!spi->irq) { | ||
956 | dev_dbg(&spi->dev, "no IRQ?\n"); | ||
957 | return -ENODEV; | ||
958 | } | ||
959 | |||
960 | if (!pdata) { | ||
961 | dev_dbg(&spi->dev, "no platform data?\n"); | ||
962 | return -ENODEV; | ||
963 | } | ||
964 | |||
965 | /* don't exceed max specified sample rate */ | ||
966 | if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) { | ||
967 | dev_dbg(&spi->dev, "f(sample) %d KHz?\n", | ||
968 | (spi->max_speed_hz/SAMPLE_BITS)/1000); | ||
969 | return -EINVAL; | ||
970 | } | ||
971 | |||
972 | /* We'd set TX wordsize 8 bits and RX wordsize to 13 bits ... except | ||
973 | * that even if the hardware can do that, the SPI controller driver | ||
974 | * may not. So we stick to very-portable 8 bit words, both RX and TX. | ||
975 | */ | ||
976 | spi->bits_per_word = 8; | ||
977 | spi->mode = SPI_MODE_0; | ||
978 | err = spi_setup(spi); | ||
979 | if (err < 0) | ||
980 | return err; | ||
981 | |||
982 | ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); | ||
983 | packet = kzalloc(sizeof(struct ads7846_packet), GFP_KERNEL); | ||
984 | input_dev = input_allocate_device(); | ||
985 | if (!ts || !packet || !input_dev) { | ||
986 | err = -ENOMEM; | ||
987 | goto err_free_mem; | ||
988 | } | ||
989 | |||
990 | dev_set_drvdata(&spi->dev, ts); | ||
991 | |||
992 | ts->packet = packet; | ||
993 | ts->spi = spi; | ||
994 | ts->input = input_dev; | ||
995 | ts->vref_mv = pdata->vref_mv; | ||
996 | ts->swap_xy = pdata->swap_xy; | ||
997 | |||
998 | hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
999 | ts->timer.function = ads7846_timer; | ||
1000 | |||
1001 | spin_lock_init(&ts->lock); | ||
1002 | |||
1003 | ts->model = pdata->model ? : 7846; | ||
1004 | ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; | ||
1005 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; | ||
1006 | ts->pressure_max = pdata->pressure_max ? : ~0; | ||
1007 | |||
1008 | if (pdata->filter != NULL) { | ||
1009 | if (pdata->filter_init != NULL) { | ||
1010 | err = pdata->filter_init(pdata, &ts->filter_data); | ||
1011 | if (err < 0) | ||
1012 | goto err_free_mem; | ||
1013 | } | ||
1014 | ts->filter = pdata->filter; | ||
1015 | ts->filter_cleanup = pdata->filter_cleanup; | ||
1016 | } else if (pdata->debounce_max) { | ||
1017 | ts->debounce_max = pdata->debounce_max; | ||
1018 | if (ts->debounce_max < 2) | ||
1019 | ts->debounce_max = 2; | ||
1020 | ts->debounce_tol = pdata->debounce_tol; | ||
1021 | ts->debounce_rep = pdata->debounce_rep; | ||
1022 | ts->filter = ads7846_debounce; | ||
1023 | ts->filter_data = ts; | ||
1024 | } else | ||
1025 | ts->filter = ads7846_no_filter; | ||
1026 | |||
1027 | err = setup_pendown(spi, ts); | ||
1028 | if (err) | ||
1029 | goto err_cleanup_filter; | ||
1030 | |||
1031 | if (pdata->penirq_recheck_delay_usecs) | ||
1032 | ts->penirq_recheck_delay_usecs = | ||
1033 | pdata->penirq_recheck_delay_usecs; | ||
1034 | |||
1035 | ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync; | ||
1036 | |||
1037 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev)); | ||
1038 | snprintf(ts->name, sizeof(ts->name), "ADS%d Touchscreen", ts->model); | ||
1039 | |||
1040 | input_dev->name = ts->name; | ||
1041 | input_dev->phys = ts->phys; | ||
1042 | input_dev->dev.parent = &spi->dev; | ||
1043 | |||
1044 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
1045 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
1046 | input_set_abs_params(input_dev, ABS_X, | ||
1047 | pdata->x_min ? : 0, | ||
1048 | pdata->x_max ? : MAX_12BIT, | ||
1049 | 0, 0); | ||
1050 | input_set_abs_params(input_dev, ABS_Y, | ||
1051 | pdata->y_min ? : 0, | ||
1052 | pdata->y_max ? : MAX_12BIT, | ||
1053 | 0, 0); | ||
1054 | input_set_abs_params(input_dev, ABS_PRESSURE, | ||
1055 | pdata->pressure_min, pdata->pressure_max, 0, 0); | ||
1056 | |||
1057 | vref = pdata->keep_vref_on; | ||
1058 | 981 | ||
1059 | if (ts->model == 7873) { | 982 | if (ts->model == 7873) { |
1060 | /* The AD7873 is almost identical to the ADS7846 | 983 | /* |
984 | * The AD7873 is almost identical to the ADS7846 | ||
1061 | * keep VREF off during differential/ratiometric | 985 | * keep VREF off during differential/ratiometric |
1062 | * conversion modes | 986 | * conversion modes. |
1063 | */ | 987 | */ |
1064 | ts->model = 7846; | 988 | ts->model = 7846; |
1065 | vref = 0; | 989 | vref = 0; |
1066 | } | 990 | } |
1067 | 991 | ||
1068 | /* set up the transfers to read touchscreen state; this assumes we | 992 | ts->msg_count = 1; |
1069 | * use formula #2 for pressure, not #3. | ||
1070 | */ | ||
1071 | m = &ts->msg[0]; | ||
1072 | x = ts->xfer; | ||
1073 | |||
1074 | spi_message_init(m); | 993 | spi_message_init(m); |
994 | m->context = ts; | ||
1075 | 995 | ||
1076 | if (ts->model == 7845) { | 996 | if (ts->model == 7845) { |
1077 | packet->read_y_cmd[0] = READ_Y(vref); | 997 | packet->read_y_cmd[0] = READ_Y(vref); |
@@ -1094,7 +1014,8 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1094 | spi_message_add_tail(x, m); | 1014 | spi_message_add_tail(x, m); |
1095 | } | 1015 | } |
1096 | 1016 | ||
1097 | /* the first sample after switching drivers can be low quality; | 1017 | /* |
1018 | * The first sample after switching drivers can be low quality; | ||
1098 | * optionally discard it, using a second one after the signals | 1019 | * optionally discard it, using a second one after the signals |
1099 | * have had enough time to stabilize. | 1020 | * have had enough time to stabilize. |
1100 | */ | 1021 | */ |
@@ -1112,11 +1033,10 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1112 | spi_message_add_tail(x, m); | 1033 | spi_message_add_tail(x, m); |
1113 | } | 1034 | } |
1114 | 1035 | ||
1115 | m->complete = ads7846_rx_val; | 1036 | ts->msg_count++; |
1116 | m->context = ts; | ||
1117 | |||
1118 | m++; | 1037 | m++; |
1119 | spi_message_init(m); | 1038 | spi_message_init(m); |
1039 | m->context = ts; | ||
1120 | 1040 | ||
1121 | if (ts->model == 7845) { | 1041 | if (ts->model == 7845) { |
1122 | x++; | 1042 | x++; |
@@ -1156,13 +1076,12 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1156 | spi_message_add_tail(x, m); | 1076 | spi_message_add_tail(x, m); |
1157 | } | 1077 | } |
1158 | 1078 | ||
1159 | m->complete = ads7846_rx_val; | ||
1160 | m->context = ts; | ||
1161 | |||
1162 | /* turn y+ off, x- on; we'll use formula #2 */ | 1079 | /* turn y+ off, x- on; we'll use formula #2 */ |
1163 | if (ts->model == 7846) { | 1080 | if (ts->model == 7846) { |
1081 | ts->msg_count++; | ||
1164 | m++; | 1082 | m++; |
1165 | spi_message_init(m); | 1083 | spi_message_init(m); |
1084 | m->context = ts; | ||
1166 | 1085 | ||
1167 | x++; | 1086 | x++; |
1168 | packet->read_z1 = READ_Z1(vref); | 1087 | packet->read_z1 = READ_Z1(vref); |
@@ -1190,11 +1109,10 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1190 | spi_message_add_tail(x, m); | 1109 | spi_message_add_tail(x, m); |
1191 | } | 1110 | } |
1192 | 1111 | ||
1193 | m->complete = ads7846_rx_val; | 1112 | ts->msg_count++; |
1194 | m->context = ts; | ||
1195 | |||
1196 | m++; | 1113 | m++; |
1197 | spi_message_init(m); | 1114 | spi_message_init(m); |
1115 | m->context = ts; | ||
1198 | 1116 | ||
1199 | x++; | 1117 | x++; |
1200 | packet->read_z2 = READ_Z2(vref); | 1118 | packet->read_z2 = READ_Z2(vref); |
@@ -1221,14 +1139,13 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1221 | x->len = 2; | 1139 | x->len = 2; |
1222 | spi_message_add_tail(x, m); | 1140 | spi_message_add_tail(x, m); |
1223 | } | 1141 | } |
1224 | |||
1225 | m->complete = ads7846_rx_val; | ||
1226 | m->context = ts; | ||
1227 | } | 1142 | } |
1228 | 1143 | ||
1229 | /* power down */ | 1144 | /* power down */ |
1145 | ts->msg_count++; | ||
1230 | m++; | 1146 | m++; |
1231 | spi_message_init(m); | 1147 | spi_message_init(m); |
1148 | m->context = ts; | ||
1232 | 1149 | ||
1233 | if (ts->model == 7845) { | 1150 | if (ts->model == 7845) { |
1234 | x++; | 1151 | x++; |
@@ -1251,11 +1168,119 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1251 | 1168 | ||
1252 | CS_CHANGE(*x); | 1169 | CS_CHANGE(*x); |
1253 | spi_message_add_tail(x, m); | 1170 | spi_message_add_tail(x, m); |
1171 | } | ||
1254 | 1172 | ||
1255 | m->complete = ads7846_rx; | 1173 | static int __devinit ads7846_probe(struct spi_device *spi) |
1256 | m->context = ts; | 1174 | { |
1175 | struct ads7846 *ts; | ||
1176 | struct ads7846_packet *packet; | ||
1177 | struct input_dev *input_dev; | ||
1178 | struct ads7846_platform_data *pdata = spi->dev.platform_data; | ||
1179 | unsigned long irq_flags; | ||
1180 | int err; | ||
1181 | |||
1182 | if (!spi->irq) { | ||
1183 | dev_dbg(&spi->dev, "no IRQ?\n"); | ||
1184 | return -ENODEV; | ||
1185 | } | ||
1186 | |||
1187 | if (!pdata) { | ||
1188 | dev_dbg(&spi->dev, "no platform data?\n"); | ||
1189 | return -ENODEV; | ||
1190 | } | ||
1191 | |||
1192 | /* don't exceed max specified sample rate */ | ||
1193 | if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) { | ||
1194 | dev_dbg(&spi->dev, "f(sample) %d KHz?\n", | ||
1195 | (spi->max_speed_hz/SAMPLE_BITS)/1000); | ||
1196 | return -EINVAL; | ||
1197 | } | ||
1198 | |||
1199 | /* We'd set TX word size 8 bits and RX word size to 13 bits ... except | ||
1200 | * that even if the hardware can do that, the SPI controller driver | ||
1201 | * may not. So we stick to very-portable 8 bit words, both RX and TX. | ||
1202 | */ | ||
1203 | spi->bits_per_word = 8; | ||
1204 | spi->mode = SPI_MODE_0; | ||
1205 | err = spi_setup(spi); | ||
1206 | if (err < 0) | ||
1207 | return err; | ||
1257 | 1208 | ||
1258 | ts->last_msg = m; | 1209 | ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); |
1210 | packet = kzalloc(sizeof(struct ads7846_packet), GFP_KERNEL); | ||
1211 | input_dev = input_allocate_device(); | ||
1212 | if (!ts || !packet || !input_dev) { | ||
1213 | err = -ENOMEM; | ||
1214 | goto err_free_mem; | ||
1215 | } | ||
1216 | |||
1217 | dev_set_drvdata(&spi->dev, ts); | ||
1218 | |||
1219 | ts->packet = packet; | ||
1220 | ts->spi = spi; | ||
1221 | ts->input = input_dev; | ||
1222 | ts->vref_mv = pdata->vref_mv; | ||
1223 | ts->swap_xy = pdata->swap_xy; | ||
1224 | |||
1225 | mutex_init(&ts->lock); | ||
1226 | init_waitqueue_head(&ts->wait); | ||
1227 | |||
1228 | ts->model = pdata->model ? : 7846; | ||
1229 | ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; | ||
1230 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; | ||
1231 | ts->pressure_max = pdata->pressure_max ? : ~0; | ||
1232 | |||
1233 | if (pdata->filter != NULL) { | ||
1234 | if (pdata->filter_init != NULL) { | ||
1235 | err = pdata->filter_init(pdata, &ts->filter_data); | ||
1236 | if (err < 0) | ||
1237 | goto err_free_mem; | ||
1238 | } | ||
1239 | ts->filter = pdata->filter; | ||
1240 | ts->filter_cleanup = pdata->filter_cleanup; | ||
1241 | } else if (pdata->debounce_max) { | ||
1242 | ts->debounce_max = pdata->debounce_max; | ||
1243 | if (ts->debounce_max < 2) | ||
1244 | ts->debounce_max = 2; | ||
1245 | ts->debounce_tol = pdata->debounce_tol; | ||
1246 | ts->debounce_rep = pdata->debounce_rep; | ||
1247 | ts->filter = ads7846_debounce_filter; | ||
1248 | ts->filter_data = ts; | ||
1249 | } else { | ||
1250 | ts->filter = ads7846_no_filter; | ||
1251 | } | ||
1252 | |||
1253 | err = ads7846_setup_pendown(spi, ts); | ||
1254 | if (err) | ||
1255 | goto err_cleanup_filter; | ||
1256 | |||
1257 | if (pdata->penirq_recheck_delay_usecs) | ||
1258 | ts->penirq_recheck_delay_usecs = | ||
1259 | pdata->penirq_recheck_delay_usecs; | ||
1260 | |||
1261 | ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync; | ||
1262 | |||
1263 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev)); | ||
1264 | snprintf(ts->name, sizeof(ts->name), "ADS%d Touchscreen", ts->model); | ||
1265 | |||
1266 | input_dev->name = ts->name; | ||
1267 | input_dev->phys = ts->phys; | ||
1268 | input_dev->dev.parent = &spi->dev; | ||
1269 | |||
1270 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
1271 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
1272 | input_set_abs_params(input_dev, ABS_X, | ||
1273 | pdata->x_min ? : 0, | ||
1274 | pdata->x_max ? : MAX_12BIT, | ||
1275 | 0, 0); | ||
1276 | input_set_abs_params(input_dev, ABS_Y, | ||
1277 | pdata->y_min ? : 0, | ||
1278 | pdata->y_max ? : MAX_12BIT, | ||
1279 | 0, 0); | ||
1280 | input_set_abs_params(input_dev, ABS_PRESSURE, | ||
1281 | pdata->pressure_min, pdata->pressure_max, 0, 0); | ||
1282 | |||
1283 | ads7846_setup_spi_msg(ts, pdata); | ||
1259 | 1284 | ||
1260 | ts->reg = regulator_get(&spi->dev, "vcc"); | 1285 | ts->reg = regulator_get(&spi->dev, "vcc"); |
1261 | if (IS_ERR(ts->reg)) { | 1286 | if (IS_ERR(ts->reg)) { |
@@ -1271,16 +1296,17 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1271 | } | 1296 | } |
1272 | 1297 | ||
1273 | irq_flags = pdata->irq_flags ? : IRQF_TRIGGER_FALLING; | 1298 | irq_flags = pdata->irq_flags ? : IRQF_TRIGGER_FALLING; |
1299 | irq_flags |= IRQF_ONESHOT; | ||
1274 | 1300 | ||
1275 | err = request_irq(spi->irq, ads7846_irq, irq_flags, | 1301 | err = request_threaded_irq(spi->irq, ads7846_hard_irq, ads7846_irq, |
1276 | spi->dev.driver->name, ts); | 1302 | irq_flags, spi->dev.driver->name, ts); |
1277 | |||
1278 | if (err && !pdata->irq_flags) { | 1303 | if (err && !pdata->irq_flags) { |
1279 | dev_info(&spi->dev, | 1304 | dev_info(&spi->dev, |
1280 | "trying pin change workaround on irq %d\n", spi->irq); | 1305 | "trying pin change workaround on irq %d\n", spi->irq); |
1281 | err = request_irq(spi->irq, ads7846_irq, | 1306 | irq_flags |= IRQF_TRIGGER_RISING; |
1282 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | 1307 | err = request_threaded_irq(spi->irq, |
1283 | spi->dev.driver->name, ts); | 1308 | ads7846_hard_irq, ads7846_irq, |
1309 | irq_flags, spi->dev.driver->name, ts); | ||
1284 | } | 1310 | } |
1285 | 1311 | ||
1286 | if (err) { | 1312 | if (err) { |
@@ -1294,7 +1320,8 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1294 | 1320 | ||
1295 | dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); | 1321 | dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); |
1296 | 1322 | ||
1297 | /* take a first sample, leaving nPENIRQ active and vREF off; avoid | 1323 | /* |
1324 | * Take a first sample, leaving nPENIRQ active and vREF off; avoid | ||
1298 | * the touchscreen, in case it's not connected. | 1325 | * the touchscreen, in case it's not connected. |
1299 | */ | 1326 | */ |
1300 | if (ts->model == 7845) | 1327 | if (ts->model == 7845) |
@@ -1340,20 +1367,18 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1340 | 1367 | ||
1341 | static int __devexit ads7846_remove(struct spi_device *spi) | 1368 | static int __devexit ads7846_remove(struct spi_device *spi) |
1342 | { | 1369 | { |
1343 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | 1370 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); |
1344 | 1371 | ||
1345 | device_init_wakeup(&spi->dev, false); | 1372 | device_init_wakeup(&spi->dev, false); |
1346 | 1373 | ||
1347 | ads784x_hwmon_unregister(spi, ts); | ||
1348 | input_unregister_device(ts->input); | ||
1349 | |||
1350 | ads7846_suspend(spi, PMSG_SUSPEND); | ||
1351 | |||
1352 | sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group); | 1374 | sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group); |
1353 | 1375 | ||
1376 | ads7846_disable(ts); | ||
1354 | free_irq(ts->spi->irq, ts); | 1377 | free_irq(ts->spi->irq, ts); |
1355 | /* suspend left the IRQ disabled */ | 1378 | |
1356 | enable_irq(ts->spi->irq); | 1379 | input_unregister_device(ts->input); |
1380 | |||
1381 | ads784x_hwmon_unregister(spi, ts); | ||
1357 | 1382 | ||
1358 | regulator_disable(ts->reg); | 1383 | regulator_disable(ts->reg); |
1359 | regulator_put(ts->reg); | 1384 | regulator_put(ts->reg); |
@@ -1368,6 +1393,7 @@ static int __devexit ads7846_remove(struct spi_device *spi) | |||
1368 | kfree(ts); | 1393 | kfree(ts); |
1369 | 1394 | ||
1370 | dev_dbg(&spi->dev, "unregistered touchscreen\n"); | 1395 | dev_dbg(&spi->dev, "unregistered touchscreen\n"); |
1396 | |||
1371 | return 0; | 1397 | return 0; |
1372 | } | 1398 | } |
1373 | 1399 | ||
diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c new file mode 100644 index 000000000000..ccde58602563 --- /dev/null +++ b/drivers/input/touchscreen/bu21013_ts.c | |||
@@ -0,0 +1,648 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * Author: Naveen Kumar G <naveen.gaddipati@stericsson.com> for ST-Ericsson | ||
4 | * License terms:GNU General Public License (GPL) version 2 | ||
5 | */ | ||
6 | |||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/delay.h> | ||
9 | #include <linux/interrupt.h> | ||
10 | #include <linux/i2c.h> | ||
11 | #include <linux/workqueue.h> | ||
12 | #include <linux/input.h> | ||
13 | #include <linux/input/bu21013.h> | ||
14 | #include <linux/slab.h> | ||
15 | |||
16 | #define PEN_DOWN_INTR 0 | ||
17 | #define MAX_FINGERS 2 | ||
18 | #define RESET_DELAY 30 | ||
19 | #define PENUP_TIMEOUT (10) | ||
20 | #define DELTA_MIN 16 | ||
21 | #define MASK_BITS 0x03 | ||
22 | #define SHIFT_8 8 | ||
23 | #define SHIFT_2 2 | ||
24 | #define LENGTH_OF_BUFFER 11 | ||
25 | #define I2C_RETRY_COUNT 5 | ||
26 | |||
27 | #define BU21013_SENSORS_BTN_0_7_REG 0x70 | ||
28 | #define BU21013_SENSORS_BTN_8_15_REG 0x71 | ||
29 | #define BU21013_SENSORS_BTN_16_23_REG 0x72 | ||
30 | #define BU21013_X1_POS_MSB_REG 0x73 | ||
31 | #define BU21013_X1_POS_LSB_REG 0x74 | ||
32 | #define BU21013_Y1_POS_MSB_REG 0x75 | ||
33 | #define BU21013_Y1_POS_LSB_REG 0x76 | ||
34 | #define BU21013_X2_POS_MSB_REG 0x77 | ||
35 | #define BU21013_X2_POS_LSB_REG 0x78 | ||
36 | #define BU21013_Y2_POS_MSB_REG 0x79 | ||
37 | #define BU21013_Y2_POS_LSB_REG 0x7A | ||
38 | #define BU21013_INT_CLR_REG 0xE8 | ||
39 | #define BU21013_INT_MODE_REG 0xE9 | ||
40 | #define BU21013_GAIN_REG 0xEA | ||
41 | #define BU21013_OFFSET_MODE_REG 0xEB | ||
42 | #define BU21013_XY_EDGE_REG 0xEC | ||
43 | #define BU21013_RESET_REG 0xED | ||
44 | #define BU21013_CALIB_REG 0xEE | ||
45 | #define BU21013_DONE_REG 0xEF | ||
46 | #define BU21013_SENSOR_0_7_REG 0xF0 | ||
47 | #define BU21013_SENSOR_8_15_REG 0xF1 | ||
48 | #define BU21013_SENSOR_16_23_REG 0xF2 | ||
49 | #define BU21013_POS_MODE1_REG 0xF3 | ||
50 | #define BU21013_POS_MODE2_REG 0xF4 | ||
51 | #define BU21013_CLK_MODE_REG 0xF5 | ||
52 | #define BU21013_IDLE_REG 0xFA | ||
53 | #define BU21013_FILTER_REG 0xFB | ||
54 | #define BU21013_TH_ON_REG 0xFC | ||
55 | #define BU21013_TH_OFF_REG 0xFD | ||
56 | |||
57 | |||
58 | #define BU21013_RESET_ENABLE 0x01 | ||
59 | |||
60 | #define BU21013_SENSORS_EN_0_7 0x3F | ||
61 | #define BU21013_SENSORS_EN_8_15 0xFC | ||
62 | #define BU21013_SENSORS_EN_16_23 0x1F | ||
63 | |||
64 | #define BU21013_POS_MODE1_0 0x02 | ||
65 | #define BU21013_POS_MODE1_1 0x04 | ||
66 | #define BU21013_POS_MODE1_2 0x08 | ||
67 | |||
68 | #define BU21013_POS_MODE2_ZERO 0x01 | ||
69 | #define BU21013_POS_MODE2_AVG1 0x02 | ||
70 | #define BU21013_POS_MODE2_AVG2 0x04 | ||
71 | #define BU21013_POS_MODE2_EN_XY 0x08 | ||
72 | #define BU21013_POS_MODE2_EN_RAW 0x10 | ||
73 | #define BU21013_POS_MODE2_MULTI 0x80 | ||
74 | |||
75 | #define BU21013_CLK_MODE_DIV 0x01 | ||
76 | #define BU21013_CLK_MODE_EXT 0x02 | ||
77 | #define BU21013_CLK_MODE_CALIB 0x80 | ||
78 | |||
79 | #define BU21013_IDLET_0 0x01 | ||
80 | #define BU21013_IDLET_1 0x02 | ||
81 | #define BU21013_IDLET_2 0x04 | ||
82 | #define BU21013_IDLET_3 0x08 | ||
83 | #define BU21013_IDLE_INTERMIT_EN 0x10 | ||
84 | |||
85 | #define BU21013_DELTA_0_6 0x7F | ||
86 | #define BU21013_FILTER_EN 0x80 | ||
87 | |||
88 | #define BU21013_INT_MODE_LEVEL 0x00 | ||
89 | #define BU21013_INT_MODE_EDGE 0x01 | ||
90 | |||
91 | #define BU21013_GAIN_0 0x01 | ||
92 | #define BU21013_GAIN_1 0x02 | ||
93 | #define BU21013_GAIN_2 0x04 | ||
94 | |||
95 | #define BU21013_OFFSET_MODE_DEFAULT 0x00 | ||
96 | #define BU21013_OFFSET_MODE_MOVE 0x01 | ||
97 | #define BU21013_OFFSET_MODE_DISABLE 0x02 | ||
98 | |||
99 | #define BU21013_TH_ON_0 0x01 | ||
100 | #define BU21013_TH_ON_1 0x02 | ||
101 | #define BU21013_TH_ON_2 0x04 | ||
102 | #define BU21013_TH_ON_3 0x08 | ||
103 | #define BU21013_TH_ON_4 0x10 | ||
104 | #define BU21013_TH_ON_5 0x20 | ||
105 | #define BU21013_TH_ON_6 0x40 | ||
106 | #define BU21013_TH_ON_7 0x80 | ||
107 | #define BU21013_TH_ON_MAX 0xFF | ||
108 | |||
109 | #define BU21013_TH_OFF_0 0x01 | ||
110 | #define BU21013_TH_OFF_1 0x02 | ||
111 | #define BU21013_TH_OFF_2 0x04 | ||
112 | #define BU21013_TH_OFF_3 0x08 | ||
113 | #define BU21013_TH_OFF_4 0x10 | ||
114 | #define BU21013_TH_OFF_5 0x20 | ||
115 | #define BU21013_TH_OFF_6 0x40 | ||
116 | #define BU21013_TH_OFF_7 0x80 | ||
117 | #define BU21013_TH_OFF_MAX 0xFF | ||
118 | |||
119 | #define BU21013_X_EDGE_0 0x01 | ||
120 | #define BU21013_X_EDGE_1 0x02 | ||
121 | #define BU21013_X_EDGE_2 0x04 | ||
122 | #define BU21013_X_EDGE_3 0x08 | ||
123 | #define BU21013_Y_EDGE_0 0x10 | ||
124 | #define BU21013_Y_EDGE_1 0x20 | ||
125 | #define BU21013_Y_EDGE_2 0x40 | ||
126 | #define BU21013_Y_EDGE_3 0x80 | ||
127 | |||
128 | #define BU21013_DONE 0x01 | ||
129 | #define BU21013_NUMBER_OF_X_SENSORS (6) | ||
130 | #define BU21013_NUMBER_OF_Y_SENSORS (11) | ||
131 | |||
132 | #define DRIVER_TP "bu21013_tp" | ||
133 | |||
134 | /** | ||
135 | * struct bu21013_ts_data - touch panel data structure | ||
136 | * @client: pointer to the i2c client | ||
137 | * @wait: variable to wait_queue_head_t structure | ||
138 | * @touch_stopped: touch stop flag | ||
139 | * @chip: pointer to the touch panel controller | ||
140 | * @in_dev: pointer to the input device structure | ||
141 | * @intr_pin: interrupt pin value | ||
142 | * | ||
143 | * Touch panel device data structure | ||
144 | */ | ||
145 | struct bu21013_ts_data { | ||
146 | struct i2c_client *client; | ||
147 | wait_queue_head_t wait; | ||
148 | bool touch_stopped; | ||
149 | const struct bu21013_platform_device *chip; | ||
150 | struct input_dev *in_dev; | ||
151 | unsigned int intr_pin; | ||
152 | }; | ||
153 | |||
154 | /** | ||
155 | * bu21013_read_block_data(): read the touch co-ordinates | ||
156 | * @data: bu21013_ts_data structure pointer | ||
157 | * @buf: byte pointer | ||
158 | * | ||
159 | * Read the touch co-ordinates using i2c read block into buffer | ||
160 | * and returns integer. | ||
161 | */ | ||
162 | static int bu21013_read_block_data(struct bu21013_ts_data *data, u8 *buf) | ||
163 | { | ||
164 | int ret, i; | ||
165 | |||
166 | for (i = 0; i < I2C_RETRY_COUNT; i++) { | ||
167 | ret = i2c_smbus_read_i2c_block_data | ||
168 | (data->client, BU21013_SENSORS_BTN_0_7_REG, | ||
169 | LENGTH_OF_BUFFER, buf); | ||
170 | if (ret == LENGTH_OF_BUFFER) | ||
171 | return 0; | ||
172 | } | ||
173 | return -EINVAL; | ||
174 | } | ||
175 | |||
176 | /** | ||
177 | * bu21013_do_touch_report(): Get the touch co-ordinates | ||
178 | * @data: bu21013_ts_data structure pointer | ||
179 | * | ||
180 | * Get the touch co-ordinates from touch sensor registers and writes | ||
181 | * into device structure and returns integer. | ||
182 | */ | ||
183 | static int bu21013_do_touch_report(struct bu21013_ts_data *data) | ||
184 | { | ||
185 | u8 buf[LENGTH_OF_BUFFER]; | ||
186 | unsigned int pos_x[2], pos_y[2]; | ||
187 | bool has_x_sensors, has_y_sensors; | ||
188 | int finger_down_count = 0; | ||
189 | int i; | ||
190 | |||
191 | if (data == NULL) | ||
192 | return -EINVAL; | ||
193 | |||
194 | if (bu21013_read_block_data(data, buf) < 0) | ||
195 | return -EINVAL; | ||
196 | |||
197 | has_x_sensors = hweight32(buf[0] & BU21013_SENSORS_EN_0_7); | ||
198 | has_y_sensors = hweight32(((buf[1] & BU21013_SENSORS_EN_8_15) | | ||
199 | ((buf[2] & BU21013_SENSORS_EN_16_23) << SHIFT_8)) >> SHIFT_2); | ||
200 | if (!has_x_sensors || !has_y_sensors) | ||
201 | return 0; | ||
202 | |||
203 | for (i = 0; i < MAX_FINGERS; i++) { | ||
204 | const u8 *p = &buf[4 * i + 3]; | ||
205 | unsigned int x = p[0] << SHIFT_2 | (p[1] & MASK_BITS); | ||
206 | unsigned int y = p[2] << SHIFT_2 | (p[3] & MASK_BITS); | ||
207 | if (x == 0 || y == 0) | ||
208 | continue; | ||
209 | pos_x[finger_down_count] = x; | ||
210 | pos_y[finger_down_count] = y; | ||
211 | finger_down_count++; | ||
212 | } | ||
213 | |||
214 | if (finger_down_count) { | ||
215 | if (finger_down_count == 2 && | ||
216 | (abs(pos_x[0] - pos_x[1]) < DELTA_MIN || | ||
217 | abs(pos_y[0] - pos_y[1]) < DELTA_MIN)) { | ||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | for (i = 0; i < finger_down_count; i++) { | ||
222 | if (data->chip->x_flip) | ||
223 | pos_x[i] = data->chip->touch_x_max - pos_x[i]; | ||
224 | if (data->chip->y_flip) | ||
225 | pos_y[i] = data->chip->touch_y_max - pos_y[i]; | ||
226 | |||
227 | input_report_abs(data->in_dev, | ||
228 | ABS_MT_POSITION_X, pos_x[i]); | ||
229 | input_report_abs(data->in_dev, | ||
230 | ABS_MT_POSITION_Y, pos_y[i]); | ||
231 | input_mt_sync(data->in_dev); | ||
232 | } | ||
233 | } else | ||
234 | input_mt_sync(data->in_dev); | ||
235 | |||
236 | input_sync(data->in_dev); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | /** | ||
241 | * bu21013_gpio_irq() - gpio thread function for touch interrupt | ||
242 | * @irq: irq value | ||
243 | * @device_data: void pointer | ||
244 | * | ||
245 | * This gpio thread function for touch interrupt | ||
246 | * and returns irqreturn_t. | ||
247 | */ | ||
248 | static irqreturn_t bu21013_gpio_irq(int irq, void *device_data) | ||
249 | { | ||
250 | struct bu21013_ts_data *data = device_data; | ||
251 | struct i2c_client *i2c = data->client; | ||
252 | int retval; | ||
253 | |||
254 | do { | ||
255 | retval = bu21013_do_touch_report(data); | ||
256 | if (retval < 0) { | ||
257 | dev_err(&i2c->dev, "bu21013_do_touch_report failed\n"); | ||
258 | return IRQ_NONE; | ||
259 | } | ||
260 | |||
261 | data->intr_pin = data->chip->irq_read_val(); | ||
262 | if (data->intr_pin == PEN_DOWN_INTR) | ||
263 | wait_event_timeout(data->wait, data->touch_stopped, | ||
264 | msecs_to_jiffies(2)); | ||
265 | } while (!data->intr_pin && !data->touch_stopped); | ||
266 | |||
267 | return IRQ_HANDLED; | ||
268 | } | ||
269 | |||
270 | /** | ||
271 | * bu21013_init_chip() - power on sequence for the bu21013 controller | ||
272 | * @data: device structure pointer | ||
273 | * | ||
274 | * This function is used to power on | ||
275 | * the bu21013 controller and returns integer. | ||
276 | */ | ||
277 | static int bu21013_init_chip(struct bu21013_ts_data *data) | ||
278 | { | ||
279 | int retval; | ||
280 | struct i2c_client *i2c = data->client; | ||
281 | |||
282 | retval = i2c_smbus_write_byte_data(i2c, BU21013_RESET_REG, | ||
283 | BU21013_RESET_ENABLE); | ||
284 | if (retval < 0) { | ||
285 | dev_err(&i2c->dev, "BU21013_RESET reg write failed\n"); | ||
286 | return retval; | ||
287 | } | ||
288 | msleep(RESET_DELAY); | ||
289 | |||
290 | retval = i2c_smbus_write_byte_data(i2c, BU21013_SENSOR_0_7_REG, | ||
291 | BU21013_SENSORS_EN_0_7); | ||
292 | if (retval < 0) { | ||
293 | dev_err(&i2c->dev, "BU21013_SENSOR_0_7 reg write failed\n"); | ||
294 | return retval; | ||
295 | } | ||
296 | |||
297 | retval = i2c_smbus_write_byte_data(i2c, BU21013_SENSOR_8_15_REG, | ||
298 | BU21013_SENSORS_EN_8_15); | ||
299 | if (retval < 0) { | ||
300 | dev_err(&i2c->dev, "BU21013_SENSOR_8_15 reg write failed\n"); | ||
301 | return retval; | ||
302 | } | ||
303 | |||
304 | retval = i2c_smbus_write_byte_data(i2c, BU21013_SENSOR_16_23_REG, | ||
305 | BU21013_SENSORS_EN_16_23); | ||
306 | if (retval < 0) { | ||
307 | dev_err(&i2c->dev, "BU21013_SENSOR_16_23 reg write failed\n"); | ||
308 | return retval; | ||
309 | } | ||
310 | |||
311 | retval = i2c_smbus_write_byte_data(i2c, BU21013_POS_MODE1_REG, | ||
312 | (BU21013_POS_MODE1_0 | BU21013_POS_MODE1_1)); | ||
313 | if (retval < 0) { | ||
314 | dev_err(&i2c->dev, "BU21013_POS_MODE1 reg write failed\n"); | ||
315 | return retval; | ||
316 | } | ||
317 | |||
318 | retval = i2c_smbus_write_byte_data(i2c, BU21013_POS_MODE2_REG, | ||
319 | (BU21013_POS_MODE2_ZERO | BU21013_POS_MODE2_AVG1 | | ||
320 | BU21013_POS_MODE2_AVG2 | BU21013_POS_MODE2_EN_RAW | | ||
321 | BU21013_POS_MODE2_MULTI)); | ||
322 | if (retval < 0) { | ||
323 | dev_err(&i2c->dev, "BU21013_POS_MODE2 reg write failed\n"); | ||
324 | return retval; | ||
325 | } | ||
326 | |||
327 | if (data->chip->ext_clk) | ||
328 | retval = i2c_smbus_write_byte_data(i2c, BU21013_CLK_MODE_REG, | ||
329 | (BU21013_CLK_MODE_EXT | BU21013_CLK_MODE_CALIB)); | ||
330 | else | ||
331 | retval = i2c_smbus_write_byte_data(i2c, BU21013_CLK_MODE_REG, | ||
332 | (BU21013_CLK_MODE_DIV | BU21013_CLK_MODE_CALIB)); | ||
333 | if (retval < 0) { | ||
334 | dev_err(&i2c->dev, "BU21013_CLK_MODE reg write failed\n"); | ||
335 | return retval; | ||
336 | } | ||
337 | |||
338 | retval = i2c_smbus_write_byte_data(i2c, BU21013_IDLE_REG, | ||
339 | (BU21013_IDLET_0 | BU21013_IDLE_INTERMIT_EN)); | ||
340 | if (retval < 0) { | ||
341 | dev_err(&i2c->dev, "BU21013_IDLE reg write failed\n"); | ||
342 | return retval; | ||
343 | } | ||
344 | |||
345 | retval = i2c_smbus_write_byte_data(i2c, BU21013_INT_MODE_REG, | ||
346 | BU21013_INT_MODE_LEVEL); | ||
347 | if (retval < 0) { | ||
348 | dev_err(&i2c->dev, "BU21013_INT_MODE reg write failed\n"); | ||
349 | return retval; | ||
350 | } | ||
351 | |||
352 | retval = i2c_smbus_write_byte_data(i2c, BU21013_FILTER_REG, | ||
353 | (BU21013_DELTA_0_6 | | ||
354 | BU21013_FILTER_EN)); | ||
355 | if (retval < 0) { | ||
356 | dev_err(&i2c->dev, "BU21013_FILTER reg write failed\n"); | ||
357 | return retval; | ||
358 | } | ||
359 | |||
360 | retval = i2c_smbus_write_byte_data(i2c, BU21013_TH_ON_REG, | ||
361 | BU21013_TH_ON_5); | ||
362 | if (retval < 0) { | ||
363 | dev_err(&i2c->dev, "BU21013_TH_ON reg write failed\n"); | ||
364 | return retval; | ||
365 | } | ||
366 | |||
367 | retval = i2c_smbus_write_byte_data(i2c, BU21013_TH_OFF_REG, | ||
368 | BU21013_TH_OFF_4 || BU21013_TH_OFF_3); | ||
369 | if (retval < 0) { | ||
370 | dev_err(&i2c->dev, "BU21013_TH_OFF reg write failed\n"); | ||
371 | return retval; | ||
372 | } | ||
373 | |||
374 | retval = i2c_smbus_write_byte_data(i2c, BU21013_GAIN_REG, | ||
375 | (BU21013_GAIN_0 | BU21013_GAIN_1)); | ||
376 | if (retval < 0) { | ||
377 | dev_err(&i2c->dev, "BU21013_GAIN reg write failed\n"); | ||
378 | return retval; | ||
379 | } | ||
380 | |||
381 | retval = i2c_smbus_write_byte_data(i2c, BU21013_OFFSET_MODE_REG, | ||
382 | BU21013_OFFSET_MODE_DEFAULT); | ||
383 | if (retval < 0) { | ||
384 | dev_err(&i2c->dev, "BU21013_OFFSET_MODE reg write failed\n"); | ||
385 | return retval; | ||
386 | } | ||
387 | |||
388 | retval = i2c_smbus_write_byte_data(i2c, BU21013_XY_EDGE_REG, | ||
389 | (BU21013_X_EDGE_0 | BU21013_X_EDGE_2 | | ||
390 | BU21013_Y_EDGE_1 | BU21013_Y_EDGE_3)); | ||
391 | if (retval < 0) { | ||
392 | dev_err(&i2c->dev, "BU21013_XY_EDGE reg write failed\n"); | ||
393 | return retval; | ||
394 | } | ||
395 | |||
396 | retval = i2c_smbus_write_byte_data(i2c, BU21013_DONE_REG, | ||
397 | BU21013_DONE); | ||
398 | if (retval < 0) { | ||
399 | dev_err(&i2c->dev, "BU21013_REG_DONE reg write failed\n"); | ||
400 | return retval; | ||
401 | } | ||
402 | |||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | /** | ||
407 | * bu21013_free_irq() - frees IRQ registered for touchscreen | ||
408 | * @bu21013_data: device structure pointer | ||
409 | * | ||
410 | * This function signals interrupt thread to stop processing and | ||
411 | * frees interrupt. | ||
412 | */ | ||
413 | static void bu21013_free_irq(struct bu21013_ts_data *bu21013_data) | ||
414 | { | ||
415 | bu21013_data->touch_stopped = true; | ||
416 | wake_up(&bu21013_data->wait); | ||
417 | free_irq(bu21013_data->chip->irq, bu21013_data); | ||
418 | } | ||
419 | |||
420 | /** | ||
421 | * bu21013_probe() - initializes the i2c-client touchscreen driver | ||
422 | * @client: i2c client structure pointer | ||
423 | * @id: i2c device id pointer | ||
424 | * | ||
425 | * This function used to initializes the i2c-client touchscreen | ||
426 | * driver and returns integer. | ||
427 | */ | ||
428 | static int __devinit bu21013_probe(struct i2c_client *client, | ||
429 | const struct i2c_device_id *id) | ||
430 | { | ||
431 | struct bu21013_ts_data *bu21013_data; | ||
432 | struct input_dev *in_dev; | ||
433 | const struct bu21013_platform_device *pdata = | ||
434 | client->dev.platform_data; | ||
435 | int error; | ||
436 | |||
437 | if (!i2c_check_functionality(client->adapter, | ||
438 | I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
439 | dev_err(&client->dev, "i2c smbus byte data not supported\n"); | ||
440 | return -EIO; | ||
441 | } | ||
442 | |||
443 | if (!pdata) { | ||
444 | dev_err(&client->dev, "platform data not defined\n"); | ||
445 | return -EINVAL; | ||
446 | } | ||
447 | |||
448 | bu21013_data = kzalloc(sizeof(struct bu21013_ts_data), GFP_KERNEL); | ||
449 | in_dev = input_allocate_device(); | ||
450 | if (!bu21013_data || !in_dev) { | ||
451 | dev_err(&client->dev, "device memory alloc failed\n"); | ||
452 | error = -ENOMEM; | ||
453 | goto err_free_mem; | ||
454 | } | ||
455 | |||
456 | bu21013_data->in_dev = in_dev; | ||
457 | bu21013_data->chip = pdata; | ||
458 | bu21013_data->client = client; | ||
459 | bu21013_data->touch_stopped = false; | ||
460 | init_waitqueue_head(&bu21013_data->wait); | ||
461 | |||
462 | /* configure the gpio pins */ | ||
463 | if (pdata->cs_en) { | ||
464 | error = pdata->cs_en(pdata->cs_pin); | ||
465 | if (error < 0) { | ||
466 | dev_err(&client->dev, "chip init failed\n"); | ||
467 | goto err_free_mem; | ||
468 | } | ||
469 | } | ||
470 | |||
471 | /* configure the touch panel controller */ | ||
472 | error = bu21013_init_chip(bu21013_data); | ||
473 | if (error) { | ||
474 | dev_err(&client->dev, "error in bu21013 config\n"); | ||
475 | goto err_cs_disable; | ||
476 | } | ||
477 | |||
478 | /* register the device to input subsystem */ | ||
479 | in_dev->name = DRIVER_TP; | ||
480 | in_dev->id.bustype = BUS_I2C; | ||
481 | in_dev->dev.parent = &client->dev; | ||
482 | |||
483 | __set_bit(EV_SYN, in_dev->evbit); | ||
484 | __set_bit(EV_KEY, in_dev->evbit); | ||
485 | __set_bit(EV_ABS, in_dev->evbit); | ||
486 | |||
487 | input_set_abs_params(in_dev, ABS_MT_POSITION_X, 0, | ||
488 | pdata->x_max_res, 0, 0); | ||
489 | input_set_abs_params(in_dev, ABS_MT_POSITION_Y, 0, | ||
490 | pdata->y_max_res, 0, 0); | ||
491 | input_set_drvdata(in_dev, bu21013_data); | ||
492 | |||
493 | error = request_threaded_irq(pdata->irq, NULL, bu21013_gpio_irq, | ||
494 | IRQF_TRIGGER_FALLING | IRQF_SHARED, | ||
495 | DRIVER_TP, bu21013_data); | ||
496 | if (error) { | ||
497 | dev_err(&client->dev, "request irq %d failed\n", pdata->irq); | ||
498 | goto err_cs_disable; | ||
499 | } | ||
500 | |||
501 | error = input_register_device(in_dev); | ||
502 | if (error) { | ||
503 | dev_err(&client->dev, "failed to register input device\n"); | ||
504 | goto err_free_irq; | ||
505 | } | ||
506 | |||
507 | device_init_wakeup(&client->dev, pdata->wakeup); | ||
508 | i2c_set_clientdata(client, bu21013_data); | ||
509 | |||
510 | return 0; | ||
511 | |||
512 | err_free_irq: | ||
513 | bu21013_free_irq(bu21013_data); | ||
514 | err_cs_disable: | ||
515 | pdata->cs_dis(pdata->cs_pin); | ||
516 | err_free_mem: | ||
517 | input_free_device(bu21013_data->in_dev); | ||
518 | kfree(bu21013_data); | ||
519 | |||
520 | return error; | ||
521 | } | ||
522 | /** | ||
523 | * bu21013_remove() - removes the i2c-client touchscreen driver | ||
524 | * @client: i2c client structure pointer | ||
525 | * | ||
526 | * This function uses to remove the i2c-client | ||
527 | * touchscreen driver and returns integer. | ||
528 | */ | ||
529 | static int __devexit bu21013_remove(struct i2c_client *client) | ||
530 | { | ||
531 | struct bu21013_ts_data *bu21013_data = i2c_get_clientdata(client); | ||
532 | |||
533 | bu21013_free_irq(bu21013_data); | ||
534 | |||
535 | bu21013_data->chip->cs_dis(bu21013_data->chip->cs_pin); | ||
536 | |||
537 | input_unregister_device(bu21013_data->in_dev); | ||
538 | kfree(bu21013_data); | ||
539 | |||
540 | device_init_wakeup(&client->dev, false); | ||
541 | |||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | #ifdef CONFIG_PM | ||
546 | /** | ||
547 | * bu21013_suspend() - suspend the touch screen controller | ||
548 | * @dev: pointer to device structure | ||
549 | * | ||
550 | * This function is used to suspend the | ||
551 | * touch panel controller and returns integer | ||
552 | */ | ||
553 | static int bu21013_suspend(struct device *dev) | ||
554 | { | ||
555 | struct bu21013_ts_data *bu21013_data = dev_get_drvdata(dev); | ||
556 | struct i2c_client *client = bu21013_data->client; | ||
557 | |||
558 | bu21013_data->touch_stopped = true; | ||
559 | if (device_may_wakeup(&client->dev)) | ||
560 | enable_irq_wake(bu21013_data->chip->irq); | ||
561 | else | ||
562 | disable_irq(bu21013_data->chip->irq); | ||
563 | |||
564 | return 0; | ||
565 | } | ||
566 | |||
567 | /** | ||
568 | * bu21013_resume() - resume the touch screen controller | ||
569 | * @dev: pointer to device structure | ||
570 | * | ||
571 | * This function is used to resume the touch panel | ||
572 | * controller and returns integer. | ||
573 | */ | ||
574 | static int bu21013_resume(struct device *dev) | ||
575 | { | ||
576 | struct bu21013_ts_data *bu21013_data = dev_get_drvdata(dev); | ||
577 | struct i2c_client *client = bu21013_data->client; | ||
578 | int retval; | ||
579 | |||
580 | retval = bu21013_init_chip(bu21013_data); | ||
581 | if (retval < 0) { | ||
582 | dev_err(&client->dev, "bu21013 controller config failed\n"); | ||
583 | return retval; | ||
584 | } | ||
585 | |||
586 | bu21013_data->touch_stopped = false; | ||
587 | |||
588 | if (device_may_wakeup(&client->dev)) | ||
589 | disable_irq_wake(bu21013_data->chip->irq); | ||
590 | else | ||
591 | enable_irq(bu21013_data->chip->irq); | ||
592 | |||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | static const struct dev_pm_ops bu21013_dev_pm_ops = { | ||
597 | .suspend = bu21013_suspend, | ||
598 | .resume = bu21013_resume, | ||
599 | }; | ||
600 | #endif | ||
601 | |||
602 | static const struct i2c_device_id bu21013_id[] = { | ||
603 | { DRIVER_TP, 0 }, | ||
604 | { } | ||
605 | }; | ||
606 | MODULE_DEVICE_TABLE(i2c, bu21013_id); | ||
607 | |||
608 | static struct i2c_driver bu21013_driver = { | ||
609 | .driver = { | ||
610 | .name = DRIVER_TP, | ||
611 | .owner = THIS_MODULE, | ||
612 | #ifdef CONFIG_PM | ||
613 | .pm = &bu21013_dev_pm_ops, | ||
614 | #endif | ||
615 | }, | ||
616 | .probe = bu21013_probe, | ||
617 | .remove = __devexit_p(bu21013_remove), | ||
618 | .id_table = bu21013_id, | ||
619 | }; | ||
620 | |||
621 | /** | ||
622 | * bu21013_init() - initializes the bu21013 touchscreen driver | ||
623 | * | ||
624 | * This function used to initializes the bu21013 | ||
625 | * touchscreen driver and returns integer. | ||
626 | */ | ||
627 | static int __init bu21013_init(void) | ||
628 | { | ||
629 | return i2c_add_driver(&bu21013_driver); | ||
630 | } | ||
631 | |||
632 | /** | ||
633 | * bu21013_exit() - de-initializes the bu21013 touchscreen driver | ||
634 | * | ||
635 | * This function uses to de-initializes the bu21013 | ||
636 | * touchscreen driver and returns none. | ||
637 | */ | ||
638 | static void __exit bu21013_exit(void) | ||
639 | { | ||
640 | i2c_del_driver(&bu21013_driver); | ||
641 | } | ||
642 | |||
643 | module_init(bu21013_init); | ||
644 | module_exit(bu21013_exit); | ||
645 | |||
646 | MODULE_LICENSE("GPL v2"); | ||
647 | MODULE_AUTHOR("Naveen Kumar G <naveen.gaddipati@stericsson.com>"); | ||
648 | MODULE_DESCRIPTION("bu21013 touch screen controller driver"); | ||
diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c index 5ec0946938fe..d0c3a7229adf 100644 --- a/drivers/input/touchscreen/cy8ctmg110_ts.c +++ b/drivers/input/touchscreen/cy8ctmg110_ts.c | |||
@@ -206,9 +206,9 @@ static int __devinit cy8ctmg110_probe(struct i2c_client *client, | |||
206 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | 206 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); |
207 | 207 | ||
208 | input_set_abs_params(input_dev, ABS_X, | 208 | input_set_abs_params(input_dev, ABS_X, |
209 | CY8CTMG110_X_MIN, CY8CTMG110_X_MAX, 0, 0); | 209 | CY8CTMG110_X_MIN, CY8CTMG110_X_MAX, 4, 0); |
210 | input_set_abs_params(input_dev, ABS_Y, | 210 | input_set_abs_params(input_dev, ABS_Y, |
211 | CY8CTMG110_Y_MIN, CY8CTMG110_Y_MAX, 0, 0); | 211 | CY8CTMG110_Y_MIN, CY8CTMG110_Y_MAX, 4, 0); |
212 | 212 | ||
213 | if (ts->reset_pin) { | 213 | if (ts->reset_pin) { |
214 | err = gpio_request(ts->reset_pin, NULL); | 214 | err = gpio_request(ts->reset_pin, NULL); |
diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c index a89700e7ace4..498bd62af09a 100644 --- a/drivers/input/touchscreen/hp680_ts_input.c +++ b/drivers/input/touchscreen/hp680_ts_input.c | |||
@@ -107,8 +107,7 @@ static int __init hp680_ts_init(void) | |||
107 | return 0; | 107 | return 0; |
108 | 108 | ||
109 | fail2: free_irq(HP680_TS_IRQ, NULL); | 109 | fail2: free_irq(HP680_TS_IRQ, NULL); |
110 | cancel_delayed_work(&work); | 110 | cancel_delayed_work_sync(&work); |
111 | flush_scheduled_work(); | ||
112 | fail1: input_free_device(hp680_ts_dev); | 111 | fail1: input_free_device(hp680_ts_dev); |
113 | return err; | 112 | return err; |
114 | } | 113 | } |
@@ -116,8 +115,7 @@ static int __init hp680_ts_init(void) | |||
116 | static void __exit hp680_ts_exit(void) | 115 | static void __exit hp680_ts_exit(void) |
117 | { | 116 | { |
118 | free_irq(HP680_TS_IRQ, NULL); | 117 | free_irq(HP680_TS_IRQ, NULL); |
119 | cancel_delayed_work(&work); | 118 | cancel_delayed_work_sync(&work); |
120 | flush_scheduled_work(); | ||
121 | input_unregister_device(hp680_ts_dev); | 119 | input_unregister_device(hp680_ts_dev); |
122 | } | 120 | } |
123 | 121 | ||
diff --git a/drivers/input/touchscreen/intel-mid-touch.c b/drivers/input/touchscreen/intel-mid-touch.c new file mode 100644 index 000000000000..c0307b22d86f --- /dev/null +++ b/drivers/input/touchscreen/intel-mid-touch.c | |||
@@ -0,0 +1,687 @@ | |||
1 | /* | ||
2 | * Intel MID Resistive Touch Screen Driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Intel Corp | ||
5 | * | ||
6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along | ||
18 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
20 | * | ||
21 | * Questions/Comments/Bug fixes to Sreedhara (sreedhara.ds@intel.com) | ||
22 | * Ramesh Agarwal (ramesh.agarwal@intel.com) | ||
23 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
24 | * | ||
25 | * TODO: | ||
26 | * review conversion of r/m/w sequences | ||
27 | */ | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/input.h> | ||
32 | #include <linux/interrupt.h> | ||
33 | #include <linux/err.h> | ||
34 | #include <linux/param.h> | ||
35 | #include <linux/slab.h> | ||
36 | #include <linux/platform_device.h> | ||
37 | #include <linux/irq.h> | ||
38 | #include <linux/delay.h> | ||
39 | #include <asm/intel_scu_ipc.h> | ||
40 | |||
41 | /* PMIC Interrupt registers */ | ||
42 | #define PMIC_REG_ID1 0x00 /* PMIC ID1 register */ | ||
43 | |||
44 | /* PMIC Interrupt registers */ | ||
45 | #define PMIC_REG_INT 0x04 /* PMIC interrupt register */ | ||
46 | #define PMIC_REG_MINT 0x05 /* PMIC interrupt mask register */ | ||
47 | |||
48 | /* ADC Interrupt registers */ | ||
49 | #define PMIC_REG_ADCINT 0x5F /* ADC interrupt register */ | ||
50 | #define PMIC_REG_MADCINT 0x60 /* ADC interrupt mask register */ | ||
51 | |||
52 | /* ADC Control registers */ | ||
53 | #define PMIC_REG_ADCCNTL1 0x61 /* ADC control register */ | ||
54 | |||
55 | /* ADC Channel Selection registers */ | ||
56 | #define PMICADDR0 0xA4 | ||
57 | #define END_OF_CHANNEL 0x1F | ||
58 | |||
59 | /* ADC Result register */ | ||
60 | #define PMIC_REG_ADCSNS0H 0x64 | ||
61 | |||
62 | /* ADC channels for touch screen */ | ||
63 | #define MRST_TS_CHAN10 0xA /* Touch screen X+ connection */ | ||
64 | #define MRST_TS_CHAN11 0xB /* Touch screen X- connection */ | ||
65 | #define MRST_TS_CHAN12 0xC /* Touch screen Y+ connection */ | ||
66 | #define MRST_TS_CHAN13 0xD /* Touch screen Y- connection */ | ||
67 | |||
68 | /* Touch screen channel BIAS constants */ | ||
69 | #define MRST_XBIAS 0x20 | ||
70 | #define MRST_YBIAS 0x40 | ||
71 | #define MRST_ZBIAS 0x80 | ||
72 | |||
73 | /* Touch screen coordinates */ | ||
74 | #define MRST_X_MIN 10 | ||
75 | #define MRST_X_MAX 1024 | ||
76 | #define MRST_X_FUZZ 5 | ||
77 | #define MRST_Y_MIN 10 | ||
78 | #define MRST_Y_MAX 1024 | ||
79 | #define MRST_Y_FUZZ 5 | ||
80 | #define MRST_PRESSURE_MIN 0 | ||
81 | #define MRST_PRESSURE_NOMINAL 50 | ||
82 | #define MRST_PRESSURE_MAX 100 | ||
83 | |||
84 | #define WAIT_ADC_COMPLETION 10 /* msec */ | ||
85 | |||
86 | /* PMIC ADC round robin delays */ | ||
87 | #define ADC_LOOP_DELAY0 0x0 /* Continuous loop */ | ||
88 | #define ADC_LOOP_DELAY1 0x1 /* 4.5 ms approximate */ | ||
89 | |||
90 | /* PMIC Vendor Identifiers */ | ||
91 | #define PMIC_VENDOR_FS 0 /* PMIC vendor FreeScale */ | ||
92 | #define PMIC_VENDOR_MAXIM 1 /* PMIC vendor MAXIM */ | ||
93 | #define PMIC_VENDOR_NEC 2 /* PMIC vendor NEC */ | ||
94 | #define MRSTOUCH_MAX_CHANNELS 32 /* Maximum ADC channels */ | ||
95 | |||
96 | /* Touch screen device structure */ | ||
97 | struct mrstouch_dev { | ||
98 | struct device *dev; /* device associated with touch screen */ | ||
99 | struct input_dev *input; | ||
100 | char phys[32]; | ||
101 | u16 asr; /* Address selection register */ | ||
102 | int irq; | ||
103 | unsigned int vendor; /* PMIC vendor */ | ||
104 | unsigned int rev; /* PMIC revision */ | ||
105 | |||
106 | int (*read_prepare)(struct mrstouch_dev *tsdev); | ||
107 | int (*read)(struct mrstouch_dev *tsdev, u16 *x, u16 *y, u16 *z); | ||
108 | int (*read_finish)(struct mrstouch_dev *tsdev); | ||
109 | }; | ||
110 | |||
111 | |||
112 | /*************************** NEC and Maxim Interface ************************/ | ||
113 | |||
114 | static int mrstouch_nec_adc_read_prepare(struct mrstouch_dev *tsdev) | ||
115 | { | ||
116 | return intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0, 0x20); | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * Enables PENDET interrupt. | ||
121 | */ | ||
122 | static int mrstouch_nec_adc_read_finish(struct mrstouch_dev *tsdev) | ||
123 | { | ||
124 | int err; | ||
125 | |||
126 | err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x20, 0x20); | ||
127 | if (!err) | ||
128 | err = intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1, 0, 0x05); | ||
129 | |||
130 | return err; | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * Reads PMIC ADC touch screen result | ||
135 | * Reads ADC storage registers for higher 7 and lower 3 bits and | ||
136 | * converts the two readings into a single value and turns off gain bit | ||
137 | */ | ||
138 | static int mrstouch_ts_chan_read(u16 offset, u16 chan, u16 *vp, u16 *vm) | ||
139 | { | ||
140 | int err; | ||
141 | u16 result; | ||
142 | u32 res; | ||
143 | |||
144 | result = PMIC_REG_ADCSNS0H + offset; | ||
145 | |||
146 | if (chan == MRST_TS_CHAN12) | ||
147 | result += 4; | ||
148 | |||
149 | err = intel_scu_ipc_ioread32(result, &res); | ||
150 | if (err) | ||
151 | return err; | ||
152 | |||
153 | /* Mash the bits up */ | ||
154 | |||
155 | *vp = (res & 0xFF) << 3; /* Highest 7 bits */ | ||
156 | *vp |= (res >> 8) & 0x07; /* Lower 3 bits */ | ||
157 | *vp &= 0x3FF; | ||
158 | |||
159 | res >>= 16; | ||
160 | |||
161 | *vm = (res & 0xFF) << 3; /* Highest 7 bits */ | ||
162 | *vm |= (res >> 8) & 0x07; /* Lower 3 bits */ | ||
163 | *vm &= 0x3FF; | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * Enables X, Y and Z bias values | ||
170 | * Enables YPYM for X channels and XPXM for Y channels | ||
171 | */ | ||
172 | static int mrstouch_ts_bias_set(uint offset, uint bias) | ||
173 | { | ||
174 | int count; | ||
175 | u16 chan, start; | ||
176 | u16 reg[4]; | ||
177 | u8 data[4]; | ||
178 | |||
179 | chan = PMICADDR0 + offset; | ||
180 | start = MRST_TS_CHAN10; | ||
181 | |||
182 | for (count = 0; count <= 3; count++) { | ||
183 | reg[count] = chan++; | ||
184 | data[count] = bias | (start + count); | ||
185 | } | ||
186 | |||
187 | return intel_scu_ipc_writev(reg, data, 4); | ||
188 | } | ||
189 | |||
190 | /* To read touch screen channel values */ | ||
191 | static int mrstouch_nec_adc_read(struct mrstouch_dev *tsdev, | ||
192 | u16 *x, u16 *y, u16 *z) | ||
193 | { | ||
194 | int err; | ||
195 | u16 xm, ym, zm; | ||
196 | |||
197 | /* configure Y bias for X channels */ | ||
198 | err = mrstouch_ts_bias_set(tsdev->asr, MRST_YBIAS); | ||
199 | if (err) | ||
200 | goto ipc_error; | ||
201 | |||
202 | msleep(WAIT_ADC_COMPLETION); | ||
203 | |||
204 | /* read x+ and x- channels */ | ||
205 | err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, x, &xm); | ||
206 | if (err) | ||
207 | goto ipc_error; | ||
208 | |||
209 | /* configure x bias for y channels */ | ||
210 | err = mrstouch_ts_bias_set(tsdev->asr, MRST_XBIAS); | ||
211 | if (err) | ||
212 | goto ipc_error; | ||
213 | |||
214 | msleep(WAIT_ADC_COMPLETION); | ||
215 | |||
216 | /* read y+ and y- channels */ | ||
217 | err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN12, y, &ym); | ||
218 | if (err) | ||
219 | goto ipc_error; | ||
220 | |||
221 | /* configure z bias for x and y channels */ | ||
222 | err = mrstouch_ts_bias_set(tsdev->asr, MRST_ZBIAS); | ||
223 | if (err) | ||
224 | goto ipc_error; | ||
225 | |||
226 | msleep(WAIT_ADC_COMPLETION); | ||
227 | |||
228 | /* read z+ and z- channels */ | ||
229 | err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, z, &zm); | ||
230 | if (err) | ||
231 | goto ipc_error; | ||
232 | |||
233 | return 0; | ||
234 | |||
235 | ipc_error: | ||
236 | dev_err(tsdev->dev, "ipc error during adc read\n"); | ||
237 | return err; | ||
238 | } | ||
239 | |||
240 | |||
241 | /*************************** Freescale Interface ************************/ | ||
242 | |||
243 | static int mrstouch_fs_adc_read_prepare(struct mrstouch_dev *tsdev) | ||
244 | { | ||
245 | int err, count; | ||
246 | u16 chan; | ||
247 | u16 reg[5]; | ||
248 | u8 data[5]; | ||
249 | |||
250 | /* Stop the ADC */ | ||
251 | err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x00, 0x02); | ||
252 | if (err) | ||
253 | goto ipc_error; | ||
254 | |||
255 | chan = PMICADDR0 + tsdev->asr; | ||
256 | |||
257 | /* Set X BIAS */ | ||
258 | for (count = 0; count <= 3; count++) { | ||
259 | reg[count] = chan++; | ||
260 | data[count] = 0x2A; | ||
261 | } | ||
262 | reg[count] = chan++; /* Dummy */ | ||
263 | data[count] = 0; | ||
264 | |||
265 | err = intel_scu_ipc_writev(reg, data, 5); | ||
266 | if (err) | ||
267 | goto ipc_error; | ||
268 | |||
269 | msleep(WAIT_ADC_COMPLETION); | ||
270 | |||
271 | /* Set Y BIAS */ | ||
272 | for (count = 0; count <= 3; count++) { | ||
273 | reg[count] = chan++; | ||
274 | data[count] = 0x4A; | ||
275 | } | ||
276 | reg[count] = chan++; /* Dummy */ | ||
277 | data[count] = 0; | ||
278 | |||
279 | err = intel_scu_ipc_writev(reg, data, 5); | ||
280 | if (err) | ||
281 | goto ipc_error; | ||
282 | |||
283 | msleep(WAIT_ADC_COMPLETION); | ||
284 | |||
285 | /* Set Z BIAS */ | ||
286 | err = intel_scu_ipc_iowrite32(chan + 2, 0x8A8A8A8A); | ||
287 | if (err) | ||
288 | goto ipc_error; | ||
289 | |||
290 | msleep(WAIT_ADC_COMPLETION); | ||
291 | |||
292 | return 0; | ||
293 | |||
294 | ipc_error: | ||
295 | dev_err(tsdev->dev, "ipc error during %s\n", __func__); | ||
296 | return err; | ||
297 | } | ||
298 | |||
299 | static int mrstouch_fs_adc_read(struct mrstouch_dev *tsdev, | ||
300 | u16 *x, u16 *y, u16 *z) | ||
301 | { | ||
302 | int err; | ||
303 | u16 result; | ||
304 | u16 reg[4]; | ||
305 | u8 data[4]; | ||
306 | |||
307 | result = PMIC_REG_ADCSNS0H + tsdev->asr; | ||
308 | |||
309 | reg[0] = result + 4; | ||
310 | reg[1] = result + 5; | ||
311 | reg[2] = result + 16; | ||
312 | reg[3] = result + 17; | ||
313 | |||
314 | err = intel_scu_ipc_readv(reg, data, 4); | ||
315 | if (err) | ||
316 | goto ipc_error; | ||
317 | |||
318 | *x = data[0] << 3; /* Higher 7 bits */ | ||
319 | *x |= data[1] & 0x7; /* Lower 3 bits */ | ||
320 | *x &= 0x3FF; | ||
321 | |||
322 | *y = data[2] << 3; /* Higher 7 bits */ | ||
323 | *y |= data[3] & 0x7; /* Lower 3 bits */ | ||
324 | *y &= 0x3FF; | ||
325 | |||
326 | /* Read Z value */ | ||
327 | reg[0] = result + 28; | ||
328 | reg[1] = result + 29; | ||
329 | |||
330 | err = intel_scu_ipc_readv(reg, data, 4); | ||
331 | if (err) | ||
332 | goto ipc_error; | ||
333 | |||
334 | *z = data[0] << 3; /* Higher 7 bits */ | ||
335 | *z |= data[1] & 0x7; /* Lower 3 bits */ | ||
336 | *z &= 0x3FF; | ||
337 | |||
338 | return 0; | ||
339 | |||
340 | ipc_error: | ||
341 | dev_err(tsdev->dev, "ipc error during %s\n", __func__); | ||
342 | return err; | ||
343 | } | ||
344 | |||
345 | static int mrstouch_fs_adc_read_finish(struct mrstouch_dev *tsdev) | ||
346 | { | ||
347 | int err, count; | ||
348 | u16 chan; | ||
349 | u16 reg[5]; | ||
350 | u8 data[5]; | ||
351 | |||
352 | /* Clear all TS channels */ | ||
353 | chan = PMICADDR0 + tsdev->asr; | ||
354 | for (count = 0; count <= 4; count++) { | ||
355 | reg[count] = chan++; | ||
356 | data[count] = 0; | ||
357 | } | ||
358 | err = intel_scu_ipc_writev(reg, data, 5); | ||
359 | if (err) | ||
360 | goto ipc_error; | ||
361 | |||
362 | for (count = 0; count <= 4; count++) { | ||
363 | reg[count] = chan++; | ||
364 | data[count] = 0; | ||
365 | } | ||
366 | err = intel_scu_ipc_writev(reg, data, 5); | ||
367 | if (err) | ||
368 | goto ipc_error; | ||
369 | |||
370 | err = intel_scu_ipc_iowrite32(chan + 2, 0x00000000); | ||
371 | if (err) | ||
372 | goto ipc_error; | ||
373 | |||
374 | /* Start ADC */ | ||
375 | err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x02, 0x02); | ||
376 | if (err) | ||
377 | goto ipc_error; | ||
378 | |||
379 | return 0; | ||
380 | |||
381 | ipc_error: | ||
382 | dev_err(tsdev->dev, "ipc error during %s\n", __func__); | ||
383 | return err; | ||
384 | } | ||
385 | |||
386 | static void mrstouch_report_event(struct input_dev *input, | ||
387 | unsigned int x, unsigned int y, unsigned int z) | ||
388 | { | ||
389 | if (z > MRST_PRESSURE_NOMINAL) { | ||
390 | /* Pen touched, report button touch and coordinates */ | ||
391 | input_report_key(input, BTN_TOUCH, 1); | ||
392 | input_report_abs(input, ABS_X, x); | ||
393 | input_report_abs(input, ABS_Y, y); | ||
394 | } else { | ||
395 | input_report_key(input, BTN_TOUCH, 0); | ||
396 | } | ||
397 | |||
398 | input_report_abs(input, ABS_PRESSURE, z); | ||
399 | input_sync(input); | ||
400 | } | ||
401 | |||
402 | /* PENDET interrupt handler */ | ||
403 | static irqreturn_t mrstouch_pendet_irq(int irq, void *dev_id) | ||
404 | { | ||
405 | struct mrstouch_dev *tsdev = dev_id; | ||
406 | u16 x, y, z; | ||
407 | |||
408 | /* | ||
409 | * Should we lower thread priority? Probably not, since we are | ||
410 | * not spinning but sleeping... | ||
411 | */ | ||
412 | |||
413 | if (tsdev->read_prepare(tsdev)) | ||
414 | goto out; | ||
415 | |||
416 | do { | ||
417 | if (tsdev->read(tsdev, &x, &y, &z)) | ||
418 | break; | ||
419 | |||
420 | mrstouch_report_event(tsdev->input, x, y, z); | ||
421 | } while (z > MRST_PRESSURE_NOMINAL); | ||
422 | |||
423 | tsdev->read_finish(tsdev); | ||
424 | |||
425 | out: | ||
426 | return IRQ_HANDLED; | ||
427 | } | ||
428 | |||
429 | /* Utility to read PMIC ID */ | ||
430 | static int __devinit mrstouch_read_pmic_id(uint *vendor, uint *rev) | ||
431 | { | ||
432 | int err; | ||
433 | u8 r; | ||
434 | |||
435 | err = intel_scu_ipc_ioread8(PMIC_REG_ID1, &r); | ||
436 | if (err) | ||
437 | return err; | ||
438 | |||
439 | *vendor = r & 0x7; | ||
440 | *rev = (r >> 3) & 0x7; | ||
441 | |||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | /* | ||
446 | * Parse ADC channels to find end of the channel configured by other ADC user | ||
447 | * NEC and MAXIM requires 4 channels and FreeScale needs 18 channels | ||
448 | */ | ||
449 | static int __devinit mrstouch_chan_parse(struct mrstouch_dev *tsdev) | ||
450 | { | ||
451 | int err, i, found; | ||
452 | u8 r8; | ||
453 | |||
454 | found = -1; | ||
455 | |||
456 | for (i = 0; i < MRSTOUCH_MAX_CHANNELS; i++) { | ||
457 | if (found >= 0) | ||
458 | break; | ||
459 | |||
460 | err = intel_scu_ipc_ioread8(PMICADDR0 + i, &r8); | ||
461 | if (err) | ||
462 | return err; | ||
463 | |||
464 | if (r8 == END_OF_CHANNEL) { | ||
465 | found = i; | ||
466 | break; | ||
467 | } | ||
468 | } | ||
469 | if (found < 0) | ||
470 | return 0; | ||
471 | |||
472 | if (tsdev->vendor == PMIC_VENDOR_FS) { | ||
473 | if (found && found > (MRSTOUCH_MAX_CHANNELS - 18)) | ||
474 | return -ENOSPC; | ||
475 | } else { | ||
476 | if (found && found > (MRSTOUCH_MAX_CHANNELS - 4)) | ||
477 | return -ENOSPC; | ||
478 | } | ||
479 | return found; | ||
480 | } | ||
481 | |||
482 | |||
483 | /* | ||
484 | * Writes touch screen channels to ADC address selection registers | ||
485 | */ | ||
486 | static int __devinit mrstouch_ts_chan_set(uint offset) | ||
487 | { | ||
488 | u16 chan; | ||
489 | |||
490 | int ret, count; | ||
491 | |||
492 | chan = PMICADDR0 + offset; | ||
493 | for (count = 0; count <= 3; count++) { | ||
494 | ret = intel_scu_ipc_iowrite8(chan++, MRST_TS_CHAN10 + count); | ||
495 | if (ret) | ||
496 | return ret; | ||
497 | } | ||
498 | return intel_scu_ipc_iowrite8(chan++, END_OF_CHANNEL); | ||
499 | } | ||
500 | |||
501 | /* Initialize ADC */ | ||
502 | static int __devinit mrstouch_adc_init(struct mrstouch_dev *tsdev) | ||
503 | { | ||
504 | int err, start; | ||
505 | u8 ra, rm; | ||
506 | |||
507 | err = mrstouch_read_pmic_id(&tsdev->vendor, &tsdev->rev); | ||
508 | if (err) { | ||
509 | dev_err(tsdev->dev, "Unable to read PMIC id\n"); | ||
510 | return err; | ||
511 | } | ||
512 | |||
513 | switch (tsdev->vendor) { | ||
514 | case PMIC_VENDOR_NEC: | ||
515 | case PMIC_VENDOR_MAXIM: | ||
516 | tsdev->read_prepare = mrstouch_nec_adc_read_prepare; | ||
517 | tsdev->read = mrstouch_nec_adc_read; | ||
518 | tsdev->read_finish = mrstouch_nec_adc_read_finish; | ||
519 | break; | ||
520 | |||
521 | case PMIC_VENDOR_FS: | ||
522 | tsdev->read_prepare = mrstouch_fs_adc_read_prepare; | ||
523 | tsdev->read = mrstouch_fs_adc_read; | ||
524 | tsdev->read_finish = mrstouch_fs_adc_read_finish; | ||
525 | break; | ||
526 | |||
527 | default: | ||
528 | dev_err(tsdev->dev, | ||
529 | "Unsupported touchscreen: %d\n", tsdev->vendor); | ||
530 | return -ENXIO; | ||
531 | } | ||
532 | |||
533 | start = mrstouch_chan_parse(tsdev); | ||
534 | if (start < 0) { | ||
535 | dev_err(tsdev->dev, "Unable to parse channels\n"); | ||
536 | return start; | ||
537 | } | ||
538 | |||
539 | tsdev->asr = start; | ||
540 | |||
541 | /* | ||
542 | * ADC power on, start, enable PENDET and set loop delay | ||
543 | * ADC loop delay is set to 4.5 ms approximately | ||
544 | * Loop delay more than this results in jitter in adc readings | ||
545 | * Setting loop delay to 0 (continous loop) in MAXIM stops PENDET | ||
546 | * interrupt generation sometimes. | ||
547 | */ | ||
548 | |||
549 | if (tsdev->vendor == PMIC_VENDOR_FS) { | ||
550 | ra = 0xE0 | ADC_LOOP_DELAY0; | ||
551 | rm = 0x5; | ||
552 | } else { | ||
553 | /* NEC and MAXIm not consistent with loop delay 0 */ | ||
554 | ra = 0xE0 | ADC_LOOP_DELAY1; | ||
555 | rm = 0x0; | ||
556 | |||
557 | /* configure touch screen channels */ | ||
558 | err = mrstouch_ts_chan_set(tsdev->asr); | ||
559 | if (err) | ||
560 | return err; | ||
561 | } | ||
562 | |||
563 | err = intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1, ra, 0xE7); | ||
564 | if (err) | ||
565 | return err; | ||
566 | |||
567 | err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, rm, 0x03); | ||
568 | if (err) | ||
569 | return err; | ||
570 | |||
571 | return 0; | ||
572 | } | ||
573 | |||
574 | |||
575 | /* Probe function for touch screen driver */ | ||
576 | static int __devinit mrstouch_probe(struct platform_device *pdev) | ||
577 | { | ||
578 | struct mrstouch_dev *tsdev; | ||
579 | struct input_dev *input; | ||
580 | int err; | ||
581 | int irq; | ||
582 | |||
583 | irq = platform_get_irq(pdev, 0); | ||
584 | if (irq < 0) { | ||
585 | dev_err(&pdev->dev, "no interrupt assigned\n"); | ||
586 | return -EINVAL; | ||
587 | } | ||
588 | |||
589 | tsdev = kzalloc(sizeof(struct mrstouch_dev), GFP_KERNEL); | ||
590 | input = input_allocate_device(); | ||
591 | if (!tsdev || !input) { | ||
592 | dev_err(&pdev->dev, "unable to allocate memory\n"); | ||
593 | err = -ENOMEM; | ||
594 | goto err_free_mem; | ||
595 | } | ||
596 | |||
597 | tsdev->dev = &pdev->dev; | ||
598 | tsdev->input = input; | ||
599 | tsdev->irq = irq; | ||
600 | |||
601 | snprintf(tsdev->phys, sizeof(tsdev->phys), | ||
602 | "%s/input0", dev_name(tsdev->dev)); | ||
603 | |||
604 | err = mrstouch_adc_init(tsdev); | ||
605 | if (err) { | ||
606 | dev_err(&pdev->dev, "ADC initialization failed\n"); | ||
607 | goto err_free_mem; | ||
608 | } | ||
609 | |||
610 | input->name = "mrst_touchscreen"; | ||
611 | input->phys = tsdev->phys; | ||
612 | input->dev.parent = tsdev->dev; | ||
613 | |||
614 | input->id.vendor = tsdev->vendor; | ||
615 | input->id.version = tsdev->rev; | ||
616 | |||
617 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
618 | input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
619 | |||
620 | input_set_abs_params(tsdev->input, ABS_X, | ||
621 | MRST_X_MIN, MRST_X_MAX, MRST_X_FUZZ, 0); | ||
622 | input_set_abs_params(tsdev->input, ABS_Y, | ||
623 | MRST_Y_MIN, MRST_Y_MAX, MRST_Y_FUZZ, 0); | ||
624 | input_set_abs_params(tsdev->input, ABS_PRESSURE, | ||
625 | MRST_PRESSURE_MIN, MRST_PRESSURE_MAX, 0, 0); | ||
626 | |||
627 | err = request_threaded_irq(tsdev->irq, NULL, mrstouch_pendet_irq, | ||
628 | 0, "mrstouch", tsdev); | ||
629 | if (err) { | ||
630 | dev_err(tsdev->dev, "unable to allocate irq\n"); | ||
631 | goto err_free_mem; | ||
632 | } | ||
633 | |||
634 | err = input_register_device(tsdev->input); | ||
635 | if (err) { | ||
636 | dev_err(tsdev->dev, "unable to register input device\n"); | ||
637 | goto err_free_irq; | ||
638 | } | ||
639 | |||
640 | platform_set_drvdata(pdev, tsdev); | ||
641 | return 0; | ||
642 | |||
643 | err_free_irq: | ||
644 | free_irq(tsdev->irq, tsdev); | ||
645 | err_free_mem: | ||
646 | input_free_device(input); | ||
647 | kfree(tsdev); | ||
648 | return err; | ||
649 | } | ||
650 | |||
651 | static int __devexit mrstouch_remove(struct platform_device *pdev) | ||
652 | { | ||
653 | struct mrstouch_dev *tsdev = platform_get_drvdata(pdev); | ||
654 | |||
655 | free_irq(tsdev->irq, tsdev); | ||
656 | input_unregister_device(tsdev->input); | ||
657 | kfree(tsdev); | ||
658 | |||
659 | platform_set_drvdata(pdev, NULL); | ||
660 | |||
661 | return 0; | ||
662 | } | ||
663 | |||
664 | static struct platform_driver mrstouch_driver = { | ||
665 | .driver = { | ||
666 | .name = "pmic_touch", | ||
667 | .owner = THIS_MODULE, | ||
668 | }, | ||
669 | .probe = mrstouch_probe, | ||
670 | .remove = __devexit_p(mrstouch_remove), | ||
671 | }; | ||
672 | |||
673 | static int __init mrstouch_init(void) | ||
674 | { | ||
675 | return platform_driver_register(&mrstouch_driver); | ||
676 | } | ||
677 | module_init(mrstouch_init); | ||
678 | |||
679 | static void __exit mrstouch_exit(void) | ||
680 | { | ||
681 | platform_driver_unregister(&mrstouch_driver); | ||
682 | } | ||
683 | module_exit(mrstouch_exit); | ||
684 | |||
685 | MODULE_AUTHOR("Sreedhara Murthy. D.S, sreedhara.ds@intel.com"); | ||
686 | MODULE_DESCRIPTION("Intel Moorestown Resistive Touch Screen Driver"); | ||
687 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/lpc32xx_ts.c b/drivers/input/touchscreen/lpc32xx_ts.c new file mode 100644 index 000000000000..dcf803f5a1f7 --- /dev/null +++ b/drivers/input/touchscreen/lpc32xx_ts.c | |||
@@ -0,0 +1,411 @@ | |||
1 | /* | ||
2 | * LPC32xx built-in touchscreen driver | ||
3 | * | ||
4 | * Copyright (C) 2010 NXP Semiconductors | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/input.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/clk.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/slab.h> | ||
25 | |||
26 | /* | ||
27 | * Touchscreen controller register offsets | ||
28 | */ | ||
29 | #define LPC32XX_TSC_STAT 0x00 | ||
30 | #define LPC32XX_TSC_SEL 0x04 | ||
31 | #define LPC32XX_TSC_CON 0x08 | ||
32 | #define LPC32XX_TSC_FIFO 0x0C | ||
33 | #define LPC32XX_TSC_DTR 0x10 | ||
34 | #define LPC32XX_TSC_RTR 0x14 | ||
35 | #define LPC32XX_TSC_UTR 0x18 | ||
36 | #define LPC32XX_TSC_TTR 0x1C | ||
37 | #define LPC32XX_TSC_DXP 0x20 | ||
38 | #define LPC32XX_TSC_MIN_X 0x24 | ||
39 | #define LPC32XX_TSC_MAX_X 0x28 | ||
40 | #define LPC32XX_TSC_MIN_Y 0x2C | ||
41 | #define LPC32XX_TSC_MAX_Y 0x30 | ||
42 | #define LPC32XX_TSC_AUX_UTR 0x34 | ||
43 | #define LPC32XX_TSC_AUX_MIN 0x38 | ||
44 | #define LPC32XX_TSC_AUX_MAX 0x3C | ||
45 | |||
46 | #define LPC32XX_TSC_STAT_FIFO_OVRRN (1 << 8) | ||
47 | #define LPC32XX_TSC_STAT_FIFO_EMPTY (1 << 7) | ||
48 | |||
49 | #define LPC32XX_TSC_SEL_DEFVAL 0x0284 | ||
50 | |||
51 | #define LPC32XX_TSC_ADCCON_IRQ_TO_FIFO_4 (0x1 << 11) | ||
52 | #define LPC32XX_TSC_ADCCON_X_SAMPLE_SIZE(s) ((10 - (s)) << 7) | ||
53 | #define LPC32XX_TSC_ADCCON_Y_SAMPLE_SIZE(s) ((10 - (s)) << 4) | ||
54 | #define LPC32XX_TSC_ADCCON_POWER_UP (1 << 2) | ||
55 | #define LPC32XX_TSC_ADCCON_AUTO_EN (1 << 0) | ||
56 | |||
57 | #define LPC32XX_TSC_FIFO_TS_P_LEVEL (1 << 31) | ||
58 | #define LPC32XX_TSC_FIFO_NORMALIZE_X_VAL(x) (((x) & 0x03FF0000) >> 16) | ||
59 | #define LPC32XX_TSC_FIFO_NORMALIZE_Y_VAL(y) ((y) & 0x000003FF) | ||
60 | |||
61 | #define LPC32XX_TSC_ADCDAT_VALUE_MASK 0x000003FF | ||
62 | |||
63 | #define LPC32XX_TSC_MIN_XY_VAL 0x0 | ||
64 | #define LPC32XX_TSC_MAX_XY_VAL 0x3FF | ||
65 | |||
66 | #define MOD_NAME "ts-lpc32xx" | ||
67 | |||
68 | #define tsc_readl(dev, reg) \ | ||
69 | __raw_readl((dev)->tsc_base + (reg)) | ||
70 | #define tsc_writel(dev, reg, val) \ | ||
71 | __raw_writel((val), (dev)->tsc_base + (reg)) | ||
72 | |||
73 | struct lpc32xx_tsc { | ||
74 | struct input_dev *dev; | ||
75 | void __iomem *tsc_base; | ||
76 | int irq; | ||
77 | struct clk *clk; | ||
78 | }; | ||
79 | |||
80 | static void lpc32xx_fifo_clear(struct lpc32xx_tsc *tsc) | ||
81 | { | ||
82 | while (!(tsc_readl(tsc, LPC32XX_TSC_STAT) & | ||
83 | LPC32XX_TSC_STAT_FIFO_EMPTY)) | ||
84 | tsc_readl(tsc, LPC32XX_TSC_FIFO); | ||
85 | } | ||
86 | |||
87 | static irqreturn_t lpc32xx_ts_interrupt(int irq, void *dev_id) | ||
88 | { | ||
89 | u32 tmp, rv[4], xs[4], ys[4]; | ||
90 | int idx; | ||
91 | struct lpc32xx_tsc *tsc = dev_id; | ||
92 | struct input_dev *input = tsc->dev; | ||
93 | |||
94 | tmp = tsc_readl(tsc, LPC32XX_TSC_STAT); | ||
95 | |||
96 | if (tmp & LPC32XX_TSC_STAT_FIFO_OVRRN) { | ||
97 | /* FIFO overflow - throw away samples */ | ||
98 | lpc32xx_fifo_clear(tsc); | ||
99 | return IRQ_HANDLED; | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | * Gather and normalize 4 samples. Pen-up events may have less | ||
104 | * than 4 samples, but its ok to pop 4 and let the last sample | ||
105 | * pen status check drop the samples. | ||
106 | */ | ||
107 | idx = 0; | ||
108 | while (idx < 4 && | ||
109 | !(tsc_readl(tsc, LPC32XX_TSC_STAT) & | ||
110 | LPC32XX_TSC_STAT_FIFO_EMPTY)) { | ||
111 | tmp = tsc_readl(tsc, LPC32XX_TSC_FIFO); | ||
112 | xs[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK - | ||
113 | LPC32XX_TSC_FIFO_NORMALIZE_X_VAL(tmp); | ||
114 | ys[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK - | ||
115 | LPC32XX_TSC_FIFO_NORMALIZE_Y_VAL(tmp); | ||
116 | rv[idx] = tmp; | ||
117 | idx++; | ||
118 | } | ||
119 | |||
120 | /* Data is only valid if pen is still down in last sample */ | ||
121 | if (!(rv[3] & LPC32XX_TSC_FIFO_TS_P_LEVEL) && idx == 4) { | ||
122 | /* Use average of 2nd and 3rd sample for position */ | ||
123 | input_report_abs(input, ABS_X, (xs[1] + xs[2]) / 2); | ||
124 | input_report_abs(input, ABS_Y, (ys[1] + ys[2]) / 2); | ||
125 | input_report_key(input, BTN_TOUCH, 1); | ||
126 | } else { | ||
127 | input_report_key(input, BTN_TOUCH, 0); | ||
128 | } | ||
129 | |||
130 | input_sync(input); | ||
131 | |||
132 | return IRQ_HANDLED; | ||
133 | } | ||
134 | |||
135 | static void lpc32xx_stop_tsc(struct lpc32xx_tsc *tsc) | ||
136 | { | ||
137 | /* Disable auto mode */ | ||
138 | tsc_writel(tsc, LPC32XX_TSC_CON, | ||
139 | tsc_readl(tsc, LPC32XX_TSC_CON) & | ||
140 | ~LPC32XX_TSC_ADCCON_AUTO_EN); | ||
141 | |||
142 | clk_disable(tsc->clk); | ||
143 | } | ||
144 | |||
145 | static void lpc32xx_setup_tsc(struct lpc32xx_tsc *tsc) | ||
146 | { | ||
147 | u32 tmp; | ||
148 | |||
149 | clk_enable(tsc->clk); | ||
150 | |||
151 | tmp = tsc_readl(tsc, LPC32XX_TSC_CON) & ~LPC32XX_TSC_ADCCON_POWER_UP; | ||
152 | |||
153 | /* Set the TSC FIFO depth to 4 samples @ 10-bits per sample (max) */ | ||
154 | tmp = LPC32XX_TSC_ADCCON_IRQ_TO_FIFO_4 | | ||
155 | LPC32XX_TSC_ADCCON_X_SAMPLE_SIZE(10) | | ||
156 | LPC32XX_TSC_ADCCON_Y_SAMPLE_SIZE(10); | ||
157 | tsc_writel(tsc, LPC32XX_TSC_CON, tmp); | ||
158 | |||
159 | /* These values are all preset */ | ||
160 | tsc_writel(tsc, LPC32XX_TSC_SEL, LPC32XX_TSC_SEL_DEFVAL); | ||
161 | tsc_writel(tsc, LPC32XX_TSC_MIN_X, LPC32XX_TSC_MIN_XY_VAL); | ||
162 | tsc_writel(tsc, LPC32XX_TSC_MAX_X, LPC32XX_TSC_MAX_XY_VAL); | ||
163 | tsc_writel(tsc, LPC32XX_TSC_MIN_Y, LPC32XX_TSC_MIN_XY_VAL); | ||
164 | tsc_writel(tsc, LPC32XX_TSC_MAX_Y, LPC32XX_TSC_MAX_XY_VAL); | ||
165 | |||
166 | /* Aux support is not used */ | ||
167 | tsc_writel(tsc, LPC32XX_TSC_AUX_UTR, 0); | ||
168 | tsc_writel(tsc, LPC32XX_TSC_AUX_MIN, 0); | ||
169 | tsc_writel(tsc, LPC32XX_TSC_AUX_MAX, 0); | ||
170 | |||
171 | /* | ||
172 | * Set sample rate to about 240Hz per X/Y pair. A single measurement | ||
173 | * consists of 4 pairs which gives about a 60Hz sample rate based on | ||
174 | * a stable 32768Hz clock source. Values are in clocks. | ||
175 | * Rate is (32768 / (RTR + XCONV + RTR + YCONV + DXP + TTR + UTR) / 4 | ||
176 | */ | ||
177 | tsc_writel(tsc, LPC32XX_TSC_RTR, 0x2); | ||
178 | tsc_writel(tsc, LPC32XX_TSC_DTR, 0x2); | ||
179 | tsc_writel(tsc, LPC32XX_TSC_TTR, 0x10); | ||
180 | tsc_writel(tsc, LPC32XX_TSC_DXP, 0x4); | ||
181 | tsc_writel(tsc, LPC32XX_TSC_UTR, 88); | ||
182 | |||
183 | lpc32xx_fifo_clear(tsc); | ||
184 | |||
185 | /* Enable automatic ts event capture */ | ||
186 | tsc_writel(tsc, LPC32XX_TSC_CON, tmp | LPC32XX_TSC_ADCCON_AUTO_EN); | ||
187 | } | ||
188 | |||
189 | static int lpc32xx_ts_open(struct input_dev *dev) | ||
190 | { | ||
191 | struct lpc32xx_tsc *tsc = input_get_drvdata(dev); | ||
192 | |||
193 | lpc32xx_setup_tsc(tsc); | ||
194 | |||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static void lpc32xx_ts_close(struct input_dev *dev) | ||
199 | { | ||
200 | struct lpc32xx_tsc *tsc = input_get_drvdata(dev); | ||
201 | |||
202 | lpc32xx_stop_tsc(tsc); | ||
203 | } | ||
204 | |||
205 | static int __devinit lpc32xx_ts_probe(struct platform_device *pdev) | ||
206 | { | ||
207 | struct lpc32xx_tsc *tsc; | ||
208 | struct input_dev *input; | ||
209 | struct resource *res; | ||
210 | resource_size_t size; | ||
211 | int irq; | ||
212 | int error; | ||
213 | |||
214 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
215 | if (!res) { | ||
216 | dev_err(&pdev->dev, "Can't get memory resource\n"); | ||
217 | return -ENOENT; | ||
218 | } | ||
219 | |||
220 | irq = platform_get_irq(pdev, 0); | ||
221 | if (irq < 0) { | ||
222 | dev_err(&pdev->dev, "Can't get interrupt resource\n"); | ||
223 | return irq; | ||
224 | } | ||
225 | |||
226 | tsc = kzalloc(sizeof(*tsc), GFP_KERNEL); | ||
227 | input = input_allocate_device(); | ||
228 | if (!tsc || !input) { | ||
229 | dev_err(&pdev->dev, "failed allocating memory\n"); | ||
230 | error = -ENOMEM; | ||
231 | goto err_free_mem; | ||
232 | } | ||
233 | |||
234 | tsc->dev = input; | ||
235 | tsc->irq = irq; | ||
236 | |||
237 | size = resource_size(res); | ||
238 | |||
239 | if (!request_mem_region(res->start, size, pdev->name)) { | ||
240 | dev_err(&pdev->dev, "TSC registers are not free\n"); | ||
241 | error = -EBUSY; | ||
242 | goto err_free_mem; | ||
243 | } | ||
244 | |||
245 | tsc->tsc_base = ioremap(res->start, size); | ||
246 | if (!tsc->tsc_base) { | ||
247 | dev_err(&pdev->dev, "Can't map memory\n"); | ||
248 | error = -ENOMEM; | ||
249 | goto err_release_mem; | ||
250 | } | ||
251 | |||
252 | tsc->clk = clk_get(&pdev->dev, NULL); | ||
253 | if (IS_ERR(tsc->clk)) { | ||
254 | dev_err(&pdev->dev, "failed getting clock\n"); | ||
255 | error = PTR_ERR(tsc->clk); | ||
256 | goto err_unmap; | ||
257 | } | ||
258 | |||
259 | input->name = MOD_NAME; | ||
260 | input->phys = "lpc32xx/input0"; | ||
261 | input->id.bustype = BUS_HOST; | ||
262 | input->id.vendor = 0x0001; | ||
263 | input->id.product = 0x0002; | ||
264 | input->id.version = 0x0100; | ||
265 | input->dev.parent = &pdev->dev; | ||
266 | input->open = lpc32xx_ts_open; | ||
267 | input->close = lpc32xx_ts_close; | ||
268 | |||
269 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
270 | input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
271 | input_set_abs_params(input, ABS_X, LPC32XX_TSC_MIN_XY_VAL, | ||
272 | LPC32XX_TSC_MAX_XY_VAL, 0, 0); | ||
273 | input_set_abs_params(input, ABS_Y, LPC32XX_TSC_MIN_XY_VAL, | ||
274 | LPC32XX_TSC_MAX_XY_VAL, 0, 0); | ||
275 | |||
276 | input_set_drvdata(input, tsc); | ||
277 | |||
278 | error = request_irq(tsc->irq, lpc32xx_ts_interrupt, | ||
279 | IRQF_DISABLED, pdev->name, tsc); | ||
280 | if (error) { | ||
281 | dev_err(&pdev->dev, "failed requesting interrupt\n"); | ||
282 | goto err_put_clock; | ||
283 | } | ||
284 | |||
285 | error = input_register_device(input); | ||
286 | if (error) { | ||
287 | dev_err(&pdev->dev, "failed registering input device\n"); | ||
288 | goto err_free_irq; | ||
289 | } | ||
290 | |||
291 | platform_set_drvdata(pdev, tsc); | ||
292 | device_init_wakeup(&pdev->dev, 1); | ||
293 | |||
294 | return 0; | ||
295 | |||
296 | err_free_irq: | ||
297 | free_irq(tsc->irq, tsc); | ||
298 | err_put_clock: | ||
299 | clk_put(tsc->clk); | ||
300 | err_unmap: | ||
301 | iounmap(tsc->tsc_base); | ||
302 | err_release_mem: | ||
303 | release_mem_region(res->start, size); | ||
304 | err_free_mem: | ||
305 | input_free_device(input); | ||
306 | kfree(tsc); | ||
307 | |||
308 | return error; | ||
309 | } | ||
310 | |||
311 | static int __devexit lpc32xx_ts_remove(struct platform_device *pdev) | ||
312 | { | ||
313 | struct lpc32xx_tsc *tsc = platform_get_drvdata(pdev); | ||
314 | struct resource *res; | ||
315 | |||
316 | device_init_wakeup(&pdev->dev, 0); | ||
317 | free_irq(tsc->irq, tsc); | ||
318 | |||
319 | input_unregister_device(tsc->dev); | ||
320 | |||
321 | clk_put(tsc->clk); | ||
322 | |||
323 | iounmap(tsc->tsc_base); | ||
324 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
325 | release_mem_region(res->start, resource_size(res)); | ||
326 | |||
327 | kfree(tsc); | ||
328 | |||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | #ifdef CONFIG_PM | ||
333 | static int lpc32xx_ts_suspend(struct device *dev) | ||
334 | { | ||
335 | struct lpc32xx_tsc *tsc = dev_get_drvdata(dev); | ||
336 | struct input_dev *input = tsc->dev; | ||
337 | |||
338 | /* | ||
339 | * Suspend and resume can be called when the device hasn't been | ||
340 | * enabled. If there are no users that have the device open, then | ||
341 | * avoid calling the TSC stop and start functions as the TSC | ||
342 | * isn't yet clocked. | ||
343 | */ | ||
344 | mutex_lock(&input->mutex); | ||
345 | |||
346 | if (input->users) { | ||
347 | if (device_may_wakeup(dev)) | ||
348 | enable_irq_wake(tsc->irq); | ||
349 | else | ||
350 | lpc32xx_stop_tsc(tsc); | ||
351 | } | ||
352 | |||
353 | mutex_unlock(&input->mutex); | ||
354 | |||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | static int lpc32xx_ts_resume(struct device *dev) | ||
359 | { | ||
360 | struct lpc32xx_tsc *tsc = dev_get_drvdata(dev); | ||
361 | struct input_dev *input = tsc->dev; | ||
362 | |||
363 | mutex_lock(&input->mutex); | ||
364 | |||
365 | if (input->users) { | ||
366 | if (device_may_wakeup(dev)) | ||
367 | disable_irq_wake(tsc->irq); | ||
368 | else | ||
369 | lpc32xx_setup_tsc(tsc); | ||
370 | } | ||
371 | |||
372 | mutex_unlock(&input->mutex); | ||
373 | |||
374 | return 0; | ||
375 | } | ||
376 | |||
377 | static const struct dev_pm_ops lpc32xx_ts_pm_ops = { | ||
378 | .suspend = lpc32xx_ts_suspend, | ||
379 | .resume = lpc32xx_ts_resume, | ||
380 | }; | ||
381 | #define LPC32XX_TS_PM_OPS (&lpc32xx_ts_pm_ops) | ||
382 | #else | ||
383 | #define LPC32XX_TS_PM_OPS NULL | ||
384 | #endif | ||
385 | |||
386 | static struct platform_driver lpc32xx_ts_driver = { | ||
387 | .probe = lpc32xx_ts_probe, | ||
388 | .remove = __devexit_p(lpc32xx_ts_remove), | ||
389 | .driver = { | ||
390 | .name = MOD_NAME, | ||
391 | .owner = THIS_MODULE, | ||
392 | .pm = LPC32XX_TS_PM_OPS, | ||
393 | }, | ||
394 | }; | ||
395 | |||
396 | static int __init lpc32xx_ts_init(void) | ||
397 | { | ||
398 | return platform_driver_register(&lpc32xx_ts_driver); | ||
399 | } | ||
400 | module_init(lpc32xx_ts_init); | ||
401 | |||
402 | static void __exit lpc32xx_ts_exit(void) | ||
403 | { | ||
404 | platform_driver_unregister(&lpc32xx_ts_driver); | ||
405 | } | ||
406 | module_exit(lpc32xx_ts_exit); | ||
407 | |||
408 | MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com"); | ||
409 | MODULE_DESCRIPTION("LPC32XX TSC Driver"); | ||
410 | MODULE_LICENSE("GPL"); | ||
411 | MODULE_ALIAS("platform:lpc32xx_ts"); | ||
diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c index 6085d12fd561..8feb7f3c8be1 100644 --- a/drivers/input/touchscreen/s3c2410_ts.c +++ b/drivers/input/touchscreen/s3c2410_ts.c | |||
@@ -350,7 +350,7 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev) | |||
350 | err_tcirq: | 350 | err_tcirq: |
351 | free_irq(ts.irq_tc, ts.input); | 351 | free_irq(ts.irq_tc, ts.input); |
352 | err_inputdev: | 352 | err_inputdev: |
353 | input_unregister_device(ts.input); | 353 | input_free_device(ts.input); |
354 | err_iomap: | 354 | err_iomap: |
355 | iounmap(ts.io); | 355 | iounmap(ts.io); |
356 | err_clk: | 356 | err_clk: |
diff --git a/drivers/input/touchscreen/stmpe-ts.c b/drivers/input/touchscreen/stmpe-ts.c index 656148ec0027..ae88e13c99ff 100644 --- a/drivers/input/touchscreen/stmpe-ts.c +++ b/drivers/input/touchscreen/stmpe-ts.c | |||
@@ -268,7 +268,7 @@ static int __devinit stmpe_input_probe(struct platform_device *pdev) | |||
268 | struct stmpe_touch *ts; | 268 | struct stmpe_touch *ts; |
269 | struct input_dev *idev; | 269 | struct input_dev *idev; |
270 | struct stmpe_ts_platform_data *ts_pdata = NULL; | 270 | struct stmpe_ts_platform_data *ts_pdata = NULL; |
271 | int ret = 0; | 271 | int ret; |
272 | int ts_irq; | 272 | int ts_irq; |
273 | 273 | ||
274 | ts_irq = platform_get_irq_byname(pdev, "FIFO_TH"); | 274 | ts_irq = platform_get_irq_byname(pdev, "FIFO_TH"); |
@@ -276,12 +276,16 @@ static int __devinit stmpe_input_probe(struct platform_device *pdev) | |||
276 | return ts_irq; | 276 | return ts_irq; |
277 | 277 | ||
278 | ts = kzalloc(sizeof(*ts), GFP_KERNEL); | 278 | ts = kzalloc(sizeof(*ts), GFP_KERNEL); |
279 | if (!ts) | 279 | if (!ts) { |
280 | ret = -ENOMEM; | ||
280 | goto err_out; | 281 | goto err_out; |
282 | } | ||
281 | 283 | ||
282 | idev = input_allocate_device(); | 284 | idev = input_allocate_device(); |
283 | if (!idev) | 285 | if (!idev) { |
286 | ret = -ENOMEM; | ||
284 | goto err_free_ts; | 287 | goto err_free_ts; |
288 | } | ||
285 | 289 | ||
286 | platform_set_drvdata(pdev, ts); | 290 | platform_set_drvdata(pdev, ts); |
287 | ts->stmpe = stmpe; | 291 | ts->stmpe = stmpe; |
@@ -361,7 +365,6 @@ static int __devexit stmpe_ts_remove(struct platform_device *pdev) | |||
361 | platform_set_drvdata(pdev, NULL); | 365 | platform_set_drvdata(pdev, NULL); |
362 | 366 | ||
363 | input_unregister_device(ts->idev); | 367 | input_unregister_device(ts->idev); |
364 | input_free_device(ts->idev); | ||
365 | 368 | ||
366 | kfree(ts); | 369 | kfree(ts); |
367 | 370 | ||
diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c index a644d18c04dc..c8c136cf7bbc 100644 --- a/drivers/input/touchscreen/tps6507x-ts.c +++ b/drivers/input/touchscreen/tps6507x-ts.c | |||
@@ -335,6 +335,7 @@ static int tps6507x_ts_probe(struct platform_device *pdev) | |||
335 | dev_err(tsc->dev, "schedule failed"); | 335 | dev_err(tsc->dev, "schedule failed"); |
336 | goto err2; | 336 | goto err2; |
337 | } | 337 | } |
338 | platform_set_drvdata(pdev, tps6507x_dev); | ||
338 | 339 | ||
339 | return 0; | 340 | return 0; |
340 | 341 | ||
@@ -358,7 +359,7 @@ static int __devexit tps6507x_ts_remove(struct platform_device *pdev) | |||
358 | cancel_delayed_work_sync(&tsc->work); | 359 | cancel_delayed_work_sync(&tsc->work); |
359 | destroy_workqueue(tsc->wq); | 360 | destroy_workqueue(tsc->wq); |
360 | 361 | ||
361 | input_free_device(input_dev); | 362 | input_unregister_device(input_dev); |
362 | 363 | ||
363 | tps6507x_dev->ts = NULL; | 364 | tps6507x_dev->ts = NULL; |
364 | kfree(tsc); | 365 | kfree(tsc); |
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c index be23780e8a3e..80467f262331 100644 --- a/drivers/input/touchscreen/tsc2007.c +++ b/drivers/input/touchscreen/tsc2007.c | |||
@@ -265,7 +265,7 @@ static int __devinit tsc2007_probe(struct i2c_client *client, | |||
265 | const struct i2c_device_id *id) | 265 | const struct i2c_device_id *id) |
266 | { | 266 | { |
267 | struct tsc2007 *ts; | 267 | struct tsc2007 *ts; |
268 | struct tsc2007_platform_data *pdata = pdata = client->dev.platform_data; | 268 | struct tsc2007_platform_data *pdata = client->dev.platform_data; |
269 | struct input_dev *input_dev; | 269 | struct input_dev *input_dev; |
270 | int err; | 270 | int err; |
271 | 271 | ||
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index 56dc35c94bb1..9ae4c7b16ba7 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Wacom W8001 penabled serial touchscreen driver | 2 | * Wacom W8001 penabled serial touchscreen driver |
3 | * | 3 | * |
4 | * Copyright (c) 2008 Jaya Kumar | 4 | * Copyright (c) 2008 Jaya Kumar |
5 | * Copyright (c) 2010 Red Hat, Inc. | ||
5 | * | 6 | * |
6 | * This file is subject to the terms and conditions of the GNU General Public | 7 | * This file is subject to the terms and conditions of the GNU General Public |
7 | * License. See the file COPYING in the main directory of this archive for | 8 | * License. See the file COPYING in the main directory of this archive for |
@@ -30,11 +31,24 @@ MODULE_LICENSE("GPL"); | |||
30 | #define W8001_LEAD_BYTE 0x80 | 31 | #define W8001_LEAD_BYTE 0x80 |
31 | #define W8001_TAB_MASK 0x40 | 32 | #define W8001_TAB_MASK 0x40 |
32 | #define W8001_TAB_BYTE 0x40 | 33 | #define W8001_TAB_BYTE 0x40 |
34 | /* set in first byte of touch data packets */ | ||
35 | #define W8001_TOUCH_MASK (0x10 | W8001_LEAD_MASK) | ||
36 | #define W8001_TOUCH_BYTE (0x10 | W8001_LEAD_BYTE) | ||
33 | 37 | ||
34 | #define W8001_QUERY_PACKET 0x20 | 38 | #define W8001_QUERY_PACKET 0x20 |
35 | 39 | ||
36 | #define W8001_CMD_START '1' | 40 | #define W8001_CMD_START '1' |
37 | #define W8001_CMD_QUERY '*' | 41 | #define W8001_CMD_QUERY '*' |
42 | #define W8001_CMD_TOUCHQUERY '%' | ||
43 | |||
44 | /* length of data packets in bytes, depends on device. */ | ||
45 | #define W8001_PKTLEN_TOUCH93 5 | ||
46 | #define W8001_PKTLEN_TOUCH9A 7 | ||
47 | #define W8001_PKTLEN_TPCPEN 9 | ||
48 | #define W8001_PKTLEN_TPCCTL 11 /* control packet */ | ||
49 | #define W8001_PKTLEN_TOUCH2FG 13 | ||
50 | |||
51 | #define MAX_TRACKING_ID 0xFF /* arbitrarily chosen */ | ||
38 | 52 | ||
39 | struct w8001_coord { | 53 | struct w8001_coord { |
40 | u8 rdy; | 54 | u8 rdy; |
@@ -48,6 +62,15 @@ struct w8001_coord { | |||
48 | u8 tilt_y; | 62 | u8 tilt_y; |
49 | }; | 63 | }; |
50 | 64 | ||
65 | /* touch query reply packet */ | ||
66 | struct w8001_touch_query { | ||
67 | u8 panel_res; | ||
68 | u8 capacity_res; | ||
69 | u8 sensor_id; | ||
70 | u16 x; | ||
71 | u16 y; | ||
72 | }; | ||
73 | |||
51 | /* | 74 | /* |
52 | * Per-touchscreen data. | 75 | * Per-touchscreen data. |
53 | */ | 76 | */ |
@@ -62,6 +85,9 @@ struct w8001 { | |||
62 | unsigned char response[W8001_MAX_LENGTH]; | 85 | unsigned char response[W8001_MAX_LENGTH]; |
63 | unsigned char data[W8001_MAX_LENGTH]; | 86 | unsigned char data[W8001_MAX_LENGTH]; |
64 | char phys[32]; | 87 | char phys[32]; |
88 | int type; | ||
89 | unsigned int pktlen; | ||
90 | int trkid[2]; | ||
65 | }; | 91 | }; |
66 | 92 | ||
67 | static void parse_data(u8 *data, struct w8001_coord *coord) | 93 | static void parse_data(u8 *data, struct w8001_coord *coord) |
@@ -88,11 +114,98 @@ static void parse_data(u8 *data, struct w8001_coord *coord) | |||
88 | coord->tilt_y = data[8] & 0x7F; | 114 | coord->tilt_y = data[8] & 0x7F; |
89 | } | 115 | } |
90 | 116 | ||
117 | static void parse_touch(struct w8001 *w8001) | ||
118 | { | ||
119 | static int trkid; | ||
120 | struct input_dev *dev = w8001->dev; | ||
121 | unsigned char *data = w8001->data; | ||
122 | int i; | ||
123 | |||
124 | for (i = 0; i < 2; i++) { | ||
125 | input_mt_slot(dev, i); | ||
126 | |||
127 | if (data[0] & (1 << i)) { | ||
128 | int x = (data[6 * i + 1] << 7) | (data[6 * i + 2]); | ||
129 | int y = (data[6 * i + 3] << 7) | (data[6 * i + 4]); | ||
130 | /* data[5,6] and [11,12] is finger capacity */ | ||
131 | |||
132 | input_report_abs(dev, ABS_MT_POSITION_X, x); | ||
133 | input_report_abs(dev, ABS_MT_POSITION_Y, y); | ||
134 | input_report_abs(dev, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER); | ||
135 | if (w8001->trkid[i] < 0) | ||
136 | w8001->trkid[i] = trkid++ & MAX_TRACKING_ID; | ||
137 | } else { | ||
138 | w8001->trkid[i] = -1; | ||
139 | } | ||
140 | input_report_abs(dev, ABS_MT_TRACKING_ID, w8001->trkid[i]); | ||
141 | } | ||
142 | |||
143 | input_sync(dev); | ||
144 | } | ||
145 | |||
146 | static void parse_touchquery(u8 *data, struct w8001_touch_query *query) | ||
147 | { | ||
148 | memset(query, 0, sizeof(*query)); | ||
149 | |||
150 | query->panel_res = data[1]; | ||
151 | query->sensor_id = data[2] & 0x7; | ||
152 | query->capacity_res = data[7]; | ||
153 | |||
154 | query->x = data[3] << 9; | ||
155 | query->x |= data[4] << 2; | ||
156 | query->x |= (data[2] >> 5) & 0x3; | ||
157 | |||
158 | query->y = data[5] << 9; | ||
159 | query->y |= data[6] << 2; | ||
160 | query->y |= (data[2] >> 3) & 0x3; | ||
161 | } | ||
162 | |||
163 | static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord) | ||
164 | { | ||
165 | struct input_dev *dev = w8001->dev; | ||
166 | |||
167 | /* | ||
168 | * We have 1 bit for proximity (rdy) and 3 bits for tip, side, | ||
169 | * side2/eraser. If rdy && f2 are set, this can be either pen + side2, | ||
170 | * or eraser. assume | ||
171 | * - if dev is already in proximity and f2 is toggled → pen + side2 | ||
172 | * - if dev comes into proximity with f2 set → eraser | ||
173 | * If f2 disappears after assuming eraser, fake proximity out for | ||
174 | * eraser and in for pen. | ||
175 | */ | ||
176 | |||
177 | if (!w8001->type) { | ||
178 | w8001->type = coord->f2 ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | ||
179 | } else if (w8001->type == BTN_TOOL_RUBBER) { | ||
180 | if (!coord->f2) { | ||
181 | input_report_abs(dev, ABS_PRESSURE, 0); | ||
182 | input_report_key(dev, BTN_TOUCH, 0); | ||
183 | input_report_key(dev, BTN_STYLUS, 0); | ||
184 | input_report_key(dev, BTN_STYLUS2, 0); | ||
185 | input_report_key(dev, BTN_TOOL_RUBBER, 0); | ||
186 | input_sync(dev); | ||
187 | w8001->type = BTN_TOOL_PEN; | ||
188 | } | ||
189 | } else { | ||
190 | input_report_key(dev, BTN_STYLUS2, coord->f2); | ||
191 | } | ||
192 | |||
193 | input_report_abs(dev, ABS_X, coord->x); | ||
194 | input_report_abs(dev, ABS_Y, coord->y); | ||
195 | input_report_abs(dev, ABS_PRESSURE, coord->pen_pressure); | ||
196 | input_report_key(dev, BTN_TOUCH, coord->tsw); | ||
197 | input_report_key(dev, BTN_STYLUS, coord->f1); | ||
198 | input_report_key(dev, w8001->type, coord->rdy); | ||
199 | input_sync(dev); | ||
200 | |||
201 | if (!coord->rdy) | ||
202 | w8001->type = 0; | ||
203 | } | ||
204 | |||
91 | static irqreturn_t w8001_interrupt(struct serio *serio, | 205 | static irqreturn_t w8001_interrupt(struct serio *serio, |
92 | unsigned char data, unsigned int flags) | 206 | unsigned char data, unsigned int flags) |
93 | { | 207 | { |
94 | struct w8001 *w8001 = serio_get_drvdata(serio); | 208 | struct w8001 *w8001 = serio_get_drvdata(serio); |
95 | struct input_dev *dev = w8001->dev; | ||
96 | struct w8001_coord coord; | 209 | struct w8001_coord coord; |
97 | unsigned char tmp; | 210 | unsigned char tmp; |
98 | 211 | ||
@@ -105,26 +218,45 @@ static irqreturn_t w8001_interrupt(struct serio *serio, | |||
105 | } | 218 | } |
106 | break; | 219 | break; |
107 | 220 | ||
108 | case 8: | 221 | case W8001_PKTLEN_TOUCH93 - 1: |
222 | case W8001_PKTLEN_TOUCH9A - 1: | ||
223 | /* ignore one-finger touch packet. */ | ||
224 | if (w8001->pktlen == w8001->idx) | ||
225 | w8001->idx = 0; | ||
226 | break; | ||
227 | |||
228 | /* Pen coordinates packet */ | ||
229 | case W8001_PKTLEN_TPCPEN - 1: | ||
109 | tmp = w8001->data[0] & W8001_TAB_MASK; | 230 | tmp = w8001->data[0] & W8001_TAB_MASK; |
110 | if (unlikely(tmp == W8001_TAB_BYTE)) | 231 | if (unlikely(tmp == W8001_TAB_BYTE)) |
111 | break; | 232 | break; |
112 | 233 | ||
234 | tmp = (w8001->data[0] & W8001_TOUCH_BYTE); | ||
235 | if (tmp == W8001_TOUCH_BYTE) | ||
236 | break; | ||
237 | |||
113 | w8001->idx = 0; | 238 | w8001->idx = 0; |
114 | parse_data(w8001->data, &coord); | 239 | parse_data(w8001->data, &coord); |
115 | input_report_abs(dev, ABS_X, coord.x); | 240 | report_pen_events(w8001, &coord); |
116 | input_report_abs(dev, ABS_Y, coord.y); | ||
117 | input_report_abs(dev, ABS_PRESSURE, coord.pen_pressure); | ||
118 | input_report_key(dev, BTN_TOUCH, coord.tsw); | ||
119 | input_sync(dev); | ||
120 | break; | 241 | break; |
121 | 242 | ||
122 | case 10: | 243 | /* control packet */ |
244 | case W8001_PKTLEN_TPCCTL - 1: | ||
245 | tmp = (w8001->data[0] & W8001_TOUCH_MASK); | ||
246 | if (tmp == W8001_TOUCH_BYTE) | ||
247 | break; | ||
248 | |||
123 | w8001->idx = 0; | 249 | w8001->idx = 0; |
124 | memcpy(w8001->response, w8001->data, W8001_MAX_LENGTH); | 250 | memcpy(w8001->response, w8001->data, W8001_MAX_LENGTH); |
125 | w8001->response_type = W8001_QUERY_PACKET; | 251 | w8001->response_type = W8001_QUERY_PACKET; |
126 | complete(&w8001->cmd_done); | 252 | complete(&w8001->cmd_done); |
127 | break; | 253 | break; |
254 | |||
255 | /* 2 finger touch packet */ | ||
256 | case W8001_PKTLEN_TOUCH2FG - 1: | ||
257 | w8001->idx = 0; | ||
258 | parse_touch(w8001); | ||
259 | break; | ||
128 | } | 260 | } |
129 | 261 | ||
130 | return IRQ_HANDLED; | 262 | return IRQ_HANDLED; |
@@ -167,6 +299,38 @@ static int w8001_setup(struct w8001 *w8001) | |||
167 | input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); | 299 | input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); |
168 | input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0); | 300 | input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0); |
169 | 301 | ||
302 | error = w8001_command(w8001, W8001_CMD_TOUCHQUERY, true); | ||
303 | if (!error) { | ||
304 | struct w8001_touch_query touch; | ||
305 | |||
306 | parse_touchquery(w8001->response, &touch); | ||
307 | |||
308 | switch (touch.sensor_id) { | ||
309 | case 0: | ||
310 | case 2: | ||
311 | w8001->pktlen = W8001_PKTLEN_TOUCH93; | ||
312 | break; | ||
313 | case 1: | ||
314 | case 3: | ||
315 | case 4: | ||
316 | w8001->pktlen = W8001_PKTLEN_TOUCH9A; | ||
317 | break; | ||
318 | case 5: | ||
319 | w8001->pktlen = W8001_PKTLEN_TOUCH2FG; | ||
320 | |||
321 | input_mt_create_slots(dev, 2); | ||
322 | input_set_abs_params(dev, ABS_MT_TRACKING_ID, | ||
323 | 0, MAX_TRACKING_ID, 0, 0); | ||
324 | input_set_abs_params(dev, ABS_MT_POSITION_X, | ||
325 | 0, touch.x, 0, 0); | ||
326 | input_set_abs_params(dev, ABS_MT_POSITION_Y, | ||
327 | 0, touch.y, 0, 0); | ||
328 | input_set_abs_params(dev, ABS_MT_TOOL_TYPE, | ||
329 | 0, 0, 0, 0); | ||
330 | break; | ||
331 | } | ||
332 | } | ||
333 | |||
170 | return w8001_command(w8001, W8001_CMD_START, false); | 334 | return w8001_command(w8001, W8001_CMD_START, false); |
171 | } | 335 | } |
172 | 336 | ||
@@ -208,6 +372,7 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) | |||
208 | w8001->serio = serio; | 372 | w8001->serio = serio; |
209 | w8001->id = serio->id.id; | 373 | w8001->id = serio->id.id; |
210 | w8001->dev = input_dev; | 374 | w8001->dev = input_dev; |
375 | w8001->trkid[0] = w8001->trkid[1] = -1; | ||
211 | init_completion(&w8001->cmd_done); | 376 | init_completion(&w8001->cmd_done); |
212 | snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys); | 377 | snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys); |
213 | 378 | ||
@@ -221,6 +386,10 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) | |||
221 | 386 | ||
222 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 387 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
223 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | 388 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); |
389 | input_dev->keybit[BIT_WORD(BTN_TOOL_PEN)] |= BIT_MASK(BTN_TOOL_PEN); | ||
390 | input_dev->keybit[BIT_WORD(BTN_TOOL_RUBBER)] |= BIT_MASK(BTN_TOOL_RUBBER); | ||
391 | input_dev->keybit[BIT_WORD(BTN_STYLUS)] |= BIT_MASK(BTN_STYLUS); | ||
392 | input_dev->keybit[BIT_WORD(BTN_STYLUS2)] |= BIT_MASK(BTN_STYLUS2); | ||
224 | 393 | ||
225 | serio_set_drvdata(serio, w8001); | 394 | serio_set_drvdata(serio, w8001); |
226 | err = serio_open(serio, drv); | 395 | err = serio_open(serio, drv); |
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index cbfef1ea7e30..6b75c9f660ae 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c | |||
@@ -125,6 +125,8 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel) | |||
125 | { | 125 | { |
126 | int power_adc = 0, auxval; | 126 | int power_adc = 0, auxval; |
127 | u16 power = 0; | 127 | u16 power = 0; |
128 | int rc = 0; | ||
129 | int timeout = 0; | ||
128 | 130 | ||
129 | /* get codec */ | 131 | /* get codec */ |
130 | mutex_lock(&wm->codec_mutex); | 132 | mutex_lock(&wm->codec_mutex); |
@@ -143,7 +145,9 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel) | |||
143 | 145 | ||
144 | /* Turn polling mode on to read AUX ADC */ | 146 | /* Turn polling mode on to read AUX ADC */ |
145 | wm->pen_probably_down = 1; | 147 | wm->pen_probably_down = 1; |
146 | wm->codec->poll_sample(wm, adcsel, &auxval); | 148 | |
149 | while (rc != RC_VALID && timeout++ < 5) | ||
150 | rc = wm->codec->poll_sample(wm, adcsel, &auxval); | ||
147 | 151 | ||
148 | if (power_adc) | 152 | if (power_adc) |
149 | wm97xx_reg_write(wm, AC97_EXTENDED_MID, power | 0x8000); | 153 | wm97xx_reg_write(wm, AC97_EXTENDED_MID, power | 0x8000); |
@@ -152,8 +156,15 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel) | |||
152 | 156 | ||
153 | wm->pen_probably_down = 0; | 157 | wm->pen_probably_down = 0; |
154 | 158 | ||
159 | if (timeout >= 5) { | ||
160 | dev_err(wm->dev, | ||
161 | "timeout reading auxadc %d, disabling digitiser\n", | ||
162 | adcsel); | ||
163 | wm->codec->dig_enable(wm, false); | ||
164 | } | ||
165 | |||
155 | mutex_unlock(&wm->codec_mutex); | 166 | mutex_unlock(&wm->codec_mutex); |
156 | return auxval & 0xfff; | 167 | return (rc == RC_VALID ? auxval & 0xfff : -EBUSY); |
157 | } | 168 | } |
158 | EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc); | 169 | EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc); |
159 | 170 | ||
@@ -684,8 +695,7 @@ static int wm97xx_probe(struct device *dev) | |||
684 | touch_reg_err: | 695 | touch_reg_err: |
685 | platform_device_put(wm->touch_dev); | 696 | platform_device_put(wm->touch_dev); |
686 | touch_err: | 697 | touch_err: |
687 | platform_device_unregister(wm->battery_dev); | 698 | platform_device_del(wm->battery_dev); |
688 | wm->battery_dev = NULL; | ||
689 | batt_reg_err: | 699 | batt_reg_err: |
690 | platform_device_put(wm->battery_dev); | 700 | platform_device_put(wm->battery_dev); |
691 | batt_err: | 701 | batt_err: |
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index 7961d59f5cac..c06b4d50a3dc 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c | |||
@@ -25,14 +25,56 @@ | |||
25 | #define IR_KEYPRESS_TIMEOUT 250 | 25 | #define IR_KEYPRESS_TIMEOUT 250 |
26 | 26 | ||
27 | /** | 27 | /** |
28 | * ir_create_table() - initializes a scancode table | ||
29 | * @rc_tab: the ir_scancode_table to initialize | ||
30 | * @name: name to assign to the table | ||
31 | * @ir_type: ir type to assign to the new table | ||
32 | * @size: initial size of the table | ||
33 | * @return: zero on success or a negative error code | ||
34 | * | ||
35 | * This routine will initialize the ir_scancode_table and will allocate | ||
36 | * memory to hold at least the specified number elements. | ||
37 | */ | ||
38 | static int ir_create_table(struct ir_scancode_table *rc_tab, | ||
39 | const char *name, u64 ir_type, size_t size) | ||
40 | { | ||
41 | rc_tab->name = name; | ||
42 | rc_tab->ir_type = ir_type; | ||
43 | rc_tab->alloc = roundup_pow_of_two(size * sizeof(struct ir_scancode)); | ||
44 | rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode); | ||
45 | rc_tab->scan = kmalloc(rc_tab->alloc, GFP_KERNEL); | ||
46 | if (!rc_tab->scan) | ||
47 | return -ENOMEM; | ||
48 | |||
49 | IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", | ||
50 | rc_tab->size, rc_tab->alloc); | ||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | /** | ||
55 | * ir_free_table() - frees memory allocated by a scancode table | ||
56 | * @rc_tab: the table whose mappings need to be freed | ||
57 | * | ||
58 | * This routine will free memory alloctaed for key mappings used by given | ||
59 | * scancode table. | ||
60 | */ | ||
61 | static void ir_free_table(struct ir_scancode_table *rc_tab) | ||
62 | { | ||
63 | rc_tab->size = 0; | ||
64 | kfree(rc_tab->scan); | ||
65 | rc_tab->scan = NULL; | ||
66 | } | ||
67 | |||
68 | /** | ||
28 | * ir_resize_table() - resizes a scancode table if necessary | 69 | * ir_resize_table() - resizes a scancode table if necessary |
29 | * @rc_tab: the ir_scancode_table to resize | 70 | * @rc_tab: the ir_scancode_table to resize |
71 | * @gfp_flags: gfp flags to use when allocating memory | ||
30 | * @return: zero on success or a negative error code | 72 | * @return: zero on success or a negative error code |
31 | * | 73 | * |
32 | * This routine will shrink the ir_scancode_table if it has lots of | 74 | * This routine will shrink the ir_scancode_table if it has lots of |
33 | * unused entries and grow it if it is full. | 75 | * unused entries and grow it if it is full. |
34 | */ | 76 | */ |
35 | static int ir_resize_table(struct ir_scancode_table *rc_tab) | 77 | static int ir_resize_table(struct ir_scancode_table *rc_tab, gfp_t gfp_flags) |
36 | { | 78 | { |
37 | unsigned int oldalloc = rc_tab->alloc; | 79 | unsigned int oldalloc = rc_tab->alloc; |
38 | unsigned int newalloc = oldalloc; | 80 | unsigned int newalloc = oldalloc; |
@@ -57,7 +99,7 @@ static int ir_resize_table(struct ir_scancode_table *rc_tab) | |||
57 | if (newalloc == oldalloc) | 99 | if (newalloc == oldalloc) |
58 | return 0; | 100 | return 0; |
59 | 101 | ||
60 | newscan = kmalloc(newalloc, GFP_ATOMIC); | 102 | newscan = kmalloc(newalloc, gfp_flags); |
61 | if (!newscan) { | 103 | if (!newscan) { |
62 | IR_dprintk(1, "Failed to kmalloc %u bytes\n", newalloc); | 104 | IR_dprintk(1, "Failed to kmalloc %u bytes\n", newalloc); |
63 | return -ENOMEM; | 105 | return -ENOMEM; |
@@ -72,26 +114,78 @@ static int ir_resize_table(struct ir_scancode_table *rc_tab) | |||
72 | } | 114 | } |
73 | 115 | ||
74 | /** | 116 | /** |
75 | * ir_do_setkeycode() - internal function to set a keycode in the | 117 | * ir_update_mapping() - set a keycode in the scancode->keycode table |
76 | * scancode->keycode table | ||
77 | * @dev: the struct input_dev device descriptor | 118 | * @dev: the struct input_dev device descriptor |
78 | * @rc_tab: the struct ir_scancode_table to set the keycode in | 119 | * @rc_tab: scancode table to be adjusted |
79 | * @scancode: the scancode for the ir command | 120 | * @index: index of the mapping that needs to be updated |
80 | * @keycode: the keycode for the ir command | 121 | * @keycode: the desired keycode |
81 | * @resize: whether the keytable may be shrunk | 122 | * @return: previous keycode assigned to the mapping |
82 | * @return: -EINVAL if the keycode could not be inserted, otherwise zero. | 123 | * |
124 | * This routine is used to update scancode->keycopde mapping at given | ||
125 | * position. | ||
126 | */ | ||
127 | static unsigned int ir_update_mapping(struct input_dev *dev, | ||
128 | struct ir_scancode_table *rc_tab, | ||
129 | unsigned int index, | ||
130 | unsigned int new_keycode) | ||
131 | { | ||
132 | int old_keycode = rc_tab->scan[index].keycode; | ||
133 | int i; | ||
134 | |||
135 | /* Did the user wish to remove the mapping? */ | ||
136 | if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) { | ||
137 | IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", | ||
138 | index, rc_tab->scan[index].scancode); | ||
139 | rc_tab->len--; | ||
140 | memmove(&rc_tab->scan[index], &rc_tab->scan[index+ 1], | ||
141 | (rc_tab->len - index) * sizeof(struct ir_scancode)); | ||
142 | } else { | ||
143 | IR_dprintk(1, "#%d: %s scan 0x%04x with key 0x%04x\n", | ||
144 | index, | ||
145 | old_keycode == KEY_RESERVED ? "New" : "Replacing", | ||
146 | rc_tab->scan[index].scancode, new_keycode); | ||
147 | rc_tab->scan[index].keycode = new_keycode; | ||
148 | __set_bit(new_keycode, dev->keybit); | ||
149 | } | ||
150 | |||
151 | if (old_keycode != KEY_RESERVED) { | ||
152 | /* A previous mapping was updated... */ | ||
153 | __clear_bit(old_keycode, dev->keybit); | ||
154 | /* ... but another scancode might use the same keycode */ | ||
155 | for (i = 0; i < rc_tab->len; i++) { | ||
156 | if (rc_tab->scan[i].keycode == old_keycode) { | ||
157 | __set_bit(old_keycode, dev->keybit); | ||
158 | break; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | /* Possibly shrink the keytable, failure is not a problem */ | ||
163 | ir_resize_table(rc_tab, GFP_ATOMIC); | ||
164 | } | ||
165 | |||
166 | return old_keycode; | ||
167 | } | ||
168 | |||
169 | /** | ||
170 | * ir_locate_scancode() - set a keycode in the scancode->keycode table | ||
171 | * @ir_dev: the struct ir_input_dev device descriptor | ||
172 | * @rc_tab: scancode table to be searched | ||
173 | * @scancode: the desired scancode | ||
174 | * @resize: controls whether we allowed to resize the table to | ||
175 | * accomodate not yet present scancodes | ||
176 | * @return: index of the mapping containing scancode in question | ||
177 | * or -1U in case of failure. | ||
83 | * | 178 | * |
84 | * This routine is used internally to manipulate the scancode->keycode table. | 179 | * This routine is used to locate given scancode in ir_scancode_table. |
85 | * The caller has to hold @rc_tab->lock. | 180 | * If scancode is not yet present the routine will allocate a new slot |
181 | * for it. | ||
86 | */ | 182 | */ |
87 | static int ir_do_setkeycode(struct input_dev *dev, | 183 | static unsigned int ir_establish_scancode(struct ir_input_dev *ir_dev, |
88 | struct ir_scancode_table *rc_tab, | 184 | struct ir_scancode_table *rc_tab, |
89 | unsigned scancode, unsigned keycode, | 185 | unsigned int scancode, |
90 | bool resize) | 186 | bool resize) |
91 | { | 187 | { |
92 | unsigned int i; | 188 | unsigned int i; |
93 | int old_keycode = KEY_RESERVED; | ||
94 | struct ir_input_dev *ir_dev = input_get_drvdata(dev); | ||
95 | 189 | ||
96 | /* | 190 | /* |
97 | * Unfortunately, some hardware-based IR decoders don't provide | 191 | * Unfortunately, some hardware-based IR decoders don't provide |
@@ -100,65 +194,34 @@ static int ir_do_setkeycode(struct input_dev *dev, | |||
100 | * the provided IR with another one, it is needed to allow loading | 194 | * the provided IR with another one, it is needed to allow loading |
101 | * IR tables from other remotes. So, | 195 | * IR tables from other remotes. So, |
102 | */ | 196 | */ |
103 | if (ir_dev->props && ir_dev->props->scanmask) { | 197 | if (ir_dev->props && ir_dev->props->scanmask) |
104 | scancode &= ir_dev->props->scanmask; | 198 | scancode &= ir_dev->props->scanmask; |
105 | } | ||
106 | 199 | ||
107 | /* First check if we already have a mapping for this ir command */ | 200 | /* First check if we already have a mapping for this ir command */ |
108 | for (i = 0; i < rc_tab->len; i++) { | 201 | for (i = 0; i < rc_tab->len; i++) { |
202 | if (rc_tab->scan[i].scancode == scancode) | ||
203 | return i; | ||
204 | |||
109 | /* Keytable is sorted from lowest to highest scancode */ | 205 | /* Keytable is sorted from lowest to highest scancode */ |
110 | if (rc_tab->scan[i].scancode > scancode) | 206 | if (rc_tab->scan[i].scancode >= scancode) |
111 | break; | 207 | break; |
112 | else if (rc_tab->scan[i].scancode < scancode) | ||
113 | continue; | ||
114 | |||
115 | old_keycode = rc_tab->scan[i].keycode; | ||
116 | rc_tab->scan[i].keycode = keycode; | ||
117 | |||
118 | /* Did the user wish to remove the mapping? */ | ||
119 | if (keycode == KEY_RESERVED || keycode == KEY_UNKNOWN) { | ||
120 | IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", | ||
121 | i, scancode); | ||
122 | rc_tab->len--; | ||
123 | memmove(&rc_tab->scan[i], &rc_tab->scan[i + 1], | ||
124 | (rc_tab->len - i) * sizeof(struct ir_scancode)); | ||
125 | } | ||
126 | |||
127 | /* Possibly shrink the keytable, failure is not a problem */ | ||
128 | ir_resize_table(rc_tab); | ||
129 | break; | ||
130 | } | 208 | } |
131 | 209 | ||
132 | if (old_keycode == KEY_RESERVED && keycode != KEY_RESERVED) { | 210 | /* No previous mapping found, we might need to grow the table */ |
133 | /* No previous mapping found, we might need to grow the table */ | 211 | if (rc_tab->size == rc_tab->len) { |
134 | if (resize && ir_resize_table(rc_tab)) | 212 | if (!resize || ir_resize_table(rc_tab, GFP_ATOMIC)) |
135 | return -ENOMEM; | 213 | return -1U; |
136 | 214 | } | |
137 | IR_dprintk(1, "#%d: New scan 0x%04x with key 0x%04x\n", | ||
138 | i, scancode, keycode); | ||
139 | 215 | ||
140 | /* i is the proper index to insert our new keycode */ | 216 | /* i is the proper index to insert our new keycode */ |
217 | if (i < rc_tab->len) | ||
141 | memmove(&rc_tab->scan[i + 1], &rc_tab->scan[i], | 218 | memmove(&rc_tab->scan[i + 1], &rc_tab->scan[i], |
142 | (rc_tab->len - i) * sizeof(struct ir_scancode)); | 219 | (rc_tab->len - i) * sizeof(struct ir_scancode)); |
143 | rc_tab->scan[i].scancode = scancode; | 220 | rc_tab->scan[i].scancode = scancode; |
144 | rc_tab->scan[i].keycode = keycode; | 221 | rc_tab->scan[i].keycode = KEY_RESERVED; |
145 | rc_tab->len++; | 222 | rc_tab->len++; |
146 | set_bit(keycode, dev->keybit); | ||
147 | } else { | ||
148 | IR_dprintk(1, "#%d: Replacing scan 0x%04x with key 0x%04x\n", | ||
149 | i, scancode, keycode); | ||
150 | /* A previous mapping was updated... */ | ||
151 | clear_bit(old_keycode, dev->keybit); | ||
152 | /* ...but another scancode might use the same keycode */ | ||
153 | for (i = 0; i < rc_tab->len; i++) { | ||
154 | if (rc_tab->scan[i].keycode == old_keycode) { | ||
155 | set_bit(old_keycode, dev->keybit); | ||
156 | break; | ||
157 | } | ||
158 | } | ||
159 | } | ||
160 | 223 | ||
161 | return 0; | 224 | return i; |
162 | } | 225 | } |
163 | 226 | ||
164 | /** | 227 | /** |
@@ -171,17 +234,41 @@ static int ir_do_setkeycode(struct input_dev *dev, | |||
171 | * This routine is used to handle evdev EVIOCSKEY ioctl. | 234 | * This routine is used to handle evdev EVIOCSKEY ioctl. |
172 | */ | 235 | */ |
173 | static int ir_setkeycode(struct input_dev *dev, | 236 | static int ir_setkeycode(struct input_dev *dev, |
174 | unsigned int scancode, unsigned int keycode) | 237 | const struct input_keymap_entry *ke, |
238 | unsigned int *old_keycode) | ||
175 | { | 239 | { |
176 | int rc; | ||
177 | unsigned long flags; | ||
178 | struct ir_input_dev *ir_dev = input_get_drvdata(dev); | 240 | struct ir_input_dev *ir_dev = input_get_drvdata(dev); |
179 | struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; | 241 | struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; |
242 | unsigned int index; | ||
243 | unsigned int scancode; | ||
244 | int retval; | ||
245 | unsigned long flags; | ||
180 | 246 | ||
181 | spin_lock_irqsave(&rc_tab->lock, flags); | 247 | spin_lock_irqsave(&rc_tab->lock, flags); |
182 | rc = ir_do_setkeycode(dev, rc_tab, scancode, keycode, true); | 248 | |
249 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) { | ||
250 | index = ke->index; | ||
251 | if (index >= rc_tab->len) { | ||
252 | retval = -EINVAL; | ||
253 | goto out; | ||
254 | } | ||
255 | } else { | ||
256 | retval = input_scancode_to_scalar(ke, &scancode); | ||
257 | if (retval) | ||
258 | goto out; | ||
259 | |||
260 | index = ir_establish_scancode(ir_dev, rc_tab, scancode, true); | ||
261 | if (index >= rc_tab->len) { | ||
262 | retval = -ENOMEM; | ||
263 | goto out; | ||
264 | } | ||
265 | } | ||
266 | |||
267 | *old_keycode = ir_update_mapping(dev, rc_tab, index, ke->keycode); | ||
268 | |||
269 | out: | ||
183 | spin_unlock_irqrestore(&rc_tab->lock, flags); | 270 | spin_unlock_irqrestore(&rc_tab->lock, flags); |
184 | return rc; | 271 | return retval; |
185 | } | 272 | } |
186 | 273 | ||
187 | /** | 274 | /** |
@@ -189,32 +276,73 @@ static int ir_setkeycode(struct input_dev *dev, | |||
189 | * @dev: the struct input_dev device descriptor | 276 | * @dev: the struct input_dev device descriptor |
190 | * @to: the struct ir_scancode_table to copy entries to | 277 | * @to: the struct ir_scancode_table to copy entries to |
191 | * @from: the struct ir_scancode_table to copy entries from | 278 | * @from: the struct ir_scancode_table to copy entries from |
192 | * @return: -EINVAL if all keycodes could not be inserted, otherwise zero. | 279 | * @return: -ENOMEM if all keycodes could not be inserted, otherwise zero. |
193 | * | 280 | * |
194 | * This routine is used to handle table initialization. | 281 | * This routine is used to handle table initialization. |
195 | */ | 282 | */ |
196 | static int ir_setkeytable(struct input_dev *dev, | 283 | static int ir_setkeytable(struct ir_input_dev *ir_dev, |
197 | struct ir_scancode_table *to, | ||
198 | const struct ir_scancode_table *from) | 284 | const struct ir_scancode_table *from) |
199 | { | 285 | { |
200 | struct ir_input_dev *ir_dev = input_get_drvdata(dev); | ||
201 | struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; | 286 | struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; |
202 | unsigned long flags; | 287 | unsigned int i, index; |
203 | unsigned int i; | 288 | int rc; |
204 | int rc = 0; | 289 | |
290 | rc = ir_create_table(&ir_dev->rc_tab, | ||
291 | from->name, from->ir_type, from->size); | ||
292 | if (rc) | ||
293 | return rc; | ||
294 | |||
295 | IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", | ||
296 | rc_tab->size, rc_tab->alloc); | ||
205 | 297 | ||
206 | spin_lock_irqsave(&rc_tab->lock, flags); | ||
207 | for (i = 0; i < from->size; i++) { | 298 | for (i = 0; i < from->size; i++) { |
208 | rc = ir_do_setkeycode(dev, to, from->scan[i].scancode, | 299 | index = ir_establish_scancode(ir_dev, rc_tab, |
209 | from->scan[i].keycode, false); | 300 | from->scan[i].scancode, false); |
210 | if (rc) | 301 | if (index >= rc_tab->len) { |
302 | rc = -ENOMEM; | ||
211 | break; | 303 | break; |
304 | } | ||
305 | |||
306 | ir_update_mapping(ir_dev->input_dev, rc_tab, index, | ||
307 | from->scan[i].keycode); | ||
212 | } | 308 | } |
213 | spin_unlock_irqrestore(&rc_tab->lock, flags); | 309 | |
310 | if (rc) | ||
311 | ir_free_table(rc_tab); | ||
312 | |||
214 | return rc; | 313 | return rc; |
215 | } | 314 | } |
216 | 315 | ||
217 | /** | 316 | /** |
317 | * ir_lookup_by_scancode() - locate mapping by scancode | ||
318 | * @rc_tab: the &struct ir_scancode_table to search | ||
319 | * @scancode: scancode to look for in the table | ||
320 | * @return: index in the table, -1U if not found | ||
321 | * | ||
322 | * This routine performs binary search in RC keykeymap table for | ||
323 | * given scancode. | ||
324 | */ | ||
325 | static unsigned int ir_lookup_by_scancode(const struct ir_scancode_table *rc_tab, | ||
326 | unsigned int scancode) | ||
327 | { | ||
328 | unsigned int start = 0; | ||
329 | unsigned int end = rc_tab->len - 1; | ||
330 | unsigned int mid; | ||
331 | |||
332 | while (start <= end) { | ||
333 | mid = (start + end) / 2; | ||
334 | if (rc_tab->scan[mid].scancode < scancode) | ||
335 | start = mid + 1; | ||
336 | else if (rc_tab->scan[mid].scancode > scancode) | ||
337 | end = mid - 1; | ||
338 | else | ||
339 | return mid; | ||
340 | } | ||
341 | |||
342 | return -1U; | ||
343 | } | ||
344 | |||
345 | /** | ||
218 | * ir_getkeycode() - get a keycode from the scancode->keycode table | 346 | * ir_getkeycode() - get a keycode from the scancode->keycode table |
219 | * @dev: the struct input_dev device descriptor | 347 | * @dev: the struct input_dev device descriptor |
220 | * @scancode: the desired scancode | 348 | * @scancode: the desired scancode |
@@ -224,36 +352,46 @@ static int ir_setkeytable(struct input_dev *dev, | |||
224 | * This routine is used to handle evdev EVIOCGKEY ioctl. | 352 | * This routine is used to handle evdev EVIOCGKEY ioctl. |
225 | */ | 353 | */ |
226 | static int ir_getkeycode(struct input_dev *dev, | 354 | static int ir_getkeycode(struct input_dev *dev, |
227 | unsigned int scancode, unsigned int *keycode) | 355 | struct input_keymap_entry *ke) |
228 | { | 356 | { |
229 | int start, end, mid; | ||
230 | unsigned long flags; | ||
231 | int key = KEY_RESERVED; | ||
232 | struct ir_input_dev *ir_dev = input_get_drvdata(dev); | 357 | struct ir_input_dev *ir_dev = input_get_drvdata(dev); |
233 | struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; | 358 | struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; |
359 | struct ir_scancode *entry; | ||
360 | unsigned long flags; | ||
361 | unsigned int index; | ||
362 | unsigned int scancode; | ||
363 | int retval; | ||
234 | 364 | ||
235 | spin_lock_irqsave(&rc_tab->lock, flags); | 365 | spin_lock_irqsave(&rc_tab->lock, flags); |
236 | start = 0; | 366 | |
237 | end = rc_tab->len - 1; | 367 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) { |
238 | while (start <= end) { | 368 | index = ke->index; |
239 | mid = (start + end) / 2; | 369 | } else { |
240 | if (rc_tab->scan[mid].scancode < scancode) | 370 | retval = input_scancode_to_scalar(ke, &scancode); |
241 | start = mid + 1; | 371 | if (retval) |
242 | else if (rc_tab->scan[mid].scancode > scancode) | 372 | goto out; |
243 | end = mid - 1; | 373 | |
244 | else { | 374 | index = ir_lookup_by_scancode(rc_tab, scancode); |
245 | key = rc_tab->scan[mid].keycode; | 375 | } |
246 | break; | 376 | |
247 | } | 377 | if (index >= rc_tab->len) { |
378 | if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) | ||
379 | IR_dprintk(1, "unknown key for scancode 0x%04x\n", | ||
380 | scancode); | ||
381 | retval = -EINVAL; | ||
382 | goto out; | ||
248 | } | 383 | } |
249 | spin_unlock_irqrestore(&rc_tab->lock, flags); | ||
250 | 384 | ||
251 | if (key == KEY_RESERVED) | 385 | entry = &rc_tab->scan[index]; |
252 | IR_dprintk(1, "unknown key for scancode 0x%04x\n", | ||
253 | scancode); | ||
254 | 386 | ||
255 | *keycode = key; | 387 | ke->index = index; |
256 | return 0; | 388 | ke->keycode = entry->keycode; |
389 | ke->len = sizeof(entry->scancode); | ||
390 | memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode)); | ||
391 | |||
392 | out: | ||
393 | spin_unlock_irqrestore(&rc_tab->lock, flags); | ||
394 | return retval; | ||
257 | } | 395 | } |
258 | 396 | ||
259 | /** | 397 | /** |
@@ -268,12 +406,24 @@ static int ir_getkeycode(struct input_dev *dev, | |||
268 | */ | 406 | */ |
269 | u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) | 407 | u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) |
270 | { | 408 | { |
271 | int keycode; | 409 | struct ir_input_dev *ir_dev = input_get_drvdata(dev); |
410 | struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; | ||
411 | unsigned int keycode; | ||
412 | unsigned int index; | ||
413 | unsigned long flags; | ||
414 | |||
415 | spin_lock_irqsave(&rc_tab->lock, flags); | ||
416 | |||
417 | index = ir_lookup_by_scancode(rc_tab, scancode); | ||
418 | keycode = index < rc_tab->len ? | ||
419 | rc_tab->scan[index].keycode : KEY_RESERVED; | ||
420 | |||
421 | spin_unlock_irqrestore(&rc_tab->lock, flags); | ||
272 | 422 | ||
273 | ir_getkeycode(dev, scancode, &keycode); | ||
274 | if (keycode != KEY_RESERVED) | 423 | if (keycode != KEY_RESERVED) |
275 | IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", | 424 | IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", |
276 | dev->name, scancode, keycode); | 425 | dev->name, scancode, keycode); |
426 | |||
277 | return keycode; | 427 | return keycode; |
278 | } | 428 | } |
279 | EXPORT_SYMBOL_GPL(ir_g_keycode_from_table); | 429 | EXPORT_SYMBOL_GPL(ir_g_keycode_from_table); |
@@ -453,8 +603,8 @@ int __ir_input_register(struct input_dev *input_dev, | |||
453 | goto out_dev; | 603 | goto out_dev; |
454 | } | 604 | } |
455 | 605 | ||
456 | input_dev->getkeycode = ir_getkeycode; | 606 | input_dev->getkeycode_new = ir_getkeycode; |
457 | input_dev->setkeycode = ir_setkeycode; | 607 | input_dev->setkeycode_new = ir_setkeycode; |
458 | input_set_drvdata(input_dev, ir_dev); | 608 | input_set_drvdata(input_dev, ir_dev); |
459 | ir_dev->input_dev = input_dev; | 609 | ir_dev->input_dev = input_dev; |
460 | 610 | ||
@@ -462,12 +612,6 @@ int __ir_input_register(struct input_dev *input_dev, | |||
462 | spin_lock_init(&ir_dev->keylock); | 612 | spin_lock_init(&ir_dev->keylock); |
463 | setup_timer(&ir_dev->timer_keyup, ir_timer_keyup, (unsigned long)ir_dev); | 613 | setup_timer(&ir_dev->timer_keyup, ir_timer_keyup, (unsigned long)ir_dev); |
464 | 614 | ||
465 | ir_dev->rc_tab.name = rc_tab->name; | ||
466 | ir_dev->rc_tab.ir_type = rc_tab->ir_type; | ||
467 | ir_dev->rc_tab.alloc = roundup_pow_of_two(rc_tab->size * | ||
468 | sizeof(struct ir_scancode)); | ||
469 | ir_dev->rc_tab.scan = kmalloc(ir_dev->rc_tab.alloc, GFP_KERNEL); | ||
470 | ir_dev->rc_tab.size = ir_dev->rc_tab.alloc / sizeof(struct ir_scancode); | ||
471 | if (props) { | 615 | if (props) { |
472 | ir_dev->props = props; | 616 | ir_dev->props = props; |
473 | if (props->open) | 617 | if (props->open) |
@@ -476,23 +620,14 @@ int __ir_input_register(struct input_dev *input_dev, | |||
476 | input_dev->close = ir_close; | 620 | input_dev->close = ir_close; |
477 | } | 621 | } |
478 | 622 | ||
479 | if (!ir_dev->rc_tab.scan) { | ||
480 | rc = -ENOMEM; | ||
481 | goto out_name; | ||
482 | } | ||
483 | |||
484 | IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", | ||
485 | ir_dev->rc_tab.size, ir_dev->rc_tab.alloc); | ||
486 | |||
487 | set_bit(EV_KEY, input_dev->evbit); | 623 | set_bit(EV_KEY, input_dev->evbit); |
488 | set_bit(EV_REP, input_dev->evbit); | 624 | set_bit(EV_REP, input_dev->evbit); |
489 | set_bit(EV_MSC, input_dev->evbit); | 625 | set_bit(EV_MSC, input_dev->evbit); |
490 | set_bit(MSC_SCAN, input_dev->mscbit); | 626 | set_bit(MSC_SCAN, input_dev->mscbit); |
491 | 627 | ||
492 | if (ir_setkeytable(input_dev, &ir_dev->rc_tab, rc_tab)) { | 628 | rc = ir_setkeytable(ir_dev, rc_tab); |
493 | rc = -ENOMEM; | 629 | if (rc) |
494 | goto out_table; | 630 | goto out_name; |
495 | } | ||
496 | 631 | ||
497 | rc = ir_register_class(input_dev); | 632 | rc = ir_register_class(input_dev); |
498 | if (rc < 0) | 633 | if (rc < 0) |
@@ -522,7 +657,7 @@ int __ir_input_register(struct input_dev *input_dev, | |||
522 | out_event: | 657 | out_event: |
523 | ir_unregister_class(input_dev); | 658 | ir_unregister_class(input_dev); |
524 | out_table: | 659 | out_table: |
525 | kfree(ir_dev->rc_tab.scan); | 660 | ir_free_table(&ir_dev->rc_tab); |
526 | out_name: | 661 | out_name: |
527 | kfree(ir_dev->driver_name); | 662 | kfree(ir_dev->driver_name); |
528 | out_dev: | 663 | out_dev: |
@@ -540,7 +675,6 @@ EXPORT_SYMBOL_GPL(__ir_input_register); | |||
540 | void ir_input_unregister(struct input_dev *input_dev) | 675 | void ir_input_unregister(struct input_dev *input_dev) |
541 | { | 676 | { |
542 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | 677 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); |
543 | struct ir_scancode_table *rc_tab; | ||
544 | 678 | ||
545 | if (!ir_dev) | 679 | if (!ir_dev) |
546 | return; | 680 | return; |
@@ -552,10 +686,7 @@ void ir_input_unregister(struct input_dev *input_dev) | |||
552 | if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) | 686 | if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) |
553 | ir_raw_event_unregister(input_dev); | 687 | ir_raw_event_unregister(input_dev); |
554 | 688 | ||
555 | rc_tab = &ir_dev->rc_tab; | 689 | ir_free_table(&ir_dev->rc_tab); |
556 | rc_tab->size = 0; | ||
557 | kfree(rc_tab->scan); | ||
558 | rc_tab->scan = NULL; | ||
559 | 690 | ||
560 | ir_unregister_class(input_dev); | 691 | ir_unregister_class(input_dev); |
561 | 692 | ||
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index defa786dee34..b8c4b80e4c43 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -338,6 +338,21 @@ static struct resource ab8500_rtc_resources[] = { | |||
338 | }, | 338 | }, |
339 | }; | 339 | }; |
340 | 340 | ||
341 | static struct resource ab8500_poweronkey_db_resources[] = { | ||
342 | { | ||
343 | .name = "ONKEY_DBF", | ||
344 | .start = AB8500_INT_PON_KEY1DB_F, | ||
345 | .end = AB8500_INT_PON_KEY1DB_F, | ||
346 | .flags = IORESOURCE_IRQ, | ||
347 | }, | ||
348 | { | ||
349 | .name = "ONKEY_DBR", | ||
350 | .start = AB8500_INT_PON_KEY1DB_R, | ||
351 | .end = AB8500_INT_PON_KEY1DB_R, | ||
352 | .flags = IORESOURCE_IRQ, | ||
353 | }, | ||
354 | }; | ||
355 | |||
341 | static struct mfd_cell ab8500_devs[] = { | 356 | static struct mfd_cell ab8500_devs[] = { |
342 | { | 357 | { |
343 | .name = "ab8500-gpadc", | 358 | .name = "ab8500-gpadc", |
@@ -354,6 +369,11 @@ static struct mfd_cell ab8500_devs[] = { | |||
354 | { .name = "ab8500-usb", }, | 369 | { .name = "ab8500-usb", }, |
355 | { .name = "ab8500-pwm", }, | 370 | { .name = "ab8500-pwm", }, |
356 | { .name = "ab8500-regulator", }, | 371 | { .name = "ab8500-regulator", }, |
372 | { | ||
373 | .name = "ab8500-poweron-key", | ||
374 | .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources), | ||
375 | .resources = ab8500_poweronkey_db_resources, | ||
376 | }, | ||
357 | }; | 377 | }; |
358 | 378 | ||
359 | int __devinit ab8500_init(struct ab8500 *ab8500) | 379 | int __devinit ab8500_init(struct ab8500 *ab8500) |
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 335311a98fdc..8e03e7600239 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
@@ -139,8 +139,6 @@ source "drivers/staging/adis16255/Kconfig" | |||
139 | 139 | ||
140 | source "drivers/staging/xgifb/Kconfig" | 140 | source "drivers/staging/xgifb/Kconfig" |
141 | 141 | ||
142 | source "drivers/staging/mrst-touchscreen/Kconfig" | ||
143 | |||
144 | source "drivers/staging/msm/Kconfig" | 142 | source "drivers/staging/msm/Kconfig" |
145 | 143 | ||
146 | source "drivers/staging/lirc/Kconfig" | 144 | source "drivers/staging/lirc/Kconfig" |
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index e3f1e1b6095e..0e7d7559d379 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile | |||
@@ -51,7 +51,6 @@ obj-$(CONFIG_CXT1E1) += cxt1e1/ | |||
51 | obj-$(CONFIG_TI_ST) += ti-st/ | 51 | obj-$(CONFIG_TI_ST) += ti-st/ |
52 | obj-$(CONFIG_ADIS16255) += adis16255/ | 52 | obj-$(CONFIG_ADIS16255) += adis16255/ |
53 | obj-$(CONFIG_FB_XGI) += xgifb/ | 53 | obj-$(CONFIG_FB_XGI) += xgifb/ |
54 | obj-$(CONFIG_TOUCHSCREEN_MRSTOUCH) += mrst-touchscreen/ | ||
55 | obj-$(CONFIG_MSM_STAGING) += msm/ | 54 | obj-$(CONFIG_MSM_STAGING) += msm/ |
56 | obj-$(CONFIG_EASYCAP) += easycap/ | 55 | obj-$(CONFIG_EASYCAP) += easycap/ |
57 | obj-$(CONFIG_SOLO6X10) += solo6x10/ | 56 | obj-$(CONFIG_SOLO6X10) += solo6x10/ |
diff --git a/drivers/staging/mrst-touchscreen/Kconfig b/drivers/staging/mrst-touchscreen/Kconfig deleted file mode 100644 index c2af49217084..000000000000 --- a/drivers/staging/mrst-touchscreen/Kconfig +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | config TOUCHSCREEN_INTEL_MID | ||
2 | tristate "Intel MID platform resistive touchscreen" | ||
3 | depends on INTEL_SCU_IPC | ||
4 | default y | ||
5 | help | ||
6 | Say Y here if you have a Intel MID based touchscreen | ||
7 | If unsure, say N. | ||
diff --git a/drivers/staging/mrst-touchscreen/Makefile b/drivers/staging/mrst-touchscreen/Makefile deleted file mode 100644 index 2d638b0d70bf..000000000000 --- a/drivers/staging/mrst-touchscreen/Makefile +++ /dev/null | |||
@@ -1,3 +0,0 @@ | |||
1 | obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) := intel_mid_touch.o | ||
2 | |||
3 | |||
diff --git a/drivers/staging/mrst-touchscreen/TODO b/drivers/staging/mrst-touchscreen/TODO deleted file mode 100644 index 7157028d634a..000000000000 --- a/drivers/staging/mrst-touchscreen/TODO +++ /dev/null | |||
@@ -1,2 +0,0 @@ | |||
1 | - Move the driver to not think it is SPI (requires fixing some of the SFI | ||
2 | and firmware side) | ||
diff --git a/drivers/staging/mrst-touchscreen/intel-mid-touch.c b/drivers/staging/mrst-touchscreen/intel-mid-touch.c deleted file mode 100644 index abba22f921be..000000000000 --- a/drivers/staging/mrst-touchscreen/intel-mid-touch.c +++ /dev/null | |||
@@ -1,864 +0,0 @@ | |||
1 | /* | ||
2 | * intel_mid_touch.c - Intel MID Resistive Touch Screen Driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Intel Corp | ||
5 | * | ||
6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along | ||
18 | * with this program; ifnot, write to the Free Software Foundation, Inc., | ||
19 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
20 | * | ||
21 | * Questions/Comments/Bug fixes to Sreedhara (sreedhara.ds@intel.com) | ||
22 | * Ramesh Agarwal (ramesh.agarwal@intel.com) | ||
23 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
24 | * | ||
25 | * TODO: | ||
26 | * kill off mrstouch_debug eventually | ||
27 | * review conversion of r/m/w sequences | ||
28 | * Replace interrupt mutex abuse | ||
29 | * Kill of mrstouchdevp pointer | ||
30 | * | ||
31 | */ | ||
32 | |||
33 | #include <linux/module.h> | ||
34 | #include <linux/init.h> | ||
35 | #include <linux/input.h> | ||
36 | #include <linux/interrupt.h> | ||
37 | #include <linux/err.h> | ||
38 | #include <linux/param.h> | ||
39 | #include <linux/spi/spi.h> | ||
40 | #include <linux/irq.h> | ||
41 | #include <linux/delay.h> | ||
42 | #include <linux/kthread.h> | ||
43 | #include <asm/intel_scu_ipc.h> | ||
44 | |||
45 | |||
46 | #if defined(MRSTOUCH_DEBUG) | ||
47 | #define mrstouch_debug(fmt, args...)\ | ||
48 | do { \ | ||
49 | printk(KERN_DEBUG "\n[MRSTOUCH(%d)] - ", __LINE__); \ | ||
50 | printk(KERN_DEBUG fmt, ##args); \ | ||
51 | } while (0); | ||
52 | #else | ||
53 | #define mrstouch_debug(fmt, args...) | ||
54 | #endif | ||
55 | |||
56 | /* PMIC Interrupt registers */ | ||
57 | #define PMIC_REG_ID1 0x00 /*PMIC ID1 register */ | ||
58 | |||
59 | /* PMIC Interrupt registers */ | ||
60 | #define PMIC_REG_INT 0x04 /*PMIC interrupt register */ | ||
61 | #define PMIC_REG_MINT 0x05 /*PMIC interrupt mask register */ | ||
62 | |||
63 | /* ADC Interrupt registers */ | ||
64 | #define PMIC_REG_ADCINT 0x5F /*ADC interrupt register */ | ||
65 | #define PMIC_REG_MADCINT 0x60 /*ADC interrupt mask register */ | ||
66 | |||
67 | /* ADC Control registers */ | ||
68 | #define PMIC_REG_ADCCNTL1 0x61 /*ADC control register */ | ||
69 | |||
70 | /* ADC Channel Selection registers */ | ||
71 | #define PMICADDR0 0xA4 | ||
72 | #define END_OF_CHANNEL 0x1F | ||
73 | |||
74 | /* ADC Result register */ | ||
75 | #define PMIC_REG_ADCSNS0H 0x64 | ||
76 | |||
77 | /* ADC channels for touch screen */ | ||
78 | #define MRST_TS_CHAN10 0xA /* Touch screen X+ connection */ | ||
79 | #define MRST_TS_CHAN11 0xB /* Touch screen X- connection */ | ||
80 | #define MRST_TS_CHAN12 0xC /* Touch screen Y+ connection */ | ||
81 | #define MRST_TS_CHAN13 0xD /* Touch screen Y- connection */ | ||
82 | |||
83 | /* Touch screen coordinate constants */ | ||
84 | #define TOUCH_PRESSURE 50 | ||
85 | #define TOUCH_PRESSURE_FS 100 | ||
86 | |||
87 | #define XMOVE_LIMIT 5 | ||
88 | #define YMOVE_LIMIT 5 | ||
89 | #define XYMOVE_CNT 3 | ||
90 | |||
91 | #define MAX_10BIT ((1<<10)-1) | ||
92 | |||
93 | /* Touch screen channel BIAS constants */ | ||
94 | #define XBIAS 0x20 | ||
95 | #define YBIAS 0x40 | ||
96 | #define ZBIAS 0x80 | ||
97 | |||
98 | /* Touch screen coordinates */ | ||
99 | #define MIN_X 10 | ||
100 | #define MAX_X 1024 | ||
101 | #define MIN_Y 10 | ||
102 | #define MAX_Y 1024 | ||
103 | #define WAIT_ADC_COMPLETION 10 | ||
104 | |||
105 | /* PMIC ADC round robin delays */ | ||
106 | #define ADC_LOOP_DELAY0 0x0 /* Continuous loop */ | ||
107 | #define ADC_LOOP_DELAY1 0x1 /* 4.5 ms approximate */ | ||
108 | |||
109 | /* PMIC Vendor Identifiers */ | ||
110 | #define PMIC_VENDOR_FS 0 /* PMIC vendor FreeScale */ | ||
111 | #define PMIC_VENDOR_MAXIM 1 /* PMIC vendor MAXIM */ | ||
112 | #define PMIC_VENDOR_NEC 2 /* PMIC vendor NEC */ | ||
113 | #define MRSTOUCH_MAX_CHANNELS 32 /* Maximum ADC channels */ | ||
114 | |||
115 | /* Touch screen device structure */ | ||
116 | struct mrstouch_dev { | ||
117 | struct spi_device *spi; /* SPI device associated with touch screen */ | ||
118 | struct input_dev *input; /* input device for touchscreen*/ | ||
119 | char phys[32]; /* Device name */ | ||
120 | struct task_struct *pendet_thrd; /* PENDET interrupt handler */ | ||
121 | struct mutex lock; /* Sync between interrupt and PENDET handler */ | ||
122 | bool busy; /* Busy flag */ | ||
123 | u16 asr; /* Address selection register */ | ||
124 | int irq; /* Touch screen IRQ # */ | ||
125 | uint vendor; /* PMIC vendor */ | ||
126 | uint rev; /* PMIC revision */ | ||
127 | bool suspended; /* Device suspended status */ | ||
128 | bool disabled; /* Device disabled status */ | ||
129 | u16 x; /* X coordinate */ | ||
130 | u16 y; /* Y coordinate */ | ||
131 | bool pendown; /* PEN position */ | ||
132 | } ; | ||
133 | |||
134 | |||
135 | /* Global Pointer to Touch screen device */ | ||
136 | static struct mrstouch_dev *mrstouchdevp; | ||
137 | |||
138 | /* Utility to read PMIC ID */ | ||
139 | static int mrstouch_pmic_id(uint *vendor, uint *rev) | ||
140 | { | ||
141 | int err; | ||
142 | u8 r; | ||
143 | |||
144 | err = intel_scu_ipc_ioread8(PMIC_REG_ID1, &r); | ||
145 | if (err) | ||
146 | return err; | ||
147 | |||
148 | *vendor = r & 0x7; | ||
149 | *rev = (r >> 3) & 0x7; | ||
150 | |||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | /* | ||
155 | * Parse ADC channels to find end of the channel configured by other ADC user | ||
156 | * NEC and MAXIM requires 4 channels and FreeScale needs 18 channels | ||
157 | */ | ||
158 | static int mrstouch_chan_parse(struct mrstouch_dev *tsdev) | ||
159 | { | ||
160 | int err, i, j, found; | ||
161 | u32 r32; | ||
162 | |||
163 | found = -1; | ||
164 | |||
165 | for (i = 0; i < MRSTOUCH_MAX_CHANNELS; i++) { | ||
166 | if (found >= 0) | ||
167 | break; | ||
168 | |||
169 | err = intel_scu_ipc_ioread32(PMICADDR0, &r32); | ||
170 | if (err) | ||
171 | return err; | ||
172 | |||
173 | for (j = 0; j < 32; j+= 8) { | ||
174 | if (((r32 >> j) & 0xFF) == END_OF_CHANNEL) { | ||
175 | found = i; | ||
176 | break; | ||
177 | } | ||
178 | } | ||
179 | } | ||
180 | if (found < 0) | ||
181 | return 0; | ||
182 | |||
183 | if (tsdev->vendor == PMIC_VENDOR_FS) { | ||
184 | if (found && found > (MRSTOUCH_MAX_CHANNELS - 18)) | ||
185 | return -ENOSPC; | ||
186 | } else { | ||
187 | if (found && found > (MRSTOUCH_MAX_CHANNELS - 4)) | ||
188 | return -ENOSPC; | ||
189 | } | ||
190 | return found; | ||
191 | } | ||
192 | |||
193 | /* Utility to enable/disable pendet. | ||
194 | * pendet set to true enables PENDET interrupt | ||
195 | * pendet set to false disables PENDET interrupt | ||
196 | * Also clears RND mask bit | ||
197 | */ | ||
198 | static int pendet_enable(struct mrstouch_dev *tsdev, bool pendet) | ||
199 | { | ||
200 | u16 reg; | ||
201 | u8 r; | ||
202 | u8 pendet_enabled = 0; | ||
203 | int retry = 0; | ||
204 | int err; | ||
205 | |||
206 | err = intel_scu_ipc_ioread16(PMIC_REG_MADCINT, ®); | ||
207 | if (err) | ||
208 | return err; | ||
209 | |||
210 | if (pendet) { | ||
211 | reg &= ~0x0005; | ||
212 | reg |= 0x2000; /* Enable pendet */ | ||
213 | } else | ||
214 | reg &= 0xDFFF; /* Disable pendet */ | ||
215 | |||
216 | /* Set MADCINT and update ADCCNTL1 (next reg byte) */ | ||
217 | err = intel_scu_ipc_iowrite16(PMIC_REG_MADCINT, reg); | ||
218 | if (!pendet || err) | ||
219 | return err; | ||
220 | |||
221 | /* | ||
222 | * Sometimes even after the register write succeeds | ||
223 | * the PMIC register value is not updated. Retry few iterations | ||
224 | * to enable pendet. | ||
225 | */ | ||
226 | |||
227 | err = intel_scu_ipc_ioread8(PMIC_REG_ADCCNTL1, &r); | ||
228 | pendet_enabled = (r >> 5) & 0x01; | ||
229 | |||
230 | retry = 0; | ||
231 | while (!err && !pendet_enabled) { | ||
232 | retry++; | ||
233 | msleep(10); | ||
234 | err = intel_scu_ipc_iowrite8(PMIC_REG_ADCCNTL1, reg >> 8); | ||
235 | if (err) | ||
236 | break; | ||
237 | err = intel_scu_ipc_ioread8(PMIC_REG_ADCCNTL1, &r); | ||
238 | if (err == 0) | ||
239 | pendet_enabled = (r >> 5) & 0x01; | ||
240 | if (retry >= 10) { | ||
241 | dev_err(&tsdev->spi->dev, "Touch screen disabled.\n"); | ||
242 | return -EIO; | ||
243 | } | ||
244 | } | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | /* To read PMIC ADC touch screen result | ||
249 | * Reads ADC storage registers for higher 7 and lower 3 bits | ||
250 | * converts the two readings to single value and turns off gain bit | ||
251 | */ | ||
252 | static int mrstouch_ts_chan_read(u16 offset, u16 chan, u16 *vp, u16 *vm) | ||
253 | { | ||
254 | int err; | ||
255 | u16 result; | ||
256 | u32 res; | ||
257 | |||
258 | result = PMIC_REG_ADCSNS0H + offset; | ||
259 | |||
260 | if (chan == MRST_TS_CHAN12) | ||
261 | result += 4; | ||
262 | |||
263 | err = intel_scu_ipc_ioread32(result, &res); | ||
264 | if (err) | ||
265 | return err; | ||
266 | |||
267 | /* Mash the bits up */ | ||
268 | |||
269 | *vp = (res & 0xFF) << 3; /* Highest 7 bits */ | ||
270 | *vp |= (res >> 8) & 0x07; /* Lower 3 bits */ | ||
271 | *vp &= 0x3FF; | ||
272 | |||
273 | res >>= 16; | ||
274 | |||
275 | *vm = (res & 0xFF) << 3; /* Highest 7 bits */ | ||
276 | *vm |= (res >> 8) & 0x07; /* Lower 3 bits */ | ||
277 | *vm &= 0x3FF; | ||
278 | |||
279 | return 0; | ||
280 | } | ||
281 | |||
282 | /* To configure touch screen channels | ||
283 | * Writes touch screen channels to ADC address selection registers | ||
284 | */ | ||
285 | static int mrstouch_ts_chan_set(uint offset) | ||
286 | { | ||
287 | int count; | ||
288 | u16 chan; | ||
289 | u16 reg[5]; | ||
290 | u8 data[5]; | ||
291 | |||
292 | chan = PMICADDR0 + offset; | ||
293 | for (count = 0; count <= 3; count++) { | ||
294 | reg[count] = chan++; | ||
295 | data[count] = MRST_TS_CHAN10 + count; | ||
296 | } | ||
297 | reg[count] = chan; | ||
298 | data[count] = END_OF_CHANNEL; | ||
299 | |||
300 | return intel_scu_ipc_writev(reg, data, 5); | ||
301 | } | ||
302 | |||
303 | /* Initialize ADC */ | ||
304 | static int mrstouch_adc_init(struct mrstouch_dev *tsdev) | ||
305 | { | ||
306 | int err, start; | ||
307 | u8 ra, rm; | ||
308 | |||
309 | err = mrstouch_pmic_id(&tsdev->vendor, &tsdev->rev); | ||
310 | if (err) { | ||
311 | dev_err(&tsdev->spi->dev, "Unable to read PMIC id\n"); | ||
312 | return err; | ||
313 | } | ||
314 | |||
315 | start = mrstouch_chan_parse(tsdev); | ||
316 | if (start < 0) { | ||
317 | dev_err(&tsdev->spi->dev, "Unable to parse channels\n"); | ||
318 | return start; | ||
319 | } | ||
320 | |||
321 | tsdev->asr = start; | ||
322 | |||
323 | mrstouch_debug("Channel offset(%d): 0x%X\n", tsdev->asr, tsdev->vendor); | ||
324 | |||
325 | /* ADC power on, start, enable PENDET and set loop delay | ||
326 | * ADC loop delay is set to 4.5 ms approximately | ||
327 | * Loop delay more than this results in jitter in adc readings | ||
328 | * Setting loop delay to 0 (continous loop) in MAXIM stops PENDET | ||
329 | * interrupt generation sometimes. | ||
330 | */ | ||
331 | |||
332 | if (tsdev->vendor == PMIC_VENDOR_FS) { | ||
333 | ra = 0xE0 | ADC_LOOP_DELAY0; | ||
334 | rm = 0x5; | ||
335 | } else { | ||
336 | /* NEC and MAXIm not consistent with loop delay 0 */ | ||
337 | ra = 0xE0 | ADC_LOOP_DELAY1; | ||
338 | rm = 0x0; | ||
339 | |||
340 | /* configure touch screen channels */ | ||
341 | err = mrstouch_ts_chan_set(tsdev->asr); | ||
342 | if (err) | ||
343 | return err; | ||
344 | } | ||
345 | err = intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1, ra, 0xE7); | ||
346 | if (err == 0) | ||
347 | err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, rm, 0x03); | ||
348 | return err; | ||
349 | } | ||
350 | |||
351 | /* Reports x,y coordinates to event subsystem */ | ||
352 | static void mrstouch_report_xy(struct mrstouch_dev *tsdev, u16 x, u16 y, u16 z) | ||
353 | { | ||
354 | int xdiff, ydiff; | ||
355 | |||
356 | if (tsdev->pendown && z <= TOUCH_PRESSURE) { | ||
357 | /* Pen removed, report button release */ | ||
358 | mrstouch_debug("BTN REL(%d)", z); | ||
359 | input_report_key(tsdev->input, BTN_TOUCH, 0); | ||
360 | tsdev->pendown = false; | ||
361 | } | ||
362 | |||
363 | xdiff = abs(x - tsdev->x); | ||
364 | ydiff = abs(y - tsdev->y); | ||
365 | |||
366 | /* | ||
367 | if x and y values changes for XYMOVE_CNT readings it is considered | ||
368 | as stylus is moving. This is required to differentiate between stylus | ||
369 | movement and jitter | ||
370 | */ | ||
371 | if (x < MIN_X || x > MAX_X || y < MIN_Y || y > MAX_Y) { | ||
372 | /* Spurious values, release button if touched and return */ | ||
373 | if (tsdev->pendown) { | ||
374 | mrstouch_debug("BTN REL(%d)", z); | ||
375 | input_report_key(tsdev->input, BTN_TOUCH, 0); | ||
376 | tsdev->pendown = false; | ||
377 | } | ||
378 | return; | ||
379 | } else if (xdiff >= XMOVE_LIMIT || ydiff >= YMOVE_LIMIT) { | ||
380 | tsdev->x = x; | ||
381 | tsdev->y = y; | ||
382 | |||
383 | input_report_abs(tsdev->input, ABS_X, x); | ||
384 | input_report_abs(tsdev->input, ABS_Y, y); | ||
385 | input_sync(tsdev->input); | ||
386 | } | ||
387 | |||
388 | |||
389 | if (!tsdev->pendown && z > TOUCH_PRESSURE) { | ||
390 | /* Pen touched, report button touch */ | ||
391 | mrstouch_debug("BTN TCH(%d, %d, %d)", x, y, z); | ||
392 | input_report_key(tsdev->input, BTN_TOUCH, 1); | ||
393 | tsdev->pendown = true; | ||
394 | } | ||
395 | } | ||
396 | |||
397 | |||
398 | /* Utility to start ADC, used by freescale handler */ | ||
399 | static int pendet_mask(void) | ||
400 | { | ||
401 | return intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x02, 0x02); | ||
402 | } | ||
403 | |||
404 | /* Utility to stop ADC, used by freescale handler */ | ||
405 | static int pendet_umask(void) | ||
406 | { | ||
407 | return intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x00, 0x02); | ||
408 | } | ||
409 | |||
410 | /* Utility to read ADC, used by freescale handler */ | ||
411 | static int mrstouch_pmic_fs_adc_read(struct mrstouch_dev *tsdev) | ||
412 | { | ||
413 | int err; | ||
414 | u16 x, y, z, result; | ||
415 | u16 reg[4]; | ||
416 | u8 data[4]; | ||
417 | |||
418 | result = PMIC_REG_ADCSNS0H + tsdev->asr; | ||
419 | |||
420 | reg[0] = result + 4; | ||
421 | reg[1] = result + 5; | ||
422 | reg[2] = result + 16; | ||
423 | reg[3] = result + 17; | ||
424 | |||
425 | err = intel_scu_ipc_readv(reg, data, 4); | ||
426 | if (err) | ||
427 | goto ipc_error; | ||
428 | |||
429 | x = data[0] << 3; /* Higher 7 bits */ | ||
430 | x |= data[1] & 0x7; /* Lower 3 bits */ | ||
431 | x &= 0x3FF; | ||
432 | |||
433 | y = data[2] << 3; /* Higher 7 bits */ | ||
434 | y |= data[3] & 0x7; /* Lower 3 bits */ | ||
435 | y &= 0x3FF; | ||
436 | |||
437 | /* Read Z value */ | ||
438 | reg[0] = result + 28; | ||
439 | reg[1] = result + 29; | ||
440 | |||
441 | err = intel_scu_ipc_readv(reg, data, 4); | ||
442 | if (err) | ||
443 | goto ipc_error; | ||
444 | |||
445 | z = data[0] << 3; /* Higher 7 bits */ | ||
446 | z |= data[1] & 0x7; /* Lower 3 bits */ | ||
447 | z &= 0x3FF; | ||
448 | |||
449 | #if defined(MRSTOUCH_PRINT_XYZP) | ||
450 | mrstouch_debug("X: %d, Y: %d, Z: %d", x, y, z); | ||
451 | #endif | ||
452 | |||
453 | if (z >= TOUCH_PRESSURE_FS) { | ||
454 | mrstouch_report_xy(tsdev, x, y, TOUCH_PRESSURE - 1); /* Pen Removed */ | ||
455 | return TOUCH_PRESSURE - 1; | ||
456 | } else { | ||
457 | mrstouch_report_xy(tsdev, x, y, TOUCH_PRESSURE + 1); /* Pen Touched */ | ||
458 | return TOUCH_PRESSURE + 1; | ||
459 | } | ||
460 | |||
461 | return 0; | ||
462 | |||
463 | ipc_error: | ||
464 | dev_err(&tsdev->spi->dev, "ipc error during fs_adc read\n"); | ||
465 | return err; | ||
466 | } | ||
467 | |||
468 | /* To handle free scale pmic pendet interrupt */ | ||
469 | static int pmic0_pendet(void *dev_id) | ||
470 | { | ||
471 | int err, count; | ||
472 | u16 chan; | ||
473 | unsigned int touched; | ||
474 | struct mrstouch_dev *tsdev = (struct mrstouch_dev *)dev_id; | ||
475 | u16 reg[5]; | ||
476 | u8 data[5]; | ||
477 | |||
478 | chan = PMICADDR0 + tsdev->asr; | ||
479 | |||
480 | /* Set X BIAS */ | ||
481 | for (count = 0; count <= 3; count++) { | ||
482 | reg[count] = chan++; | ||
483 | data[count] = 0x2A; | ||
484 | } | ||
485 | reg[count] = chan++; /* Dummy */ | ||
486 | data[count] = 0; | ||
487 | |||
488 | err = intel_scu_ipc_writev(reg, data, 5); | ||
489 | if (err) | ||
490 | goto ipc_error; | ||
491 | |||
492 | msleep(WAIT_ADC_COMPLETION); | ||
493 | |||
494 | /* Set Y BIAS */ | ||
495 | for (count = 0; count <= 3; count++) { | ||
496 | reg[count] = chan++; | ||
497 | data[count] = 0x4A; | ||
498 | } | ||
499 | reg[count] = chan++; /* Dummy */ | ||
500 | data[count] = 0; | ||
501 | |||
502 | err = intel_scu_ipc_writev(reg, data, 5); | ||
503 | if (err) | ||
504 | goto ipc_error; | ||
505 | |||
506 | msleep(WAIT_ADC_COMPLETION); | ||
507 | |||
508 | /* Set Z BIAS */ | ||
509 | err = intel_scu_ipc_iowrite32(chan + 2, 0x8A8A8A8A); | ||
510 | if (err) | ||
511 | goto ipc_error; | ||
512 | |||
513 | msleep(WAIT_ADC_COMPLETION); | ||
514 | |||
515 | /*Read touch screen channels till pen removed | ||
516 | * Freescale reports constant value of z for all points | ||
517 | * z is high when screen is not touched and low when touched | ||
518 | * Map high z value to not touched and low z value to pen touched | ||
519 | */ | ||
520 | touched = mrstouch_pmic_fs_adc_read(tsdev); | ||
521 | while (touched > TOUCH_PRESSURE) { | ||
522 | touched = mrstouch_pmic_fs_adc_read(tsdev); | ||
523 | msleep(WAIT_ADC_COMPLETION); | ||
524 | } | ||
525 | |||
526 | /* Clear all TS channels */ | ||
527 | chan = PMICADDR0 + tsdev->asr; | ||
528 | for (count = 0; count <= 4; count++) { | ||
529 | reg[count] = chan++; | ||
530 | data[count] = 0; | ||
531 | } | ||
532 | err = intel_scu_ipc_writev(reg, data, 5); | ||
533 | if (err) | ||
534 | goto ipc_error; | ||
535 | |||
536 | for (count = 0; count <= 4; count++) { | ||
537 | reg[count] = chan++; | ||
538 | data[count] = 0; | ||
539 | } | ||
540 | err = intel_scu_ipc_writev(reg, data, 5); | ||
541 | if (err) | ||
542 | goto ipc_error; | ||
543 | |||
544 | err = intel_scu_ipc_iowrite32(chan + 2, 0x00000000); | ||
545 | if (err) | ||
546 | goto ipc_error; | ||
547 | |||
548 | return 0; | ||
549 | |||
550 | ipc_error: | ||
551 | dev_err(&tsdev->spi->dev, "ipc error during pendet\n"); | ||
552 | return err; | ||
553 | } | ||
554 | |||
555 | |||
556 | /* To enable X, Y and Z bias values | ||
557 | * Enables YPYM for X channels and XPXM for Y channels | ||
558 | */ | ||
559 | static int mrstouch_ts_bias_set(uint offset, uint bias) | ||
560 | { | ||
561 | int count; | ||
562 | u16 chan, start; | ||
563 | u16 reg[4]; | ||
564 | u8 data[4]; | ||
565 | |||
566 | chan = PMICADDR0 + offset; | ||
567 | start = MRST_TS_CHAN10; | ||
568 | |||
569 | for (count = 0; count <= 3; count++) { | ||
570 | reg[count] = chan++; | ||
571 | data[count] = bias | (start + count); | ||
572 | } | ||
573 | return intel_scu_ipc_writev(reg, data, 4); | ||
574 | } | ||
575 | |||
576 | /* To read touch screen channel values */ | ||
577 | static int mrstouch_adc_read(struct mrstouch_dev *tsdev) | ||
578 | { | ||
579 | int err; | ||
580 | u16 xp, xm, yp, ym, zp, zm; | ||
581 | |||
582 | /* configure Y bias for X channels */ | ||
583 | err = mrstouch_ts_bias_set(tsdev->asr, YBIAS); | ||
584 | if (err) | ||
585 | goto ipc_error; | ||
586 | |||
587 | msleep(WAIT_ADC_COMPLETION); | ||
588 | |||
589 | /* read x+ and x- channels */ | ||
590 | err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, &xp, &xm); | ||
591 | if (err) | ||
592 | goto ipc_error; | ||
593 | |||
594 | /* configure x bias for y channels */ | ||
595 | err = mrstouch_ts_bias_set(tsdev->asr, XBIAS); | ||
596 | if (err) | ||
597 | goto ipc_error; | ||
598 | |||
599 | msleep(WAIT_ADC_COMPLETION); | ||
600 | |||
601 | /* read y+ and y- channels */ | ||
602 | err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN12, &yp, &ym); | ||
603 | if (err) | ||
604 | goto ipc_error; | ||
605 | |||
606 | /* configure z bias for x and y channels */ | ||
607 | err = mrstouch_ts_bias_set(tsdev->asr, ZBIAS); | ||
608 | if (err) | ||
609 | goto ipc_error; | ||
610 | |||
611 | msleep(WAIT_ADC_COMPLETION); | ||
612 | |||
613 | /* read z+ and z- channels */ | ||
614 | err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, &zp, &zm); | ||
615 | if (err) | ||
616 | goto ipc_error; | ||
617 | |||
618 | #if defined(MRSTOUCH_PRINT_XYZP) | ||
619 | printk(KERN_INFO "X+: %d, Y+: %d, Z+: %d\n", xp, yp, zp); | ||
620 | #endif | ||
621 | |||
622 | #if defined(MRSTOUCH_PRINT_XYZM) | ||
623 | printk(KERN_INFO "X-: %d, Y-: %d, Z-: %d\n", xm, ym, zm); | ||
624 | #endif | ||
625 | |||
626 | mrstouch_report_xy(tsdev, xp, yp, zp); /* report x and y to eventX */ | ||
627 | |||
628 | return zp; | ||
629 | |||
630 | ipc_error: | ||
631 | dev_err(&tsdev->spi->dev, "ipc error during adc read\n"); | ||
632 | return err; | ||
633 | } | ||
634 | |||
635 | /* PENDET interrupt handler function for NEC and MAXIM */ | ||
636 | static void pmic12_pendet(void *data) | ||
637 | { | ||
638 | unsigned int touched; | ||
639 | struct mrstouch_dev *tsdev = (struct mrstouch_dev *)data; | ||
640 | |||
641 | /* read touch screen channels till pen removed */ | ||
642 | do { | ||
643 | touched = mrstouch_adc_read(tsdev); | ||
644 | } while (touched > TOUCH_PRESSURE); | ||
645 | } | ||
646 | |||
647 | /* Handler to process PENDET interrupt */ | ||
648 | int mrstouch_pendet(void *data) | ||
649 | { | ||
650 | struct mrstouch_dev *tsdev = (struct mrstouch_dev *)data; | ||
651 | while (1) { | ||
652 | /* Wait for PENDET interrupt */ | ||
653 | if (mutex_lock_interruptible(&tsdev->lock)) { | ||
654 | msleep(WAIT_ADC_COMPLETION); | ||
655 | continue; | ||
656 | } | ||
657 | |||
658 | if (tsdev->busy) | ||
659 | return 0; | ||
660 | |||
661 | tsdev->busy = true; | ||
662 | |||
663 | if (tsdev->vendor == PMIC_VENDOR_NEC || | ||
664 | tsdev->vendor == PMIC_VENDOR_MAXIM) { | ||
665 | /* PENDET must be disabled in NEC before reading ADC */ | ||
666 | pendet_enable(tsdev,false); /* Disbale PENDET */ | ||
667 | pmic12_pendet(tsdev); | ||
668 | pendet_enable(tsdev, true); /*Enable PENDET */ | ||
669 | } else if (tsdev->vendor == PMIC_VENDOR_FS) { | ||
670 | pendet_umask(); /* Stop ADC */ | ||
671 | pmic0_pendet(tsdev); | ||
672 | pendet_mask(); /* Stop ADC */ | ||
673 | } else | ||
674 | dev_err(&tsdev->spi->dev, "Unsupported touchscreen: %d\n", | ||
675 | tsdev->vendor); | ||
676 | |||
677 | tsdev->busy = false; | ||
678 | |||
679 | } | ||
680 | return 0; | ||
681 | } | ||
682 | |||
683 | /* PENDET interrupt handler */ | ||
684 | static irqreturn_t pendet_intr_handler(int irq, void *handle) | ||
685 | { | ||
686 | struct mrstouch_dev *tsdev = (struct mrstouch_dev *)handle; | ||
687 | |||
688 | mutex_unlock(&tsdev->lock); | ||
689 | return IRQ_HANDLED; | ||
690 | } | ||
691 | |||
692 | /* Intializes input device and registers with input subsystem */ | ||
693 | static int ts_input_dev_init(struct mrstouch_dev *tsdev, struct spi_device *spi) | ||
694 | { | ||
695 | int err = 0; | ||
696 | |||
697 | mrstouch_debug("%s", __func__); | ||
698 | |||
699 | tsdev->input = input_allocate_device(); | ||
700 | if (!tsdev->input) { | ||
701 | dev_err(&tsdev->spi->dev, "Unable to allocate input device.\n"); | ||
702 | return -EINVAL; | ||
703 | } | ||
704 | |||
705 | tsdev->input->name = "mrst_touchscreen"; | ||
706 | snprintf(tsdev->phys, sizeof(tsdev->phys), | ||
707 | "%s/input0", dev_name(&spi->dev)); | ||
708 | tsdev->input->phys = tsdev->phys; | ||
709 | tsdev->input->dev.parent = &spi->dev; | ||
710 | |||
711 | tsdev->input->id.vendor = tsdev->vendor; | ||
712 | tsdev->input->id.version = tsdev->rev; | ||
713 | |||
714 | tsdev->input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
715 | tsdev->input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
716 | |||
717 | input_set_abs_params(tsdev->input, ABS_X, MIN_X, MIN_Y, 0, 0); | ||
718 | input_set_abs_params(tsdev->input, ABS_Y, MIN_X, MIN_Y, 0, 0); | ||
719 | |||
720 | err = input_register_device(tsdev->input); | ||
721 | if (err) { | ||
722 | dev_err(&tsdev->spi->dev, "unable to register input device\n"); | ||
723 | input_free_device(tsdev->input); | ||
724 | return err; | ||
725 | } | ||
726 | |||
727 | mrstouch_debug("%s", "mrstouch initialized"); | ||
728 | |||
729 | return 0; | ||
730 | |||
731 | } | ||
732 | |||
733 | /* Probe function for touch screen driver */ | ||
734 | static int __devinit mrstouch_probe(struct spi_device *mrstouch_spi) | ||
735 | { | ||
736 | int err; | ||
737 | unsigned int myirq; | ||
738 | struct mrstouch_dev *tsdev; | ||
739 | |||
740 | mrstouch_debug("%s(%p)", __func__, mrstouch_spi); | ||
741 | |||
742 | mrstouchdevp = NULL; | ||
743 | myirq = mrstouch_spi->irq; | ||
744 | |||
745 | if (!mrstouch_spi->irq) { | ||
746 | dev_err(&mrstouch_spi->dev, "no interrupt assigned\n"); | ||
747 | return -EINVAL; | ||
748 | } | ||
749 | |||
750 | tsdev = kzalloc(sizeof(struct mrstouch_dev), GFP_KERNEL); | ||
751 | if (!tsdev) { | ||
752 | dev_err(&mrstouch_spi->dev, "unable to allocate memory\n"); | ||
753 | return -ENOMEM; | ||
754 | } | ||
755 | |||
756 | tsdev->irq = myirq; | ||
757 | mrstouchdevp = tsdev; | ||
758 | |||
759 | err = mrstouch_adc_init(tsdev); | ||
760 | if (err) { | ||
761 | dev_err(&mrstouch_spi->dev, "ADC init failed\n"); | ||
762 | goto mrstouch_err_free_mem; | ||
763 | } | ||
764 | |||
765 | dev_set_drvdata(&mrstouch_spi->dev, tsdev); | ||
766 | tsdev->spi = mrstouch_spi; | ||
767 | |||
768 | err = ts_input_dev_init(tsdev, mrstouch_spi); | ||
769 | if (err) { | ||
770 | dev_err(&tsdev->spi->dev, "ts_input_dev_init failed"); | ||
771 | goto mrstouch_err_free_mem; | ||
772 | } | ||
773 | |||
774 | mutex_init(&tsdev->lock); | ||
775 | mutex_lock(&tsdev->lock) | ||
776 | |||
777 | mrstouch_debug("Requesting IRQ-%d", myirq); | ||
778 | err = request_irq(myirq, pendet_intr_handler, | ||
779 | 0, "mrstouch", tsdev); | ||
780 | if (err) { | ||
781 | dev_err(&tsdev->spi->dev, "unable to allocate irq\n"); | ||
782 | goto mrstouch_err_free_mem; | ||
783 | } | ||
784 | |||
785 | tsdev->pendet_thrd = kthread_run(mrstouch_pendet, | ||
786 | (void *)tsdev, "pendet handler"); | ||
787 | if (IS_ERR(tsdev->pendet_thrd)) { | ||
788 | dev_err(&tsdev->spi->dev, "kthread_run failed\n"); | ||
789 | err = PTR_ERR(tsdev->pendet_thrd); | ||
790 | goto mrstouch_err_free_mem; | ||
791 | } | ||
792 | mrstouch_debug("%s", "Driver initialized"); | ||
793 | return 0; | ||
794 | |||
795 | mrstouch_err_free_mem: | ||
796 | kfree(tsdev); | ||
797 | return err; | ||
798 | } | ||
799 | |||
800 | static int mrstouch_suspend(struct spi_device *spi, pm_message_t msg) | ||
801 | { | ||
802 | mrstouch_debug("%s", __func__); | ||
803 | mrstouchdevp->suspended = 1; | ||
804 | return 0; | ||
805 | } | ||
806 | |||
807 | static int mrstouch_resume(struct spi_device *spi) | ||
808 | { | ||
809 | mrstouch_debug("%s", __func__); | ||
810 | mrstouchdevp->suspended = 0; | ||
811 | return 0; | ||
812 | } | ||
813 | |||
814 | static int mrstouch_remove(struct spi_device *spi) | ||
815 | { | ||
816 | mrstouch_debug("%s", __func__); | ||
817 | free_irq(mrstouchdevp->irq, mrstouchdevp); | ||
818 | input_unregister_device(mrstouchdevp->input); | ||
819 | input_free_device(mrstouchdevp->input); | ||
820 | if (mrstouchdevp->pendet_thrd) | ||
821 | kthread_stop(mrstouchdevp->pendet_thrd); | ||
822 | kfree(mrstouchdevp); | ||
823 | return 0; | ||
824 | } | ||
825 | |||
826 | static struct spi_driver mrstouch_driver = { | ||
827 | .driver = { | ||
828 | .name = "pmic_touch", | ||
829 | .bus = &spi_bus_type, | ||
830 | .owner = THIS_MODULE, | ||
831 | }, | ||
832 | .probe = mrstouch_probe, | ||
833 | .suspend = mrstouch_suspend, | ||
834 | .resume = mrstouch_resume, | ||
835 | .remove = mrstouch_remove, | ||
836 | }; | ||
837 | |||
838 | static int __init mrstouch_module_init(void) | ||
839 | { | ||
840 | int err; | ||
841 | |||
842 | mrstouch_debug("%s", __func__); | ||
843 | err = spi_register_driver(&mrstouch_driver); | ||
844 | if (err) { | ||
845 | mrstouch_debug("%s(%d)", "SPI PENDET failed", err); | ||
846 | return -1; | ||
847 | } | ||
848 | |||
849 | return 0; | ||
850 | } | ||
851 | |||
852 | static void __exit mrstouch_module_exit(void) | ||
853 | { | ||
854 | mrstouch_debug("%s", __func__); | ||
855 | spi_unregister_driver(&mrstouch_driver); | ||
856 | return; | ||
857 | } | ||
858 | |||
859 | module_init(mrstouch_module_init); | ||
860 | module_exit(mrstouch_module_exit); | ||
861 | |||
862 | MODULE_AUTHOR("Sreedhara Murthy. D.S, sreedhara.ds@intel.com"); | ||
863 | MODULE_DESCRIPTION("Intel Moorestown Resistive Touch Screen Driver"); | ||
864 | MODULE_LICENSE("GPL"); | ||