aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/Kconfig21
-rw-r--r--drivers/hid/Makefile21
-rw-r--r--drivers/hid/hid-core.c3
-rw-r--r--drivers/hid/hid-ids.h6
-rw-r--r--drivers/hid/hid-input.c11
-rw-r--r--drivers/hid/hid-magicmouse.c2
-rw-r--r--drivers/hid/hid-multitouch.c185
-rw-r--r--drivers/hid/hid-picolcd.c2748
-rw-r--r--drivers/hid/hid-picolcd.h309
-rw-r--r--drivers/hid/hid-picolcd_backlight.c122
-rw-r--r--drivers/hid/hid-picolcd_cir.c152
-rw-r--r--drivers/hid/hid-picolcd_core.c689
-rw-r--r--drivers/hid/hid-picolcd_debugfs.c899
-rw-r--r--drivers/hid/hid-picolcd_fb.c615
-rw-r--r--drivers/hid/hid-picolcd_lcd.c107
-rw-r--r--drivers/hid/hid-picolcd_leds.c175
-rw-r--r--drivers/hid/hid-ps3remote.c215
-rw-r--r--drivers/hid/hid-uclogic.c98
-rw-r--r--drivers/hid/hid-wacom.c169
-rw-r--r--drivers/hid/hid-wiimote-ext.c97
-rw-r--r--drivers/hid/hidraw.c69
21 files changed, 3808 insertions, 2905 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index fbf49503508d..bf0617e47b89 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -527,6 +527,14 @@ config HID_PICOLCD_LEDS
527 ---help--- 527 ---help---
528 Provide access to PicoLCD's GPO pins via leds class. 528 Provide access to PicoLCD's GPO pins via leds class.
529 529
530config HID_PICOLCD_CIR
531 bool "CIR via RC class" if EXPERT
532 default !EXPERT
533 depends on HID_PICOLCD
534 depends on HID_PICOLCD=RC_CORE || RC_CORE=y
535 ---help---
536 Provide access to PicoLCD's CIR interface via remote control (LIRC).
537
530config HID_PRIMAX 538config HID_PRIMAX
531 tristate "Primax non-fully HID-compliant devices" 539 tristate "Primax non-fully HID-compliant devices"
532 depends on USB_HID 540 depends on USB_HID
@@ -534,6 +542,15 @@ config HID_PRIMAX
534 Support for Primax devices that are not fully compliant with the 542 Support for Primax devices that are not fully compliant with the
535 HID standard. 543 HID standard.
536 544
545config HID_PS3REMOTE
546 tristate "Sony PS3 BD Remote Control"
547 depends on BT_HIDP
548 ---help---
549 Support for the Sony PS3 Blue-ray Disk Remote Control and Logitech
550 Harmony Adapter for PS3, which connect over Bluetooth.
551
552 Support for the 6-axis controllers is provided by HID_SONY.
553
537config HID_ROCCAT 554config HID_ROCCAT
538 tristate "Roccat device support" 555 tristate "Roccat device support"
539 depends on USB_HID 556 depends on USB_HID
@@ -561,7 +578,9 @@ config HID_SONY
561 tristate "Sony PS3 controller" 578 tristate "Sony PS3 controller"
562 depends on USB_HID 579 depends on USB_HID
563 ---help--- 580 ---help---
564 Support for Sony PS3 controller. 581 Support for Sony PS3 6-axis controllers.
582
583 Support for the Sony PS3 BD Remote is provided by HID_PS3REMOTE.
565 584
566config HID_SPEEDLINK 585config HID_SPEEDLINK
567 tristate "Speedlink VAD Cezanne mouse support" 586 tristate "Speedlink VAD Cezanne mouse support"
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index f975485f88b2..5a3690ff9bf2 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -69,7 +69,28 @@ obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o
69obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o 69obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o
70obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o 70obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
71obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o 71obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o
72hid-picolcd-y += hid-picolcd_core.o
73ifdef CONFIG_HID_PICOLCD_FB
74hid-picolcd-y += hid-picolcd_fb.o
75endif
76ifdef CONFIG_HID_PICOLCD_BACKLIGHT
77hid-picolcd-y += hid-picolcd_backlight.o
78endif
79ifdef CONFIG_HID_PICOLCD_LCD
80hid-picolcd-y += hid-picolcd_lcd.o
81endif
82ifdef CONFIG_HID_PICOLCD_LEDS
83hid-picolcd-y += hid-picolcd_leds.o
84endif
85ifdef CONFIG_HID_PICOLCD_CIR
86hid-picolcd-y += hid-picolcd_cir.o
87endif
88ifdef CONFIG_DEBUG_FS
89hid-picolcd-y += hid-picolcd_debugfs.o
90endif
91
72obj-$(CONFIG_HID_PRIMAX) += hid-primax.o 92obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
93obj-$(CONFIG_HID_PS3REMOTE) += hid-ps3remote.o
73obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ 94obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \
74 hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ 95 hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \
75 hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-pyra.o \ 96 hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-pyra.o \
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 8bcd168fffae..9072e0ed1876 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1566,6 +1566,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1566 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, 1566 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
1567 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, 1567 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) },
1568 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) }, 1568 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) },
1569 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) },
1569 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) }, 1570 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) },
1570 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) }, 1571 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) },
1571 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) }, 1572 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) },
@@ -1639,6 +1640,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1639 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, 1640 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
1640 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, 1641 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
1641 { HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) }, 1642 { HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
1643 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) },
1642 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 1644 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
1643 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) }, 1645 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) },
1644 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 1646 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
@@ -1663,6 +1665,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1663 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) }, 1665 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) },
1664 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP1062) }, 1666 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP1062) },
1665 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850) }, 1667 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850) },
1668 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWHA60) },
1666 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, 1669 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
1667 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SUPER_JOY_BOX_3) }, 1670 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SUPER_JOY_BOX_3) },
1668 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD) }, 1671 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 1dcb76ff51e3..a534375fdf2e 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -283,6 +283,9 @@
283#define USB_VENDOR_ID_EMS 0x2006 283#define USB_VENDOR_ID_EMS 0x2006
284#define USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II 0x0118 284#define USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II 0x0118
285 285
286#define USB_VENDOR_ID_FLATFROG 0x25b5
287#define USB_DEVICE_ID_MULTITOUCH_3200 0x0002
288
286#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f 289#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
287#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 290#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
288 291
@@ -496,6 +499,7 @@
496#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 499#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
497#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 500#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110
498#define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f 501#define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f
502#define USB_DEVICE_ID_LOGITECH_HARMONY_PS3 0x0306
499#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD 0xc20a 503#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD 0xc20a
500#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211 504#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211
501#define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215 505#define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215
@@ -683,6 +687,7 @@
683 687
684#define USB_VENDOR_ID_SONY 0x054c 688#define USB_VENDOR_ID_SONY 0x054c
685#define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b 689#define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b
690#define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306
686#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 691#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
687#define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f 692#define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f
688 693
@@ -758,6 +763,7 @@
758#define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005 763#define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005
759#define USB_DEVICE_ID_UCLOGIC_TABLET_WP1062 0x0064 764#define USB_DEVICE_ID_UCLOGIC_TABLET_WP1062 0x0064
760#define USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850 0x0522 765#define USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850 0x0522
766#define USB_DEVICE_ID_UCLOGIC_TABLET_TWHA60 0x0781
761 767
762#define USB_VENDOR_ID_UNITEC 0x227d 768#define USB_VENDOR_ID_UNITEC 0x227d
763#define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709 769#define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 811bfad64609..d917c0d53685 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1154,6 +1154,7 @@ static void report_features(struct hid_device *hid)
1154 1154
1155int hidinput_connect(struct hid_device *hid, unsigned int force) 1155int hidinput_connect(struct hid_device *hid, unsigned int force)
1156{ 1156{
1157 struct hid_driver *drv = hid->driver;
1157 struct hid_report *report; 1158 struct hid_report *report;
1158 struct hid_input *hidinput = NULL; 1159 struct hid_input *hidinput = NULL;
1159 struct input_dev *input_dev; 1160 struct input_dev *input_dev;
@@ -1228,6 +1229,8 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
1228 * UGCI) cram a lot of unrelated inputs into the 1229 * UGCI) cram a lot of unrelated inputs into the
1229 * same interface. */ 1230 * same interface. */
1230 hidinput->report = report; 1231 hidinput->report = report;
1232 if (drv->input_configured)
1233 drv->input_configured(hid, hidinput);
1231 if (input_register_device(hidinput->input)) 1234 if (input_register_device(hidinput->input))
1232 goto out_cleanup; 1235 goto out_cleanup;
1233 hidinput = NULL; 1236 hidinput = NULL;
@@ -1235,8 +1238,12 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
1235 } 1238 }
1236 } 1239 }
1237 1240
1238 if (hidinput && input_register_device(hidinput->input)) 1241 if (hidinput) {
1239 goto out_cleanup; 1242 if (drv->input_configured)
1243 drv->input_configured(hid, hidinput);
1244 if (input_register_device(hidinput->input))
1245 goto out_cleanup;
1246 }
1240 1247
1241 return 0; 1248 return 0;
1242 1249
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 73647266daad..25ddf3e3aec6 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -392,7 +392,7 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
392 392
393 __set_bit(EV_ABS, input->evbit); 393 __set_bit(EV_ABS, input->evbit);
394 394
395 error = input_mt_init_slots(input, 16); 395 error = input_mt_init_slots(input, 16, 0);
396 if (error) 396 if (error)
397 return error; 397 return error;
398 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2, 398 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2,
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 59c8b5c1d2de..ee0b76b398cb 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -51,12 +51,12 @@ MODULE_LICENSE("GPL");
51#define MT_QUIRK_VALID_IS_INRANGE (1 << 5) 51#define MT_QUIRK_VALID_IS_INRANGE (1 << 5)
52#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 6) 52#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 6)
53#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 8) 53#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 8)
54#define MT_QUIRK_NO_AREA (1 << 9)
54 55
55struct mt_slot { 56struct mt_slot {
56 __s32 x, y, p, w, h; 57 __s32 x, y, p, w, h;
57 __s32 contactid; /* the device ContactID assigned to this slot */ 58 __s32 contactid; /* the device ContactID assigned to this slot */
58 bool touch_state; /* is the touch valid? */ 59 bool touch_state; /* is the touch valid? */
59 bool seen_in_this_frame;/* has this slot been updated */
60}; 60};
61 61
62struct mt_class { 62struct mt_class {
@@ -92,8 +92,9 @@ struct mt_device {
92 __u8 touches_by_report; /* how many touches are present in one report: 92 __u8 touches_by_report; /* how many touches are present in one report:
93 * 1 means we should use a serial protocol 93 * 1 means we should use a serial protocol
94 * > 1 means hybrid (multitouch) protocol */ 94 * > 1 means hybrid (multitouch) protocol */
95 bool serial_maybe; /* need to check for serial protocol */
95 bool curvalid; /* is the current contact valid? */ 96 bool curvalid; /* is the current contact valid? */
96 struct mt_slot *slots; 97 unsigned mt_flags; /* flags to pass to input-mt */
97}; 98};
98 99
99/* classes of device behavior */ 100/* classes of device behavior */
@@ -115,6 +116,7 @@ struct mt_device {
115#define MT_CLS_EGALAX_SERIAL 0x0104 116#define MT_CLS_EGALAX_SERIAL 0x0104
116#define MT_CLS_TOPSEED 0x0105 117#define MT_CLS_TOPSEED 0x0105
117#define MT_CLS_PANASONIC 0x0106 118#define MT_CLS_PANASONIC 0x0106
119#define MT_CLS_FLATFROG 0x0107
118 120
119#define MT_DEFAULT_MAXCONTACT 10 121#define MT_DEFAULT_MAXCONTACT 10
120 122
@@ -134,25 +136,6 @@ static int cypress_compute_slot(struct mt_device *td)
134 return -1; 136 return -1;
135} 137}
136 138
137static int find_slot_from_contactid(struct mt_device *td)
138{
139 int i;
140 for (i = 0; i < td->maxcontacts; ++i) {
141 if (td->slots[i].contactid == td->curdata.contactid &&
142 td->slots[i].touch_state)
143 return i;
144 }
145 for (i = 0; i < td->maxcontacts; ++i) {
146 if (!td->slots[i].seen_in_this_frame &&
147 !td->slots[i].touch_state)
148 return i;
149 }
150 /* should not occurs. If this happens that means
151 * that the device sent more touches that it says
152 * in the report descriptor. It is ignored then. */
153 return -1;
154}
155
156static struct mt_class mt_classes[] = { 139static struct mt_class mt_classes[] = {
157 { .name = MT_CLS_DEFAULT, 140 { .name = MT_CLS_DEFAULT,
158 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP }, 141 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP },
@@ -190,7 +173,9 @@ static struct mt_class mt_classes[] = {
190 MT_QUIRK_SLOT_IS_CONTACTID, 173 MT_QUIRK_SLOT_IS_CONTACTID,
191 .sn_move = 2048, 174 .sn_move = 2048,
192 .sn_width = 128, 175 .sn_width = 128,
193 .sn_height = 128 }, 176 .sn_height = 128,
177 .maxcontacts = 60,
178 },
194 { .name = MT_CLS_CYPRESS, 179 { .name = MT_CLS_CYPRESS,
195 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | 180 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
196 MT_QUIRK_CYPRESS, 181 MT_QUIRK_CYPRESS,
@@ -216,6 +201,12 @@ static struct mt_class mt_classes[] = {
216 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP, 201 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP,
217 .maxcontacts = 4 }, 202 .maxcontacts = 4 },
218 203
204 { .name = MT_CLS_FLATFROG,
205 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
206 MT_QUIRK_NO_AREA,
207 .sn_move = 2048,
208 .maxcontacts = 40,
209 },
219 { } 210 { }
220}; 211};
221 212
@@ -319,24 +310,16 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
319 * We need to ignore fields that belong to other collections 310 * We need to ignore fields that belong to other collections
320 * such as Mouse that might have the same GenericDesktop usages. */ 311 * such as Mouse that might have the same GenericDesktop usages. */
321 if (field->application == HID_DG_TOUCHSCREEN) 312 if (field->application == HID_DG_TOUCHSCREEN)
322 set_bit(INPUT_PROP_DIRECT, hi->input->propbit); 313 td->mt_flags |= INPUT_MT_DIRECT;
323 else if (field->application != HID_DG_TOUCHPAD) 314 else if (field->application != HID_DG_TOUCHPAD)
324 return 0; 315 return 0;
325 316
326 /* In case of an indirect device (touchpad), we need to add 317 /*
327 * specific BTN_TOOL_* to be handled by the synaptics xorg 318 * Model touchscreens providing buttons as touchpads.
328 * driver.
329 * We also consider that touchscreens providing buttons are touchpads.
330 */ 319 */
331 if (field->application == HID_DG_TOUCHPAD || 320 if (field->application == HID_DG_TOUCHPAD ||
332 (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON || 321 (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON)
333 cls->is_indirect) { 322 td->mt_flags |= INPUT_MT_POINTER;
334 set_bit(INPUT_PROP_POINTER, hi->input->propbit);
335 set_bit(BTN_TOOL_FINGER, hi->input->keybit);
336 set_bit(BTN_TOOL_DOUBLETAP, hi->input->keybit);
337 set_bit(BTN_TOOL_TRIPLETAP, hi->input->keybit);
338 set_bit(BTN_TOOL_QUADTAP, hi->input->keybit);
339 }
340 323
341 /* eGalax devices provide a Digitizer.Stylus input which overrides 324 /* eGalax devices provide a Digitizer.Stylus input which overrides
342 * the correct Digitizers.Finger X/Y ranges. 325 * the correct Digitizers.Finger X/Y ranges.
@@ -353,8 +336,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
353 EV_ABS, ABS_MT_POSITION_X); 336 EV_ABS, ABS_MT_POSITION_X);
354 set_abs(hi->input, ABS_MT_POSITION_X, field, 337 set_abs(hi->input, ABS_MT_POSITION_X, field,
355 cls->sn_move); 338 cls->sn_move);
356 /* touchscreen emulation */
357 set_abs(hi->input, ABS_X, field, cls->sn_move);
358 mt_store_field(usage, td, hi); 339 mt_store_field(usage, td, hi);
359 td->last_field_index = field->index; 340 td->last_field_index = field->index;
360 return 1; 341 return 1;
@@ -363,8 +344,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
363 EV_ABS, ABS_MT_POSITION_Y); 344 EV_ABS, ABS_MT_POSITION_Y);
364 set_abs(hi->input, ABS_MT_POSITION_Y, field, 345 set_abs(hi->input, ABS_MT_POSITION_Y, field,
365 cls->sn_move); 346 cls->sn_move);
366 /* touchscreen emulation */
367 set_abs(hi->input, ABS_Y, field, cls->sn_move);
368 mt_store_field(usage, td, hi); 347 mt_store_field(usage, td, hi);
369 td->last_field_index = field->index; 348 td->last_field_index = field->index;
370 return 1; 349 return 1;
@@ -388,9 +367,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
388 td->last_field_index = field->index; 367 td->last_field_index = field->index;
389 return 1; 368 return 1;
390 case HID_DG_CONTACTID: 369 case HID_DG_CONTACTID:
391 if (!td->maxcontacts)
392 td->maxcontacts = MT_DEFAULT_MAXCONTACT;
393 input_mt_init_slots(hi->input, td->maxcontacts);
394 mt_store_field(usage, td, hi); 370 mt_store_field(usage, td, hi);
395 td->last_field_index = field->index; 371 td->last_field_index = field->index;
396 td->touches_by_report++; 372 td->touches_by_report++;
@@ -398,18 +374,21 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
398 case HID_DG_WIDTH: 374 case HID_DG_WIDTH:
399 hid_map_usage(hi, usage, bit, max, 375 hid_map_usage(hi, usage, bit, max,
400 EV_ABS, ABS_MT_TOUCH_MAJOR); 376 EV_ABS, ABS_MT_TOUCH_MAJOR);
401 set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, 377 if (!(cls->quirks & MT_QUIRK_NO_AREA))
402 cls->sn_width); 378 set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,
379 cls->sn_width);
403 mt_store_field(usage, td, hi); 380 mt_store_field(usage, td, hi);
404 td->last_field_index = field->index; 381 td->last_field_index = field->index;
405 return 1; 382 return 1;
406 case HID_DG_HEIGHT: 383 case HID_DG_HEIGHT:
407 hid_map_usage(hi, usage, bit, max, 384 hid_map_usage(hi, usage, bit, max,
408 EV_ABS, ABS_MT_TOUCH_MINOR); 385 EV_ABS, ABS_MT_TOUCH_MINOR);
409 set_abs(hi->input, ABS_MT_TOUCH_MINOR, field, 386 if (!(cls->quirks & MT_QUIRK_NO_AREA)) {
410 cls->sn_height); 387 set_abs(hi->input, ABS_MT_TOUCH_MINOR, field,
411 input_set_abs_params(hi->input, 388 cls->sn_height);
389 input_set_abs_params(hi->input,
412 ABS_MT_ORIENTATION, 0, 1, 0, 0); 390 ABS_MT_ORIENTATION, 0, 1, 0, 0);
391 }
413 mt_store_field(usage, td, hi); 392 mt_store_field(usage, td, hi);
414 td->last_field_index = field->index; 393 td->last_field_index = field->index;
415 return 1; 394 return 1;
@@ -418,9 +397,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
418 EV_ABS, ABS_MT_PRESSURE); 397 EV_ABS, ABS_MT_PRESSURE);
419 set_abs(hi->input, ABS_MT_PRESSURE, field, 398 set_abs(hi->input, ABS_MT_PRESSURE, field,
420 cls->sn_pressure); 399 cls->sn_pressure);
421 /* touchscreen emulation */
422 set_abs(hi->input, ABS_PRESSURE, field,
423 cls->sn_pressure);
424 mt_store_field(usage, td, hi); 400 mt_store_field(usage, td, hi);
425 td->last_field_index = field->index; 401 td->last_field_index = field->index;
426 return 1; 402 return 1;
@@ -464,7 +440,7 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
464 return -1; 440 return -1;
465} 441}
466 442
467static int mt_compute_slot(struct mt_device *td) 443static int mt_compute_slot(struct mt_device *td, struct input_dev *input)
468{ 444{
469 __s32 quirks = td->mtclass.quirks; 445 __s32 quirks = td->mtclass.quirks;
470 446
@@ -480,42 +456,23 @@ static int mt_compute_slot(struct mt_device *td)
480 if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE) 456 if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE)
481 return td->curdata.contactid - 1; 457 return td->curdata.contactid - 1;
482 458
483 return find_slot_from_contactid(td); 459 return input_mt_get_slot_by_key(input, td->curdata.contactid);
484} 460}
485 461
486/* 462/*
487 * this function is called when a whole contact has been processed, 463 * this function is called when a whole contact has been processed,
488 * so that it can assign it to a slot and store the data there 464 * so that it can assign it to a slot and store the data there
489 */ 465 */
490static void mt_complete_slot(struct mt_device *td) 466static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
491{ 467{
492 td->curdata.seen_in_this_frame = true;
493 if (td->curvalid) { 468 if (td->curvalid) {
494 int slotnum = mt_compute_slot(td); 469 int slotnum = mt_compute_slot(td, input);
495 470 struct mt_slot *s = &td->curdata;
496 if (slotnum >= 0 && slotnum < td->maxcontacts)
497 td->slots[slotnum] = td->curdata;
498 }
499 td->num_received++;
500}
501
502 471
503/* 472 if (slotnum < 0 || slotnum >= td->maxcontacts)
504 * this function is called when a whole packet has been received and processed, 473 return;
505 * so that it can decide what to send to the input layer.
506 */
507static void mt_emit_event(struct mt_device *td, struct input_dev *input)
508{
509 int i;
510 474
511 for (i = 0; i < td->maxcontacts; ++i) { 475 input_mt_slot(input, slotnum);
512 struct mt_slot *s = &(td->slots[i]);
513 if ((td->mtclass.quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) &&
514 !s->seen_in_this_frame) {
515 s->touch_state = false;
516 }
517
518 input_mt_slot(input, i);
519 input_mt_report_slot_state(input, MT_TOOL_FINGER, 476 input_mt_report_slot_state(input, MT_TOOL_FINGER,
520 s->touch_state); 477 s->touch_state);
521 if (s->touch_state) { 478 if (s->touch_state) {
@@ -532,24 +489,29 @@ static void mt_emit_event(struct mt_device *td, struct input_dev *input)
532 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); 489 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
533 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); 490 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
534 } 491 }
535 s->seen_in_this_frame = false;
536
537 } 492 }
538 493
539 input_mt_report_pointer_emulation(input, true); 494 td->num_received++;
495}
496
497/*
498 * this function is called when a whole packet has been received and processed,
499 * so that it can decide what to send to the input layer.
500 */
501static void mt_sync_frame(struct mt_device *td, struct input_dev *input)
502{
503 input_mt_sync_frame(input);
540 input_sync(input); 504 input_sync(input);
541 td->num_received = 0; 505 td->num_received = 0;
542} 506}
543 507
544
545
546static int mt_event(struct hid_device *hid, struct hid_field *field, 508static int mt_event(struct hid_device *hid, struct hid_field *field,
547 struct hid_usage *usage, __s32 value) 509 struct hid_usage *usage, __s32 value)
548{ 510{
549 struct mt_device *td = hid_get_drvdata(hid); 511 struct mt_device *td = hid_get_drvdata(hid);
550 __s32 quirks = td->mtclass.quirks; 512 __s32 quirks = td->mtclass.quirks;
551 513
552 if (hid->claimed & HID_CLAIMED_INPUT && td->slots) { 514 if (hid->claimed & HID_CLAIMED_INPUT) {
553 switch (usage->hid) { 515 switch (usage->hid) {
554 case HID_DG_INRANGE: 516 case HID_DG_INRANGE:
555 if (quirks & MT_QUIRK_ALWAYS_VALID) 517 if (quirks & MT_QUIRK_ALWAYS_VALID)
@@ -602,11 +564,11 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
602 } 564 }
603 565
604 if (usage->hid == td->last_slot_field) 566 if (usage->hid == td->last_slot_field)
605 mt_complete_slot(td); 567 mt_complete_slot(td, field->hidinput->input);
606 568
607 if (field->index == td->last_field_index 569 if (field->index == td->last_field_index
608 && td->num_received >= td->num_expected) 570 && td->num_received >= td->num_expected)
609 mt_emit_event(td, field->hidinput->input); 571 mt_sync_frame(td, field->hidinput->input);
610 572
611 } 573 }
612 574
@@ -685,6 +647,35 @@ static void mt_post_parse(struct mt_device *td)
685 } 647 }
686} 648}
687 649
650static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
651
652{
653 struct mt_device *td = hid_get_drvdata(hdev);
654 struct mt_class *cls = &td->mtclass;
655 struct input_dev *input = hi->input;
656
657 /* Only initialize slots for MT input devices */
658 if (!test_bit(ABS_MT_POSITION_X, input->absbit))
659 return;
660
661 if (!td->maxcontacts)
662 td->maxcontacts = MT_DEFAULT_MAXCONTACT;
663
664 mt_post_parse(td);
665 if (td->serial_maybe)
666 mt_post_parse_default_settings(td);
667
668 if (cls->is_indirect)
669 td->mt_flags |= INPUT_MT_POINTER;
670
671 if (cls->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
672 td->mt_flags |= INPUT_MT_DROP_UNUSED;
673
674 input_mt_init_slots(input, td->maxcontacts, td->mt_flags);
675
676 td->mt_flags = 0;
677}
678
688static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) 679static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
689{ 680{
690 int ret, i; 681 int ret, i;
@@ -722,6 +713,9 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
722 goto fail; 713 goto fail;
723 } 714 }
724 715
716 if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID)
717 td->serial_maybe = true;
718
725 ret = hid_parse(hdev); 719 ret = hid_parse(hdev);
726 if (ret != 0) 720 if (ret != 0)
727 goto fail; 721 goto fail;
@@ -730,20 +724,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
730 if (ret) 724 if (ret)
731 goto fail; 725 goto fail;
732 726
733 mt_post_parse(td);
734
735 if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID)
736 mt_post_parse_default_settings(td);
737
738 td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot),
739 GFP_KERNEL);
740 if (!td->slots) {
741 dev_err(&hdev->dev, "cannot allocate multitouch slots\n");
742 hid_hw_stop(hdev);
743 ret = -ENOMEM;
744 goto fail;
745 }
746
747 ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); 727 ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group);
748 728
749 mt_set_maxcontacts(hdev); 729 mt_set_maxcontacts(hdev);
@@ -774,7 +754,6 @@ static void mt_remove(struct hid_device *hdev)
774 struct mt_device *td = hid_get_drvdata(hdev); 754 struct mt_device *td = hid_get_drvdata(hdev);
775 sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group); 755 sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group);
776 hid_hw_stop(hdev); 756 hid_hw_stop(hdev);
777 kfree(td->slots);
778 kfree(td); 757 kfree(td);
779 hid_set_drvdata(hdev, NULL); 758 hid_set_drvdata(hdev, NULL);
780} 759}
@@ -892,6 +871,11 @@ static const struct hid_device_id mt_devices[] = {
892 MT_USB_DEVICE(USB_VENDOR_ID_ELO, 871 MT_USB_DEVICE(USB_VENDOR_ID_ELO,
893 USB_DEVICE_ID_ELO_TS2515) }, 872 USB_DEVICE_ID_ELO_TS2515) },
894 873
874 /* Flatfrog Panels */
875 { .driver_data = MT_CLS_FLATFROG,
876 MT_USB_DEVICE(USB_VENDOR_ID_FLATFROG,
877 USB_DEVICE_ID_MULTITOUCH_3200) },
878
895 /* GeneralTouch panel */ 879 /* GeneralTouch panel */
896 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, 880 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
897 MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 881 MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
@@ -1087,6 +1071,7 @@ static struct hid_driver mt_driver = {
1087 .remove = mt_remove, 1071 .remove = mt_remove,
1088 .input_mapping = mt_input_mapping, 1072 .input_mapping = mt_input_mapping,
1089 .input_mapped = mt_input_mapped, 1073 .input_mapped = mt_input_mapped,
1074 .input_configured = mt_input_configured,
1090 .feature_mapping = mt_feature_mapping, 1075 .feature_mapping = mt_feature_mapping,
1091 .usage_table = mt_grabbed_usages, 1076 .usage_table = mt_grabbed_usages,
1092 .event = mt_event, 1077 .event = mt_event,
diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c
deleted file mode 100644
index 27c8ebdfad01..000000000000
--- a/drivers/hid/hid-picolcd.c
+++ /dev/null
@@ -1,2748 +0,0 @@
1/***************************************************************************
2 * Copyright (C) 2010 by Bruno Prémont <bonbons@linux-vserver.org> *
3 * *
4 * Based on Logitech G13 driver (v0.4) *
5 * Copyright (C) 2009 by Rick L. Vinyard, Jr. <rvinyard@cs.nmsu.edu> *
6 * *
7 * This program is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, version 2 of the License. *
10 * *
11 * This driver is distributed in the hope that it will be useful, but *
12 * WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14 * General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this software. If not see <http://www.gnu.org/licenses/>. *
18 ***************************************************************************/
19
20#include <linux/hid.h>
21#include <linux/hid-debug.h>
22#include <linux/input.h>
23#include "hid-ids.h"
24#include "usbhid/usbhid.h"
25#include <linux/usb.h>
26
27#include <linux/fb.h>
28#include <linux/vmalloc.h>
29#include <linux/backlight.h>
30#include <linux/lcd.h>
31
32#include <linux/leds.h>
33
34#include <linux/seq_file.h>
35#include <linux/debugfs.h>
36
37#include <linux/completion.h>
38#include <linux/uaccess.h>
39#include <linux/module.h>
40
41#define PICOLCD_NAME "PicoLCD (graphic)"
42
43/* Report numbers */
44#define REPORT_ERROR_CODE 0x10 /* LCD: IN[16] */
45#define ERR_SUCCESS 0x00
46#define ERR_PARAMETER_MISSING 0x01
47#define ERR_DATA_MISSING 0x02
48#define ERR_BLOCK_READ_ONLY 0x03
49#define ERR_BLOCK_NOT_ERASABLE 0x04
50#define ERR_BLOCK_TOO_BIG 0x05
51#define ERR_SECTION_OVERFLOW 0x06
52#define ERR_INVALID_CMD_LEN 0x07
53#define ERR_INVALID_DATA_LEN 0x08
54#define REPORT_KEY_STATE 0x11 /* LCD: IN[2] */
55#define REPORT_IR_DATA 0x21 /* LCD: IN[63] */
56#define REPORT_EE_DATA 0x32 /* LCD: IN[63] */
57#define REPORT_MEMORY 0x41 /* LCD: IN[63] */
58#define REPORT_LED_STATE 0x81 /* LCD: OUT[1] */
59#define REPORT_BRIGHTNESS 0x91 /* LCD: OUT[1] */
60#define REPORT_CONTRAST 0x92 /* LCD: OUT[1] */
61#define REPORT_RESET 0x93 /* LCD: OUT[2] */
62#define REPORT_LCD_CMD 0x94 /* LCD: OUT[63] */
63#define REPORT_LCD_DATA 0x95 /* LCD: OUT[63] */
64#define REPORT_LCD_CMD_DATA 0x96 /* LCD: OUT[63] */
65#define REPORT_EE_READ 0xa3 /* LCD: OUT[63] */
66#define REPORT_EE_WRITE 0xa4 /* LCD: OUT[63] */
67#define REPORT_ERASE_MEMORY 0xb2 /* LCD: OUT[2] */
68#define REPORT_READ_MEMORY 0xb3 /* LCD: OUT[3] */
69#define REPORT_WRITE_MEMORY 0xb4 /* LCD: OUT[63] */
70#define REPORT_SPLASH_RESTART 0xc1 /* LCD: OUT[1] */
71#define REPORT_EXIT_KEYBOARD 0xef /* LCD: OUT[2] */
72#define REPORT_VERSION 0xf1 /* LCD: IN[2],OUT[1] Bootloader: IN[2],OUT[1] */
73#define REPORT_BL_ERASE_MEMORY 0xf2 /* Bootloader: IN[36],OUT[4] */
74#define REPORT_BL_READ_MEMORY 0xf3 /* Bootloader: IN[36],OUT[4] */
75#define REPORT_BL_WRITE_MEMORY 0xf4 /* Bootloader: IN[36],OUT[36] */
76#define REPORT_DEVID 0xf5 /* LCD: IN[5], OUT[1] Bootloader: IN[5],OUT[1] */
77#define REPORT_SPLASH_SIZE 0xf6 /* LCD: IN[4], OUT[1] */
78#define REPORT_HOOK_VERSION 0xf7 /* LCD: IN[2], OUT[1] */
79#define REPORT_EXIT_FLASHER 0xff /* Bootloader: OUT[2] */
80
81#ifdef CONFIG_HID_PICOLCD_FB
82/* Framebuffer
83 *
84 * The PicoLCD use a Topway LCD module of 256x64 pixel
85 * This display area is tiled over 4 controllers with 8 tiles
86 * each. Each tile has 8x64 pixel, each data byte representing
87 * a 1-bit wide vertical line of the tile.
88 *
89 * The display can be updated at a tile granularity.
90 *
91 * Chip 1 Chip 2 Chip 3 Chip 4
92 * +----------------+----------------+----------------+----------------+
93 * | Tile 1 | Tile 1 | Tile 1 | Tile 1 |
94 * +----------------+----------------+----------------+----------------+
95 * | Tile 2 | Tile 2 | Tile 2 | Tile 2 |
96 * +----------------+----------------+----------------+----------------+
97 * ...
98 * +----------------+----------------+----------------+----------------+
99 * | Tile 8 | Tile 8 | Tile 8 | Tile 8 |
100 * +----------------+----------------+----------------+----------------+
101 */
102#define PICOLCDFB_NAME "picolcdfb"
103#define PICOLCDFB_WIDTH (256)
104#define PICOLCDFB_HEIGHT (64)
105#define PICOLCDFB_SIZE (PICOLCDFB_WIDTH * PICOLCDFB_HEIGHT / 8)
106
107#define PICOLCDFB_UPDATE_RATE_LIMIT 10
108#define PICOLCDFB_UPDATE_RATE_DEFAULT 2
109
110/* Framebuffer visual structures */
111static const struct fb_fix_screeninfo picolcdfb_fix = {
112 .id = PICOLCDFB_NAME,
113 .type = FB_TYPE_PACKED_PIXELS,
114 .visual = FB_VISUAL_MONO01,
115 .xpanstep = 0,
116 .ypanstep = 0,
117 .ywrapstep = 0,
118 .line_length = PICOLCDFB_WIDTH / 8,
119 .accel = FB_ACCEL_NONE,
120};
121
122static const struct fb_var_screeninfo picolcdfb_var = {
123 .xres = PICOLCDFB_WIDTH,
124 .yres = PICOLCDFB_HEIGHT,
125 .xres_virtual = PICOLCDFB_WIDTH,
126 .yres_virtual = PICOLCDFB_HEIGHT,
127 .width = 103,
128 .height = 26,
129 .bits_per_pixel = 1,
130 .grayscale = 1,
131 .red = {
132 .offset = 0,
133 .length = 1,
134 .msb_right = 0,
135 },
136 .green = {
137 .offset = 0,
138 .length = 1,
139 .msb_right = 0,
140 },
141 .blue = {
142 .offset = 0,
143 .length = 1,
144 .msb_right = 0,
145 },
146 .transp = {
147 .offset = 0,
148 .length = 0,
149 .msb_right = 0,
150 },
151};
152#endif /* CONFIG_HID_PICOLCD_FB */
153
154/* Input device
155 *
156 * The PicoLCD has an IR receiver header, a built-in keypad with 5 keys
157 * and header for 4x4 key matrix. The built-in keys are part of the matrix.
158 */
159static const unsigned short def_keymap[] = {
160 KEY_RESERVED, /* none */
161 KEY_BACK, /* col 4 + row 1 */
162 KEY_HOMEPAGE, /* col 3 + row 1 */
163 KEY_RESERVED, /* col 2 + row 1 */
164 KEY_RESERVED, /* col 1 + row 1 */
165 KEY_SCROLLUP, /* col 4 + row 2 */
166 KEY_OK, /* col 3 + row 2 */
167 KEY_SCROLLDOWN, /* col 2 + row 2 */
168 KEY_RESERVED, /* col 1 + row 2 */
169 KEY_RESERVED, /* col 4 + row 3 */
170 KEY_RESERVED, /* col 3 + row 3 */
171 KEY_RESERVED, /* col 2 + row 3 */
172 KEY_RESERVED, /* col 1 + row 3 */
173 KEY_RESERVED, /* col 4 + row 4 */
174 KEY_RESERVED, /* col 3 + row 4 */
175 KEY_RESERVED, /* col 2 + row 4 */
176 KEY_RESERVED, /* col 1 + row 4 */
177};
178#define PICOLCD_KEYS ARRAY_SIZE(def_keymap)
179
180/* Description of in-progress IO operation, used for operations
181 * that trigger response from device */
182struct picolcd_pending {
183 struct hid_report *out_report;
184 struct hid_report *in_report;
185 struct completion ready;
186 int raw_size;
187 u8 raw_data[64];
188};
189
190/* Per device data structure */
191struct picolcd_data {
192 struct hid_device *hdev;
193#ifdef CONFIG_DEBUG_FS
194 struct dentry *debug_reset;
195 struct dentry *debug_eeprom;
196 struct dentry *debug_flash;
197 struct mutex mutex_flash;
198 int addr_sz;
199#endif
200 u8 version[2];
201 unsigned short opmode_delay;
202 /* input stuff */
203 u8 pressed_keys[2];
204 struct input_dev *input_keys;
205 struct input_dev *input_cir;
206 unsigned short keycode[PICOLCD_KEYS];
207
208#ifdef CONFIG_HID_PICOLCD_FB
209 /* Framebuffer stuff */
210 u8 fb_update_rate;
211 u8 fb_bpp;
212 u8 fb_force;
213 u8 *fb_vbitmap; /* local copy of what was sent to PicoLCD */
214 u8 *fb_bitmap; /* framebuffer */
215 struct fb_info *fb_info;
216 struct fb_deferred_io fb_defio;
217#endif /* CONFIG_HID_PICOLCD_FB */
218#ifdef CONFIG_HID_PICOLCD_LCD
219 struct lcd_device *lcd;
220 u8 lcd_contrast;
221#endif /* CONFIG_HID_PICOLCD_LCD */
222#ifdef CONFIG_HID_PICOLCD_BACKLIGHT
223 struct backlight_device *backlight;
224 u8 lcd_brightness;
225 u8 lcd_power;
226#endif /* CONFIG_HID_PICOLCD_BACKLIGHT */
227#ifdef CONFIG_HID_PICOLCD_LEDS
228 /* LED stuff */
229 u8 led_state;
230 struct led_classdev *led[8];
231#endif /* CONFIG_HID_PICOLCD_LEDS */
232
233 /* Housekeeping stuff */
234 spinlock_t lock;
235 struct mutex mutex;
236 struct picolcd_pending *pending;
237 int status;
238#define PICOLCD_BOOTLOADER 1
239#define PICOLCD_FAILED 2
240#define PICOLCD_READY_FB 4
241};
242
243
244/* Find a given report */
245#define picolcd_in_report(id, dev) picolcd_report(id, dev, HID_INPUT_REPORT)
246#define picolcd_out_report(id, dev) picolcd_report(id, dev, HID_OUTPUT_REPORT)
247
248static struct hid_report *picolcd_report(int id, struct hid_device *hdev, int dir)
249{
250 struct list_head *feature_report_list = &hdev->report_enum[dir].report_list;
251 struct hid_report *report = NULL;
252
253 list_for_each_entry(report, feature_report_list, list) {
254 if (report->id == id)
255 return report;
256 }
257 hid_warn(hdev, "No report with id 0x%x found\n", id);
258 return NULL;
259}
260
261#ifdef CONFIG_DEBUG_FS
262static void picolcd_debug_out_report(struct picolcd_data *data,
263 struct hid_device *hdev, struct hid_report *report);
264#define usbhid_submit_report(a, b, c) \
265 do { \
266 picolcd_debug_out_report(hid_get_drvdata(a), a, b); \
267 usbhid_submit_report(a, b, c); \
268 } while (0)
269#endif
270
271/* Submit a report and wait for a reply from device - if device fades away
272 * or does not respond in time, return NULL */
273static struct picolcd_pending *picolcd_send_and_wait(struct hid_device *hdev,
274 int report_id, const u8 *raw_data, int size)
275{
276 struct picolcd_data *data = hid_get_drvdata(hdev);
277 struct picolcd_pending *work;
278 struct hid_report *report = picolcd_out_report(report_id, hdev);
279 unsigned long flags;
280 int i, j, k;
281
282 if (!report || !data)
283 return NULL;
284 if (data->status & PICOLCD_FAILED)
285 return NULL;
286 work = kzalloc(sizeof(*work), GFP_KERNEL);
287 if (!work)
288 return NULL;
289
290 init_completion(&work->ready);
291 work->out_report = report;
292 work->in_report = NULL;
293 work->raw_size = 0;
294
295 mutex_lock(&data->mutex);
296 spin_lock_irqsave(&data->lock, flags);
297 for (i = k = 0; i < report->maxfield; i++)
298 for (j = 0; j < report->field[i]->report_count; j++) {
299 hid_set_field(report->field[i], j, k < size ? raw_data[k] : 0);
300 k++;
301 }
302 data->pending = work;
303 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
304 spin_unlock_irqrestore(&data->lock, flags);
305 wait_for_completion_interruptible_timeout(&work->ready, HZ*2);
306 spin_lock_irqsave(&data->lock, flags);
307 data->pending = NULL;
308 spin_unlock_irqrestore(&data->lock, flags);
309 mutex_unlock(&data->mutex);
310 return work;
311}
312
313#ifdef CONFIG_HID_PICOLCD_FB
314/* Send a given tile to PicoLCD */
315static int picolcd_fb_send_tile(struct hid_device *hdev, int chip, int tile)
316{
317 struct picolcd_data *data = hid_get_drvdata(hdev);
318 struct hid_report *report1 = picolcd_out_report(REPORT_LCD_CMD_DATA, hdev);
319 struct hid_report *report2 = picolcd_out_report(REPORT_LCD_DATA, hdev);
320 unsigned long flags;
321 u8 *tdata;
322 int i;
323
324 if (!report1 || report1->maxfield != 1 || !report2 || report2->maxfield != 1)
325 return -ENODEV;
326
327 spin_lock_irqsave(&data->lock, flags);
328 hid_set_field(report1->field[0], 0, chip << 2);
329 hid_set_field(report1->field[0], 1, 0x02);
330 hid_set_field(report1->field[0], 2, 0x00);
331 hid_set_field(report1->field[0], 3, 0x00);
332 hid_set_field(report1->field[0], 4, 0xb8 | tile);
333 hid_set_field(report1->field[0], 5, 0x00);
334 hid_set_field(report1->field[0], 6, 0x00);
335 hid_set_field(report1->field[0], 7, 0x40);
336 hid_set_field(report1->field[0], 8, 0x00);
337 hid_set_field(report1->field[0], 9, 0x00);
338 hid_set_field(report1->field[0], 10, 32);
339
340 hid_set_field(report2->field[0], 0, (chip << 2) | 0x01);
341 hid_set_field(report2->field[0], 1, 0x00);
342 hid_set_field(report2->field[0], 2, 0x00);
343 hid_set_field(report2->field[0], 3, 32);
344
345 tdata = data->fb_vbitmap + (tile * 4 + chip) * 64;
346 for (i = 0; i < 64; i++)
347 if (i < 32)
348 hid_set_field(report1->field[0], 11 + i, tdata[i]);
349 else
350 hid_set_field(report2->field[0], 4 + i - 32, tdata[i]);
351
352 usbhid_submit_report(data->hdev, report1, USB_DIR_OUT);
353 usbhid_submit_report(data->hdev, report2, USB_DIR_OUT);
354 spin_unlock_irqrestore(&data->lock, flags);
355 return 0;
356}
357
358/* Translate a single tile*/
359static int picolcd_fb_update_tile(u8 *vbitmap, const u8 *bitmap, int bpp,
360 int chip, int tile)
361{
362 int i, b, changed = 0;
363 u8 tdata[64];
364 u8 *vdata = vbitmap + (tile * 4 + chip) * 64;
365
366 if (bpp == 1) {
367 for (b = 7; b >= 0; b--) {
368 const u8 *bdata = bitmap + tile * 256 + chip * 8 + b * 32;
369 for (i = 0; i < 64; i++) {
370 tdata[i] <<= 1;
371 tdata[i] |= (bdata[i/8] >> (i % 8)) & 0x01;
372 }
373 }
374 } else if (bpp == 8) {
375 for (b = 7; b >= 0; b--) {
376 const u8 *bdata = bitmap + (tile * 256 + chip * 8 + b * 32) * 8;
377 for (i = 0; i < 64; i++) {
378 tdata[i] <<= 1;
379 tdata[i] |= (bdata[i] & 0x80) ? 0x01 : 0x00;
380 }
381 }
382 } else {
383 /* Oops, we should never get here! */
384 WARN_ON(1);
385 return 0;
386 }
387
388 for (i = 0; i < 64; i++)
389 if (tdata[i] != vdata[i]) {
390 changed = 1;
391 vdata[i] = tdata[i];
392 }
393 return changed;
394}
395
396/* Reconfigure LCD display */
397static int picolcd_fb_reset(struct picolcd_data *data, int clear)
398{
399 struct hid_report *report = picolcd_out_report(REPORT_LCD_CMD, data->hdev);
400 int i, j;
401 unsigned long flags;
402 static const u8 mapcmd[8] = { 0x00, 0x02, 0x00, 0x64, 0x3f, 0x00, 0x64, 0xc0 };
403
404 if (!report || report->maxfield != 1)
405 return -ENODEV;
406
407 spin_lock_irqsave(&data->lock, flags);
408 for (i = 0; i < 4; i++) {
409 for (j = 0; j < report->field[0]->maxusage; j++)
410 if (j == 0)
411 hid_set_field(report->field[0], j, i << 2);
412 else if (j < sizeof(mapcmd))
413 hid_set_field(report->field[0], j, mapcmd[j]);
414 else
415 hid_set_field(report->field[0], j, 0);
416 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
417 }
418
419 data->status |= PICOLCD_READY_FB;
420 spin_unlock_irqrestore(&data->lock, flags);
421
422 if (data->fb_bitmap) {
423 if (clear) {
424 memset(data->fb_vbitmap, 0, PICOLCDFB_SIZE);
425 memset(data->fb_bitmap, 0, PICOLCDFB_SIZE*data->fb_bpp);
426 }
427 data->fb_force = 1;
428 }
429
430 /* schedule first output of framebuffer */
431 if (data->fb_info)
432 schedule_delayed_work(&data->fb_info->deferred_work, 0);
433
434 return 0;
435}
436
437/* Update fb_vbitmap from the screen_base and send changed tiles to device */
438static void picolcd_fb_update(struct picolcd_data *data)
439{
440 int chip, tile, n;
441 unsigned long flags;
442
443 if (!data)
444 return;
445
446 spin_lock_irqsave(&data->lock, flags);
447 if (!(data->status & PICOLCD_READY_FB)) {
448 spin_unlock_irqrestore(&data->lock, flags);
449 picolcd_fb_reset(data, 0);
450 } else {
451 spin_unlock_irqrestore(&data->lock, flags);
452 }
453
454 /*
455 * Translate the framebuffer into the format needed by the PicoLCD.
456 * See display layout above.
457 * Do this one tile after the other and push those tiles that changed.
458 *
459 * Wait for our IO to complete as otherwise we might flood the queue!
460 */
461 n = 0;
462 for (chip = 0; chip < 4; chip++)
463 for (tile = 0; tile < 8; tile++)
464 if (picolcd_fb_update_tile(data->fb_vbitmap,
465 data->fb_bitmap, data->fb_bpp, chip, tile) ||
466 data->fb_force) {
467 n += 2;
468 if (!data->fb_info->par)
469 return; /* device lost! */
470 if (n >= HID_OUTPUT_FIFO_SIZE / 2) {
471 usbhid_wait_io(data->hdev);
472 n = 0;
473 }
474 picolcd_fb_send_tile(data->hdev, chip, tile);
475 }
476 data->fb_force = false;
477 if (n)
478 usbhid_wait_io(data->hdev);
479}
480
481/* Stub to call the system default and update the image on the picoLCD */
482static void picolcd_fb_fillrect(struct fb_info *info,
483 const struct fb_fillrect *rect)
484{
485 if (!info->par)
486 return;
487 sys_fillrect(info, rect);
488
489 schedule_delayed_work(&info->deferred_work, 0);
490}
491
492/* Stub to call the system default and update the image on the picoLCD */
493static void picolcd_fb_copyarea(struct fb_info *info,
494 const struct fb_copyarea *area)
495{
496 if (!info->par)
497 return;
498 sys_copyarea(info, area);
499
500 schedule_delayed_work(&info->deferred_work, 0);
501}
502
503/* Stub to call the system default and update the image on the picoLCD */
504static void picolcd_fb_imageblit(struct fb_info *info, const struct fb_image *image)
505{
506 if (!info->par)
507 return;
508 sys_imageblit(info, image);
509
510 schedule_delayed_work(&info->deferred_work, 0);
511}
512
513/*
514 * this is the slow path from userspace. they can seek and write to
515 * the fb. it's inefficient to do anything less than a full screen draw
516 */
517static ssize_t picolcd_fb_write(struct fb_info *info, const char __user *buf,
518 size_t count, loff_t *ppos)
519{
520 ssize_t ret;
521 if (!info->par)
522 return -ENODEV;
523 ret = fb_sys_write(info, buf, count, ppos);
524 if (ret >= 0)
525 schedule_delayed_work(&info->deferred_work, 0);
526 return ret;
527}
528
529static int picolcd_fb_blank(int blank, struct fb_info *info)
530{
531 if (!info->par)
532 return -ENODEV;
533 /* We let fb notification do this for us via lcd/backlight device */
534 return 0;
535}
536
537static void picolcd_fb_destroy(struct fb_info *info)
538{
539 struct picolcd_data *data = info->par;
540 u32 *ref_cnt = info->pseudo_palette;
541 int may_release;
542
543 info->par = NULL;
544 if (data)
545 data->fb_info = NULL;
546 fb_deferred_io_cleanup(info);
547
548 ref_cnt--;
549 mutex_lock(&info->lock);
550 (*ref_cnt)--;
551 may_release = !*ref_cnt;
552 mutex_unlock(&info->lock);
553 if (may_release) {
554 vfree((u8 *)info->fix.smem_start);
555 framebuffer_release(info);
556 }
557}
558
559static int picolcd_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
560{
561 __u32 bpp = var->bits_per_pixel;
562 __u32 activate = var->activate;
563
564 /* only allow 1/8 bit depth (8-bit is grayscale) */
565 *var = picolcdfb_var;
566 var->activate = activate;
567 if (bpp >= 8) {
568 var->bits_per_pixel = 8;
569 var->red.length = 8;
570 var->green.length = 8;
571 var->blue.length = 8;
572 } else {
573 var->bits_per_pixel = 1;
574 var->red.length = 1;
575 var->green.length = 1;
576 var->blue.length = 1;
577 }
578 return 0;
579}
580
581static int picolcd_set_par(struct fb_info *info)
582{
583 struct picolcd_data *data = info->par;
584 u8 *tmp_fb, *o_fb;
585 if (!data)
586 return -ENODEV;
587 if (info->var.bits_per_pixel == data->fb_bpp)
588 return 0;
589 /* switch between 1/8 bit depths */
590 if (info->var.bits_per_pixel != 1 && info->var.bits_per_pixel != 8)
591 return -EINVAL;
592
593 o_fb = data->fb_bitmap;
594 tmp_fb = kmalloc(PICOLCDFB_SIZE*info->var.bits_per_pixel, GFP_KERNEL);
595 if (!tmp_fb)
596 return -ENOMEM;
597
598 /* translate FB content to new bits-per-pixel */
599 if (info->var.bits_per_pixel == 1) {
600 int i, b;
601 for (i = 0; i < PICOLCDFB_SIZE; i++) {
602 u8 p = 0;
603 for (b = 0; b < 8; b++) {
604 p <<= 1;
605 p |= o_fb[i*8+b] ? 0x01 : 0x00;
606 }
607 tmp_fb[i] = p;
608 }
609 memcpy(o_fb, tmp_fb, PICOLCDFB_SIZE);
610 info->fix.visual = FB_VISUAL_MONO01;
611 info->fix.line_length = PICOLCDFB_WIDTH / 8;
612 } else {
613 int i;
614 memcpy(tmp_fb, o_fb, PICOLCDFB_SIZE);
615 for (i = 0; i < PICOLCDFB_SIZE * 8; i++)
616 o_fb[i] = tmp_fb[i/8] & (0x01 << (7 - i % 8)) ? 0xff : 0x00;
617 info->fix.visual = FB_VISUAL_DIRECTCOLOR;
618 info->fix.line_length = PICOLCDFB_WIDTH;
619 }
620
621 kfree(tmp_fb);
622 data->fb_bpp = info->var.bits_per_pixel;
623 return 0;
624}
625
626/* Do refcounting on our FB and cleanup per worker if FB is
627 * closed after unplug of our device
628 * (fb_release holds info->lock and still touches info after
629 * we return so we can't release it immediately.
630 */
631struct picolcd_fb_cleanup_item {
632 struct fb_info *info;
633 struct picolcd_fb_cleanup_item *next;
634};
635static struct picolcd_fb_cleanup_item *fb_pending;
636static DEFINE_SPINLOCK(fb_pending_lock);
637
638static void picolcd_fb_do_cleanup(struct work_struct *data)
639{
640 struct picolcd_fb_cleanup_item *item;
641 unsigned long flags;
642
643 do {
644 spin_lock_irqsave(&fb_pending_lock, flags);
645 item = fb_pending;
646 fb_pending = item ? item->next : NULL;
647 spin_unlock_irqrestore(&fb_pending_lock, flags);
648
649 if (item) {
650 u8 *fb = (u8 *)item->info->fix.smem_start;
651 /* make sure we do not race against fb core when
652 * releasing */
653 mutex_lock(&item->info->lock);
654 mutex_unlock(&item->info->lock);
655 framebuffer_release(item->info);
656 vfree(fb);
657 }
658 } while (item);
659}
660
661static DECLARE_WORK(picolcd_fb_cleanup, picolcd_fb_do_cleanup);
662
663static int picolcd_fb_open(struct fb_info *info, int u)
664{
665 u32 *ref_cnt = info->pseudo_palette;
666 ref_cnt--;
667
668 (*ref_cnt)++;
669 return 0;
670}
671
672static int picolcd_fb_release(struct fb_info *info, int u)
673{
674 u32 *ref_cnt = info->pseudo_palette;
675 ref_cnt--;
676
677 (*ref_cnt)++;
678 if (!*ref_cnt) {
679 unsigned long flags;
680 struct picolcd_fb_cleanup_item *item = (struct picolcd_fb_cleanup_item *)ref_cnt;
681 item--;
682 spin_lock_irqsave(&fb_pending_lock, flags);
683 item->next = fb_pending;
684 fb_pending = item;
685 spin_unlock_irqrestore(&fb_pending_lock, flags);
686 schedule_work(&picolcd_fb_cleanup);
687 }
688 return 0;
689}
690
691/* Note this can't be const because of struct fb_info definition */
692static struct fb_ops picolcdfb_ops = {
693 .owner = THIS_MODULE,
694 .fb_destroy = picolcd_fb_destroy,
695 .fb_open = picolcd_fb_open,
696 .fb_release = picolcd_fb_release,
697 .fb_read = fb_sys_read,
698 .fb_write = picolcd_fb_write,
699 .fb_blank = picolcd_fb_blank,
700 .fb_fillrect = picolcd_fb_fillrect,
701 .fb_copyarea = picolcd_fb_copyarea,
702 .fb_imageblit = picolcd_fb_imageblit,
703 .fb_check_var = picolcd_fb_check_var,
704 .fb_set_par = picolcd_set_par,
705};
706
707
708/* Callback from deferred IO workqueue */
709static void picolcd_fb_deferred_io(struct fb_info *info, struct list_head *pagelist)
710{
711 picolcd_fb_update(info->par);
712}
713
714static const struct fb_deferred_io picolcd_fb_defio = {
715 .delay = HZ / PICOLCDFB_UPDATE_RATE_DEFAULT,
716 .deferred_io = picolcd_fb_deferred_io,
717};
718
719
720/*
721 * The "fb_update_rate" sysfs attribute
722 */
723static ssize_t picolcd_fb_update_rate_show(struct device *dev,
724 struct device_attribute *attr, char *buf)
725{
726 struct picolcd_data *data = dev_get_drvdata(dev);
727 unsigned i, fb_update_rate = data->fb_update_rate;
728 size_t ret = 0;
729
730 for (i = 1; i <= PICOLCDFB_UPDATE_RATE_LIMIT; i++)
731 if (ret >= PAGE_SIZE)
732 break;
733 else if (i == fb_update_rate)
734 ret += snprintf(buf+ret, PAGE_SIZE-ret, "[%u] ", i);
735 else
736 ret += snprintf(buf+ret, PAGE_SIZE-ret, "%u ", i);
737 if (ret > 0)
738 buf[min(ret, (size_t)PAGE_SIZE)-1] = '\n';
739 return ret;
740}
741
742static ssize_t picolcd_fb_update_rate_store(struct device *dev,
743 struct device_attribute *attr, const char *buf, size_t count)
744{
745 struct picolcd_data *data = dev_get_drvdata(dev);
746 int i;
747 unsigned u;
748
749 if (count < 1 || count > 10)
750 return -EINVAL;
751
752 i = sscanf(buf, "%u", &u);
753 if (i != 1)
754 return -EINVAL;
755
756 if (u > PICOLCDFB_UPDATE_RATE_LIMIT)
757 return -ERANGE;
758 else if (u == 0)
759 u = PICOLCDFB_UPDATE_RATE_DEFAULT;
760
761 data->fb_update_rate = u;
762 data->fb_defio.delay = HZ / data->fb_update_rate;
763 return count;
764}
765
766static DEVICE_ATTR(fb_update_rate, 0666, picolcd_fb_update_rate_show,
767 picolcd_fb_update_rate_store);
768
769/* initialize Framebuffer device */
770static int picolcd_init_framebuffer(struct picolcd_data *data)
771{
772 struct device *dev = &data->hdev->dev;
773 struct fb_info *info = NULL;
774 int i, error = -ENOMEM;
775 u8 *fb_vbitmap = NULL;
776 u8 *fb_bitmap = NULL;
777 u32 *palette;
778
779 fb_bitmap = vmalloc(PICOLCDFB_SIZE*8);
780 if (fb_bitmap == NULL) {
781 dev_err(dev, "can't get a free page for framebuffer\n");
782 goto err_nomem;
783 }
784
785 fb_vbitmap = kmalloc(PICOLCDFB_SIZE, GFP_KERNEL);
786 if (fb_vbitmap == NULL) {
787 dev_err(dev, "can't alloc vbitmap image buffer\n");
788 goto err_nomem;
789 }
790
791 data->fb_update_rate = PICOLCDFB_UPDATE_RATE_DEFAULT;
792 data->fb_defio = picolcd_fb_defio;
793 /* The extra memory is:
794 * - struct picolcd_fb_cleanup_item
795 * - u32 for ref_count
796 * - 256*u32 for pseudo_palette
797 */
798 info = framebuffer_alloc(257 * sizeof(u32) + sizeof(struct picolcd_fb_cleanup_item), dev);
799 if (info == NULL) {
800 dev_err(dev, "failed to allocate a framebuffer\n");
801 goto err_nomem;
802 }
803
804 palette = info->par + sizeof(struct picolcd_fb_cleanup_item);
805 *palette = 1;
806 palette++;
807 for (i = 0; i < 256; i++)
808 palette[i] = i > 0 && i < 16 ? 0xff : 0;
809 info->pseudo_palette = palette;
810 info->fbdefio = &data->fb_defio;
811 info->screen_base = (char __force __iomem *)fb_bitmap;
812 info->fbops = &picolcdfb_ops;
813 info->var = picolcdfb_var;
814 info->fix = picolcdfb_fix;
815 info->fix.smem_len = PICOLCDFB_SIZE*8;
816 info->fix.smem_start = (unsigned long)fb_bitmap;
817 info->par = data;
818 info->flags = FBINFO_FLAG_DEFAULT;
819
820 data->fb_vbitmap = fb_vbitmap;
821 data->fb_bitmap = fb_bitmap;
822 data->fb_bpp = picolcdfb_var.bits_per_pixel;
823 error = picolcd_fb_reset(data, 1);
824 if (error) {
825 dev_err(dev, "failed to configure display\n");
826 goto err_cleanup;
827 }
828 error = device_create_file(dev, &dev_attr_fb_update_rate);
829 if (error) {
830 dev_err(dev, "failed to create sysfs attributes\n");
831 goto err_cleanup;
832 }
833 fb_deferred_io_init(info);
834 data->fb_info = info;
835 error = register_framebuffer(info);
836 if (error) {
837 dev_err(dev, "failed to register framebuffer\n");
838 goto err_sysfs;
839 }
840 /* schedule first output of framebuffer */
841 data->fb_force = 1;
842 schedule_delayed_work(&info->deferred_work, 0);
843 return 0;
844
845err_sysfs:
846 fb_deferred_io_cleanup(info);
847 device_remove_file(dev, &dev_attr_fb_update_rate);
848err_cleanup:
849 data->fb_vbitmap = NULL;
850 data->fb_bitmap = NULL;
851 data->fb_bpp = 0;
852 data->fb_info = NULL;
853
854err_nomem:
855 framebuffer_release(info);
856 vfree(fb_bitmap);
857 kfree(fb_vbitmap);
858 return error;
859}
860
861static void picolcd_exit_framebuffer(struct picolcd_data *data)
862{
863 struct fb_info *info = data->fb_info;
864 u8 *fb_vbitmap = data->fb_vbitmap;
865
866 if (!info)
867 return;
868
869 info->par = NULL;
870 device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate);
871 unregister_framebuffer(info);
872 data->fb_vbitmap = NULL;
873 data->fb_bitmap = NULL;
874 data->fb_bpp = 0;
875 data->fb_info = NULL;
876 kfree(fb_vbitmap);
877}
878
879#define picolcd_fbinfo(d) ((d)->fb_info)
880#else
881static inline int picolcd_fb_reset(struct picolcd_data *data, int clear)
882{
883 return 0;
884}
885static inline int picolcd_init_framebuffer(struct picolcd_data *data)
886{
887 return 0;
888}
889static inline void picolcd_exit_framebuffer(struct picolcd_data *data)
890{
891}
892#define picolcd_fbinfo(d) NULL
893#endif /* CONFIG_HID_PICOLCD_FB */
894
895#ifdef CONFIG_HID_PICOLCD_BACKLIGHT
896/*
897 * backlight class device
898 */
899static int picolcd_get_brightness(struct backlight_device *bdev)
900{
901 struct picolcd_data *data = bl_get_data(bdev);
902 return data->lcd_brightness;
903}
904
905static int picolcd_set_brightness(struct backlight_device *bdev)
906{
907 struct picolcd_data *data = bl_get_data(bdev);
908 struct hid_report *report = picolcd_out_report(REPORT_BRIGHTNESS, data->hdev);
909 unsigned long flags;
910
911 if (!report || report->maxfield != 1 || report->field[0]->report_count != 1)
912 return -ENODEV;
913
914 data->lcd_brightness = bdev->props.brightness & 0x0ff;
915 data->lcd_power = bdev->props.power;
916 spin_lock_irqsave(&data->lock, flags);
917 hid_set_field(report->field[0], 0, data->lcd_power == FB_BLANK_UNBLANK ? data->lcd_brightness : 0);
918 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
919 spin_unlock_irqrestore(&data->lock, flags);
920 return 0;
921}
922
923static int picolcd_check_bl_fb(struct backlight_device *bdev, struct fb_info *fb)
924{
925 return fb && fb == picolcd_fbinfo((struct picolcd_data *)bl_get_data(bdev));
926}
927
928static const struct backlight_ops picolcd_blops = {
929 .update_status = picolcd_set_brightness,
930 .get_brightness = picolcd_get_brightness,
931 .check_fb = picolcd_check_bl_fb,
932};
933
934static int picolcd_init_backlight(struct picolcd_data *data, struct hid_report *report)
935{
936 struct device *dev = &data->hdev->dev;
937 struct backlight_device *bdev;
938 struct backlight_properties props;
939 if (!report)
940 return -ENODEV;
941 if (report->maxfield != 1 || report->field[0]->report_count != 1 ||
942 report->field[0]->report_size != 8) {
943 dev_err(dev, "unsupported BRIGHTNESS report");
944 return -EINVAL;
945 }
946
947 memset(&props, 0, sizeof(props));
948 props.type = BACKLIGHT_RAW;
949 props.max_brightness = 0xff;
950 bdev = backlight_device_register(dev_name(dev), dev, data,
951 &picolcd_blops, &props);
952 if (IS_ERR(bdev)) {
953 dev_err(dev, "failed to register backlight\n");
954 return PTR_ERR(bdev);
955 }
956 bdev->props.brightness = 0xff;
957 data->lcd_brightness = 0xff;
958 data->backlight = bdev;
959 picolcd_set_brightness(bdev);
960 return 0;
961}
962
963static void picolcd_exit_backlight(struct picolcd_data *data)
964{
965 struct backlight_device *bdev = data->backlight;
966
967 data->backlight = NULL;
968 if (bdev)
969 backlight_device_unregister(bdev);
970}
971
972static inline int picolcd_resume_backlight(struct picolcd_data *data)
973{
974 if (!data->backlight)
975 return 0;
976 return picolcd_set_brightness(data->backlight);
977}
978
979#ifdef CONFIG_PM
980static void picolcd_suspend_backlight(struct picolcd_data *data)
981{
982 int bl_power = data->lcd_power;
983 if (!data->backlight)
984 return;
985
986 data->backlight->props.power = FB_BLANK_POWERDOWN;
987 picolcd_set_brightness(data->backlight);
988 data->lcd_power = data->backlight->props.power = bl_power;
989}
990#endif /* CONFIG_PM */
991#else
992static inline int picolcd_init_backlight(struct picolcd_data *data,
993 struct hid_report *report)
994{
995 return 0;
996}
997static inline void picolcd_exit_backlight(struct picolcd_data *data)
998{
999}
1000static inline int picolcd_resume_backlight(struct picolcd_data *data)
1001{
1002 return 0;
1003}
1004static inline void picolcd_suspend_backlight(struct picolcd_data *data)
1005{
1006}
1007#endif /* CONFIG_HID_PICOLCD_BACKLIGHT */
1008
1009#ifdef CONFIG_HID_PICOLCD_LCD
1010/*
1011 * lcd class device
1012 */
1013static int picolcd_get_contrast(struct lcd_device *ldev)
1014{
1015 struct picolcd_data *data = lcd_get_data(ldev);
1016 return data->lcd_contrast;
1017}
1018
1019static int picolcd_set_contrast(struct lcd_device *ldev, int contrast)
1020{
1021 struct picolcd_data *data = lcd_get_data(ldev);
1022 struct hid_report *report = picolcd_out_report(REPORT_CONTRAST, data->hdev);
1023 unsigned long flags;
1024
1025 if (!report || report->maxfield != 1 || report->field[0]->report_count != 1)
1026 return -ENODEV;
1027
1028 data->lcd_contrast = contrast & 0x0ff;
1029 spin_lock_irqsave(&data->lock, flags);
1030 hid_set_field(report->field[0], 0, data->lcd_contrast);
1031 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
1032 spin_unlock_irqrestore(&data->lock, flags);
1033 return 0;
1034}
1035
1036static int picolcd_check_lcd_fb(struct lcd_device *ldev, struct fb_info *fb)
1037{
1038 return fb && fb == picolcd_fbinfo((struct picolcd_data *)lcd_get_data(ldev));
1039}
1040
1041static struct lcd_ops picolcd_lcdops = {
1042 .get_contrast = picolcd_get_contrast,
1043 .set_contrast = picolcd_set_contrast,
1044 .check_fb = picolcd_check_lcd_fb,
1045};
1046
1047static int picolcd_init_lcd(struct picolcd_data *data, struct hid_report *report)
1048{
1049 struct device *dev = &data->hdev->dev;
1050 struct lcd_device *ldev;
1051
1052 if (!report)
1053 return -ENODEV;
1054 if (report->maxfield != 1 || report->field[0]->report_count != 1 ||
1055 report->field[0]->report_size != 8) {
1056 dev_err(dev, "unsupported CONTRAST report");
1057 return -EINVAL;
1058 }
1059
1060 ldev = lcd_device_register(dev_name(dev), dev, data, &picolcd_lcdops);
1061 if (IS_ERR(ldev)) {
1062 dev_err(dev, "failed to register LCD\n");
1063 return PTR_ERR(ldev);
1064 }
1065 ldev->props.max_contrast = 0x0ff;
1066 data->lcd_contrast = 0xe5;
1067 data->lcd = ldev;
1068 picolcd_set_contrast(ldev, 0xe5);
1069 return 0;
1070}
1071
1072static void picolcd_exit_lcd(struct picolcd_data *data)
1073{
1074 struct lcd_device *ldev = data->lcd;
1075
1076 data->lcd = NULL;
1077 if (ldev)
1078 lcd_device_unregister(ldev);
1079}
1080
1081static inline int picolcd_resume_lcd(struct picolcd_data *data)
1082{
1083 if (!data->lcd)
1084 return 0;
1085 return picolcd_set_contrast(data->lcd, data->lcd_contrast);
1086}
1087#else
1088static inline int picolcd_init_lcd(struct picolcd_data *data,
1089 struct hid_report *report)
1090{
1091 return 0;
1092}
1093static inline void picolcd_exit_lcd(struct picolcd_data *data)
1094{
1095}
1096static inline int picolcd_resume_lcd(struct picolcd_data *data)
1097{
1098 return 0;
1099}
1100#endif /* CONFIG_HID_PICOLCD_LCD */
1101
1102#ifdef CONFIG_HID_PICOLCD_LEDS
1103/**
1104 * LED class device
1105 */
1106static void picolcd_leds_set(struct picolcd_data *data)
1107{
1108 struct hid_report *report;
1109 unsigned long flags;
1110
1111 if (!data->led[0])
1112 return;
1113 report = picolcd_out_report(REPORT_LED_STATE, data->hdev);
1114 if (!report || report->maxfield != 1 || report->field[0]->report_count != 1)
1115 return;
1116
1117 spin_lock_irqsave(&data->lock, flags);
1118 hid_set_field(report->field[0], 0, data->led_state);
1119 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
1120 spin_unlock_irqrestore(&data->lock, flags);
1121}
1122
1123static void picolcd_led_set_brightness(struct led_classdev *led_cdev,
1124 enum led_brightness value)
1125{
1126 struct device *dev;
1127 struct hid_device *hdev;
1128 struct picolcd_data *data;
1129 int i, state = 0;
1130
1131 dev = led_cdev->dev->parent;
1132 hdev = container_of(dev, struct hid_device, dev);
1133 data = hid_get_drvdata(hdev);
1134 for (i = 0; i < 8; i++) {
1135 if (led_cdev != data->led[i])
1136 continue;
1137 state = (data->led_state >> i) & 1;
1138 if (value == LED_OFF && state) {
1139 data->led_state &= ~(1 << i);
1140 picolcd_leds_set(data);
1141 } else if (value != LED_OFF && !state) {
1142 data->led_state |= 1 << i;
1143 picolcd_leds_set(data);
1144 }
1145 break;
1146 }
1147}
1148
1149static enum led_brightness picolcd_led_get_brightness(struct led_classdev *led_cdev)
1150{
1151 struct device *dev;
1152 struct hid_device *hdev;
1153 struct picolcd_data *data;
1154 int i, value = 0;
1155
1156 dev = led_cdev->dev->parent;
1157 hdev = container_of(dev, struct hid_device, dev);
1158 data = hid_get_drvdata(hdev);
1159 for (i = 0; i < 8; i++)
1160 if (led_cdev == data->led[i]) {
1161 value = (data->led_state >> i) & 1;
1162 break;
1163 }
1164 return value ? LED_FULL : LED_OFF;
1165}
1166
1167static int picolcd_init_leds(struct picolcd_data *data, struct hid_report *report)
1168{
1169 struct device *dev = &data->hdev->dev;
1170 struct led_classdev *led;
1171 size_t name_sz = strlen(dev_name(dev)) + 8;
1172 char *name;
1173 int i, ret = 0;
1174
1175 if (!report)
1176 return -ENODEV;
1177 if (report->maxfield != 1 || report->field[0]->report_count != 1 ||
1178 report->field[0]->report_size != 8) {
1179 dev_err(dev, "unsupported LED_STATE report");
1180 return -EINVAL;
1181 }
1182
1183 for (i = 0; i < 8; i++) {
1184 led = kzalloc(sizeof(struct led_classdev)+name_sz, GFP_KERNEL);
1185 if (!led) {
1186 dev_err(dev, "can't allocate memory for LED %d\n", i);
1187 ret = -ENOMEM;
1188 goto err;
1189 }
1190 name = (void *)(&led[1]);
1191 snprintf(name, name_sz, "%s::GPO%d", dev_name(dev), i);
1192 led->name = name;
1193 led->brightness = 0;
1194 led->max_brightness = 1;
1195 led->brightness_get = picolcd_led_get_brightness;
1196 led->brightness_set = picolcd_led_set_brightness;
1197
1198 data->led[i] = led;
1199 ret = led_classdev_register(dev, data->led[i]);
1200 if (ret) {
1201 data->led[i] = NULL;
1202 kfree(led);
1203 dev_err(dev, "can't register LED %d\n", i);
1204 goto err;
1205 }
1206 }
1207 return 0;
1208err:
1209 for (i = 0; i < 8; i++)
1210 if (data->led[i]) {
1211 led = data->led[i];
1212 data->led[i] = NULL;
1213 led_classdev_unregister(led);
1214 kfree(led);
1215 }
1216 return ret;
1217}
1218
1219static void picolcd_exit_leds(struct picolcd_data *data)
1220{
1221 struct led_classdev *led;
1222 int i;
1223
1224 for (i = 0; i < 8; i++) {
1225 led = data->led[i];
1226 data->led[i] = NULL;
1227 if (!led)
1228 continue;
1229 led_classdev_unregister(led);
1230 kfree(led);
1231 }
1232}
1233
1234#else
1235static inline int picolcd_init_leds(struct picolcd_data *data,
1236 struct hid_report *report)
1237{
1238 return 0;
1239}
1240static inline void picolcd_exit_leds(struct picolcd_data *data)
1241{
1242}
1243static inline int picolcd_leds_set(struct picolcd_data *data)
1244{
1245 return 0;
1246}
1247#endif /* CONFIG_HID_PICOLCD_LEDS */
1248
1249/*
1250 * input class device
1251 */
1252static int picolcd_raw_keypad(struct picolcd_data *data,
1253 struct hid_report *report, u8 *raw_data, int size)
1254{
1255 /*
1256 * Keypad event
1257 * First and second data bytes list currently pressed keys,
1258 * 0x00 means no key and at most 2 keys may be pressed at same time
1259 */
1260 int i, j;
1261
1262 /* determine newly pressed keys */
1263 for (i = 0; i < size; i++) {
1264 unsigned int key_code;
1265 if (raw_data[i] == 0)
1266 continue;
1267 for (j = 0; j < sizeof(data->pressed_keys); j++)
1268 if (data->pressed_keys[j] == raw_data[i])
1269 goto key_already_down;
1270 for (j = 0; j < sizeof(data->pressed_keys); j++)
1271 if (data->pressed_keys[j] == 0) {
1272 data->pressed_keys[j] = raw_data[i];
1273 break;
1274 }
1275 input_event(data->input_keys, EV_MSC, MSC_SCAN, raw_data[i]);
1276 if (raw_data[i] < PICOLCD_KEYS)
1277 key_code = data->keycode[raw_data[i]];
1278 else
1279 key_code = KEY_UNKNOWN;
1280 if (key_code != KEY_UNKNOWN) {
1281 dbg_hid(PICOLCD_NAME " got key press for %u:%d",
1282 raw_data[i], key_code);
1283 input_report_key(data->input_keys, key_code, 1);
1284 }
1285 input_sync(data->input_keys);
1286key_already_down:
1287 continue;
1288 }
1289
1290 /* determine newly released keys */
1291 for (j = 0; j < sizeof(data->pressed_keys); j++) {
1292 unsigned int key_code;
1293 if (data->pressed_keys[j] == 0)
1294 continue;
1295 for (i = 0; i < size; i++)
1296 if (data->pressed_keys[j] == raw_data[i])
1297 goto key_still_down;
1298 input_event(data->input_keys, EV_MSC, MSC_SCAN, data->pressed_keys[j]);
1299 if (data->pressed_keys[j] < PICOLCD_KEYS)
1300 key_code = data->keycode[data->pressed_keys[j]];
1301 else
1302 key_code = KEY_UNKNOWN;
1303 if (key_code != KEY_UNKNOWN) {
1304 dbg_hid(PICOLCD_NAME " got key release for %u:%d",
1305 data->pressed_keys[j], key_code);
1306 input_report_key(data->input_keys, key_code, 0);
1307 }
1308 input_sync(data->input_keys);
1309 data->pressed_keys[j] = 0;
1310key_still_down:
1311 continue;
1312 }
1313 return 1;
1314}
1315
1316static int picolcd_raw_cir(struct picolcd_data *data,
1317 struct hid_report *report, u8 *raw_data, int size)
1318{
1319 /* Need understanding of CIR data format to implement ... */
1320 return 1;
1321}
1322
1323static int picolcd_check_version(struct hid_device *hdev)
1324{
1325 struct picolcd_data *data = hid_get_drvdata(hdev);
1326 struct picolcd_pending *verinfo;
1327 int ret = 0;
1328
1329 if (!data)
1330 return -ENODEV;
1331
1332 verinfo = picolcd_send_and_wait(hdev, REPORT_VERSION, NULL, 0);
1333 if (!verinfo) {
1334 hid_err(hdev, "no version response from PicoLCD\n");
1335 return -ENODEV;
1336 }
1337
1338 if (verinfo->raw_size == 2) {
1339 data->version[0] = verinfo->raw_data[1];
1340 data->version[1] = verinfo->raw_data[0];
1341 if (data->status & PICOLCD_BOOTLOADER) {
1342 hid_info(hdev, "PicoLCD, bootloader version %d.%d\n",
1343 verinfo->raw_data[1], verinfo->raw_data[0]);
1344 } else {
1345 hid_info(hdev, "PicoLCD, firmware version %d.%d\n",
1346 verinfo->raw_data[1], verinfo->raw_data[0]);
1347 }
1348 } else {
1349 hid_err(hdev, "confused, got unexpected version response from PicoLCD\n");
1350 ret = -EINVAL;
1351 }
1352 kfree(verinfo);
1353 return ret;
1354}
1355
1356/*
1357 * Reset our device and wait for answer to VERSION request
1358 */
1359static int picolcd_reset(struct hid_device *hdev)
1360{
1361 struct picolcd_data *data = hid_get_drvdata(hdev);
1362 struct hid_report *report = picolcd_out_report(REPORT_RESET, hdev);
1363 unsigned long flags;
1364 int error;
1365
1366 if (!data || !report || report->maxfield != 1)
1367 return -ENODEV;
1368
1369 spin_lock_irqsave(&data->lock, flags);
1370 if (hdev->product == USB_DEVICE_ID_PICOLCD_BOOTLOADER)
1371 data->status |= PICOLCD_BOOTLOADER;
1372
1373 /* perform the reset */
1374 hid_set_field(report->field[0], 0, 1);
1375 usbhid_submit_report(hdev, report, USB_DIR_OUT);
1376 spin_unlock_irqrestore(&data->lock, flags);
1377
1378 error = picolcd_check_version(hdev);
1379 if (error)
1380 return error;
1381
1382 picolcd_resume_lcd(data);
1383 picolcd_resume_backlight(data);
1384#ifdef CONFIG_HID_PICOLCD_FB
1385 if (data->fb_info)
1386 schedule_delayed_work(&data->fb_info->deferred_work, 0);
1387#endif /* CONFIG_HID_PICOLCD_FB */
1388
1389 picolcd_leds_set(data);
1390 return 0;
1391}
1392
1393/*
1394 * The "operation_mode" sysfs attribute
1395 */
1396static ssize_t picolcd_operation_mode_show(struct device *dev,
1397 struct device_attribute *attr, char *buf)
1398{
1399 struct picolcd_data *data = dev_get_drvdata(dev);
1400
1401 if (data->status & PICOLCD_BOOTLOADER)
1402 return snprintf(buf, PAGE_SIZE, "[bootloader] lcd\n");
1403 else
1404 return snprintf(buf, PAGE_SIZE, "bootloader [lcd]\n");
1405}
1406
1407static ssize_t picolcd_operation_mode_store(struct device *dev,
1408 struct device_attribute *attr, const char *buf, size_t count)
1409{
1410 struct picolcd_data *data = dev_get_drvdata(dev);
1411 struct hid_report *report = NULL;
1412 size_t cnt = count;
1413 int timeout = data->opmode_delay;
1414 unsigned long flags;
1415
1416 if (cnt >= 3 && strncmp("lcd", buf, 3) == 0) {
1417 if (data->status & PICOLCD_BOOTLOADER)
1418 report = picolcd_out_report(REPORT_EXIT_FLASHER, data->hdev);
1419 buf += 3;
1420 cnt -= 3;
1421 } else if (cnt >= 10 && strncmp("bootloader", buf, 10) == 0) {
1422 if (!(data->status & PICOLCD_BOOTLOADER))
1423 report = picolcd_out_report(REPORT_EXIT_KEYBOARD, data->hdev);
1424 buf += 10;
1425 cnt -= 10;
1426 }
1427 if (!report)
1428 return -EINVAL;
1429
1430 while (cnt > 0 && (buf[cnt-1] == '\n' || buf[cnt-1] == '\r'))
1431 cnt--;
1432 if (cnt != 0)
1433 return -EINVAL;
1434
1435 spin_lock_irqsave(&data->lock, flags);
1436 hid_set_field(report->field[0], 0, timeout & 0xff);
1437 hid_set_field(report->field[0], 1, (timeout >> 8) & 0xff);
1438 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
1439 spin_unlock_irqrestore(&data->lock, flags);
1440 return count;
1441}
1442
1443static DEVICE_ATTR(operation_mode, 0644, picolcd_operation_mode_show,
1444 picolcd_operation_mode_store);
1445
1446/*
1447 * The "operation_mode_delay" sysfs attribute
1448 */
1449static ssize_t picolcd_operation_mode_delay_show(struct device *dev,
1450 struct device_attribute *attr, char *buf)
1451{
1452 struct picolcd_data *data = dev_get_drvdata(dev);
1453
1454 return snprintf(buf, PAGE_SIZE, "%hu\n", data->opmode_delay);
1455}
1456
1457static ssize_t picolcd_operation_mode_delay_store(struct device *dev,
1458 struct device_attribute *attr, const char *buf, size_t count)
1459{
1460 struct picolcd_data *data = dev_get_drvdata(dev);
1461 unsigned u;
1462 if (sscanf(buf, "%u", &u) != 1)
1463 return -EINVAL;
1464 if (u > 30000)
1465 return -EINVAL;
1466 else
1467 data->opmode_delay = u;
1468 return count;
1469}
1470
1471static DEVICE_ATTR(operation_mode_delay, 0644, picolcd_operation_mode_delay_show,
1472 picolcd_operation_mode_delay_store);
1473
1474
1475#ifdef CONFIG_DEBUG_FS
1476/*
1477 * The "reset" file
1478 */
1479static int picolcd_debug_reset_show(struct seq_file *f, void *p)
1480{
1481 if (picolcd_fbinfo((struct picolcd_data *)f->private))
1482 seq_printf(f, "all fb\n");
1483 else
1484 seq_printf(f, "all\n");
1485 return 0;
1486}
1487
1488static int picolcd_debug_reset_open(struct inode *inode, struct file *f)
1489{
1490 return single_open(f, picolcd_debug_reset_show, inode->i_private);
1491}
1492
1493static ssize_t picolcd_debug_reset_write(struct file *f, const char __user *user_buf,
1494 size_t count, loff_t *ppos)
1495{
1496 struct picolcd_data *data = ((struct seq_file *)f->private_data)->private;
1497 char buf[32];
1498 size_t cnt = min(count, sizeof(buf)-1);
1499 if (copy_from_user(buf, user_buf, cnt))
1500 return -EFAULT;
1501
1502 while (cnt > 0 && (buf[cnt-1] == ' ' || buf[cnt-1] == '\n'))
1503 cnt--;
1504 buf[cnt] = '\0';
1505 if (strcmp(buf, "all") == 0) {
1506 picolcd_reset(data->hdev);
1507 picolcd_fb_reset(data, 1);
1508 } else if (strcmp(buf, "fb") == 0) {
1509 picolcd_fb_reset(data, 1);
1510 } else {
1511 return -EINVAL;
1512 }
1513 return count;
1514}
1515
1516static const struct file_operations picolcd_debug_reset_fops = {
1517 .owner = THIS_MODULE,
1518 .open = picolcd_debug_reset_open,
1519 .read = seq_read,
1520 .llseek = seq_lseek,
1521 .write = picolcd_debug_reset_write,
1522 .release = single_release,
1523};
1524
1525/*
1526 * The "eeprom" file
1527 */
1528static ssize_t picolcd_debug_eeprom_read(struct file *f, char __user *u,
1529 size_t s, loff_t *off)
1530{
1531 struct picolcd_data *data = f->private_data;
1532 struct picolcd_pending *resp;
1533 u8 raw_data[3];
1534 ssize_t ret = -EIO;
1535
1536 if (s == 0)
1537 return -EINVAL;
1538 if (*off > 0x0ff)
1539 return 0;
1540
1541 /* prepare buffer with info about what we want to read (addr & len) */
1542 raw_data[0] = *off & 0xff;
1543 raw_data[1] = (*off >> 8) & 0xff;
1544 raw_data[2] = s < 20 ? s : 20;
1545 if (*off + raw_data[2] > 0xff)
1546 raw_data[2] = 0x100 - *off;
1547 resp = picolcd_send_and_wait(data->hdev, REPORT_EE_READ, raw_data,
1548 sizeof(raw_data));
1549 if (!resp)
1550 return -EIO;
1551
1552 if (resp->in_report && resp->in_report->id == REPORT_EE_DATA) {
1553 /* successful read :) */
1554 ret = resp->raw_data[2];
1555 if (ret > s)
1556 ret = s;
1557 if (copy_to_user(u, resp->raw_data+3, ret))
1558 ret = -EFAULT;
1559 else
1560 *off += ret;
1561 } /* anything else is some kind of IO error */
1562
1563 kfree(resp);
1564 return ret;
1565}
1566
1567static ssize_t picolcd_debug_eeprom_write(struct file *f, const char __user *u,
1568 size_t s, loff_t *off)
1569{
1570 struct picolcd_data *data = f->private_data;
1571 struct picolcd_pending *resp;
1572 ssize_t ret = -EIO;
1573 u8 raw_data[23];
1574
1575 if (s == 0)
1576 return -EINVAL;
1577 if (*off > 0x0ff)
1578 return -ENOSPC;
1579
1580 memset(raw_data, 0, sizeof(raw_data));
1581 raw_data[0] = *off & 0xff;
1582 raw_data[1] = (*off >> 8) & 0xff;
1583 raw_data[2] = min((size_t)20, s);
1584 if (*off + raw_data[2] > 0xff)
1585 raw_data[2] = 0x100 - *off;
1586
1587 if (copy_from_user(raw_data+3, u, min((u8)20, raw_data[2])))
1588 return -EFAULT;
1589 resp = picolcd_send_and_wait(data->hdev, REPORT_EE_WRITE, raw_data,
1590 sizeof(raw_data));
1591
1592 if (!resp)
1593 return -EIO;
1594
1595 if (resp->in_report && resp->in_report->id == REPORT_EE_DATA) {
1596 /* check if written data matches */
1597 if (memcmp(raw_data, resp->raw_data, 3+raw_data[2]) == 0) {
1598 *off += raw_data[2];
1599 ret = raw_data[2];
1600 }
1601 }
1602 kfree(resp);
1603 return ret;
1604}
1605
1606/*
1607 * Notes:
1608 * - read/write happens in chunks of at most 20 bytes, it's up to userspace
1609 * to loop in order to get more data.
1610 * - on write errors on otherwise correct write request the bytes
1611 * that should have been written are in undefined state.
1612 */
1613static const struct file_operations picolcd_debug_eeprom_fops = {
1614 .owner = THIS_MODULE,
1615 .open = simple_open,
1616 .read = picolcd_debug_eeprom_read,
1617 .write = picolcd_debug_eeprom_write,
1618 .llseek = generic_file_llseek,
1619};
1620
1621/*
1622 * The "flash" file
1623 */
1624/* record a flash address to buf (bounds check to be done by caller) */
1625static int _picolcd_flash_setaddr(struct picolcd_data *data, u8 *buf, long off)
1626{
1627 buf[0] = off & 0xff;
1628 buf[1] = (off >> 8) & 0xff;
1629 if (data->addr_sz == 3)
1630 buf[2] = (off >> 16) & 0xff;
1631 return data->addr_sz == 2 ? 2 : 3;
1632}
1633
1634/* read a given size of data (bounds check to be done by caller) */
1635static ssize_t _picolcd_flash_read(struct picolcd_data *data, int report_id,
1636 char __user *u, size_t s, loff_t *off)
1637{
1638 struct picolcd_pending *resp;
1639 u8 raw_data[4];
1640 ssize_t ret = 0;
1641 int len_off, err = -EIO;
1642
1643 while (s > 0) {
1644 err = -EIO;
1645 len_off = _picolcd_flash_setaddr(data, raw_data, *off);
1646 raw_data[len_off] = s > 32 ? 32 : s;
1647 resp = picolcd_send_and_wait(data->hdev, report_id, raw_data, len_off+1);
1648 if (!resp || !resp->in_report)
1649 goto skip;
1650 if (resp->in_report->id == REPORT_MEMORY ||
1651 resp->in_report->id == REPORT_BL_READ_MEMORY) {
1652 if (memcmp(raw_data, resp->raw_data, len_off+1) != 0)
1653 goto skip;
1654 if (copy_to_user(u+ret, resp->raw_data+len_off+1, raw_data[len_off])) {
1655 err = -EFAULT;
1656 goto skip;
1657 }
1658 *off += raw_data[len_off];
1659 s -= raw_data[len_off];
1660 ret += raw_data[len_off];
1661 err = 0;
1662 }
1663skip:
1664 kfree(resp);
1665 if (err)
1666 return ret > 0 ? ret : err;
1667 }
1668 return ret;
1669}
1670
1671static ssize_t picolcd_debug_flash_read(struct file *f, char __user *u,
1672 size_t s, loff_t *off)
1673{
1674 struct picolcd_data *data = f->private_data;
1675
1676 if (s == 0)
1677 return -EINVAL;
1678 if (*off > 0x05fff)
1679 return 0;
1680 if (*off + s > 0x05fff)
1681 s = 0x06000 - *off;
1682
1683 if (data->status & PICOLCD_BOOTLOADER)
1684 return _picolcd_flash_read(data, REPORT_BL_READ_MEMORY, u, s, off);
1685 else
1686 return _picolcd_flash_read(data, REPORT_READ_MEMORY, u, s, off);
1687}
1688
1689/* erase block aligned to 64bytes boundary */
1690static ssize_t _picolcd_flash_erase64(struct picolcd_data *data, int report_id,
1691 loff_t *off)
1692{
1693 struct picolcd_pending *resp;
1694 u8 raw_data[3];
1695 int len_off;
1696 ssize_t ret = -EIO;
1697
1698 if (*off & 0x3f)
1699 return -EINVAL;
1700
1701 len_off = _picolcd_flash_setaddr(data, raw_data, *off);
1702 resp = picolcd_send_and_wait(data->hdev, report_id, raw_data, len_off);
1703 if (!resp || !resp->in_report)
1704 goto skip;
1705 if (resp->in_report->id == REPORT_MEMORY ||
1706 resp->in_report->id == REPORT_BL_ERASE_MEMORY) {
1707 if (memcmp(raw_data, resp->raw_data, len_off) != 0)
1708 goto skip;
1709 ret = 0;
1710 }
1711skip:
1712 kfree(resp);
1713 return ret;
1714}
1715
1716/* write a given size of data (bounds check to be done by caller) */
1717static ssize_t _picolcd_flash_write(struct picolcd_data *data, int report_id,
1718 const char __user *u, size_t s, loff_t *off)
1719{
1720 struct picolcd_pending *resp;
1721 u8 raw_data[36];
1722 ssize_t ret = 0;
1723 int len_off, err = -EIO;
1724
1725 while (s > 0) {
1726 err = -EIO;
1727 len_off = _picolcd_flash_setaddr(data, raw_data, *off);
1728 raw_data[len_off] = s > 32 ? 32 : s;
1729 if (copy_from_user(raw_data+len_off+1, u, raw_data[len_off])) {
1730 err = -EFAULT;
1731 break;
1732 }
1733 resp = picolcd_send_and_wait(data->hdev, report_id, raw_data,
1734 len_off+1+raw_data[len_off]);
1735 if (!resp || !resp->in_report)
1736 goto skip;
1737 if (resp->in_report->id == REPORT_MEMORY ||
1738 resp->in_report->id == REPORT_BL_WRITE_MEMORY) {
1739 if (memcmp(raw_data, resp->raw_data, len_off+1+raw_data[len_off]) != 0)
1740 goto skip;
1741 *off += raw_data[len_off];
1742 s -= raw_data[len_off];
1743 ret += raw_data[len_off];
1744 err = 0;
1745 }
1746skip:
1747 kfree(resp);
1748 if (err)
1749 break;
1750 }
1751 return ret > 0 ? ret : err;
1752}
1753
1754static ssize_t picolcd_debug_flash_write(struct file *f, const char __user *u,
1755 size_t s, loff_t *off)
1756{
1757 struct picolcd_data *data = f->private_data;
1758 ssize_t err, ret = 0;
1759 int report_erase, report_write;
1760
1761 if (s == 0)
1762 return -EINVAL;
1763 if (*off > 0x5fff)
1764 return -ENOSPC;
1765 if (s & 0x3f)
1766 return -EINVAL;
1767 if (*off & 0x3f)
1768 return -EINVAL;
1769
1770 if (data->status & PICOLCD_BOOTLOADER) {
1771 report_erase = REPORT_BL_ERASE_MEMORY;
1772 report_write = REPORT_BL_WRITE_MEMORY;
1773 } else {
1774 report_erase = REPORT_ERASE_MEMORY;
1775 report_write = REPORT_WRITE_MEMORY;
1776 }
1777 mutex_lock(&data->mutex_flash);
1778 while (s > 0) {
1779 err = _picolcd_flash_erase64(data, report_erase, off);
1780 if (err)
1781 break;
1782 err = _picolcd_flash_write(data, report_write, u, 64, off);
1783 if (err < 0)
1784 break;
1785 ret += err;
1786 *off += err;
1787 s -= err;
1788 if (err != 64)
1789 break;
1790 }
1791 mutex_unlock(&data->mutex_flash);
1792 return ret > 0 ? ret : err;
1793}
1794
1795/*
1796 * Notes:
1797 * - concurrent writing is prevented by mutex and all writes must be
1798 * n*64 bytes and 64-byte aligned, each write being preceded by an
1799 * ERASE which erases a 64byte block.
1800 * If less than requested was written or an error is returned for an
1801 * otherwise correct write request the next 64-byte block which should
1802 * have been written is in undefined state (mostly: original, erased,
1803 * (half-)written with write error)
1804 * - reading can happen without special restriction
1805 */
1806static const struct file_operations picolcd_debug_flash_fops = {
1807 .owner = THIS_MODULE,
1808 .open = simple_open,
1809 .read = picolcd_debug_flash_read,
1810 .write = picolcd_debug_flash_write,
1811 .llseek = generic_file_llseek,
1812};
1813
1814
1815/*
1816 * Helper code for HID report level dumping/debugging
1817 */
1818static const char *error_codes[] = {
1819 "success", "parameter missing", "data_missing", "block readonly",
1820 "block not erasable", "block too big", "section overflow",
1821 "invalid command length", "invalid data length",
1822};
1823
1824static void dump_buff_as_hex(char *dst, size_t dst_sz, const u8 *data,
1825 const size_t data_len)
1826{
1827 int i, j;
1828 for (i = j = 0; i < data_len && j + 3 < dst_sz; i++) {
1829 dst[j++] = hex_asc[(data[i] >> 4) & 0x0f];
1830 dst[j++] = hex_asc[data[i] & 0x0f];
1831 dst[j++] = ' ';
1832 }
1833 if (j < dst_sz) {
1834 dst[j--] = '\0';
1835 dst[j] = '\n';
1836 } else
1837 dst[j] = '\0';
1838}
1839
1840static void picolcd_debug_out_report(struct picolcd_data *data,
1841 struct hid_device *hdev, struct hid_report *report)
1842{
1843 u8 raw_data[70];
1844 int raw_size = (report->size >> 3) + 1;
1845 char *buff;
1846#define BUFF_SZ 256
1847
1848 /* Avoid unnecessary overhead if debugfs is disabled */
1849 if (list_empty(&hdev->debug_list))
1850 return;
1851
1852 buff = kmalloc(BUFF_SZ, GFP_ATOMIC);
1853 if (!buff)
1854 return;
1855
1856 snprintf(buff, BUFF_SZ, "\nout report %d (size %d) = ",
1857 report->id, raw_size);
1858 hid_debug_event(hdev, buff);
1859 if (raw_size + 5 > sizeof(raw_data)) {
1860 kfree(buff);
1861 hid_debug_event(hdev, " TOO BIG\n");
1862 return;
1863 } else {
1864 raw_data[0] = report->id;
1865 hid_output_report(report, raw_data);
1866 dump_buff_as_hex(buff, BUFF_SZ, raw_data, raw_size);
1867 hid_debug_event(hdev, buff);
1868 }
1869
1870 switch (report->id) {
1871 case REPORT_LED_STATE:
1872 /* 1 data byte with GPO state */
1873 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1874 "REPORT_LED_STATE", report->id, raw_size-1);
1875 hid_debug_event(hdev, buff);
1876 snprintf(buff, BUFF_SZ, "\tGPO state: 0x%02x\n", raw_data[1]);
1877 hid_debug_event(hdev, buff);
1878 break;
1879 case REPORT_BRIGHTNESS:
1880 /* 1 data byte with brightness */
1881 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1882 "REPORT_BRIGHTNESS", report->id, raw_size-1);
1883 hid_debug_event(hdev, buff);
1884 snprintf(buff, BUFF_SZ, "\tBrightness: 0x%02x\n", raw_data[1]);
1885 hid_debug_event(hdev, buff);
1886 break;
1887 case REPORT_CONTRAST:
1888 /* 1 data byte with contrast */
1889 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1890 "REPORT_CONTRAST", report->id, raw_size-1);
1891 hid_debug_event(hdev, buff);
1892 snprintf(buff, BUFF_SZ, "\tContrast: 0x%02x\n", raw_data[1]);
1893 hid_debug_event(hdev, buff);
1894 break;
1895 case REPORT_RESET:
1896 /* 2 data bytes with reset duration in ms */
1897 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1898 "REPORT_RESET", report->id, raw_size-1);
1899 hid_debug_event(hdev, buff);
1900 snprintf(buff, BUFF_SZ, "\tDuration: 0x%02x%02x (%dms)\n",
1901 raw_data[2], raw_data[1], raw_data[2] << 8 | raw_data[1]);
1902 hid_debug_event(hdev, buff);
1903 break;
1904 case REPORT_LCD_CMD:
1905 /* 63 data bytes with LCD commands */
1906 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1907 "REPORT_LCD_CMD", report->id, raw_size-1);
1908 hid_debug_event(hdev, buff);
1909 /* TODO: format decoding */
1910 break;
1911 case REPORT_LCD_DATA:
1912 /* 63 data bytes with LCD data */
1913 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1914 "REPORT_LCD_CMD", report->id, raw_size-1);
1915 /* TODO: format decoding */
1916 hid_debug_event(hdev, buff);
1917 break;
1918 case REPORT_LCD_CMD_DATA:
1919 /* 63 data bytes with LCD commands and data */
1920 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1921 "REPORT_LCD_CMD", report->id, raw_size-1);
1922 /* TODO: format decoding */
1923 hid_debug_event(hdev, buff);
1924 break;
1925 case REPORT_EE_READ:
1926 /* 3 data bytes with read area description */
1927 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1928 "REPORT_EE_READ", report->id, raw_size-1);
1929 hid_debug_event(hdev, buff);
1930 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
1931 raw_data[2], raw_data[1]);
1932 hid_debug_event(hdev, buff);
1933 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
1934 hid_debug_event(hdev, buff);
1935 break;
1936 case REPORT_EE_WRITE:
1937 /* 3+1..20 data bytes with write area description */
1938 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1939 "REPORT_EE_WRITE", report->id, raw_size-1);
1940 hid_debug_event(hdev, buff);
1941 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
1942 raw_data[2], raw_data[1]);
1943 hid_debug_event(hdev, buff);
1944 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
1945 hid_debug_event(hdev, buff);
1946 if (raw_data[3] == 0) {
1947 snprintf(buff, BUFF_SZ, "\tNo data\n");
1948 } else if (raw_data[3] + 4 <= raw_size) {
1949 snprintf(buff, BUFF_SZ, "\tData: ");
1950 hid_debug_event(hdev, buff);
1951 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
1952 } else {
1953 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
1954 }
1955 hid_debug_event(hdev, buff);
1956 break;
1957 case REPORT_ERASE_MEMORY:
1958 case REPORT_BL_ERASE_MEMORY:
1959 /* 3 data bytes with pointer inside erase block */
1960 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1961 "REPORT_ERASE_MEMORY", report->id, raw_size-1);
1962 hid_debug_event(hdev, buff);
1963 switch (data->addr_sz) {
1964 case 2:
1965 snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x\n",
1966 raw_data[2], raw_data[1]);
1967 break;
1968 case 3:
1969 snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x%02x\n",
1970 raw_data[3], raw_data[2], raw_data[1]);
1971 break;
1972 default:
1973 snprintf(buff, BUFF_SZ, "\tNot supported\n");
1974 }
1975 hid_debug_event(hdev, buff);
1976 break;
1977 case REPORT_READ_MEMORY:
1978 case REPORT_BL_READ_MEMORY:
1979 /* 4 data bytes with read area description */
1980 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1981 "REPORT_READ_MEMORY", report->id, raw_size-1);
1982 hid_debug_event(hdev, buff);
1983 switch (data->addr_sz) {
1984 case 2:
1985 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
1986 raw_data[2], raw_data[1]);
1987 hid_debug_event(hdev, buff);
1988 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
1989 break;
1990 case 3:
1991 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
1992 raw_data[3], raw_data[2], raw_data[1]);
1993 hid_debug_event(hdev, buff);
1994 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
1995 break;
1996 default:
1997 snprintf(buff, BUFF_SZ, "\tNot supported\n");
1998 }
1999 hid_debug_event(hdev, buff);
2000 break;
2001 case REPORT_WRITE_MEMORY:
2002 case REPORT_BL_WRITE_MEMORY:
2003 /* 4+1..32 data bytes with write adrea description */
2004 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
2005 "REPORT_WRITE_MEMORY", report->id, raw_size-1);
2006 hid_debug_event(hdev, buff);
2007 switch (data->addr_sz) {
2008 case 2:
2009 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
2010 raw_data[2], raw_data[1]);
2011 hid_debug_event(hdev, buff);
2012 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
2013 hid_debug_event(hdev, buff);
2014 if (raw_data[3] == 0) {
2015 snprintf(buff, BUFF_SZ, "\tNo data\n");
2016 } else if (raw_data[3] + 4 <= raw_size) {
2017 snprintf(buff, BUFF_SZ, "\tData: ");
2018 hid_debug_event(hdev, buff);
2019 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
2020 } else {
2021 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
2022 }
2023 break;
2024 case 3:
2025 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
2026 raw_data[3], raw_data[2], raw_data[1]);
2027 hid_debug_event(hdev, buff);
2028 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
2029 hid_debug_event(hdev, buff);
2030 if (raw_data[4] == 0) {
2031 snprintf(buff, BUFF_SZ, "\tNo data\n");
2032 } else if (raw_data[4] + 5 <= raw_size) {
2033 snprintf(buff, BUFF_SZ, "\tData: ");
2034 hid_debug_event(hdev, buff);
2035 dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]);
2036 } else {
2037 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
2038 }
2039 break;
2040 default:
2041 snprintf(buff, BUFF_SZ, "\tNot supported\n");
2042 }
2043 hid_debug_event(hdev, buff);
2044 break;
2045 case REPORT_SPLASH_RESTART:
2046 /* TODO */
2047 break;
2048 case REPORT_EXIT_KEYBOARD:
2049 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
2050 "REPORT_EXIT_KEYBOARD", report->id, raw_size-1);
2051 hid_debug_event(hdev, buff);
2052 snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n",
2053 raw_data[1] | (raw_data[2] << 8),
2054 raw_data[2], raw_data[1]);
2055 hid_debug_event(hdev, buff);
2056 break;
2057 case REPORT_VERSION:
2058 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
2059 "REPORT_VERSION", report->id, raw_size-1);
2060 hid_debug_event(hdev, buff);
2061 break;
2062 case REPORT_DEVID:
2063 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
2064 "REPORT_DEVID", report->id, raw_size-1);
2065 hid_debug_event(hdev, buff);
2066 break;
2067 case REPORT_SPLASH_SIZE:
2068 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
2069 "REPORT_SPLASH_SIZE", report->id, raw_size-1);
2070 hid_debug_event(hdev, buff);
2071 break;
2072 case REPORT_HOOK_VERSION:
2073 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
2074 "REPORT_HOOK_VERSION", report->id, raw_size-1);
2075 hid_debug_event(hdev, buff);
2076 break;
2077 case REPORT_EXIT_FLASHER:
2078 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
2079 "REPORT_VERSION", report->id, raw_size-1);
2080 hid_debug_event(hdev, buff);
2081 snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n",
2082 raw_data[1] | (raw_data[2] << 8),
2083 raw_data[2], raw_data[1]);
2084 hid_debug_event(hdev, buff);
2085 break;
2086 default:
2087 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
2088 "<unknown>", report->id, raw_size-1);
2089 hid_debug_event(hdev, buff);
2090 break;
2091 }
2092 wake_up_interruptible(&hdev->debug_wait);
2093 kfree(buff);
2094}
2095
2096static void picolcd_debug_raw_event(struct picolcd_data *data,
2097 struct hid_device *hdev, struct hid_report *report,
2098 u8 *raw_data, int size)
2099{
2100 char *buff;
2101
2102#define BUFF_SZ 256
2103 /* Avoid unnecessary overhead if debugfs is disabled */
2104 if (!hdev->debug_events)
2105 return;
2106
2107 buff = kmalloc(BUFF_SZ, GFP_ATOMIC);
2108 if (!buff)
2109 return;
2110
2111 switch (report->id) {
2112 case REPORT_ERROR_CODE:
2113 /* 2 data bytes with affected report and error code */
2114 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
2115 "REPORT_ERROR_CODE", report->id, size-1);
2116 hid_debug_event(hdev, buff);
2117 if (raw_data[2] < ARRAY_SIZE(error_codes))
2118 snprintf(buff, BUFF_SZ, "\tError code 0x%02x (%s) in reply to report 0x%02x\n",
2119 raw_data[2], error_codes[raw_data[2]], raw_data[1]);
2120 else
2121 snprintf(buff, BUFF_SZ, "\tError code 0x%02x in reply to report 0x%02x\n",
2122 raw_data[2], raw_data[1]);
2123 hid_debug_event(hdev, buff);
2124 break;
2125 case REPORT_KEY_STATE:
2126 /* 2 data bytes with key state */
2127 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
2128 "REPORT_KEY_STATE", report->id, size-1);
2129 hid_debug_event(hdev, buff);
2130 if (raw_data[1] == 0)
2131 snprintf(buff, BUFF_SZ, "\tNo key pressed\n");
2132 else if (raw_data[2] == 0)
2133 snprintf(buff, BUFF_SZ, "\tOne key pressed: 0x%02x (%d)\n",
2134 raw_data[1], raw_data[1]);
2135 else
2136 snprintf(buff, BUFF_SZ, "\tTwo keys pressed: 0x%02x (%d), 0x%02x (%d)\n",
2137 raw_data[1], raw_data[1], raw_data[2], raw_data[2]);
2138 hid_debug_event(hdev, buff);
2139 break;
2140 case REPORT_IR_DATA:
2141 /* Up to 20 byes of IR scancode data */
2142 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
2143 "REPORT_IR_DATA", report->id, size-1);
2144 hid_debug_event(hdev, buff);
2145 if (raw_data[1] == 0) {
2146 snprintf(buff, BUFF_SZ, "\tUnexpectedly 0 data length\n");
2147 hid_debug_event(hdev, buff);
2148 } else if (raw_data[1] + 1 <= size) {
2149 snprintf(buff, BUFF_SZ, "\tData length: %d\n\tIR Data: ",
2150 raw_data[1]-1);
2151 hid_debug_event(hdev, buff);
2152 dump_buff_as_hex(buff, BUFF_SZ, raw_data+2, raw_data[1]-1);
2153 hid_debug_event(hdev, buff);
2154 } else {
2155 snprintf(buff, BUFF_SZ, "\tOverflowing data length: %d\n",
2156 raw_data[1]-1);
2157 hid_debug_event(hdev, buff);
2158 }
2159 break;
2160 case REPORT_EE_DATA:
2161 /* Data buffer in response to REPORT_EE_READ or REPORT_EE_WRITE */
2162 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
2163 "REPORT_EE_DATA", report->id, size-1);
2164 hid_debug_event(hdev, buff);
2165 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
2166 raw_data[2], raw_data[1]);
2167 hid_debug_event(hdev, buff);
2168 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
2169 hid_debug_event(hdev, buff);
2170 if (raw_data[3] == 0) {
2171 snprintf(buff, BUFF_SZ, "\tNo data\n");
2172 hid_debug_event(hdev, buff);
2173 } else if (raw_data[3] + 4 <= size) {
2174 snprintf(buff, BUFF_SZ, "\tData: ");
2175 hid_debug_event(hdev, buff);
2176 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
2177 hid_debug_event(hdev, buff);
2178 } else {
2179 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
2180 hid_debug_event(hdev, buff);
2181 }
2182 break;
2183 case REPORT_MEMORY:
2184 /* Data buffer in response to REPORT_READ_MEMORY or REPORT_WRTIE_MEMORY */
2185 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
2186 "REPORT_MEMORY", report->id, size-1);
2187 hid_debug_event(hdev, buff);
2188 switch (data->addr_sz) {
2189 case 2:
2190 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
2191 raw_data[2], raw_data[1]);
2192 hid_debug_event(hdev, buff);
2193 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
2194 hid_debug_event(hdev, buff);
2195 if (raw_data[3] == 0) {
2196 snprintf(buff, BUFF_SZ, "\tNo data\n");
2197 } else if (raw_data[3] + 4 <= size) {
2198 snprintf(buff, BUFF_SZ, "\tData: ");
2199 hid_debug_event(hdev, buff);
2200 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
2201 } else {
2202 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
2203 }
2204 break;
2205 case 3:
2206 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
2207 raw_data[3], raw_data[2], raw_data[1]);
2208 hid_debug_event(hdev, buff);
2209 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
2210 hid_debug_event(hdev, buff);
2211 if (raw_data[4] == 0) {
2212 snprintf(buff, BUFF_SZ, "\tNo data\n");
2213 } else if (raw_data[4] + 5 <= size) {
2214 snprintf(buff, BUFF_SZ, "\tData: ");
2215 hid_debug_event(hdev, buff);
2216 dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]);
2217 } else {
2218 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
2219 }
2220 break;
2221 default:
2222 snprintf(buff, BUFF_SZ, "\tNot supported\n");
2223 }
2224 hid_debug_event(hdev, buff);
2225 break;
2226 case REPORT_VERSION:
2227 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
2228 "REPORT_VERSION", report->id, size-1);
2229 hid_debug_event(hdev, buff);
2230 snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n",
2231 raw_data[2], raw_data[1]);
2232 hid_debug_event(hdev, buff);
2233 break;
2234 case REPORT_BL_ERASE_MEMORY:
2235 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
2236 "REPORT_BL_ERASE_MEMORY", report->id, size-1);
2237 hid_debug_event(hdev, buff);
2238 /* TODO */
2239 break;
2240 case REPORT_BL_READ_MEMORY:
2241 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
2242 "REPORT_BL_READ_MEMORY", report->id, size-1);
2243 hid_debug_event(hdev, buff);
2244 /* TODO */
2245 break;
2246 case REPORT_BL_WRITE_MEMORY:
2247 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
2248 "REPORT_BL_WRITE_MEMORY", report->id, size-1);
2249 hid_debug_event(hdev, buff);
2250 /* TODO */
2251 break;
2252 case REPORT_DEVID:
2253 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
2254 "REPORT_DEVID", report->id, size-1);
2255 hid_debug_event(hdev, buff);
2256 snprintf(buff, BUFF_SZ, "\tSerial: 0x%02x%02x%02x%02x\n",
2257 raw_data[1], raw_data[2], raw_data[3], raw_data[4]);
2258 hid_debug_event(hdev, buff);
2259 snprintf(buff, BUFF_SZ, "\tType: 0x%02x\n",
2260 raw_data[5]);
2261 hid_debug_event(hdev, buff);
2262 break;
2263 case REPORT_SPLASH_SIZE:
2264 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
2265 "REPORT_SPLASH_SIZE", report->id, size-1);
2266 hid_debug_event(hdev, buff);
2267 snprintf(buff, BUFF_SZ, "\tTotal splash space: %d\n",
2268 (raw_data[2] << 8) | raw_data[1]);
2269 hid_debug_event(hdev, buff);
2270 snprintf(buff, BUFF_SZ, "\tUsed splash space: %d\n",
2271 (raw_data[4] << 8) | raw_data[3]);
2272 hid_debug_event(hdev, buff);
2273 break;
2274 case REPORT_HOOK_VERSION:
2275 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
2276 "REPORT_HOOK_VERSION", report->id, size-1);
2277 hid_debug_event(hdev, buff);
2278 snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n",
2279 raw_data[1], raw_data[2]);
2280 hid_debug_event(hdev, buff);
2281 break;
2282 default:
2283 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
2284 "<unknown>", report->id, size-1);
2285 hid_debug_event(hdev, buff);
2286 break;
2287 }
2288 wake_up_interruptible(&hdev->debug_wait);
2289 kfree(buff);
2290}
2291
2292static void picolcd_init_devfs(struct picolcd_data *data,
2293 struct hid_report *eeprom_r, struct hid_report *eeprom_w,
2294 struct hid_report *flash_r, struct hid_report *flash_w,
2295 struct hid_report *reset)
2296{
2297 struct hid_device *hdev = data->hdev;
2298
2299 mutex_init(&data->mutex_flash);
2300
2301 /* reset */
2302 if (reset)
2303 data->debug_reset = debugfs_create_file("reset", 0600,
2304 hdev->debug_dir, data, &picolcd_debug_reset_fops);
2305
2306 /* eeprom */
2307 if (eeprom_r || eeprom_w)
2308 data->debug_eeprom = debugfs_create_file("eeprom",
2309 (eeprom_w ? S_IWUSR : 0) | (eeprom_r ? S_IRUSR : 0),
2310 hdev->debug_dir, data, &picolcd_debug_eeprom_fops);
2311
2312 /* flash */
2313 if (flash_r && flash_r->maxfield == 1 && flash_r->field[0]->report_size == 8)
2314 data->addr_sz = flash_r->field[0]->report_count - 1;
2315 else
2316 data->addr_sz = -1;
2317 if (data->addr_sz == 2 || data->addr_sz == 3) {
2318 data->debug_flash = debugfs_create_file("flash",
2319 (flash_w ? S_IWUSR : 0) | (flash_r ? S_IRUSR : 0),
2320 hdev->debug_dir, data, &picolcd_debug_flash_fops);
2321 } else if (flash_r || flash_w)
2322 hid_warn(hdev, "Unexpected FLASH access reports, please submit rdesc for review\n");
2323}
2324
2325static void picolcd_exit_devfs(struct picolcd_data *data)
2326{
2327 struct dentry *dent;
2328
2329 dent = data->debug_reset;
2330 data->debug_reset = NULL;
2331 if (dent)
2332 debugfs_remove(dent);
2333 dent = data->debug_eeprom;
2334 data->debug_eeprom = NULL;
2335 if (dent)
2336 debugfs_remove(dent);
2337 dent = data->debug_flash;
2338 data->debug_flash = NULL;
2339 if (dent)
2340 debugfs_remove(dent);
2341 mutex_destroy(&data->mutex_flash);
2342}
2343#else
2344static inline void picolcd_debug_raw_event(struct picolcd_data *data,
2345 struct hid_device *hdev, struct hid_report *report,
2346 u8 *raw_data, int size)
2347{
2348}
2349static inline void picolcd_init_devfs(struct picolcd_data *data,
2350 struct hid_report *eeprom_r, struct hid_report *eeprom_w,
2351 struct hid_report *flash_r, struct hid_report *flash_w,
2352 struct hid_report *reset)
2353{
2354}
2355static inline void picolcd_exit_devfs(struct picolcd_data *data)
2356{
2357}
2358#endif /* CONFIG_DEBUG_FS */
2359
2360/*
2361 * Handle raw report as sent by device
2362 */
2363static int picolcd_raw_event(struct hid_device *hdev,
2364 struct hid_report *report, u8 *raw_data, int size)
2365{
2366 struct picolcd_data *data = hid_get_drvdata(hdev);
2367 unsigned long flags;
2368 int ret = 0;
2369
2370 if (!data)
2371 return 1;
2372
2373 if (report->id == REPORT_KEY_STATE) {
2374 if (data->input_keys)
2375 ret = picolcd_raw_keypad(data, report, raw_data+1, size-1);
2376 } else if (report->id == REPORT_IR_DATA) {
2377 if (data->input_cir)
2378 ret = picolcd_raw_cir(data, report, raw_data+1, size-1);
2379 } else {
2380 spin_lock_irqsave(&data->lock, flags);
2381 /*
2382 * We let the caller of picolcd_send_and_wait() check if the
2383 * report we got is one of the expected ones or not.
2384 */
2385 if (data->pending) {
2386 memcpy(data->pending->raw_data, raw_data+1, size-1);
2387 data->pending->raw_size = size-1;
2388 data->pending->in_report = report;
2389 complete(&data->pending->ready);
2390 }
2391 spin_unlock_irqrestore(&data->lock, flags);
2392 }
2393
2394 picolcd_debug_raw_event(data, hdev, report, raw_data, size);
2395 return 1;
2396}
2397
2398#ifdef CONFIG_PM
2399static int picolcd_suspend(struct hid_device *hdev, pm_message_t message)
2400{
2401 if (PMSG_IS_AUTO(message))
2402 return 0;
2403
2404 picolcd_suspend_backlight(hid_get_drvdata(hdev));
2405 dbg_hid(PICOLCD_NAME " device ready for suspend\n");
2406 return 0;
2407}
2408
2409static int picolcd_resume(struct hid_device *hdev)
2410{
2411 int ret;
2412 ret = picolcd_resume_backlight(hid_get_drvdata(hdev));
2413 if (ret)
2414 dbg_hid(PICOLCD_NAME " restoring backlight failed: %d\n", ret);
2415 return 0;
2416}
2417
2418static int picolcd_reset_resume(struct hid_device *hdev)
2419{
2420 int ret;
2421 ret = picolcd_reset(hdev);
2422 if (ret)
2423 dbg_hid(PICOLCD_NAME " resetting our device failed: %d\n", ret);
2424 ret = picolcd_fb_reset(hid_get_drvdata(hdev), 0);
2425 if (ret)
2426 dbg_hid(PICOLCD_NAME " restoring framebuffer content failed: %d\n", ret);
2427 ret = picolcd_resume_lcd(hid_get_drvdata(hdev));
2428 if (ret)
2429 dbg_hid(PICOLCD_NAME " restoring lcd failed: %d\n", ret);
2430 ret = picolcd_resume_backlight(hid_get_drvdata(hdev));
2431 if (ret)
2432 dbg_hid(PICOLCD_NAME " restoring backlight failed: %d\n", ret);
2433 picolcd_leds_set(hid_get_drvdata(hdev));
2434 return 0;
2435}
2436#endif
2437
2438/* initialize keypad input device */
2439static int picolcd_init_keys(struct picolcd_data *data,
2440 struct hid_report *report)
2441{
2442 struct hid_device *hdev = data->hdev;
2443 struct input_dev *idev;
2444 int error, i;
2445
2446 if (!report)
2447 return -ENODEV;
2448 if (report->maxfield != 1 || report->field[0]->report_count != 2 ||
2449 report->field[0]->report_size != 8) {
2450 hid_err(hdev, "unsupported KEY_STATE report\n");
2451 return -EINVAL;
2452 }
2453
2454 idev = input_allocate_device();
2455 if (idev == NULL) {
2456 hid_err(hdev, "failed to allocate input device\n");
2457 return -ENOMEM;
2458 }
2459 input_set_drvdata(idev, hdev);
2460 memcpy(data->keycode, def_keymap, sizeof(def_keymap));
2461 idev->name = hdev->name;
2462 idev->phys = hdev->phys;
2463 idev->uniq = hdev->uniq;
2464 idev->id.bustype = hdev->bus;
2465 idev->id.vendor = hdev->vendor;
2466 idev->id.product = hdev->product;
2467 idev->id.version = hdev->version;
2468 idev->dev.parent = hdev->dev.parent;
2469 idev->keycode = &data->keycode;
2470 idev->keycodemax = PICOLCD_KEYS;
2471 idev->keycodesize = sizeof(data->keycode[0]);
2472 input_set_capability(idev, EV_MSC, MSC_SCAN);
2473 set_bit(EV_REP, idev->evbit);
2474 for (i = 0; i < PICOLCD_KEYS; i++)
2475 input_set_capability(idev, EV_KEY, data->keycode[i]);
2476 error = input_register_device(idev);
2477 if (error) {
2478 hid_err(hdev, "error registering the input device\n");
2479 input_free_device(idev);
2480 return error;
2481 }
2482 data->input_keys = idev;
2483 return 0;
2484}
2485
2486static void picolcd_exit_keys(struct picolcd_data *data)
2487{
2488 struct input_dev *idev = data->input_keys;
2489
2490 data->input_keys = NULL;
2491 if (idev)
2492 input_unregister_device(idev);
2493}
2494
2495/* initialize CIR input device */
2496static inline int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report)
2497{
2498 /* support not implemented yet */
2499 return 0;
2500}
2501
2502static inline void picolcd_exit_cir(struct picolcd_data *data)
2503{
2504}
2505
2506static int picolcd_probe_lcd(struct hid_device *hdev, struct picolcd_data *data)
2507{
2508 int error;
2509
2510 error = picolcd_check_version(hdev);
2511 if (error)
2512 return error;
2513
2514 if (data->version[0] != 0 && data->version[1] != 3)
2515 hid_info(hdev, "Device with untested firmware revision, please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n",
2516 dev_name(&hdev->dev));
2517
2518 /* Setup keypad input device */
2519 error = picolcd_init_keys(data, picolcd_in_report(REPORT_KEY_STATE, hdev));
2520 if (error)
2521 goto err;
2522
2523 /* Setup CIR input device */
2524 error = picolcd_init_cir(data, picolcd_in_report(REPORT_IR_DATA, hdev));
2525 if (error)
2526 goto err;
2527
2528 /* Set up the framebuffer device */
2529 error = picolcd_init_framebuffer(data);
2530 if (error)
2531 goto err;
2532
2533 /* Setup lcd class device */
2534 error = picolcd_init_lcd(data, picolcd_out_report(REPORT_CONTRAST, hdev));
2535 if (error)
2536 goto err;
2537
2538 /* Setup backlight class device */
2539 error = picolcd_init_backlight(data, picolcd_out_report(REPORT_BRIGHTNESS, hdev));
2540 if (error)
2541 goto err;
2542
2543 /* Setup the LED class devices */
2544 error = picolcd_init_leds(data, picolcd_out_report(REPORT_LED_STATE, hdev));
2545 if (error)
2546 goto err;
2547
2548 picolcd_init_devfs(data, picolcd_out_report(REPORT_EE_READ, hdev),
2549 picolcd_out_report(REPORT_EE_WRITE, hdev),
2550 picolcd_out_report(REPORT_READ_MEMORY, hdev),
2551 picolcd_out_report(REPORT_WRITE_MEMORY, hdev),
2552 picolcd_out_report(REPORT_RESET, hdev));
2553 return 0;
2554err:
2555 picolcd_exit_leds(data);
2556 picolcd_exit_backlight(data);
2557 picolcd_exit_lcd(data);
2558 picolcd_exit_framebuffer(data);
2559 picolcd_exit_cir(data);
2560 picolcd_exit_keys(data);
2561 return error;
2562}
2563
2564static int picolcd_probe_bootloader(struct hid_device *hdev, struct picolcd_data *data)
2565{
2566 int error;
2567
2568 error = picolcd_check_version(hdev);
2569 if (error)
2570 return error;
2571
2572 if (data->version[0] != 1 && data->version[1] != 0)
2573 hid_info(hdev, "Device with untested bootloader revision, please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n",
2574 dev_name(&hdev->dev));
2575
2576 picolcd_init_devfs(data, NULL, NULL,
2577 picolcd_out_report(REPORT_BL_READ_MEMORY, hdev),
2578 picolcd_out_report(REPORT_BL_WRITE_MEMORY, hdev), NULL);
2579 return 0;
2580}
2581
2582static int picolcd_probe(struct hid_device *hdev,
2583 const struct hid_device_id *id)
2584{
2585 struct picolcd_data *data;
2586 int error = -ENOMEM;
2587
2588 dbg_hid(PICOLCD_NAME " hardware probe...\n");
2589
2590 /*
2591 * Let's allocate the picolcd data structure, set some reasonable
2592 * defaults, and associate it with the device
2593 */
2594 data = kzalloc(sizeof(struct picolcd_data), GFP_KERNEL);
2595 if (data == NULL) {
2596 hid_err(hdev, "can't allocate space for Minibox PicoLCD device data\n");
2597 error = -ENOMEM;
2598 goto err_no_cleanup;
2599 }
2600
2601 spin_lock_init(&data->lock);
2602 mutex_init(&data->mutex);
2603 data->hdev = hdev;
2604 data->opmode_delay = 5000;
2605 if (hdev->product == USB_DEVICE_ID_PICOLCD_BOOTLOADER)
2606 data->status |= PICOLCD_BOOTLOADER;
2607 hid_set_drvdata(hdev, data);
2608
2609 /* Parse the device reports and start it up */
2610 error = hid_parse(hdev);
2611 if (error) {
2612 hid_err(hdev, "device report parse failed\n");
2613 goto err_cleanup_data;
2614 }
2615
2616 error = hid_hw_start(hdev, 0);
2617 if (error) {
2618 hid_err(hdev, "hardware start failed\n");
2619 goto err_cleanup_data;
2620 }
2621
2622 error = hid_hw_open(hdev);
2623 if (error) {
2624 hid_err(hdev, "failed to open input interrupt pipe for key and IR events\n");
2625 goto err_cleanup_hid_hw;
2626 }
2627
2628 error = device_create_file(&hdev->dev, &dev_attr_operation_mode_delay);
2629 if (error) {
2630 hid_err(hdev, "failed to create sysfs attributes\n");
2631 goto err_cleanup_hid_ll;
2632 }
2633
2634 error = device_create_file(&hdev->dev, &dev_attr_operation_mode);
2635 if (error) {
2636 hid_err(hdev, "failed to create sysfs attributes\n");
2637 goto err_cleanup_sysfs1;
2638 }
2639
2640 if (data->status & PICOLCD_BOOTLOADER)
2641 error = picolcd_probe_bootloader(hdev, data);
2642 else
2643 error = picolcd_probe_lcd(hdev, data);
2644 if (error)
2645 goto err_cleanup_sysfs2;
2646
2647 dbg_hid(PICOLCD_NAME " activated and initialized\n");
2648 return 0;
2649
2650err_cleanup_sysfs2:
2651 device_remove_file(&hdev->dev, &dev_attr_operation_mode);
2652err_cleanup_sysfs1:
2653 device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay);
2654err_cleanup_hid_ll:
2655 hid_hw_close(hdev);
2656err_cleanup_hid_hw:
2657 hid_hw_stop(hdev);
2658err_cleanup_data:
2659 kfree(data);
2660err_no_cleanup:
2661 hid_set_drvdata(hdev, NULL);
2662
2663 return error;
2664}
2665
2666static void picolcd_remove(struct hid_device *hdev)
2667{
2668 struct picolcd_data *data = hid_get_drvdata(hdev);
2669 unsigned long flags;
2670
2671 dbg_hid(PICOLCD_NAME " hardware remove...\n");
2672 spin_lock_irqsave(&data->lock, flags);
2673 data->status |= PICOLCD_FAILED;
2674 spin_unlock_irqrestore(&data->lock, flags);
2675#ifdef CONFIG_HID_PICOLCD_FB
2676 /* short-circuit FB as early as possible in order to
2677 * avoid long delays if we host console.
2678 */
2679 if (data->fb_info)
2680 data->fb_info->par = NULL;
2681#endif
2682
2683 picolcd_exit_devfs(data);
2684 device_remove_file(&hdev->dev, &dev_attr_operation_mode);
2685 device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay);
2686 hid_hw_close(hdev);
2687 hid_hw_stop(hdev);
2688 hid_set_drvdata(hdev, NULL);
2689
2690 /* Shortcut potential pending reply that will never arrive */
2691 spin_lock_irqsave(&data->lock, flags);
2692 if (data->pending)
2693 complete(&data->pending->ready);
2694 spin_unlock_irqrestore(&data->lock, flags);
2695
2696 /* Cleanup LED */
2697 picolcd_exit_leds(data);
2698 /* Clean up the framebuffer */
2699 picolcd_exit_backlight(data);
2700 picolcd_exit_lcd(data);
2701 picolcd_exit_framebuffer(data);
2702 /* Cleanup input */
2703 picolcd_exit_cir(data);
2704 picolcd_exit_keys(data);
2705
2706 mutex_destroy(&data->mutex);
2707 /* Finally, clean up the picolcd data itself */
2708 kfree(data);
2709}
2710
2711static const struct hid_device_id picolcd_devices[] = {
2712 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) },
2713 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) },
2714 { }
2715};
2716MODULE_DEVICE_TABLE(hid, picolcd_devices);
2717
2718static struct hid_driver picolcd_driver = {
2719 .name = "hid-picolcd",
2720 .id_table = picolcd_devices,
2721 .probe = picolcd_probe,
2722 .remove = picolcd_remove,
2723 .raw_event = picolcd_raw_event,
2724#ifdef CONFIG_PM
2725 .suspend = picolcd_suspend,
2726 .resume = picolcd_resume,
2727 .reset_resume = picolcd_reset_resume,
2728#endif
2729};
2730
2731static int __init picolcd_init(void)
2732{
2733 return hid_register_driver(&picolcd_driver);
2734}
2735
2736static void __exit picolcd_exit(void)
2737{
2738 hid_unregister_driver(&picolcd_driver);
2739#ifdef CONFIG_HID_PICOLCD_FB
2740 flush_work_sync(&picolcd_fb_cleanup);
2741 WARN_ON(fb_pending);
2742#endif
2743}
2744
2745module_init(picolcd_init);
2746module_exit(picolcd_exit);
2747MODULE_DESCRIPTION("Minibox graphics PicoLCD Driver");
2748MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-picolcd.h b/drivers/hid/hid-picolcd.h
new file mode 100644
index 000000000000..020cef69f6a1
--- /dev/null
+++ b/drivers/hid/hid-picolcd.h
@@ -0,0 +1,309 @@
1/***************************************************************************
2 * Copyright (C) 2010-2012 by Bruno Prémont <bonbons@linux-vserver.org> *
3 * *
4 * Based on Logitech G13 driver (v0.4) *
5 * Copyright (C) 2009 by Rick L. Vinyard, Jr. <rvinyard@cs.nmsu.edu> *
6 * *
7 * This program is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, version 2 of the License. *
10 * *
11 * This driver is distributed in the hope that it will be useful, but *
12 * WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14 * General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this software. If not see <http://www.gnu.org/licenses/>. *
18 ***************************************************************************/
19
20#define PICOLCD_NAME "PicoLCD (graphic)"
21
22/* Report numbers */
23#define REPORT_ERROR_CODE 0x10 /* LCD: IN[16] */
24#define ERR_SUCCESS 0x00
25#define ERR_PARAMETER_MISSING 0x01
26#define ERR_DATA_MISSING 0x02
27#define ERR_BLOCK_READ_ONLY 0x03
28#define ERR_BLOCK_NOT_ERASABLE 0x04
29#define ERR_BLOCK_TOO_BIG 0x05
30#define ERR_SECTION_OVERFLOW 0x06
31#define ERR_INVALID_CMD_LEN 0x07
32#define ERR_INVALID_DATA_LEN 0x08
33#define REPORT_KEY_STATE 0x11 /* LCD: IN[2] */
34#define REPORT_IR_DATA 0x21 /* LCD: IN[63] */
35#define REPORT_EE_DATA 0x32 /* LCD: IN[63] */
36#define REPORT_MEMORY 0x41 /* LCD: IN[63] */
37#define REPORT_LED_STATE 0x81 /* LCD: OUT[1] */
38#define REPORT_BRIGHTNESS 0x91 /* LCD: OUT[1] */
39#define REPORT_CONTRAST 0x92 /* LCD: OUT[1] */
40#define REPORT_RESET 0x93 /* LCD: OUT[2] */
41#define REPORT_LCD_CMD 0x94 /* LCD: OUT[63] */
42#define REPORT_LCD_DATA 0x95 /* LCD: OUT[63] */
43#define REPORT_LCD_CMD_DATA 0x96 /* LCD: OUT[63] */
44#define REPORT_EE_READ 0xa3 /* LCD: OUT[63] */
45#define REPORT_EE_WRITE 0xa4 /* LCD: OUT[63] */
46#define REPORT_ERASE_MEMORY 0xb2 /* LCD: OUT[2] */
47#define REPORT_READ_MEMORY 0xb3 /* LCD: OUT[3] */
48#define REPORT_WRITE_MEMORY 0xb4 /* LCD: OUT[63] */
49#define REPORT_SPLASH_RESTART 0xc1 /* LCD: OUT[1] */
50#define REPORT_EXIT_KEYBOARD 0xef /* LCD: OUT[2] */
51#define REPORT_VERSION 0xf1 /* LCD: IN[2],OUT[1] Bootloader: IN[2],OUT[1] */
52#define REPORT_BL_ERASE_MEMORY 0xf2 /* Bootloader: IN[36],OUT[4] */
53#define REPORT_BL_READ_MEMORY 0xf3 /* Bootloader: IN[36],OUT[4] */
54#define REPORT_BL_WRITE_MEMORY 0xf4 /* Bootloader: IN[36],OUT[36] */
55#define REPORT_DEVID 0xf5 /* LCD: IN[5], OUT[1] Bootloader: IN[5],OUT[1] */
56#define REPORT_SPLASH_SIZE 0xf6 /* LCD: IN[4], OUT[1] */
57#define REPORT_HOOK_VERSION 0xf7 /* LCD: IN[2], OUT[1] */
58#define REPORT_EXIT_FLASHER 0xff /* Bootloader: OUT[2] */
59
60/* Description of in-progress IO operation, used for operations
61 * that trigger response from device */
62struct picolcd_pending {
63 struct hid_report *out_report;
64 struct hid_report *in_report;
65 struct completion ready;
66 int raw_size;
67 u8 raw_data[64];
68};
69
70
71#define PICOLCD_KEYS 17
72
73/* Per device data structure */
74struct picolcd_data {
75 struct hid_device *hdev;
76#ifdef CONFIG_DEBUG_FS
77 struct dentry *debug_reset;
78 struct dentry *debug_eeprom;
79 struct dentry *debug_flash;
80 struct mutex mutex_flash;
81 int addr_sz;
82#endif
83 u8 version[2];
84 unsigned short opmode_delay;
85 /* input stuff */
86 u8 pressed_keys[2];
87 struct input_dev *input_keys;
88#ifdef CONFIG_HID_PICOLCD_CIR
89 struct rc_dev *rc_dev;
90#endif
91 unsigned short keycode[PICOLCD_KEYS];
92
93#ifdef CONFIG_HID_PICOLCD_FB
94 /* Framebuffer stuff */
95 struct fb_info *fb_info;
96#endif /* CONFIG_HID_PICOLCD_FB */
97#ifdef CONFIG_HID_PICOLCD_LCD
98 struct lcd_device *lcd;
99 u8 lcd_contrast;
100#endif /* CONFIG_HID_PICOLCD_LCD */
101#ifdef CONFIG_HID_PICOLCD_BACKLIGHT
102 struct backlight_device *backlight;
103 u8 lcd_brightness;
104 u8 lcd_power;
105#endif /* CONFIG_HID_PICOLCD_BACKLIGHT */
106#ifdef CONFIG_HID_PICOLCD_LEDS
107 /* LED stuff */
108 u8 led_state;
109 struct led_classdev *led[8];
110#endif /* CONFIG_HID_PICOLCD_LEDS */
111
112 /* Housekeeping stuff */
113 spinlock_t lock;
114 struct mutex mutex;
115 struct picolcd_pending *pending;
116 int status;
117#define PICOLCD_BOOTLOADER 1
118#define PICOLCD_FAILED 2
119#define PICOLCD_CIR_SHUN 4
120};
121
122#ifdef CONFIG_HID_PICOLCD_FB
123struct picolcd_fb_data {
124 /* Framebuffer stuff */
125 spinlock_t lock;
126 struct picolcd_data *picolcd;
127 u8 update_rate;
128 u8 bpp;
129 u8 force;
130 u8 ready;
131 u8 *vbitmap; /* local copy of what was sent to PicoLCD */
132 u8 *bitmap; /* framebuffer */
133};
134#endif /* CONFIG_HID_PICOLCD_FB */
135
136/* Find a given report */
137#define picolcd_in_report(id, dev) picolcd_report(id, dev, HID_INPUT_REPORT)
138#define picolcd_out_report(id, dev) picolcd_report(id, dev, HID_OUTPUT_REPORT)
139
140struct hid_report *picolcd_report(int id, struct hid_device *hdev, int dir);
141
142#ifdef CONFIG_DEBUG_FS
143void picolcd_debug_out_report(struct picolcd_data *data,
144 struct hid_device *hdev, struct hid_report *report);
145#define usbhid_submit_report(a, b, c) \
146 do { \
147 picolcd_debug_out_report(hid_get_drvdata(a), a, b); \
148 usbhid_submit_report(a, b, c); \
149 } while (0)
150
151void picolcd_debug_raw_event(struct picolcd_data *data,
152 struct hid_device *hdev, struct hid_report *report,
153 u8 *raw_data, int size);
154
155void picolcd_init_devfs(struct picolcd_data *data,
156 struct hid_report *eeprom_r, struct hid_report *eeprom_w,
157 struct hid_report *flash_r, struct hid_report *flash_w,
158 struct hid_report *reset);
159
160void picolcd_exit_devfs(struct picolcd_data *data);
161#else
162static inline void picolcd_debug_out_report(struct picolcd_data *data,
163 struct hid_device *hdev, struct hid_report *report)
164{
165}
166static inline void picolcd_debug_raw_event(struct picolcd_data *data,
167 struct hid_device *hdev, struct hid_report *report,
168 u8 *raw_data, int size)
169{
170}
171static inline void picolcd_init_devfs(struct picolcd_data *data,
172 struct hid_report *eeprom_r, struct hid_report *eeprom_w,
173 struct hid_report *flash_r, struct hid_report *flash_w,
174 struct hid_report *reset)
175{
176}
177static inline void picolcd_exit_devfs(struct picolcd_data *data)
178{
179}
180#endif /* CONFIG_DEBUG_FS */
181
182
183#ifdef CONFIG_HID_PICOLCD_FB
184int picolcd_fb_reset(struct picolcd_data *data, int clear);
185
186int picolcd_init_framebuffer(struct picolcd_data *data);
187
188void picolcd_exit_framebuffer(struct picolcd_data *data);
189
190void picolcd_fb_refresh(struct picolcd_data *data);
191#define picolcd_fbinfo(d) ((d)->fb_info)
192#else
193static inline int picolcd_fb_reset(struct picolcd_data *data, int clear)
194{
195 return 0;
196}
197static inline int picolcd_init_framebuffer(struct picolcd_data *data)
198{
199 return 0;
200}
201static inline void picolcd_exit_framebuffer(struct picolcd_data *data)
202{
203}
204static inline void picolcd_fb_refresh(struct picolcd_data *data)
205{
206}
207#define picolcd_fbinfo(d) NULL
208#endif /* CONFIG_HID_PICOLCD_FB */
209
210
211#ifdef CONFIG_HID_PICOLCD_BACKLIGHT
212int picolcd_init_backlight(struct picolcd_data *data,
213 struct hid_report *report);
214
215void picolcd_exit_backlight(struct picolcd_data *data);
216
217int picolcd_resume_backlight(struct picolcd_data *data);
218
219void picolcd_suspend_backlight(struct picolcd_data *data);
220#else
221static inline int picolcd_init_backlight(struct picolcd_data *data,
222 struct hid_report *report)
223{
224 return 0;
225}
226static inline void picolcd_exit_backlight(struct picolcd_data *data)
227{
228}
229static inline int picolcd_resume_backlight(struct picolcd_data *data)
230{
231 return 0;
232}
233static inline void picolcd_suspend_backlight(struct picolcd_data *data)
234{
235}
236
237#endif /* CONFIG_HID_PICOLCD_BACKLIGHT */
238
239
240#ifdef CONFIG_HID_PICOLCD_LCD
241int picolcd_init_lcd(struct picolcd_data *data,
242 struct hid_report *report);
243
244void picolcd_exit_lcd(struct picolcd_data *data);
245
246int picolcd_resume_lcd(struct picolcd_data *data);
247#else
248static inline int picolcd_init_lcd(struct picolcd_data *data,
249 struct hid_report *report)
250{
251 return 0;
252}
253static inline void picolcd_exit_lcd(struct picolcd_data *data)
254{
255}
256static inline int picolcd_resume_lcd(struct picolcd_data *data)
257{
258 return 0;
259}
260#endif /* CONFIG_HID_PICOLCD_LCD */
261
262
263#ifdef CONFIG_HID_PICOLCD_LEDS
264int picolcd_init_leds(struct picolcd_data *data,
265 struct hid_report *report);
266
267void picolcd_exit_leds(struct picolcd_data *data);
268
269void picolcd_leds_set(struct picolcd_data *data);
270#else
271static inline int picolcd_init_leds(struct picolcd_data *data,
272 struct hid_report *report)
273{
274 return 0;
275}
276static inline void picolcd_exit_leds(struct picolcd_data *data)
277{
278}
279static inline void picolcd_leds_set(struct picolcd_data *data)
280{
281}
282#endif /* CONFIG_HID_PICOLCD_LEDS */
283
284
285#ifdef CONFIG_HID_PICOLCD_CIR
286int picolcd_raw_cir(struct picolcd_data *data,
287 struct hid_report *report, u8 *raw_data, int size);
288
289int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report);
290
291void picolcd_exit_cir(struct picolcd_data *data);
292#else
293static inline int picolcd_raw_cir(struct picolcd_data *data,
294 struct hid_report *report, u8 *raw_data, int size)
295{
296 return 1;
297}
298static inline int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report)
299{
300 return 0;
301}
302static inline void picolcd_exit_cir(struct picolcd_data *data)
303{
304}
305#endif /* CONFIG_HID_PICOLCD_LIRC */
306
307int picolcd_reset(struct hid_device *hdev);
308struct picolcd_pending *picolcd_send_and_wait(struct hid_device *hdev,
309 int report_id, const u8 *raw_data, int size);
diff --git a/drivers/hid/hid-picolcd_backlight.c b/drivers/hid/hid-picolcd_backlight.c
new file mode 100644
index 000000000000..b91f30945f9c
--- /dev/null
+++ b/drivers/hid/hid-picolcd_backlight.c
@@ -0,0 +1,122 @@
1/***************************************************************************
2 * Copyright (C) 2010-2012 by Bruno Prémont <bonbons@linux-vserver.org> *
3 * *
4 * Based on Logitech G13 driver (v0.4) *
5 * Copyright (C) 2009 by Rick L. Vinyard, Jr. <rvinyard@cs.nmsu.edu> *
6 * *
7 * This program is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, version 2 of the License. *
10 * *
11 * This driver is distributed in the hope that it will be useful, but *
12 * WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14 * General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this software. If not see <http://www.gnu.org/licenses/>. *
18 ***************************************************************************/
19
20#include <linux/hid.h>
21#include "usbhid/usbhid.h"
22#include <linux/usb.h>
23
24#include <linux/fb.h>
25#include <linux/backlight.h>
26
27#include "hid-picolcd.h"
28
29static int picolcd_get_brightness(struct backlight_device *bdev)
30{
31 struct picolcd_data *data = bl_get_data(bdev);
32 return data->lcd_brightness;
33}
34
35static int picolcd_set_brightness(struct backlight_device *bdev)
36{
37 struct picolcd_data *data = bl_get_data(bdev);
38 struct hid_report *report = picolcd_out_report(REPORT_BRIGHTNESS, data->hdev);
39 unsigned long flags;
40
41 if (!report || report->maxfield != 1 || report->field[0]->report_count != 1)
42 return -ENODEV;
43
44 data->lcd_brightness = bdev->props.brightness & 0x0ff;
45 data->lcd_power = bdev->props.power;
46 spin_lock_irqsave(&data->lock, flags);
47 hid_set_field(report->field[0], 0, data->lcd_power == FB_BLANK_UNBLANK ? data->lcd_brightness : 0);
48 if (!(data->status & PICOLCD_FAILED))
49 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
50 spin_unlock_irqrestore(&data->lock, flags);
51 return 0;
52}
53
54static int picolcd_check_bl_fb(struct backlight_device *bdev, struct fb_info *fb)
55{
56 return fb && fb == picolcd_fbinfo((struct picolcd_data *)bl_get_data(bdev));
57}
58
59static const struct backlight_ops picolcd_blops = {
60 .update_status = picolcd_set_brightness,
61 .get_brightness = picolcd_get_brightness,
62 .check_fb = picolcd_check_bl_fb,
63};
64
65int picolcd_init_backlight(struct picolcd_data *data, struct hid_report *report)
66{
67 struct device *dev = &data->hdev->dev;
68 struct backlight_device *bdev;
69 struct backlight_properties props;
70 if (!report)
71 return -ENODEV;
72 if (report->maxfield != 1 || report->field[0]->report_count != 1 ||
73 report->field[0]->report_size != 8) {
74 dev_err(dev, "unsupported BRIGHTNESS report");
75 return -EINVAL;
76 }
77
78 memset(&props, 0, sizeof(props));
79 props.type = BACKLIGHT_RAW;
80 props.max_brightness = 0xff;
81 bdev = backlight_device_register(dev_name(dev), dev, data,
82 &picolcd_blops, &props);
83 if (IS_ERR(bdev)) {
84 dev_err(dev, "failed to register backlight\n");
85 return PTR_ERR(bdev);
86 }
87 bdev->props.brightness = 0xff;
88 data->lcd_brightness = 0xff;
89 data->backlight = bdev;
90 picolcd_set_brightness(bdev);
91 return 0;
92}
93
94void picolcd_exit_backlight(struct picolcd_data *data)
95{
96 struct backlight_device *bdev = data->backlight;
97
98 data->backlight = NULL;
99 if (bdev)
100 backlight_device_unregister(bdev);
101}
102
103int picolcd_resume_backlight(struct picolcd_data *data)
104{
105 if (!data->backlight)
106 return 0;
107 return picolcd_set_brightness(data->backlight);
108}
109
110#ifdef CONFIG_PM
111void picolcd_suspend_backlight(struct picolcd_data *data)
112{
113 int bl_power = data->lcd_power;
114 if (!data->backlight)
115 return;
116
117 data->backlight->props.power = FB_BLANK_POWERDOWN;
118 picolcd_set_brightness(data->backlight);
119 data->lcd_power = data->backlight->props.power = bl_power;
120}
121#endif /* CONFIG_PM */
122
diff --git a/drivers/hid/hid-picolcd_cir.c b/drivers/hid/hid-picolcd_cir.c
new file mode 100644
index 000000000000..13ca9191b630
--- /dev/null
+++ b/drivers/hid/hid-picolcd_cir.c
@@ -0,0 +1,152 @@
1/***************************************************************************
2 * Copyright (C) 2010-2012 by Bruno Prémont <bonbons@linux-vserver.org> *
3 * *
4 * Based on Logitech G13 driver (v0.4) *
5 * Copyright (C) 2009 by Rick L. Vinyard, Jr. <rvinyard@cs.nmsu.edu> *
6 * *
7 * This program is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, version 2 of the License. *
10 * *
11 * This driver is distributed in the hope that it will be useful, but *
12 * WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14 * General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this software. If not see <http://www.gnu.org/licenses/>. *
18 ***************************************************************************/
19
20#include <linux/hid.h>
21#include <linux/hid-debug.h>
22#include <linux/input.h>
23#include "hid-ids.h"
24#include "usbhid/usbhid.h"
25#include <linux/usb.h>
26
27#include <linux/fb.h>
28#include <linux/vmalloc.h>
29#include <linux/backlight.h>
30#include <linux/lcd.h>
31
32#include <linux/leds.h>
33
34#include <linux/seq_file.h>
35#include <linux/debugfs.h>
36
37#include <linux/completion.h>
38#include <linux/uaccess.h>
39#include <linux/module.h>
40#include <media/rc-core.h>
41
42#include "hid-picolcd.h"
43
44
45int picolcd_raw_cir(struct picolcd_data *data,
46 struct hid_report *report, u8 *raw_data, int size)
47{
48 unsigned long flags;
49 int i, w, sz;
50 DEFINE_IR_RAW_EVENT(rawir);
51
52 /* ignore if rc_dev is NULL or status is shunned */
53 spin_lock_irqsave(&data->lock, flags);
54 if (!data->rc_dev || (data->status & PICOLCD_CIR_SHUN)) {
55 spin_unlock_irqrestore(&data->lock, flags);
56 return 1;
57 }
58 spin_unlock_irqrestore(&data->lock, flags);
59
60 /* PicoLCD USB packets contain 16-bit intervals in network order,
61 * with value negated for pulse. Intervals are in microseconds.
62 *
63 * Note: some userspace LIRC code for PicoLCD says negated values
64 * for space - is it a matter of IR chip? (pulse for my TSOP2236)
65 *
66 * In addition, the first interval seems to be around 15000 + base
67 * interval for non-first report of IR data - thus the quirk below
68 * to get RC_CODE to understand Sony and JVC remotes I have at hand
69 */
70 sz = size > 0 ? min((int)raw_data[0], size-1) : 0;
71 for (i = 0; i+1 < sz; i += 2) {
72 init_ir_raw_event(&rawir);
73 w = (raw_data[i] << 8) | (raw_data[i+1]);
74 rawir.pulse = !!(w & 0x8000);
75 rawir.duration = US_TO_NS(rawir.pulse ? (65536 - w) : w);
76 /* Quirk!! - see above */
77 if (i == 0 && rawir.duration > 15000000)
78 rawir.duration -= 15000000;
79 ir_raw_event_store(data->rc_dev, &rawir);
80 }
81 ir_raw_event_handle(data->rc_dev);
82
83 return 1;
84}
85
86static int picolcd_cir_open(struct rc_dev *dev)
87{
88 struct picolcd_data *data = dev->priv;
89 unsigned long flags;
90
91 spin_lock_irqsave(&data->lock, flags);
92 data->status &= ~PICOLCD_CIR_SHUN;
93 spin_unlock_irqrestore(&data->lock, flags);
94 return 0;
95}
96
97static void picolcd_cir_close(struct rc_dev *dev)
98{
99 struct picolcd_data *data = dev->priv;
100 unsigned long flags;
101
102 spin_lock_irqsave(&data->lock, flags);
103 data->status |= PICOLCD_CIR_SHUN;
104 spin_unlock_irqrestore(&data->lock, flags);
105}
106
107/* initialize CIR input device */
108int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report)
109{
110 struct rc_dev *rdev;
111 int ret = 0;
112
113 rdev = rc_allocate_device();
114 if (!rdev)
115 return -ENOMEM;
116
117 rdev->priv = data;
118 rdev->driver_type = RC_DRIVER_IR_RAW;
119 rdev->allowed_protos = RC_TYPE_ALL;
120 rdev->open = picolcd_cir_open;
121 rdev->close = picolcd_cir_close;
122 rdev->input_name = data->hdev->name;
123 rdev->input_phys = data->hdev->phys;
124 rdev->input_id.bustype = data->hdev->bus;
125 rdev->input_id.vendor = data->hdev->vendor;
126 rdev->input_id.product = data->hdev->product;
127 rdev->input_id.version = data->hdev->version;
128 rdev->dev.parent = &data->hdev->dev;
129 rdev->driver_name = PICOLCD_NAME;
130 rdev->map_name = RC_MAP_RC6_MCE;
131 rdev->timeout = MS_TO_NS(100);
132 rdev->rx_resolution = US_TO_NS(1);
133
134 ret = rc_register_device(rdev);
135 if (ret)
136 goto err;
137 data->rc_dev = rdev;
138 return 0;
139
140err:
141 rc_free_device(rdev);
142 return ret;
143}
144
145void picolcd_exit_cir(struct picolcd_data *data)
146{
147 struct rc_dev *rdev = data->rc_dev;
148
149 data->rc_dev = NULL;
150 rc_unregister_device(rdev);
151}
152
diff --git a/drivers/hid/hid-picolcd_core.c b/drivers/hid/hid-picolcd_core.c
new file mode 100644
index 000000000000..86df26e58aba
--- /dev/null
+++ b/drivers/hid/hid-picolcd_core.c
@@ -0,0 +1,689 @@
1/***************************************************************************
2 * Copyright (C) 2010-2012 by Bruno Prémont <bonbons@linux-vserver.org> *
3 * *
4 * Based on Logitech G13 driver (v0.4) *
5 * Copyright (C) 2009 by Rick L. Vinyard, Jr. <rvinyard@cs.nmsu.edu> *
6 * *
7 * This program is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, version 2 of the License. *
10 * *
11 * This driver is distributed in the hope that it will be useful, but *
12 * WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14 * General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this software. If not see <http://www.gnu.org/licenses/>. *
18 ***************************************************************************/
19
20#include <linux/hid.h>
21#include <linux/hid-debug.h>
22#include <linux/input.h>
23#include "hid-ids.h"
24#include "usbhid/usbhid.h"
25#include <linux/usb.h>
26
27#include <linux/fb.h>
28#include <linux/vmalloc.h>
29
30#include <linux/completion.h>
31#include <linux/uaccess.h>
32#include <linux/module.h>
33
34#include "hid-picolcd.h"
35
36
37/* Input device
38 *
39 * The PicoLCD has an IR receiver header, a built-in keypad with 5 keys
40 * and header for 4x4 key matrix. The built-in keys are part of the matrix.
41 */
42static const unsigned short def_keymap[PICOLCD_KEYS] = {
43 KEY_RESERVED, /* none */
44 KEY_BACK, /* col 4 + row 1 */
45 KEY_HOMEPAGE, /* col 3 + row 1 */
46 KEY_RESERVED, /* col 2 + row 1 */
47 KEY_RESERVED, /* col 1 + row 1 */
48 KEY_SCROLLUP, /* col 4 + row 2 */
49 KEY_OK, /* col 3 + row 2 */
50 KEY_SCROLLDOWN, /* col 2 + row 2 */
51 KEY_RESERVED, /* col 1 + row 2 */
52 KEY_RESERVED, /* col 4 + row 3 */
53 KEY_RESERVED, /* col 3 + row 3 */
54 KEY_RESERVED, /* col 2 + row 3 */
55 KEY_RESERVED, /* col 1 + row 3 */
56 KEY_RESERVED, /* col 4 + row 4 */
57 KEY_RESERVED, /* col 3 + row 4 */
58 KEY_RESERVED, /* col 2 + row 4 */
59 KEY_RESERVED, /* col 1 + row 4 */
60};
61
62
63/* Find a given report */
64struct hid_report *picolcd_report(int id, struct hid_device *hdev, int dir)
65{
66 struct list_head *feature_report_list = &hdev->report_enum[dir].report_list;
67 struct hid_report *report = NULL;
68
69 list_for_each_entry(report, feature_report_list, list) {
70 if (report->id == id)
71 return report;
72 }
73 hid_warn(hdev, "No report with id 0x%x found\n", id);
74 return NULL;
75}
76
77/* Submit a report and wait for a reply from device - if device fades away
78 * or does not respond in time, return NULL */
79struct picolcd_pending *picolcd_send_and_wait(struct hid_device *hdev,
80 int report_id, const u8 *raw_data, int size)
81{
82 struct picolcd_data *data = hid_get_drvdata(hdev);
83 struct picolcd_pending *work;
84 struct hid_report *report = picolcd_out_report(report_id, hdev);
85 unsigned long flags;
86 int i, j, k;
87
88 if (!report || !data)
89 return NULL;
90 if (data->status & PICOLCD_FAILED)
91 return NULL;
92 work = kzalloc(sizeof(*work), GFP_KERNEL);
93 if (!work)
94 return NULL;
95
96 init_completion(&work->ready);
97 work->out_report = report;
98 work->in_report = NULL;
99 work->raw_size = 0;
100
101 mutex_lock(&data->mutex);
102 spin_lock_irqsave(&data->lock, flags);
103 for (i = k = 0; i < report->maxfield; i++)
104 for (j = 0; j < report->field[i]->report_count; j++) {
105 hid_set_field(report->field[i], j, k < size ? raw_data[k] : 0);
106 k++;
107 }
108 if (data->status & PICOLCD_FAILED) {
109 kfree(work);
110 work = NULL;
111 } else {
112 data->pending = work;
113 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
114 spin_unlock_irqrestore(&data->lock, flags);
115 wait_for_completion_interruptible_timeout(&work->ready, HZ*2);
116 spin_lock_irqsave(&data->lock, flags);
117 data->pending = NULL;
118 }
119 spin_unlock_irqrestore(&data->lock, flags);
120 mutex_unlock(&data->mutex);
121 return work;
122}
123
124/*
125 * input class device
126 */
127static int picolcd_raw_keypad(struct picolcd_data *data,
128 struct hid_report *report, u8 *raw_data, int size)
129{
130 /*
131 * Keypad event
132 * First and second data bytes list currently pressed keys,
133 * 0x00 means no key and at most 2 keys may be pressed at same time
134 */
135 int i, j;
136
137 /* determine newly pressed keys */
138 for (i = 0; i < size; i++) {
139 unsigned int key_code;
140 if (raw_data[i] == 0)
141 continue;
142 for (j = 0; j < sizeof(data->pressed_keys); j++)
143 if (data->pressed_keys[j] == raw_data[i])
144 goto key_already_down;
145 for (j = 0; j < sizeof(data->pressed_keys); j++)
146 if (data->pressed_keys[j] == 0) {
147 data->pressed_keys[j] = raw_data[i];
148 break;
149 }
150 input_event(data->input_keys, EV_MSC, MSC_SCAN, raw_data[i]);
151 if (raw_data[i] < PICOLCD_KEYS)
152 key_code = data->keycode[raw_data[i]];
153 else
154 key_code = KEY_UNKNOWN;
155 if (key_code != KEY_UNKNOWN) {
156 dbg_hid(PICOLCD_NAME " got key press for %u:%d",
157 raw_data[i], key_code);
158 input_report_key(data->input_keys, key_code, 1);
159 }
160 input_sync(data->input_keys);
161key_already_down:
162 continue;
163 }
164
165 /* determine newly released keys */
166 for (j = 0; j < sizeof(data->pressed_keys); j++) {
167 unsigned int key_code;
168 if (data->pressed_keys[j] == 0)
169 continue;
170 for (i = 0; i < size; i++)
171 if (data->pressed_keys[j] == raw_data[i])
172 goto key_still_down;
173 input_event(data->input_keys, EV_MSC, MSC_SCAN, data->pressed_keys[j]);
174 if (data->pressed_keys[j] < PICOLCD_KEYS)
175 key_code = data->keycode[data->pressed_keys[j]];
176 else
177 key_code = KEY_UNKNOWN;
178 if (key_code != KEY_UNKNOWN) {
179 dbg_hid(PICOLCD_NAME " got key release for %u:%d",
180 data->pressed_keys[j], key_code);
181 input_report_key(data->input_keys, key_code, 0);
182 }
183 input_sync(data->input_keys);
184 data->pressed_keys[j] = 0;
185key_still_down:
186 continue;
187 }
188 return 1;
189}
190
191static int picolcd_check_version(struct hid_device *hdev)
192{
193 struct picolcd_data *data = hid_get_drvdata(hdev);
194 struct picolcd_pending *verinfo;
195 int ret = 0;
196
197 if (!data)
198 return -ENODEV;
199
200 verinfo = picolcd_send_and_wait(hdev, REPORT_VERSION, NULL, 0);
201 if (!verinfo) {
202 hid_err(hdev, "no version response from PicoLCD\n");
203 return -ENODEV;
204 }
205
206 if (verinfo->raw_size == 2) {
207 data->version[0] = verinfo->raw_data[1];
208 data->version[1] = verinfo->raw_data[0];
209 if (data->status & PICOLCD_BOOTLOADER) {
210 hid_info(hdev, "PicoLCD, bootloader version %d.%d\n",
211 verinfo->raw_data[1], verinfo->raw_data[0]);
212 } else {
213 hid_info(hdev, "PicoLCD, firmware version %d.%d\n",
214 verinfo->raw_data[1], verinfo->raw_data[0]);
215 }
216 } else {
217 hid_err(hdev, "confused, got unexpected version response from PicoLCD\n");
218 ret = -EINVAL;
219 }
220 kfree(verinfo);
221 return ret;
222}
223
224/*
225 * Reset our device and wait for answer to VERSION request
226 */
227int picolcd_reset(struct hid_device *hdev)
228{
229 struct picolcd_data *data = hid_get_drvdata(hdev);
230 struct hid_report *report = picolcd_out_report(REPORT_RESET, hdev);
231 unsigned long flags;
232 int error;
233
234 if (!data || !report || report->maxfield != 1)
235 return -ENODEV;
236
237 spin_lock_irqsave(&data->lock, flags);
238 if (hdev->product == USB_DEVICE_ID_PICOLCD_BOOTLOADER)
239 data->status |= PICOLCD_BOOTLOADER;
240
241 /* perform the reset */
242 hid_set_field(report->field[0], 0, 1);
243 if (data->status & PICOLCD_FAILED) {
244 spin_unlock_irqrestore(&data->lock, flags);
245 return -ENODEV;
246 }
247 usbhid_submit_report(hdev, report, USB_DIR_OUT);
248 spin_unlock_irqrestore(&data->lock, flags);
249
250 error = picolcd_check_version(hdev);
251 if (error)
252 return error;
253
254 picolcd_resume_lcd(data);
255 picolcd_resume_backlight(data);
256 picolcd_fb_refresh(data);
257 picolcd_leds_set(data);
258 return 0;
259}
260
261/*
262 * The "operation_mode" sysfs attribute
263 */
264static ssize_t picolcd_operation_mode_show(struct device *dev,
265 struct device_attribute *attr, char *buf)
266{
267 struct picolcd_data *data = dev_get_drvdata(dev);
268
269 if (data->status & PICOLCD_BOOTLOADER)
270 return snprintf(buf, PAGE_SIZE, "[bootloader] lcd\n");
271 else
272 return snprintf(buf, PAGE_SIZE, "bootloader [lcd]\n");
273}
274
275static ssize_t picolcd_operation_mode_store(struct device *dev,
276 struct device_attribute *attr, const char *buf, size_t count)
277{
278 struct picolcd_data *data = dev_get_drvdata(dev);
279 struct hid_report *report = NULL;
280 size_t cnt = count;
281 int timeout = data->opmode_delay;
282 unsigned long flags;
283
284 if (cnt >= 3 && strncmp("lcd", buf, 3) == 0) {
285 if (data->status & PICOLCD_BOOTLOADER)
286 report = picolcd_out_report(REPORT_EXIT_FLASHER, data->hdev);
287 buf += 3;
288 cnt -= 3;
289 } else if (cnt >= 10 && strncmp("bootloader", buf, 10) == 0) {
290 if (!(data->status & PICOLCD_BOOTLOADER))
291 report = picolcd_out_report(REPORT_EXIT_KEYBOARD, data->hdev);
292 buf += 10;
293 cnt -= 10;
294 }
295 if (!report)
296 return -EINVAL;
297
298 while (cnt > 0 && (buf[cnt-1] == '\n' || buf[cnt-1] == '\r'))
299 cnt--;
300 if (cnt != 0)
301 return -EINVAL;
302
303 spin_lock_irqsave(&data->lock, flags);
304 hid_set_field(report->field[0], 0, timeout & 0xff);
305 hid_set_field(report->field[0], 1, (timeout >> 8) & 0xff);
306 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
307 spin_unlock_irqrestore(&data->lock, flags);
308 return count;
309}
310
311static DEVICE_ATTR(operation_mode, 0644, picolcd_operation_mode_show,
312 picolcd_operation_mode_store);
313
314/*
315 * The "operation_mode_delay" sysfs attribute
316 */
317static ssize_t picolcd_operation_mode_delay_show(struct device *dev,
318 struct device_attribute *attr, char *buf)
319{
320 struct picolcd_data *data = dev_get_drvdata(dev);
321
322 return snprintf(buf, PAGE_SIZE, "%hu\n", data->opmode_delay);
323}
324
325static ssize_t picolcd_operation_mode_delay_store(struct device *dev,
326 struct device_attribute *attr, const char *buf, size_t count)
327{
328 struct picolcd_data *data = dev_get_drvdata(dev);
329 unsigned u;
330 if (sscanf(buf, "%u", &u) != 1)
331 return -EINVAL;
332 if (u > 30000)
333 return -EINVAL;
334 else
335 data->opmode_delay = u;
336 return count;
337}
338
339static DEVICE_ATTR(operation_mode_delay, 0644, picolcd_operation_mode_delay_show,
340 picolcd_operation_mode_delay_store);
341
342/*
343 * Handle raw report as sent by device
344 */
345static int picolcd_raw_event(struct hid_device *hdev,
346 struct hid_report *report, u8 *raw_data, int size)
347{
348 struct picolcd_data *data = hid_get_drvdata(hdev);
349 unsigned long flags;
350 int ret = 0;
351
352 if (!data)
353 return 1;
354
355 if (report->id == REPORT_KEY_STATE) {
356 if (data->input_keys)
357 ret = picolcd_raw_keypad(data, report, raw_data+1, size-1);
358 } else if (report->id == REPORT_IR_DATA) {
359 ret = picolcd_raw_cir(data, report, raw_data+1, size-1);
360 } else {
361 spin_lock_irqsave(&data->lock, flags);
362 /*
363 * We let the caller of picolcd_send_and_wait() check if the
364 * report we got is one of the expected ones or not.
365 */
366 if (data->pending) {
367 memcpy(data->pending->raw_data, raw_data+1, size-1);
368 data->pending->raw_size = size-1;
369 data->pending->in_report = report;
370 complete(&data->pending->ready);
371 }
372 spin_unlock_irqrestore(&data->lock, flags);
373 }
374
375 picolcd_debug_raw_event(data, hdev, report, raw_data, size);
376 return 1;
377}
378
379#ifdef CONFIG_PM
380static int picolcd_suspend(struct hid_device *hdev, pm_message_t message)
381{
382 if (PMSG_IS_AUTO(message))
383 return 0;
384
385 picolcd_suspend_backlight(hid_get_drvdata(hdev));
386 dbg_hid(PICOLCD_NAME " device ready for suspend\n");
387 return 0;
388}
389
390static int picolcd_resume(struct hid_device *hdev)
391{
392 int ret;
393 ret = picolcd_resume_backlight(hid_get_drvdata(hdev));
394 if (ret)
395 dbg_hid(PICOLCD_NAME " restoring backlight failed: %d\n", ret);
396 return 0;
397}
398
399static int picolcd_reset_resume(struct hid_device *hdev)
400{
401 int ret;
402 ret = picolcd_reset(hdev);
403 if (ret)
404 dbg_hid(PICOLCD_NAME " resetting our device failed: %d\n", ret);
405 ret = picolcd_fb_reset(hid_get_drvdata(hdev), 0);
406 if (ret)
407 dbg_hid(PICOLCD_NAME " restoring framebuffer content failed: %d\n", ret);
408 ret = picolcd_resume_lcd(hid_get_drvdata(hdev));
409 if (ret)
410 dbg_hid(PICOLCD_NAME " restoring lcd failed: %d\n", ret);
411 ret = picolcd_resume_backlight(hid_get_drvdata(hdev));
412 if (ret)
413 dbg_hid(PICOLCD_NAME " restoring backlight failed: %d\n", ret);
414 picolcd_leds_set(hid_get_drvdata(hdev));
415 return 0;
416}
417#endif
418
419/* initialize keypad input device */
420static int picolcd_init_keys(struct picolcd_data *data,
421 struct hid_report *report)
422{
423 struct hid_device *hdev = data->hdev;
424 struct input_dev *idev;
425 int error, i;
426
427 if (!report)
428 return -ENODEV;
429 if (report->maxfield != 1 || report->field[0]->report_count != 2 ||
430 report->field[0]->report_size != 8) {
431 hid_err(hdev, "unsupported KEY_STATE report\n");
432 return -EINVAL;
433 }
434
435 idev = input_allocate_device();
436 if (idev == NULL) {
437 hid_err(hdev, "failed to allocate input device\n");
438 return -ENOMEM;
439 }
440 input_set_drvdata(idev, hdev);
441 memcpy(data->keycode, def_keymap, sizeof(def_keymap));
442 idev->name = hdev->name;
443 idev->phys = hdev->phys;
444 idev->uniq = hdev->uniq;
445 idev->id.bustype = hdev->bus;
446 idev->id.vendor = hdev->vendor;
447 idev->id.product = hdev->product;
448 idev->id.version = hdev->version;
449 idev->dev.parent = &hdev->dev;
450 idev->keycode = &data->keycode;
451 idev->keycodemax = PICOLCD_KEYS;
452 idev->keycodesize = sizeof(data->keycode[0]);
453 input_set_capability(idev, EV_MSC, MSC_SCAN);
454 set_bit(EV_REP, idev->evbit);
455 for (i = 0; i < PICOLCD_KEYS; i++)
456 input_set_capability(idev, EV_KEY, data->keycode[i]);
457 error = input_register_device(idev);
458 if (error) {
459 hid_err(hdev, "error registering the input device\n");
460 input_free_device(idev);
461 return error;
462 }
463 data->input_keys = idev;
464 return 0;
465}
466
467static void picolcd_exit_keys(struct picolcd_data *data)
468{
469 struct input_dev *idev = data->input_keys;
470
471 data->input_keys = NULL;
472 if (idev)
473 input_unregister_device(idev);
474}
475
476static int picolcd_probe_lcd(struct hid_device *hdev, struct picolcd_data *data)
477{
478 int error;
479
480 /* Setup keypad input device */
481 error = picolcd_init_keys(data, picolcd_in_report(REPORT_KEY_STATE, hdev));
482 if (error)
483 goto err;
484
485 /* Setup CIR input device */
486 error = picolcd_init_cir(data, picolcd_in_report(REPORT_IR_DATA, hdev));
487 if (error)
488 goto err;
489
490 /* Set up the framebuffer device */
491 error = picolcd_init_framebuffer(data);
492 if (error)
493 goto err;
494
495 /* Setup lcd class device */
496 error = picolcd_init_lcd(data, picolcd_out_report(REPORT_CONTRAST, hdev));
497 if (error)
498 goto err;
499
500 /* Setup backlight class device */
501 error = picolcd_init_backlight(data, picolcd_out_report(REPORT_BRIGHTNESS, hdev));
502 if (error)
503 goto err;
504
505 /* Setup the LED class devices */
506 error = picolcd_init_leds(data, picolcd_out_report(REPORT_LED_STATE, hdev));
507 if (error)
508 goto err;
509
510 picolcd_init_devfs(data, picolcd_out_report(REPORT_EE_READ, hdev),
511 picolcd_out_report(REPORT_EE_WRITE, hdev),
512 picolcd_out_report(REPORT_READ_MEMORY, hdev),
513 picolcd_out_report(REPORT_WRITE_MEMORY, hdev),
514 picolcd_out_report(REPORT_RESET, hdev));
515 return 0;
516err:
517 picolcd_exit_leds(data);
518 picolcd_exit_backlight(data);
519 picolcd_exit_lcd(data);
520 picolcd_exit_framebuffer(data);
521 picolcd_exit_cir(data);
522 picolcd_exit_keys(data);
523 return error;
524}
525
526static int picolcd_probe_bootloader(struct hid_device *hdev, struct picolcd_data *data)
527{
528 picolcd_init_devfs(data, NULL, NULL,
529 picolcd_out_report(REPORT_BL_READ_MEMORY, hdev),
530 picolcd_out_report(REPORT_BL_WRITE_MEMORY, hdev), NULL);
531 return 0;
532}
533
534static int picolcd_probe(struct hid_device *hdev,
535 const struct hid_device_id *id)
536{
537 struct picolcd_data *data;
538 int error = -ENOMEM;
539
540 dbg_hid(PICOLCD_NAME " hardware probe...\n");
541
542 /*
543 * Let's allocate the picolcd data structure, set some reasonable
544 * defaults, and associate it with the device
545 */
546 data = kzalloc(sizeof(struct picolcd_data), GFP_KERNEL);
547 if (data == NULL) {
548 hid_err(hdev, "can't allocate space for Minibox PicoLCD device data\n");
549 error = -ENOMEM;
550 goto err_no_cleanup;
551 }
552
553 spin_lock_init(&data->lock);
554 mutex_init(&data->mutex);
555 data->hdev = hdev;
556 data->opmode_delay = 5000;
557 if (hdev->product == USB_DEVICE_ID_PICOLCD_BOOTLOADER)
558 data->status |= PICOLCD_BOOTLOADER;
559 hid_set_drvdata(hdev, data);
560
561 /* Parse the device reports and start it up */
562 error = hid_parse(hdev);
563 if (error) {
564 hid_err(hdev, "device report parse failed\n");
565 goto err_cleanup_data;
566 }
567
568 error = hid_hw_start(hdev, 0);
569 if (error) {
570 hid_err(hdev, "hardware start failed\n");
571 goto err_cleanup_data;
572 }
573
574 error = hid_hw_open(hdev);
575 if (error) {
576 hid_err(hdev, "failed to open input interrupt pipe for key and IR events\n");
577 goto err_cleanup_hid_hw;
578 }
579
580 error = device_create_file(&hdev->dev, &dev_attr_operation_mode_delay);
581 if (error) {
582 hid_err(hdev, "failed to create sysfs attributes\n");
583 goto err_cleanup_hid_ll;
584 }
585
586 error = device_create_file(&hdev->dev, &dev_attr_operation_mode);
587 if (error) {
588 hid_err(hdev, "failed to create sysfs attributes\n");
589 goto err_cleanup_sysfs1;
590 }
591
592 if (data->status & PICOLCD_BOOTLOADER)
593 error = picolcd_probe_bootloader(hdev, data);
594 else
595 error = picolcd_probe_lcd(hdev, data);
596 if (error)
597 goto err_cleanup_sysfs2;
598
599 dbg_hid(PICOLCD_NAME " activated and initialized\n");
600 return 0;
601
602err_cleanup_sysfs2:
603 device_remove_file(&hdev->dev, &dev_attr_operation_mode);
604err_cleanup_sysfs1:
605 device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay);
606err_cleanup_hid_ll:
607 hid_hw_close(hdev);
608err_cleanup_hid_hw:
609 hid_hw_stop(hdev);
610err_cleanup_data:
611 kfree(data);
612err_no_cleanup:
613 hid_set_drvdata(hdev, NULL);
614
615 return error;
616}
617
618static void picolcd_remove(struct hid_device *hdev)
619{
620 struct picolcd_data *data = hid_get_drvdata(hdev);
621 unsigned long flags;
622
623 dbg_hid(PICOLCD_NAME " hardware remove...\n");
624 spin_lock_irqsave(&data->lock, flags);
625 data->status |= PICOLCD_FAILED;
626 spin_unlock_irqrestore(&data->lock, flags);
627
628 picolcd_exit_devfs(data);
629 device_remove_file(&hdev->dev, &dev_attr_operation_mode);
630 device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay);
631 hid_hw_close(hdev);
632 hid_hw_stop(hdev);
633
634 /* Shortcut potential pending reply that will never arrive */
635 spin_lock_irqsave(&data->lock, flags);
636 if (data->pending)
637 complete(&data->pending->ready);
638 spin_unlock_irqrestore(&data->lock, flags);
639
640 /* Cleanup LED */
641 picolcd_exit_leds(data);
642 /* Clean up the framebuffer */
643 picolcd_exit_backlight(data);
644 picolcd_exit_lcd(data);
645 picolcd_exit_framebuffer(data);
646 /* Cleanup input */
647 picolcd_exit_cir(data);
648 picolcd_exit_keys(data);
649
650 hid_set_drvdata(hdev, NULL);
651 mutex_destroy(&data->mutex);
652 /* Finally, clean up the picolcd data itself */
653 kfree(data);
654}
655
656static const struct hid_device_id picolcd_devices[] = {
657 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) },
658 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) },
659 { }
660};
661MODULE_DEVICE_TABLE(hid, picolcd_devices);
662
663static struct hid_driver picolcd_driver = {
664 .name = "hid-picolcd",
665 .id_table = picolcd_devices,
666 .probe = picolcd_probe,
667 .remove = picolcd_remove,
668 .raw_event = picolcd_raw_event,
669#ifdef CONFIG_PM
670 .suspend = picolcd_suspend,
671 .resume = picolcd_resume,
672 .reset_resume = picolcd_reset_resume,
673#endif
674};
675
676static int __init picolcd_init(void)
677{
678 return hid_register_driver(&picolcd_driver);
679}
680
681static void __exit picolcd_exit(void)
682{
683 hid_unregister_driver(&picolcd_driver);
684}
685
686module_init(picolcd_init);
687module_exit(picolcd_exit);
688MODULE_DESCRIPTION("Minibox graphics PicoLCD Driver");
689MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-picolcd_debugfs.c b/drivers/hid/hid-picolcd_debugfs.c
new file mode 100644
index 000000000000..4809aa1bdb9c
--- /dev/null
+++ b/drivers/hid/hid-picolcd_debugfs.c
@@ -0,0 +1,899 @@
1/***************************************************************************
2 * Copyright (C) 2010-2012 by Bruno Prémont <bonbons@linux-vserver.org> *
3 * *
4 * Based on Logitech G13 driver (v0.4) *
5 * Copyright (C) 2009 by Rick L. Vinyard, Jr. <rvinyard@cs.nmsu.edu> *
6 * *
7 * This program is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, version 2 of the License. *
10 * *
11 * This driver is distributed in the hope that it will be useful, but *
12 * WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14 * General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this software. If not see <http://www.gnu.org/licenses/>. *
18 ***************************************************************************/
19
20#include <linux/hid.h>
21#include <linux/hid-debug.h>
22#include "usbhid/usbhid.h"
23#include <linux/usb.h>
24
25#include <linux/fb.h>
26#include <linux/seq_file.h>
27#include <linux/debugfs.h>
28
29#include <linux/module.h>
30#include <linux/uaccess.h>
31
32#include "hid-picolcd.h"
33
34
35static int picolcd_debug_reset_show(struct seq_file *f, void *p)
36{
37 if (picolcd_fbinfo((struct picolcd_data *)f->private))
38 seq_printf(f, "all fb\n");
39 else
40 seq_printf(f, "all\n");
41 return 0;
42}
43
44static int picolcd_debug_reset_open(struct inode *inode, struct file *f)
45{
46 return single_open(f, picolcd_debug_reset_show, inode->i_private);
47}
48
49static ssize_t picolcd_debug_reset_write(struct file *f, const char __user *user_buf,
50 size_t count, loff_t *ppos)
51{
52 struct picolcd_data *data = ((struct seq_file *)f->private_data)->private;
53 char buf[32];
54 size_t cnt = min(count, sizeof(buf)-1);
55 if (copy_from_user(buf, user_buf, cnt))
56 return -EFAULT;
57
58 while (cnt > 0 && (buf[cnt-1] == ' ' || buf[cnt-1] == '\n'))
59 cnt--;
60 buf[cnt] = '\0';
61 if (strcmp(buf, "all") == 0) {
62 picolcd_reset(data->hdev);
63 picolcd_fb_reset(data, 1);
64 } else if (strcmp(buf, "fb") == 0) {
65 picolcd_fb_reset(data, 1);
66 } else {
67 return -EINVAL;
68 }
69 return count;
70}
71
72static const struct file_operations picolcd_debug_reset_fops = {
73 .owner = THIS_MODULE,
74 .open = picolcd_debug_reset_open,
75 .read = seq_read,
76 .llseek = seq_lseek,
77 .write = picolcd_debug_reset_write,
78 .release = single_release,
79};
80
81/*
82 * The "eeprom" file
83 */
84static ssize_t picolcd_debug_eeprom_read(struct file *f, char __user *u,
85 size_t s, loff_t *off)
86{
87 struct picolcd_data *data = f->private_data;
88 struct picolcd_pending *resp;
89 u8 raw_data[3];
90 ssize_t ret = -EIO;
91
92 if (s == 0)
93 return -EINVAL;
94 if (*off > 0x0ff)
95 return 0;
96
97 /* prepare buffer with info about what we want to read (addr & len) */
98 raw_data[0] = *off & 0xff;
99 raw_data[1] = (*off >> 8) & 0xff;
100 raw_data[2] = s < 20 ? s : 20;
101 if (*off + raw_data[2] > 0xff)
102 raw_data[2] = 0x100 - *off;
103 resp = picolcd_send_and_wait(data->hdev, REPORT_EE_READ, raw_data,
104 sizeof(raw_data));
105 if (!resp)
106 return -EIO;
107
108 if (resp->in_report && resp->in_report->id == REPORT_EE_DATA) {
109 /* successful read :) */
110 ret = resp->raw_data[2];
111 if (ret > s)
112 ret = s;
113 if (copy_to_user(u, resp->raw_data+3, ret))
114 ret = -EFAULT;
115 else
116 *off += ret;
117 } /* anything else is some kind of IO error */
118
119 kfree(resp);
120 return ret;
121}
122
123static ssize_t picolcd_debug_eeprom_write(struct file *f, const char __user *u,
124 size_t s, loff_t *off)
125{
126 struct picolcd_data *data = f->private_data;
127 struct picolcd_pending *resp;
128 ssize_t ret = -EIO;
129 u8 raw_data[23];
130
131 if (s == 0)
132 return -EINVAL;
133 if (*off > 0x0ff)
134 return -ENOSPC;
135
136 memset(raw_data, 0, sizeof(raw_data));
137 raw_data[0] = *off & 0xff;
138 raw_data[1] = (*off >> 8) & 0xff;
139 raw_data[2] = min_t(size_t, 20, s);
140 if (*off + raw_data[2] > 0xff)
141 raw_data[2] = 0x100 - *off;
142
143 if (copy_from_user(raw_data+3, u, min((u8)20, raw_data[2])))
144 return -EFAULT;
145 resp = picolcd_send_and_wait(data->hdev, REPORT_EE_WRITE, raw_data,
146 sizeof(raw_data));
147
148 if (!resp)
149 return -EIO;
150
151 if (resp->in_report && resp->in_report->id == REPORT_EE_DATA) {
152 /* check if written data matches */
153 if (memcmp(raw_data, resp->raw_data, 3+raw_data[2]) == 0) {
154 *off += raw_data[2];
155 ret = raw_data[2];
156 }
157 }
158 kfree(resp);
159 return ret;
160}
161
162/*
163 * Notes:
164 * - read/write happens in chunks of at most 20 bytes, it's up to userspace
165 * to loop in order to get more data.
166 * - on write errors on otherwise correct write request the bytes
167 * that should have been written are in undefined state.
168 */
169static const struct file_operations picolcd_debug_eeprom_fops = {
170 .owner = THIS_MODULE,
171 .open = simple_open,
172 .read = picolcd_debug_eeprom_read,
173 .write = picolcd_debug_eeprom_write,
174 .llseek = generic_file_llseek,
175};
176
177/*
178 * The "flash" file
179 */
180/* record a flash address to buf (bounds check to be done by caller) */
181static int _picolcd_flash_setaddr(struct picolcd_data *data, u8 *buf, long off)
182{
183 buf[0] = off & 0xff;
184 buf[1] = (off >> 8) & 0xff;
185 if (data->addr_sz == 3)
186 buf[2] = (off >> 16) & 0xff;
187 return data->addr_sz == 2 ? 2 : 3;
188}
189
190/* read a given size of data (bounds check to be done by caller) */
191static ssize_t _picolcd_flash_read(struct picolcd_data *data, int report_id,
192 char __user *u, size_t s, loff_t *off)
193{
194 struct picolcd_pending *resp;
195 u8 raw_data[4];
196 ssize_t ret = 0;
197 int len_off, err = -EIO;
198
199 while (s > 0) {
200 err = -EIO;
201 len_off = _picolcd_flash_setaddr(data, raw_data, *off);
202 raw_data[len_off] = s > 32 ? 32 : s;
203 resp = picolcd_send_and_wait(data->hdev, report_id, raw_data, len_off+1);
204 if (!resp || !resp->in_report)
205 goto skip;
206 if (resp->in_report->id == REPORT_MEMORY ||
207 resp->in_report->id == REPORT_BL_READ_MEMORY) {
208 if (memcmp(raw_data, resp->raw_data, len_off+1) != 0)
209 goto skip;
210 if (copy_to_user(u+ret, resp->raw_data+len_off+1, raw_data[len_off])) {
211 err = -EFAULT;
212 goto skip;
213 }
214 *off += raw_data[len_off];
215 s -= raw_data[len_off];
216 ret += raw_data[len_off];
217 err = 0;
218 }
219skip:
220 kfree(resp);
221 if (err)
222 return ret > 0 ? ret : err;
223 }
224 return ret;
225}
226
227static ssize_t picolcd_debug_flash_read(struct file *f, char __user *u,
228 size_t s, loff_t *off)
229{
230 struct picolcd_data *data = f->private_data;
231
232 if (s == 0)
233 return -EINVAL;
234 if (*off > 0x05fff)
235 return 0;
236 if (*off + s > 0x05fff)
237 s = 0x06000 - *off;
238
239 if (data->status & PICOLCD_BOOTLOADER)
240 return _picolcd_flash_read(data, REPORT_BL_READ_MEMORY, u, s, off);
241 else
242 return _picolcd_flash_read(data, REPORT_READ_MEMORY, u, s, off);
243}
244
245/* erase block aligned to 64bytes boundary */
246static ssize_t _picolcd_flash_erase64(struct picolcd_data *data, int report_id,
247 loff_t *off)
248{
249 struct picolcd_pending *resp;
250 u8 raw_data[3];
251 int len_off;
252 ssize_t ret = -EIO;
253
254 if (*off & 0x3f)
255 return -EINVAL;
256
257 len_off = _picolcd_flash_setaddr(data, raw_data, *off);
258 resp = picolcd_send_and_wait(data->hdev, report_id, raw_data, len_off);
259 if (!resp || !resp->in_report)
260 goto skip;
261 if (resp->in_report->id == REPORT_MEMORY ||
262 resp->in_report->id == REPORT_BL_ERASE_MEMORY) {
263 if (memcmp(raw_data, resp->raw_data, len_off) != 0)
264 goto skip;
265 ret = 0;
266 }
267skip:
268 kfree(resp);
269 return ret;
270}
271
272/* write a given size of data (bounds check to be done by caller) */
273static ssize_t _picolcd_flash_write(struct picolcd_data *data, int report_id,
274 const char __user *u, size_t s, loff_t *off)
275{
276 struct picolcd_pending *resp;
277 u8 raw_data[36];
278 ssize_t ret = 0;
279 int len_off, err = -EIO;
280
281 while (s > 0) {
282 err = -EIO;
283 len_off = _picolcd_flash_setaddr(data, raw_data, *off);
284 raw_data[len_off] = s > 32 ? 32 : s;
285 if (copy_from_user(raw_data+len_off+1, u, raw_data[len_off])) {
286 err = -EFAULT;
287 break;
288 }
289 resp = picolcd_send_and_wait(data->hdev, report_id, raw_data,
290 len_off+1+raw_data[len_off]);
291 if (!resp || !resp->in_report)
292 goto skip;
293 if (resp->in_report->id == REPORT_MEMORY ||
294 resp->in_report->id == REPORT_BL_WRITE_MEMORY) {
295 if (memcmp(raw_data, resp->raw_data, len_off+1+raw_data[len_off]) != 0)
296 goto skip;
297 *off += raw_data[len_off];
298 s -= raw_data[len_off];
299 ret += raw_data[len_off];
300 err = 0;
301 }
302skip:
303 kfree(resp);
304 if (err)
305 break;
306 }
307 return ret > 0 ? ret : err;
308}
309
310static ssize_t picolcd_debug_flash_write(struct file *f, const char __user *u,
311 size_t s, loff_t *off)
312{
313 struct picolcd_data *data = f->private_data;
314 ssize_t err, ret = 0;
315 int report_erase, report_write;
316
317 if (s == 0)
318 return -EINVAL;
319 if (*off > 0x5fff)
320 return -ENOSPC;
321 if (s & 0x3f)
322 return -EINVAL;
323 if (*off & 0x3f)
324 return -EINVAL;
325
326 if (data->status & PICOLCD_BOOTLOADER) {
327 report_erase = REPORT_BL_ERASE_MEMORY;
328 report_write = REPORT_BL_WRITE_MEMORY;
329 } else {
330 report_erase = REPORT_ERASE_MEMORY;
331 report_write = REPORT_WRITE_MEMORY;
332 }
333 mutex_lock(&data->mutex_flash);
334 while (s > 0) {
335 err = _picolcd_flash_erase64(data, report_erase, off);
336 if (err)
337 break;
338 err = _picolcd_flash_write(data, report_write, u, 64, off);
339 if (err < 0)
340 break;
341 ret += err;
342 *off += err;
343 s -= err;
344 if (err != 64)
345 break;
346 }
347 mutex_unlock(&data->mutex_flash);
348 return ret > 0 ? ret : err;
349}
350
351/*
352 * Notes:
353 * - concurrent writing is prevented by mutex and all writes must be
354 * n*64 bytes and 64-byte aligned, each write being preceded by an
355 * ERASE which erases a 64byte block.
356 * If less than requested was written or an error is returned for an
357 * otherwise correct write request the next 64-byte block which should
358 * have been written is in undefined state (mostly: original, erased,
359 * (half-)written with write error)
360 * - reading can happen without special restriction
361 */
362static const struct file_operations picolcd_debug_flash_fops = {
363 .owner = THIS_MODULE,
364 .open = simple_open,
365 .read = picolcd_debug_flash_read,
366 .write = picolcd_debug_flash_write,
367 .llseek = generic_file_llseek,
368};
369
370
371/*
372 * Helper code for HID report level dumping/debugging
373 */
374static const char * const error_codes[] = {
375 "success", "parameter missing", "data_missing", "block readonly",
376 "block not erasable", "block too big", "section overflow",
377 "invalid command length", "invalid data length",
378};
379
380static void dump_buff_as_hex(char *dst, size_t dst_sz, const u8 *data,
381 const size_t data_len)
382{
383 int i, j;
384 for (i = j = 0; i < data_len && j + 4 < dst_sz; i++) {
385 dst[j++] = hex_asc[(data[i] >> 4) & 0x0f];
386 dst[j++] = hex_asc[data[i] & 0x0f];
387 dst[j++] = ' ';
388 }
389 dst[j] = '\0';
390 if (j > 0)
391 dst[j-1] = '\n';
392 if (i < data_len && j > 2)
393 dst[j-2] = dst[j-3] = '.';
394}
395
396void picolcd_debug_out_report(struct picolcd_data *data,
397 struct hid_device *hdev, struct hid_report *report)
398{
399 u8 raw_data[70];
400 int raw_size = (report->size >> 3) + 1;
401 char *buff;
402#define BUFF_SZ 256
403
404 /* Avoid unnecessary overhead if debugfs is disabled */
405 if (list_empty(&hdev->debug_list))
406 return;
407
408 buff = kmalloc(BUFF_SZ, GFP_ATOMIC);
409 if (!buff)
410 return;
411
412 snprintf(buff, BUFF_SZ, "\nout report %d (size %d) = ",
413 report->id, raw_size);
414 hid_debug_event(hdev, buff);
415 if (raw_size + 5 > sizeof(raw_data)) {
416 kfree(buff);
417 hid_debug_event(hdev, " TOO BIG\n");
418 return;
419 } else {
420 raw_data[0] = report->id;
421 hid_output_report(report, raw_data);
422 dump_buff_as_hex(buff, BUFF_SZ, raw_data, raw_size);
423 hid_debug_event(hdev, buff);
424 }
425
426 switch (report->id) {
427 case REPORT_LED_STATE:
428 /* 1 data byte with GPO state */
429 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
430 "REPORT_LED_STATE", report->id, raw_size-1);
431 hid_debug_event(hdev, buff);
432 snprintf(buff, BUFF_SZ, "\tGPO state: 0x%02x\n", raw_data[1]);
433 hid_debug_event(hdev, buff);
434 break;
435 case REPORT_BRIGHTNESS:
436 /* 1 data byte with brightness */
437 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
438 "REPORT_BRIGHTNESS", report->id, raw_size-1);
439 hid_debug_event(hdev, buff);
440 snprintf(buff, BUFF_SZ, "\tBrightness: 0x%02x\n", raw_data[1]);
441 hid_debug_event(hdev, buff);
442 break;
443 case REPORT_CONTRAST:
444 /* 1 data byte with contrast */
445 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
446 "REPORT_CONTRAST", report->id, raw_size-1);
447 hid_debug_event(hdev, buff);
448 snprintf(buff, BUFF_SZ, "\tContrast: 0x%02x\n", raw_data[1]);
449 hid_debug_event(hdev, buff);
450 break;
451 case REPORT_RESET:
452 /* 2 data bytes with reset duration in ms */
453 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
454 "REPORT_RESET", report->id, raw_size-1);
455 hid_debug_event(hdev, buff);
456 snprintf(buff, BUFF_SZ, "\tDuration: 0x%02x%02x (%dms)\n",
457 raw_data[2], raw_data[1], raw_data[2] << 8 | raw_data[1]);
458 hid_debug_event(hdev, buff);
459 break;
460 case REPORT_LCD_CMD:
461 /* 63 data bytes with LCD commands */
462 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
463 "REPORT_LCD_CMD", report->id, raw_size-1);
464 hid_debug_event(hdev, buff);
465 /* TODO: format decoding */
466 break;
467 case REPORT_LCD_DATA:
468 /* 63 data bytes with LCD data */
469 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
470 "REPORT_LCD_CMD", report->id, raw_size-1);
471 /* TODO: format decoding */
472 hid_debug_event(hdev, buff);
473 break;
474 case REPORT_LCD_CMD_DATA:
475 /* 63 data bytes with LCD commands and data */
476 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
477 "REPORT_LCD_CMD", report->id, raw_size-1);
478 /* TODO: format decoding */
479 hid_debug_event(hdev, buff);
480 break;
481 case REPORT_EE_READ:
482 /* 3 data bytes with read area description */
483 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
484 "REPORT_EE_READ", report->id, raw_size-1);
485 hid_debug_event(hdev, buff);
486 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
487 raw_data[2], raw_data[1]);
488 hid_debug_event(hdev, buff);
489 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
490 hid_debug_event(hdev, buff);
491 break;
492 case REPORT_EE_WRITE:
493 /* 3+1..20 data bytes with write area description */
494 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
495 "REPORT_EE_WRITE", report->id, raw_size-1);
496 hid_debug_event(hdev, buff);
497 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
498 raw_data[2], raw_data[1]);
499 hid_debug_event(hdev, buff);
500 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
501 hid_debug_event(hdev, buff);
502 if (raw_data[3] == 0) {
503 snprintf(buff, BUFF_SZ, "\tNo data\n");
504 } else if (raw_data[3] + 4 <= raw_size) {
505 snprintf(buff, BUFF_SZ, "\tData: ");
506 hid_debug_event(hdev, buff);
507 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
508 } else {
509 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
510 }
511 hid_debug_event(hdev, buff);
512 break;
513 case REPORT_ERASE_MEMORY:
514 case REPORT_BL_ERASE_MEMORY:
515 /* 3 data bytes with pointer inside erase block */
516 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
517 "REPORT_ERASE_MEMORY", report->id, raw_size-1);
518 hid_debug_event(hdev, buff);
519 switch (data->addr_sz) {
520 case 2:
521 snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x\n",
522 raw_data[2], raw_data[1]);
523 break;
524 case 3:
525 snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x%02x\n",
526 raw_data[3], raw_data[2], raw_data[1]);
527 break;
528 default:
529 snprintf(buff, BUFF_SZ, "\tNot supported\n");
530 }
531 hid_debug_event(hdev, buff);
532 break;
533 case REPORT_READ_MEMORY:
534 case REPORT_BL_READ_MEMORY:
535 /* 4 data bytes with read area description */
536 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
537 "REPORT_READ_MEMORY", report->id, raw_size-1);
538 hid_debug_event(hdev, buff);
539 switch (data->addr_sz) {
540 case 2:
541 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
542 raw_data[2], raw_data[1]);
543 hid_debug_event(hdev, buff);
544 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
545 break;
546 case 3:
547 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
548 raw_data[3], raw_data[2], raw_data[1]);
549 hid_debug_event(hdev, buff);
550 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
551 break;
552 default:
553 snprintf(buff, BUFF_SZ, "\tNot supported\n");
554 }
555 hid_debug_event(hdev, buff);
556 break;
557 case REPORT_WRITE_MEMORY:
558 case REPORT_BL_WRITE_MEMORY:
559 /* 4+1..32 data bytes with write adrea description */
560 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
561 "REPORT_WRITE_MEMORY", report->id, raw_size-1);
562 hid_debug_event(hdev, buff);
563 switch (data->addr_sz) {
564 case 2:
565 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
566 raw_data[2], raw_data[1]);
567 hid_debug_event(hdev, buff);
568 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
569 hid_debug_event(hdev, buff);
570 if (raw_data[3] == 0) {
571 snprintf(buff, BUFF_SZ, "\tNo data\n");
572 } else if (raw_data[3] + 4 <= raw_size) {
573 snprintf(buff, BUFF_SZ, "\tData: ");
574 hid_debug_event(hdev, buff);
575 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
576 } else {
577 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
578 }
579 break;
580 case 3:
581 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
582 raw_data[3], raw_data[2], raw_data[1]);
583 hid_debug_event(hdev, buff);
584 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
585 hid_debug_event(hdev, buff);
586 if (raw_data[4] == 0) {
587 snprintf(buff, BUFF_SZ, "\tNo data\n");
588 } else if (raw_data[4] + 5 <= raw_size) {
589 snprintf(buff, BUFF_SZ, "\tData: ");
590 hid_debug_event(hdev, buff);
591 dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]);
592 } else {
593 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
594 }
595 break;
596 default:
597 snprintf(buff, BUFF_SZ, "\tNot supported\n");
598 }
599 hid_debug_event(hdev, buff);
600 break;
601 case REPORT_SPLASH_RESTART:
602 /* TODO */
603 break;
604 case REPORT_EXIT_KEYBOARD:
605 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
606 "REPORT_EXIT_KEYBOARD", report->id, raw_size-1);
607 hid_debug_event(hdev, buff);
608 snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n",
609 raw_data[1] | (raw_data[2] << 8),
610 raw_data[2], raw_data[1]);
611 hid_debug_event(hdev, buff);
612 break;
613 case REPORT_VERSION:
614 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
615 "REPORT_VERSION", report->id, raw_size-1);
616 hid_debug_event(hdev, buff);
617 break;
618 case REPORT_DEVID:
619 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
620 "REPORT_DEVID", report->id, raw_size-1);
621 hid_debug_event(hdev, buff);
622 break;
623 case REPORT_SPLASH_SIZE:
624 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
625 "REPORT_SPLASH_SIZE", report->id, raw_size-1);
626 hid_debug_event(hdev, buff);
627 break;
628 case REPORT_HOOK_VERSION:
629 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
630 "REPORT_HOOK_VERSION", report->id, raw_size-1);
631 hid_debug_event(hdev, buff);
632 break;
633 case REPORT_EXIT_FLASHER:
634 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
635 "REPORT_VERSION", report->id, raw_size-1);
636 hid_debug_event(hdev, buff);
637 snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n",
638 raw_data[1] | (raw_data[2] << 8),
639 raw_data[2], raw_data[1]);
640 hid_debug_event(hdev, buff);
641 break;
642 default:
643 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
644 "<unknown>", report->id, raw_size-1);
645 hid_debug_event(hdev, buff);
646 break;
647 }
648 wake_up_interruptible(&hdev->debug_wait);
649 kfree(buff);
650}
651
652void picolcd_debug_raw_event(struct picolcd_data *data,
653 struct hid_device *hdev, struct hid_report *report,
654 u8 *raw_data, int size)
655{
656 char *buff;
657
658#define BUFF_SZ 256
659 /* Avoid unnecessary overhead if debugfs is disabled */
660 if (list_empty(&hdev->debug_list))
661 return;
662
663 buff = kmalloc(BUFF_SZ, GFP_ATOMIC);
664 if (!buff)
665 return;
666
667 switch (report->id) {
668 case REPORT_ERROR_CODE:
669 /* 2 data bytes with affected report and error code */
670 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
671 "REPORT_ERROR_CODE", report->id, size-1);
672 hid_debug_event(hdev, buff);
673 if (raw_data[2] < ARRAY_SIZE(error_codes))
674 snprintf(buff, BUFF_SZ, "\tError code 0x%02x (%s) in reply to report 0x%02x\n",
675 raw_data[2], error_codes[raw_data[2]], raw_data[1]);
676 else
677 snprintf(buff, BUFF_SZ, "\tError code 0x%02x in reply to report 0x%02x\n",
678 raw_data[2], raw_data[1]);
679 hid_debug_event(hdev, buff);
680 break;
681 case REPORT_KEY_STATE:
682 /* 2 data bytes with key state */
683 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
684 "REPORT_KEY_STATE", report->id, size-1);
685 hid_debug_event(hdev, buff);
686 if (raw_data[1] == 0)
687 snprintf(buff, BUFF_SZ, "\tNo key pressed\n");
688 else if (raw_data[2] == 0)
689 snprintf(buff, BUFF_SZ, "\tOne key pressed: 0x%02x (%d)\n",
690 raw_data[1], raw_data[1]);
691 else
692 snprintf(buff, BUFF_SZ, "\tTwo keys pressed: 0x%02x (%d), 0x%02x (%d)\n",
693 raw_data[1], raw_data[1], raw_data[2], raw_data[2]);
694 hid_debug_event(hdev, buff);
695 break;
696 case REPORT_IR_DATA:
697 /* Up to 20 byes of IR scancode data */
698 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
699 "REPORT_IR_DATA", report->id, size-1);
700 hid_debug_event(hdev, buff);
701 if (raw_data[1] == 0) {
702 snprintf(buff, BUFF_SZ, "\tUnexpectedly 0 data length\n");
703 hid_debug_event(hdev, buff);
704 } else if (raw_data[1] + 1 <= size) {
705 snprintf(buff, BUFF_SZ, "\tData length: %d\n\tIR Data: ",
706 raw_data[1]);
707 hid_debug_event(hdev, buff);
708 dump_buff_as_hex(buff, BUFF_SZ, raw_data+2, raw_data[1]);
709 hid_debug_event(hdev, buff);
710 } else {
711 snprintf(buff, BUFF_SZ, "\tOverflowing data length: %d\n",
712 raw_data[1]-1);
713 hid_debug_event(hdev, buff);
714 }
715 break;
716 case REPORT_EE_DATA:
717 /* Data buffer in response to REPORT_EE_READ or REPORT_EE_WRITE */
718 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
719 "REPORT_EE_DATA", report->id, size-1);
720 hid_debug_event(hdev, buff);
721 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
722 raw_data[2], raw_data[1]);
723 hid_debug_event(hdev, buff);
724 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
725 hid_debug_event(hdev, buff);
726 if (raw_data[3] == 0) {
727 snprintf(buff, BUFF_SZ, "\tNo data\n");
728 hid_debug_event(hdev, buff);
729 } else if (raw_data[3] + 4 <= size) {
730 snprintf(buff, BUFF_SZ, "\tData: ");
731 hid_debug_event(hdev, buff);
732 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
733 hid_debug_event(hdev, buff);
734 } else {
735 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
736 hid_debug_event(hdev, buff);
737 }
738 break;
739 case REPORT_MEMORY:
740 /* Data buffer in response to REPORT_READ_MEMORY or REPORT_WRTIE_MEMORY */
741 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
742 "REPORT_MEMORY", report->id, size-1);
743 hid_debug_event(hdev, buff);
744 switch (data->addr_sz) {
745 case 2:
746 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
747 raw_data[2], raw_data[1]);
748 hid_debug_event(hdev, buff);
749 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
750 hid_debug_event(hdev, buff);
751 if (raw_data[3] == 0) {
752 snprintf(buff, BUFF_SZ, "\tNo data\n");
753 } else if (raw_data[3] + 4 <= size) {
754 snprintf(buff, BUFF_SZ, "\tData: ");
755 hid_debug_event(hdev, buff);
756 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
757 } else {
758 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
759 }
760 break;
761 case 3:
762 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
763 raw_data[3], raw_data[2], raw_data[1]);
764 hid_debug_event(hdev, buff);
765 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
766 hid_debug_event(hdev, buff);
767 if (raw_data[4] == 0) {
768 snprintf(buff, BUFF_SZ, "\tNo data\n");
769 } else if (raw_data[4] + 5 <= size) {
770 snprintf(buff, BUFF_SZ, "\tData: ");
771 hid_debug_event(hdev, buff);
772 dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]);
773 } else {
774 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
775 }
776 break;
777 default:
778 snprintf(buff, BUFF_SZ, "\tNot supported\n");
779 }
780 hid_debug_event(hdev, buff);
781 break;
782 case REPORT_VERSION:
783 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
784 "REPORT_VERSION", report->id, size-1);
785 hid_debug_event(hdev, buff);
786 snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n",
787 raw_data[2], raw_data[1]);
788 hid_debug_event(hdev, buff);
789 break;
790 case REPORT_BL_ERASE_MEMORY:
791 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
792 "REPORT_BL_ERASE_MEMORY", report->id, size-1);
793 hid_debug_event(hdev, buff);
794 /* TODO */
795 break;
796 case REPORT_BL_READ_MEMORY:
797 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
798 "REPORT_BL_READ_MEMORY", report->id, size-1);
799 hid_debug_event(hdev, buff);
800 /* TODO */
801 break;
802 case REPORT_BL_WRITE_MEMORY:
803 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
804 "REPORT_BL_WRITE_MEMORY", report->id, size-1);
805 hid_debug_event(hdev, buff);
806 /* TODO */
807 break;
808 case REPORT_DEVID:
809 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
810 "REPORT_DEVID", report->id, size-1);
811 hid_debug_event(hdev, buff);
812 snprintf(buff, BUFF_SZ, "\tSerial: 0x%02x%02x%02x%02x\n",
813 raw_data[1], raw_data[2], raw_data[3], raw_data[4]);
814 hid_debug_event(hdev, buff);
815 snprintf(buff, BUFF_SZ, "\tType: 0x%02x\n",
816 raw_data[5]);
817 hid_debug_event(hdev, buff);
818 break;
819 case REPORT_SPLASH_SIZE:
820 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
821 "REPORT_SPLASH_SIZE", report->id, size-1);
822 hid_debug_event(hdev, buff);
823 snprintf(buff, BUFF_SZ, "\tTotal splash space: %d\n",
824 (raw_data[2] << 8) | raw_data[1]);
825 hid_debug_event(hdev, buff);
826 snprintf(buff, BUFF_SZ, "\tUsed splash space: %d\n",
827 (raw_data[4] << 8) | raw_data[3]);
828 hid_debug_event(hdev, buff);
829 break;
830 case REPORT_HOOK_VERSION:
831 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
832 "REPORT_HOOK_VERSION", report->id, size-1);
833 hid_debug_event(hdev, buff);
834 snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n",
835 raw_data[1], raw_data[2]);
836 hid_debug_event(hdev, buff);
837 break;
838 default:
839 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
840 "<unknown>", report->id, size-1);
841 hid_debug_event(hdev, buff);
842 break;
843 }
844 wake_up_interruptible(&hdev->debug_wait);
845 kfree(buff);
846}
847
848void picolcd_init_devfs(struct picolcd_data *data,
849 struct hid_report *eeprom_r, struct hid_report *eeprom_w,
850 struct hid_report *flash_r, struct hid_report *flash_w,
851 struct hid_report *reset)
852{
853 struct hid_device *hdev = data->hdev;
854
855 mutex_init(&data->mutex_flash);
856
857 /* reset */
858 if (reset)
859 data->debug_reset = debugfs_create_file("reset", 0600,
860 hdev->debug_dir, data, &picolcd_debug_reset_fops);
861
862 /* eeprom */
863 if (eeprom_r || eeprom_w)
864 data->debug_eeprom = debugfs_create_file("eeprom",
865 (eeprom_w ? S_IWUSR : 0) | (eeprom_r ? S_IRUSR : 0),
866 hdev->debug_dir, data, &picolcd_debug_eeprom_fops);
867
868 /* flash */
869 if (flash_r && flash_r->maxfield == 1 && flash_r->field[0]->report_size == 8)
870 data->addr_sz = flash_r->field[0]->report_count - 1;
871 else
872 data->addr_sz = -1;
873 if (data->addr_sz == 2 || data->addr_sz == 3) {
874 data->debug_flash = debugfs_create_file("flash",
875 (flash_w ? S_IWUSR : 0) | (flash_r ? S_IRUSR : 0),
876 hdev->debug_dir, data, &picolcd_debug_flash_fops);
877 } else if (flash_r || flash_w)
878 hid_warn(hdev, "Unexpected FLASH access reports, please submit rdesc for review\n");
879}
880
881void picolcd_exit_devfs(struct picolcd_data *data)
882{
883 struct dentry *dent;
884
885 dent = data->debug_reset;
886 data->debug_reset = NULL;
887 if (dent)
888 debugfs_remove(dent);
889 dent = data->debug_eeprom;
890 data->debug_eeprom = NULL;
891 if (dent)
892 debugfs_remove(dent);
893 dent = data->debug_flash;
894 data->debug_flash = NULL;
895 if (dent)
896 debugfs_remove(dent);
897 mutex_destroy(&data->mutex_flash);
898}
899
diff --git a/drivers/hid/hid-picolcd_fb.c b/drivers/hid/hid-picolcd_fb.c
new file mode 100644
index 000000000000..0008a512211d
--- /dev/null
+++ b/drivers/hid/hid-picolcd_fb.c
@@ -0,0 +1,615 @@
1/***************************************************************************
2 * Copyright (C) 2010-2012 by Bruno Prémont <bonbons@linux-vserver.org> *
3 * *
4 * Based on Logitech G13 driver (v0.4) *
5 * Copyright (C) 2009 by Rick L. Vinyard, Jr. <rvinyard@cs.nmsu.edu> *
6 * *
7 * This program is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, version 2 of the License. *
10 * *
11 * This driver is distributed in the hope that it will be useful, but *
12 * WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14 * General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this software. If not see <http://www.gnu.org/licenses/>. *
18 ***************************************************************************/
19
20#include <linux/hid.h>
21#include <linux/vmalloc.h>
22#include "usbhid/usbhid.h"
23#include <linux/usb.h>
24
25#include <linux/fb.h>
26#include <linux/module.h>
27
28#include "hid-picolcd.h"
29
30/* Framebuffer
31 *
32 * The PicoLCD use a Topway LCD module of 256x64 pixel
33 * This display area is tiled over 4 controllers with 8 tiles
34 * each. Each tile has 8x64 pixel, each data byte representing
35 * a 1-bit wide vertical line of the tile.
36 *
37 * The display can be updated at a tile granularity.
38 *
39 * Chip 1 Chip 2 Chip 3 Chip 4
40 * +----------------+----------------+----------------+----------------+
41 * | Tile 1 | Tile 1 | Tile 1 | Tile 1 |
42 * +----------------+----------------+----------------+----------------+
43 * | Tile 2 | Tile 2 | Tile 2 | Tile 2 |
44 * +----------------+----------------+----------------+----------------+
45 * ...
46 * +----------------+----------------+----------------+----------------+
47 * | Tile 8 | Tile 8 | Tile 8 | Tile 8 |
48 * +----------------+----------------+----------------+----------------+
49 */
50#define PICOLCDFB_NAME "picolcdfb"
51#define PICOLCDFB_WIDTH (256)
52#define PICOLCDFB_HEIGHT (64)
53#define PICOLCDFB_SIZE (PICOLCDFB_WIDTH * PICOLCDFB_HEIGHT / 8)
54
55#define PICOLCDFB_UPDATE_RATE_LIMIT 10
56#define PICOLCDFB_UPDATE_RATE_DEFAULT 2
57
58/* Framebuffer visual structures */
59static const struct fb_fix_screeninfo picolcdfb_fix = {
60 .id = PICOLCDFB_NAME,
61 .type = FB_TYPE_PACKED_PIXELS,
62 .visual = FB_VISUAL_MONO01,
63 .xpanstep = 0,
64 .ypanstep = 0,
65 .ywrapstep = 0,
66 .line_length = PICOLCDFB_WIDTH / 8,
67 .accel = FB_ACCEL_NONE,
68};
69
70static const struct fb_var_screeninfo picolcdfb_var = {
71 .xres = PICOLCDFB_WIDTH,
72 .yres = PICOLCDFB_HEIGHT,
73 .xres_virtual = PICOLCDFB_WIDTH,
74 .yres_virtual = PICOLCDFB_HEIGHT,
75 .width = 103,
76 .height = 26,
77 .bits_per_pixel = 1,
78 .grayscale = 1,
79 .red = {
80 .offset = 0,
81 .length = 1,
82 .msb_right = 0,
83 },
84 .green = {
85 .offset = 0,
86 .length = 1,
87 .msb_right = 0,
88 },
89 .blue = {
90 .offset = 0,
91 .length = 1,
92 .msb_right = 0,
93 },
94 .transp = {
95 .offset = 0,
96 .length = 0,
97 .msb_right = 0,
98 },
99};
100
101/* Send a given tile to PicoLCD */
102static int picolcd_fb_send_tile(struct picolcd_data *data, u8 *vbitmap,
103 int chip, int tile)
104{
105 struct hid_report *report1, *report2;
106 unsigned long flags;
107 u8 *tdata;
108 int i;
109
110 report1 = picolcd_out_report(REPORT_LCD_CMD_DATA, data->hdev);
111 if (!report1 || report1->maxfield != 1)
112 return -ENODEV;
113 report2 = picolcd_out_report(REPORT_LCD_DATA, data->hdev);
114 if (!report2 || report2->maxfield != 1)
115 return -ENODEV;
116
117 spin_lock_irqsave(&data->lock, flags);
118 if ((data->status & PICOLCD_FAILED)) {
119 spin_unlock_irqrestore(&data->lock, flags);
120 return -ENODEV;
121 }
122 hid_set_field(report1->field[0], 0, chip << 2);
123 hid_set_field(report1->field[0], 1, 0x02);
124 hid_set_field(report1->field[0], 2, 0x00);
125 hid_set_field(report1->field[0], 3, 0x00);
126 hid_set_field(report1->field[0], 4, 0xb8 | tile);
127 hid_set_field(report1->field[0], 5, 0x00);
128 hid_set_field(report1->field[0], 6, 0x00);
129 hid_set_field(report1->field[0], 7, 0x40);
130 hid_set_field(report1->field[0], 8, 0x00);
131 hid_set_field(report1->field[0], 9, 0x00);
132 hid_set_field(report1->field[0], 10, 32);
133
134 hid_set_field(report2->field[0], 0, (chip << 2) | 0x01);
135 hid_set_field(report2->field[0], 1, 0x00);
136 hid_set_field(report2->field[0], 2, 0x00);
137 hid_set_field(report2->field[0], 3, 32);
138
139 tdata = vbitmap + (tile * 4 + chip) * 64;
140 for (i = 0; i < 64; i++)
141 if (i < 32)
142 hid_set_field(report1->field[0], 11 + i, tdata[i]);
143 else
144 hid_set_field(report2->field[0], 4 + i - 32, tdata[i]);
145
146 usbhid_submit_report(data->hdev, report1, USB_DIR_OUT);
147 usbhid_submit_report(data->hdev, report2, USB_DIR_OUT);
148 spin_unlock_irqrestore(&data->lock, flags);
149 return 0;
150}
151
152/* Translate a single tile*/
153static int picolcd_fb_update_tile(u8 *vbitmap, const u8 *bitmap, int bpp,
154 int chip, int tile)
155{
156 int i, b, changed = 0;
157 u8 tdata[64];
158 u8 *vdata = vbitmap + (tile * 4 + chip) * 64;
159
160 if (bpp == 1) {
161 for (b = 7; b >= 0; b--) {
162 const u8 *bdata = bitmap + tile * 256 + chip * 8 + b * 32;
163 for (i = 0; i < 64; i++) {
164 tdata[i] <<= 1;
165 tdata[i] |= (bdata[i/8] >> (i % 8)) & 0x01;
166 }
167 }
168 } else if (bpp == 8) {
169 for (b = 7; b >= 0; b--) {
170 const u8 *bdata = bitmap + (tile * 256 + chip * 8 + b * 32) * 8;
171 for (i = 0; i < 64; i++) {
172 tdata[i] <<= 1;
173 tdata[i] |= (bdata[i] & 0x80) ? 0x01 : 0x00;
174 }
175 }
176 } else {
177 /* Oops, we should never get here! */
178 WARN_ON(1);
179 return 0;
180 }
181
182 for (i = 0; i < 64; i++)
183 if (tdata[i] != vdata[i]) {
184 changed = 1;
185 vdata[i] = tdata[i];
186 }
187 return changed;
188}
189
190void picolcd_fb_refresh(struct picolcd_data *data)
191{
192 if (data->fb_info)
193 schedule_delayed_work(&data->fb_info->deferred_work, 0);
194}
195
196/* Reconfigure LCD display */
197int picolcd_fb_reset(struct picolcd_data *data, int clear)
198{
199 struct hid_report *report = picolcd_out_report(REPORT_LCD_CMD, data->hdev);
200 struct picolcd_fb_data *fbdata = data->fb_info->par;
201 int i, j;
202 unsigned long flags;
203 static const u8 mapcmd[8] = { 0x00, 0x02, 0x00, 0x64, 0x3f, 0x00, 0x64, 0xc0 };
204
205 if (!report || report->maxfield != 1)
206 return -ENODEV;
207
208 spin_lock_irqsave(&data->lock, flags);
209 for (i = 0; i < 4; i++) {
210 for (j = 0; j < report->field[0]->maxusage; j++)
211 if (j == 0)
212 hid_set_field(report->field[0], j, i << 2);
213 else if (j < sizeof(mapcmd))
214 hid_set_field(report->field[0], j, mapcmd[j]);
215 else
216 hid_set_field(report->field[0], j, 0);
217 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
218 }
219 spin_unlock_irqrestore(&data->lock, flags);
220
221 if (clear) {
222 memset(fbdata->vbitmap, 0, PICOLCDFB_SIZE);
223 memset(fbdata->bitmap, 0, PICOLCDFB_SIZE*fbdata->bpp);
224 }
225 fbdata->force = 1;
226
227 /* schedule first output of framebuffer */
228 if (fbdata->ready)
229 schedule_delayed_work(&data->fb_info->deferred_work, 0);
230 else
231 fbdata->ready = 1;
232
233 return 0;
234}
235
236/* Update fb_vbitmap from the screen_base and send changed tiles to device */
237static void picolcd_fb_update(struct fb_info *info)
238{
239 int chip, tile, n;
240 unsigned long flags;
241 struct picolcd_fb_data *fbdata = info->par;
242 struct picolcd_data *data;
243
244 mutex_lock(&info->lock);
245
246 spin_lock_irqsave(&fbdata->lock, flags);
247 if (!fbdata->ready && fbdata->picolcd)
248 picolcd_fb_reset(fbdata->picolcd, 0);
249 spin_unlock_irqrestore(&fbdata->lock, flags);
250
251 /*
252 * Translate the framebuffer into the format needed by the PicoLCD.
253 * See display layout above.
254 * Do this one tile after the other and push those tiles that changed.
255 *
256 * Wait for our IO to complete as otherwise we might flood the queue!
257 */
258 n = 0;
259 for (chip = 0; chip < 4; chip++)
260 for (tile = 0; tile < 8; tile++) {
261 if (!fbdata->force && !picolcd_fb_update_tile(
262 fbdata->vbitmap, fbdata->bitmap,
263 fbdata->bpp, chip, tile))
264 continue;
265 n += 2;
266 if (n >= HID_OUTPUT_FIFO_SIZE / 2) {
267 spin_lock_irqsave(&fbdata->lock, flags);
268 data = fbdata->picolcd;
269 spin_unlock_irqrestore(&fbdata->lock, flags);
270 mutex_unlock(&info->lock);
271 if (!data)
272 return;
273 usbhid_wait_io(data->hdev);
274 mutex_lock(&info->lock);
275 n = 0;
276 }
277 spin_lock_irqsave(&fbdata->lock, flags);
278 data = fbdata->picolcd;
279 spin_unlock_irqrestore(&fbdata->lock, flags);
280 if (!data || picolcd_fb_send_tile(data,
281 fbdata->vbitmap, chip, tile))
282 goto out;
283 }
284 fbdata->force = false;
285 if (n) {
286 spin_lock_irqsave(&fbdata->lock, flags);
287 data = fbdata->picolcd;
288 spin_unlock_irqrestore(&fbdata->lock, flags);
289 mutex_unlock(&info->lock);
290 if (data)
291 usbhid_wait_io(data->hdev);
292 return;
293 }
294out:
295 mutex_unlock(&info->lock);
296}
297
298/* Stub to call the system default and update the image on the picoLCD */
299static void picolcd_fb_fillrect(struct fb_info *info,
300 const struct fb_fillrect *rect)
301{
302 if (!info->par)
303 return;
304 sys_fillrect(info, rect);
305
306 schedule_delayed_work(&info->deferred_work, 0);
307}
308
309/* Stub to call the system default and update the image on the picoLCD */
310static void picolcd_fb_copyarea(struct fb_info *info,
311 const struct fb_copyarea *area)
312{
313 if (!info->par)
314 return;
315 sys_copyarea(info, area);
316
317 schedule_delayed_work(&info->deferred_work, 0);
318}
319
320/* Stub to call the system default and update the image on the picoLCD */
321static void picolcd_fb_imageblit(struct fb_info *info, const struct fb_image *image)
322{
323 if (!info->par)
324 return;
325 sys_imageblit(info, image);
326
327 schedule_delayed_work(&info->deferred_work, 0);
328}
329
330/*
331 * this is the slow path from userspace. they can seek and write to
332 * the fb. it's inefficient to do anything less than a full screen draw
333 */
334static ssize_t picolcd_fb_write(struct fb_info *info, const char __user *buf,
335 size_t count, loff_t *ppos)
336{
337 ssize_t ret;
338 if (!info->par)
339 return -ENODEV;
340 ret = fb_sys_write(info, buf, count, ppos);
341 if (ret >= 0)
342 schedule_delayed_work(&info->deferred_work, 0);
343 return ret;
344}
345
346static int picolcd_fb_blank(int blank, struct fb_info *info)
347{
348 /* We let fb notification do this for us via lcd/backlight device */
349 return 0;
350}
351
352static void picolcd_fb_destroy(struct fb_info *info)
353{
354 struct picolcd_fb_data *fbdata = info->par;
355
356 /* make sure no work is deferred */
357 fb_deferred_io_cleanup(info);
358
359 /* No thridparty should ever unregister our framebuffer! */
360 WARN_ON(fbdata->picolcd != NULL);
361
362 vfree((u8 *)info->fix.smem_start);
363 framebuffer_release(info);
364}
365
366static int picolcd_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
367{
368 __u32 bpp = var->bits_per_pixel;
369 __u32 activate = var->activate;
370
371 /* only allow 1/8 bit depth (8-bit is grayscale) */
372 *var = picolcdfb_var;
373 var->activate = activate;
374 if (bpp >= 8) {
375 var->bits_per_pixel = 8;
376 var->red.length = 8;
377 var->green.length = 8;
378 var->blue.length = 8;
379 } else {
380 var->bits_per_pixel = 1;
381 var->red.length = 1;
382 var->green.length = 1;
383 var->blue.length = 1;
384 }
385 return 0;
386}
387
388static int picolcd_set_par(struct fb_info *info)
389{
390 struct picolcd_fb_data *fbdata = info->par;
391 u8 *tmp_fb, *o_fb;
392 if (info->var.bits_per_pixel == fbdata->bpp)
393 return 0;
394 /* switch between 1/8 bit depths */
395 if (info->var.bits_per_pixel != 1 && info->var.bits_per_pixel != 8)
396 return -EINVAL;
397
398 o_fb = fbdata->bitmap;
399 tmp_fb = kmalloc(PICOLCDFB_SIZE*info->var.bits_per_pixel, GFP_KERNEL);
400 if (!tmp_fb)
401 return -ENOMEM;
402
403 /* translate FB content to new bits-per-pixel */
404 if (info->var.bits_per_pixel == 1) {
405 int i, b;
406 for (i = 0; i < PICOLCDFB_SIZE; i++) {
407 u8 p = 0;
408 for (b = 0; b < 8; b++) {
409 p <<= 1;
410 p |= o_fb[i*8+b] ? 0x01 : 0x00;
411 }
412 tmp_fb[i] = p;
413 }
414 memcpy(o_fb, tmp_fb, PICOLCDFB_SIZE);
415 info->fix.visual = FB_VISUAL_MONO01;
416 info->fix.line_length = PICOLCDFB_WIDTH / 8;
417 } else {
418 int i;
419 memcpy(tmp_fb, o_fb, PICOLCDFB_SIZE);
420 for (i = 0; i < PICOLCDFB_SIZE * 8; i++)
421 o_fb[i] = tmp_fb[i/8] & (0x01 << (7 - i % 8)) ? 0xff : 0x00;
422 info->fix.visual = FB_VISUAL_DIRECTCOLOR;
423 info->fix.line_length = PICOLCDFB_WIDTH;
424 }
425
426 kfree(tmp_fb);
427 fbdata->bpp = info->var.bits_per_pixel;
428 return 0;
429}
430
431/* Note this can't be const because of struct fb_info definition */
432static struct fb_ops picolcdfb_ops = {
433 .owner = THIS_MODULE,
434 .fb_destroy = picolcd_fb_destroy,
435 .fb_read = fb_sys_read,
436 .fb_write = picolcd_fb_write,
437 .fb_blank = picolcd_fb_blank,
438 .fb_fillrect = picolcd_fb_fillrect,
439 .fb_copyarea = picolcd_fb_copyarea,
440 .fb_imageblit = picolcd_fb_imageblit,
441 .fb_check_var = picolcd_fb_check_var,
442 .fb_set_par = picolcd_set_par,
443};
444
445
446/* Callback from deferred IO workqueue */
447static void picolcd_fb_deferred_io(struct fb_info *info, struct list_head *pagelist)
448{
449 picolcd_fb_update(info);
450}
451
452static const struct fb_deferred_io picolcd_fb_defio = {
453 .delay = HZ / PICOLCDFB_UPDATE_RATE_DEFAULT,
454 .deferred_io = picolcd_fb_deferred_io,
455};
456
457
458/*
459 * The "fb_update_rate" sysfs attribute
460 */
461static ssize_t picolcd_fb_update_rate_show(struct device *dev,
462 struct device_attribute *attr, char *buf)
463{
464 struct picolcd_data *data = dev_get_drvdata(dev);
465 struct picolcd_fb_data *fbdata = data->fb_info->par;
466 unsigned i, fb_update_rate = fbdata->update_rate;
467 size_t ret = 0;
468
469 for (i = 1; i <= PICOLCDFB_UPDATE_RATE_LIMIT; i++)
470 if (ret >= PAGE_SIZE)
471 break;
472 else if (i == fb_update_rate)
473 ret += snprintf(buf+ret, PAGE_SIZE-ret, "[%u] ", i);
474 else
475 ret += snprintf(buf+ret, PAGE_SIZE-ret, "%u ", i);
476 if (ret > 0)
477 buf[min(ret, (size_t)PAGE_SIZE)-1] = '\n';
478 return ret;
479}
480
481static ssize_t picolcd_fb_update_rate_store(struct device *dev,
482 struct device_attribute *attr, const char *buf, size_t count)
483{
484 struct picolcd_data *data = dev_get_drvdata(dev);
485 struct picolcd_fb_data *fbdata = data->fb_info->par;
486 int i;
487 unsigned u;
488
489 if (count < 1 || count > 10)
490 return -EINVAL;
491
492 i = sscanf(buf, "%u", &u);
493 if (i != 1)
494 return -EINVAL;
495
496 if (u > PICOLCDFB_UPDATE_RATE_LIMIT)
497 return -ERANGE;
498 else if (u == 0)
499 u = PICOLCDFB_UPDATE_RATE_DEFAULT;
500
501 fbdata->update_rate = u;
502 data->fb_info->fbdefio->delay = HZ / fbdata->update_rate;
503 return count;
504}
505
506static DEVICE_ATTR(fb_update_rate, 0666, picolcd_fb_update_rate_show,
507 picolcd_fb_update_rate_store);
508
509/* initialize Framebuffer device */
510int picolcd_init_framebuffer(struct picolcd_data *data)
511{
512 struct device *dev = &data->hdev->dev;
513 struct fb_info *info = NULL;
514 struct picolcd_fb_data *fbdata = NULL;
515 int i, error = -ENOMEM;
516 u32 *palette;
517
518 /* The extra memory is:
519 * - 256*u32 for pseudo_palette
520 * - struct fb_deferred_io
521 */
522 info = framebuffer_alloc(256 * sizeof(u32) +
523 sizeof(struct fb_deferred_io) +
524 sizeof(struct picolcd_fb_data) +
525 PICOLCDFB_SIZE, dev);
526 if (info == NULL) {
527 dev_err(dev, "failed to allocate a framebuffer\n");
528 goto err_nomem;
529 }
530
531 info->fbdefio = info->par;
532 *info->fbdefio = picolcd_fb_defio;
533 info->par += sizeof(struct fb_deferred_io);
534 palette = info->par;
535 info->par += 256 * sizeof(u32);
536 for (i = 0; i < 256; i++)
537 palette[i] = i > 0 && i < 16 ? 0xff : 0;
538 info->pseudo_palette = palette;
539 info->fbops = &picolcdfb_ops;
540 info->var = picolcdfb_var;
541 info->fix = picolcdfb_fix;
542 info->fix.smem_len = PICOLCDFB_SIZE*8;
543 info->flags = FBINFO_FLAG_DEFAULT;
544
545 fbdata = info->par;
546 spin_lock_init(&fbdata->lock);
547 fbdata->picolcd = data;
548 fbdata->update_rate = PICOLCDFB_UPDATE_RATE_DEFAULT;
549 fbdata->bpp = picolcdfb_var.bits_per_pixel;
550 fbdata->force = 1;
551 fbdata->vbitmap = info->par + sizeof(struct picolcd_fb_data);
552 fbdata->bitmap = vmalloc(PICOLCDFB_SIZE*8);
553 if (fbdata->bitmap == NULL) {
554 dev_err(dev, "can't get a free page for framebuffer\n");
555 goto err_nomem;
556 }
557 info->screen_base = (char __force __iomem *)fbdata->bitmap;
558 info->fix.smem_start = (unsigned long)fbdata->bitmap;
559 memset(fbdata->vbitmap, 0xff, PICOLCDFB_SIZE);
560 data->fb_info = info;
561
562 error = picolcd_fb_reset(data, 1);
563 if (error) {
564 dev_err(dev, "failed to configure display\n");
565 goto err_cleanup;
566 }
567
568 error = device_create_file(dev, &dev_attr_fb_update_rate);
569 if (error) {
570 dev_err(dev, "failed to create sysfs attributes\n");
571 goto err_cleanup;
572 }
573
574 fb_deferred_io_init(info);
575 error = register_framebuffer(info);
576 if (error) {
577 dev_err(dev, "failed to register framebuffer\n");
578 goto err_sysfs;
579 }
580 return 0;
581
582err_sysfs:
583 device_remove_file(dev, &dev_attr_fb_update_rate);
584 fb_deferred_io_cleanup(info);
585err_cleanup:
586 data->fb_info = NULL;
587
588err_nomem:
589 if (fbdata)
590 vfree(fbdata->bitmap);
591 framebuffer_release(info);
592 return error;
593}
594
595void picolcd_exit_framebuffer(struct picolcd_data *data)
596{
597 struct fb_info *info = data->fb_info;
598 struct picolcd_fb_data *fbdata = info->par;
599 unsigned long flags;
600
601 device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate);
602
603 /* disconnect framebuffer from HID dev */
604 spin_lock_irqsave(&fbdata->lock, flags);
605 fbdata->picolcd = NULL;
606 spin_unlock_irqrestore(&fbdata->lock, flags);
607
608 /* make sure there is no running update - thus that fbdata->picolcd
609 * once obtained under lock is guaranteed not to get free() under
610 * the feet of the deferred work */
611 flush_delayed_work_sync(&info->deferred_work);
612
613 data->fb_info = NULL;
614 unregister_framebuffer(info);
615}
diff --git a/drivers/hid/hid-picolcd_lcd.c b/drivers/hid/hid-picolcd_lcd.c
new file mode 100644
index 000000000000..2d0ddc5ac65f
--- /dev/null
+++ b/drivers/hid/hid-picolcd_lcd.c
@@ -0,0 +1,107 @@
1/***************************************************************************
2 * Copyright (C) 2010-2012 by Bruno Prémont <bonbons@linux-vserver.org> *
3 * *
4 * Based on Logitech G13 driver (v0.4) *
5 * Copyright (C) 2009 by Rick L. Vinyard, Jr. <rvinyard@cs.nmsu.edu> *
6 * *
7 * This program is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, version 2 of the License. *
10 * *
11 * This driver is distributed in the hope that it will be useful, but *
12 * WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14 * General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this software. If not see <http://www.gnu.org/licenses/>. *
18 ***************************************************************************/
19
20#include <linux/hid.h>
21#include "usbhid/usbhid.h"
22#include <linux/usb.h>
23
24#include <linux/fb.h>
25#include <linux/lcd.h>
26
27#include "hid-picolcd.h"
28
29/*
30 * lcd class device
31 */
32static int picolcd_get_contrast(struct lcd_device *ldev)
33{
34 struct picolcd_data *data = lcd_get_data(ldev);
35 return data->lcd_contrast;
36}
37
38static int picolcd_set_contrast(struct lcd_device *ldev, int contrast)
39{
40 struct picolcd_data *data = lcd_get_data(ldev);
41 struct hid_report *report = picolcd_out_report(REPORT_CONTRAST, data->hdev);
42 unsigned long flags;
43
44 if (!report || report->maxfield != 1 || report->field[0]->report_count != 1)
45 return -ENODEV;
46
47 data->lcd_contrast = contrast & 0x0ff;
48 spin_lock_irqsave(&data->lock, flags);
49 hid_set_field(report->field[0], 0, data->lcd_contrast);
50 if (!(data->status & PICOLCD_FAILED))
51 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
52 spin_unlock_irqrestore(&data->lock, flags);
53 return 0;
54}
55
56static int picolcd_check_lcd_fb(struct lcd_device *ldev, struct fb_info *fb)
57{
58 return fb && fb == picolcd_fbinfo((struct picolcd_data *)lcd_get_data(ldev));
59}
60
61static struct lcd_ops picolcd_lcdops = {
62 .get_contrast = picolcd_get_contrast,
63 .set_contrast = picolcd_set_contrast,
64 .check_fb = picolcd_check_lcd_fb,
65};
66
67int picolcd_init_lcd(struct picolcd_data *data, struct hid_report *report)
68{
69 struct device *dev = &data->hdev->dev;
70 struct lcd_device *ldev;
71
72 if (!report)
73 return -ENODEV;
74 if (report->maxfield != 1 || report->field[0]->report_count != 1 ||
75 report->field[0]->report_size != 8) {
76 dev_err(dev, "unsupported CONTRAST report");
77 return -EINVAL;
78 }
79
80 ldev = lcd_device_register(dev_name(dev), dev, data, &picolcd_lcdops);
81 if (IS_ERR(ldev)) {
82 dev_err(dev, "failed to register LCD\n");
83 return PTR_ERR(ldev);
84 }
85 ldev->props.max_contrast = 0x0ff;
86 data->lcd_contrast = 0xe5;
87 data->lcd = ldev;
88 picolcd_set_contrast(ldev, 0xe5);
89 return 0;
90}
91
92void picolcd_exit_lcd(struct picolcd_data *data)
93{
94 struct lcd_device *ldev = data->lcd;
95
96 data->lcd = NULL;
97 if (ldev)
98 lcd_device_unregister(ldev);
99}
100
101int picolcd_resume_lcd(struct picolcd_data *data)
102{
103 if (!data->lcd)
104 return 0;
105 return picolcd_set_contrast(data->lcd, data->lcd_contrast);
106}
107
diff --git a/drivers/hid/hid-picolcd_leds.c b/drivers/hid/hid-picolcd_leds.c
new file mode 100644
index 000000000000..28cb6a4f9634
--- /dev/null
+++ b/drivers/hid/hid-picolcd_leds.c
@@ -0,0 +1,175 @@
1/***************************************************************************
2 * Copyright (C) 2010-2012 by Bruno Prémont <bonbons@linux-vserver.org> *
3 * *
4 * Based on Logitech G13 driver (v0.4) *
5 * Copyright (C) 2009 by Rick L. Vinyard, Jr. <rvinyard@cs.nmsu.edu> *
6 * *
7 * This program is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, version 2 of the License. *
10 * *
11 * This driver is distributed in the hope that it will be useful, but *
12 * WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14 * General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this software. If not see <http://www.gnu.org/licenses/>. *
18 ***************************************************************************/
19
20#include <linux/hid.h>
21#include <linux/hid-debug.h>
22#include <linux/input.h>
23#include "hid-ids.h"
24#include "usbhid/usbhid.h"
25#include <linux/usb.h>
26
27#include <linux/fb.h>
28#include <linux/vmalloc.h>
29#include <linux/backlight.h>
30#include <linux/lcd.h>
31
32#include <linux/leds.h>
33
34#include <linux/seq_file.h>
35#include <linux/debugfs.h>
36
37#include <linux/completion.h>
38#include <linux/uaccess.h>
39#include <linux/module.h>
40
41#include "hid-picolcd.h"
42
43
44void picolcd_leds_set(struct picolcd_data *data)
45{
46 struct hid_report *report;
47 unsigned long flags;
48
49 if (!data->led[0])
50 return;
51 report = picolcd_out_report(REPORT_LED_STATE, data->hdev);
52 if (!report || report->maxfield != 1 || report->field[0]->report_count != 1)
53 return;
54
55 spin_lock_irqsave(&data->lock, flags);
56 hid_set_field(report->field[0], 0, data->led_state);
57 if (!(data->status & PICOLCD_FAILED))
58 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
59 spin_unlock_irqrestore(&data->lock, flags);
60}
61
62static void picolcd_led_set_brightness(struct led_classdev *led_cdev,
63 enum led_brightness value)
64{
65 struct device *dev;
66 struct hid_device *hdev;
67 struct picolcd_data *data;
68 int i, state = 0;
69
70 dev = led_cdev->dev->parent;
71 hdev = container_of(dev, struct hid_device, dev);
72 data = hid_get_drvdata(hdev);
73 if (!data)
74 return;
75 for (i = 0; i < 8; i++) {
76 if (led_cdev != data->led[i])
77 continue;
78 state = (data->led_state >> i) & 1;
79 if (value == LED_OFF && state) {
80 data->led_state &= ~(1 << i);
81 picolcd_leds_set(data);
82 } else if (value != LED_OFF && !state) {
83 data->led_state |= 1 << i;
84 picolcd_leds_set(data);
85 }
86 break;
87 }
88}
89
90static enum led_brightness picolcd_led_get_brightness(struct led_classdev *led_cdev)
91{
92 struct device *dev;
93 struct hid_device *hdev;
94 struct picolcd_data *data;
95 int i, value = 0;
96
97 dev = led_cdev->dev->parent;
98 hdev = container_of(dev, struct hid_device, dev);
99 data = hid_get_drvdata(hdev);
100 for (i = 0; i < 8; i++)
101 if (led_cdev == data->led[i]) {
102 value = (data->led_state >> i) & 1;
103 break;
104 }
105 return value ? LED_FULL : LED_OFF;
106}
107
108int picolcd_init_leds(struct picolcd_data *data, struct hid_report *report)
109{
110 struct device *dev = &data->hdev->dev;
111 struct led_classdev *led;
112 size_t name_sz = strlen(dev_name(dev)) + 8;
113 char *name;
114 int i, ret = 0;
115
116 if (!report)
117 return -ENODEV;
118 if (report->maxfield != 1 || report->field[0]->report_count != 1 ||
119 report->field[0]->report_size != 8) {
120 dev_err(dev, "unsupported LED_STATE report");
121 return -EINVAL;
122 }
123
124 for (i = 0; i < 8; i++) {
125 led = kzalloc(sizeof(struct led_classdev)+name_sz, GFP_KERNEL);
126 if (!led) {
127 dev_err(dev, "can't allocate memory for LED %d\n", i);
128 ret = -ENOMEM;
129 goto err;
130 }
131 name = (void *)(&led[1]);
132 snprintf(name, name_sz, "%s::GPO%d", dev_name(dev), i);
133 led->name = name;
134 led->brightness = 0;
135 led->max_brightness = 1;
136 led->brightness_get = picolcd_led_get_brightness;
137 led->brightness_set = picolcd_led_set_brightness;
138
139 data->led[i] = led;
140 ret = led_classdev_register(dev, data->led[i]);
141 if (ret) {
142 data->led[i] = NULL;
143 kfree(led);
144 dev_err(dev, "can't register LED %d\n", i);
145 goto err;
146 }
147 }
148 return 0;
149err:
150 for (i = 0; i < 8; i++)
151 if (data->led[i]) {
152 led = data->led[i];
153 data->led[i] = NULL;
154 led_classdev_unregister(led);
155 kfree(led);
156 }
157 return ret;
158}
159
160void picolcd_exit_leds(struct picolcd_data *data)
161{
162 struct led_classdev *led;
163 int i;
164
165 for (i = 0; i < 8; i++) {
166 led = data->led[i];
167 data->led[i] = NULL;
168 if (!led)
169 continue;
170 led_classdev_unregister(led);
171 kfree(led);
172 }
173}
174
175
diff --git a/drivers/hid/hid-ps3remote.c b/drivers/hid/hid-ps3remote.c
new file mode 100644
index 000000000000..03811e539d71
--- /dev/null
+++ b/drivers/hid/hid-ps3remote.c
@@ -0,0 +1,215 @@
1/*
2 * HID driver for Sony PS3 BD Remote Control
3 *
4 * Copyright (c) 2012 David Dillow <dave@thedillows.org>
5 * Based on a blend of the bluez fakehid user-space code by Marcel Holtmann
6 * and other kernel HID drivers.
7 */
8
9/*
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
13 * any later version.
14 */
15
16/* NOTE: in order for the Sony PS3 BD Remote Control to be found by
17 * a Bluetooth host, the key combination Start+Enter has to be kept pressed
18 * for about 7 seconds with the Bluetooth Host Controller in discovering mode.
19 *
20 * There will be no PIN request from the device.
21 */
22
23#include <linux/device.h>
24#include <linux/hid.h>
25#include <linux/module.h>
26
27#include "hid-ids.h"
28
29static __u8 ps3remote_rdesc[] = {
30 0x05, 0x01, /* GUsagePage Generic Desktop */
31 0x09, 0x05, /* LUsage 0x05 [Game Pad] */
32 0xA1, 0x01, /* MCollection Application (mouse, keyboard) */
33
34 /* Use collection 1 for joypad buttons */
35 0xA1, 0x02, /* MCollection Logical (interrelated data) */
36
37 /* Ignore the 1st byte, maybe it is used for a controller
38 * number but it's not needed for correct operation */
39 0x75, 0x08, /* GReportSize 0x08 [8] */
40 0x95, 0x01, /* GReportCount 0x01 [1] */
41 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
42
43 /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these
44 * buttons multiple keypresses are allowed */
45 0x05, 0x09, /* GUsagePage Button */
46 0x19, 0x01, /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */
47 0x29, 0x18, /* LUsageMaximum 0x18 [Button 24] */
48 0x14, /* GLogicalMinimum [0] */
49 0x25, 0x01, /* GLogicalMaximum 0x01 [1] */
50 0x75, 0x01, /* GReportSize 0x01 [1] */
51 0x95, 0x18, /* GReportCount 0x18 [24] */
52 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
53
54 0xC0, /* MEndCollection */
55
56 /* Use collection 2 for remote control buttons */
57 0xA1, 0x02, /* MCollection Logical (interrelated data) */
58
59 /* 5th byte is used for remote control buttons */
60 0x05, 0x09, /* GUsagePage Button */
61 0x18, /* LUsageMinimum [No button pressed] */
62 0x29, 0xFE, /* LUsageMaximum 0xFE [Button 254] */
63 0x14, /* GLogicalMinimum [0] */
64 0x26, 0xFE, 0x00, /* GLogicalMaximum 0x00FE [254] */
65 0x75, 0x08, /* GReportSize 0x08 [8] */
66 0x95, 0x01, /* GReportCount 0x01 [1] */
67 0x80, /* MInput */
68
69 /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at
70 * 0xff and 11th is for press indication */
71 0x75, 0x08, /* GReportSize 0x08 [8] */
72 0x95, 0x06, /* GReportCount 0x06 [6] */
73 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
74
75 /* 12th byte is for battery strength */
76 0x05, 0x06, /* GUsagePage Generic Device Controls */
77 0x09, 0x20, /* LUsage 0x20 [Battery Strength] */
78 0x14, /* GLogicalMinimum [0] */
79 0x25, 0x05, /* GLogicalMaximum 0x05 [5] */
80 0x75, 0x08, /* GReportSize 0x08 [8] */
81 0x95, 0x01, /* GReportCount 0x01 [1] */
82 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
83
84 0xC0, /* MEndCollection */
85
86 0xC0 /* MEndCollection [Game Pad] */
87};
88
89static const unsigned int ps3remote_keymap_joypad_buttons[] = {
90 [0x01] = KEY_SELECT,
91 [0x02] = BTN_THUMBL, /* L3 */
92 [0x03] = BTN_THUMBR, /* R3 */
93 [0x04] = BTN_START,
94 [0x05] = KEY_UP,
95 [0x06] = KEY_RIGHT,
96 [0x07] = KEY_DOWN,
97 [0x08] = KEY_LEFT,
98 [0x09] = BTN_TL2, /* L2 */
99 [0x0a] = BTN_TR2, /* R2 */
100 [0x0b] = BTN_TL, /* L1 */
101 [0x0c] = BTN_TR, /* R1 */
102 [0x0d] = KEY_OPTION, /* options/triangle */
103 [0x0e] = KEY_BACK, /* back/circle */
104 [0x0f] = BTN_0, /* cross */
105 [0x10] = KEY_SCREEN, /* view/square */
106 [0x11] = KEY_HOMEPAGE, /* PS button */
107 [0x14] = KEY_ENTER,
108};
109static const unsigned int ps3remote_keymap_remote_buttons[] = {
110 [0x00] = KEY_1,
111 [0x01] = KEY_2,
112 [0x02] = KEY_3,
113 [0x03] = KEY_4,
114 [0x04] = KEY_5,
115 [0x05] = KEY_6,
116 [0x06] = KEY_7,
117 [0x07] = KEY_8,
118 [0x08] = KEY_9,
119 [0x09] = KEY_0,
120 [0x0e] = KEY_ESC, /* return */
121 [0x0f] = KEY_CLEAR,
122 [0x16] = KEY_EJECTCD,
123 [0x1a] = KEY_MENU, /* top menu */
124 [0x28] = KEY_TIME,
125 [0x30] = KEY_PREVIOUS,
126 [0x31] = KEY_NEXT,
127 [0x32] = KEY_PLAY,
128 [0x33] = KEY_REWIND, /* scan back */
129 [0x34] = KEY_FORWARD, /* scan forward */
130 [0x38] = KEY_STOP,
131 [0x39] = KEY_PAUSE,
132 [0x40] = KEY_CONTEXT_MENU, /* pop up/menu */
133 [0x60] = KEY_FRAMEBACK, /* slow/step back */
134 [0x61] = KEY_FRAMEFORWARD, /* slow/step forward */
135 [0x63] = KEY_SUBTITLE,
136 [0x64] = KEY_AUDIO,
137 [0x65] = KEY_ANGLE,
138 [0x70] = KEY_INFO, /* display */
139 [0x80] = KEY_BLUE,
140 [0x81] = KEY_RED,
141 [0x82] = KEY_GREEN,
142 [0x83] = KEY_YELLOW,
143};
144
145static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
146 unsigned int *rsize)
147{
148 *rsize = sizeof(ps3remote_rdesc);
149 return ps3remote_rdesc;
150}
151
152static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
153 struct hid_field *field, struct hid_usage *usage,
154 unsigned long **bit, int *max)
155{
156 unsigned int key = usage->hid & HID_USAGE;
157
158 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
159 return -1;
160
161 switch (usage->collection_index) {
162 case 1:
163 if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons))
164 return -1;
165
166 key = ps3remote_keymap_joypad_buttons[key];
167 if (!key)
168 return -1;
169 break;
170 case 2:
171 if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons))
172 return -1;
173
174 key = ps3remote_keymap_remote_buttons[key];
175 if (!key)
176 return -1;
177 break;
178 default:
179 return -1;
180 }
181
182 hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
183 return 1;
184}
185
186static const struct hid_device_id ps3remote_devices[] = {
187 /* PS3 BD Remote Control */
188 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) },
189 /* Logitech Harmony Adapter for PS3 */
190 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) },
191 { }
192};
193MODULE_DEVICE_TABLE(hid, ps3remote_devices);
194
195static struct hid_driver ps3remote_driver = {
196 .name = "ps3_remote",
197 .id_table = ps3remote_devices,
198 .report_fixup = ps3remote_fixup,
199 .input_mapping = ps3remote_mapping,
200};
201
202static int __init ps3remote_init(void)
203{
204 return hid_register_driver(&ps3remote_driver);
205}
206
207static void __exit ps3remote_exit(void)
208{
209 hid_unregister_driver(&ps3remote_driver);
210}
211
212module_init(ps3remote_init);
213module_exit(ps3remote_exit);
214MODULE_LICENSE("GPL");
215MODULE_AUTHOR("David Dillow <dave@thedillows.org>, Antonio Ospite <ospite@studenti.unina.it>");
diff --git a/drivers/hid/hid-uclogic.c b/drivers/hid/hid-uclogic.c
index 3aba02be1f26..2e56a1fd2375 100644
--- a/drivers/hid/hid-uclogic.c
+++ b/drivers/hid/hid-uclogic.c
@@ -466,6 +466,86 @@ static __u8 twhl850_rdesc_fixed2[] = {
466 0xC0 /* End Collection */ 466 0xC0 /* End Collection */
467}; 467};
468 468
469/*
470 * See TWHA60 description, device and HID report descriptors at
471 * http://sf.net/apps/mediawiki/digimend/?title=UC-Logic_Tablet_TWHA60
472 */
473
474/* Size of the original descriptors of TWHA60 tablet */
475#define TWHA60_RDESC_ORIG_SIZE0 254
476#define TWHA60_RDESC_ORIG_SIZE1 139
477
478/* Fixed TWHA60 report descriptor, interface 0 (stylus) */
479static __u8 twha60_rdesc_fixed0[] = {
480 0x05, 0x0D, /* Usage Page (Digitizer), */
481 0x09, 0x02, /* Usage (Pen), */
482 0xA1, 0x01, /* Collection (Application), */
483 0x85, 0x09, /* Report ID (9), */
484 0x09, 0x20, /* Usage (Stylus), */
485 0xA0, /* Collection (Physical), */
486 0x75, 0x01, /* Report Size (1), */
487 0x09, 0x42, /* Usage (Tip Switch), */
488 0x09, 0x44, /* Usage (Barrel Switch), */
489 0x09, 0x46, /* Usage (Tablet Pick), */
490 0x14, /* Logical Minimum (0), */
491 0x25, 0x01, /* Logical Maximum (1), */
492 0x95, 0x03, /* Report Count (3), */
493 0x81, 0x02, /* Input (Variable), */
494 0x95, 0x04, /* Report Count (4), */
495 0x81, 0x01, /* Input (Constant), */
496 0x09, 0x32, /* Usage (In Range), */
497 0x95, 0x01, /* Report Count (1), */
498 0x81, 0x02, /* Input (Variable), */
499 0x75, 0x10, /* Report Size (16), */
500 0x95, 0x01, /* Report Count (1), */
501 0x14, /* Logical Minimum (0), */
502 0xA4, /* Push, */
503 0x05, 0x01, /* Usage Page (Desktop), */
504 0x55, 0xFD, /* Unit Exponent (-3), */
505 0x65, 0x13, /* Unit (Inch), */
506 0x34, /* Physical Minimum (0), */
507 0x09, 0x30, /* Usage (X), */
508 0x46, 0x10, 0x27, /* Physical Maximum (10000), */
509 0x27, 0x3F, 0x9C,
510 0x00, 0x00, /* Logical Maximum (39999), */
511 0x81, 0x02, /* Input (Variable), */
512 0x09, 0x31, /* Usage (Y), */
513 0x46, 0x6A, 0x18, /* Physical Maximum (6250), */
514 0x26, 0xA7, 0x61, /* Logical Maximum (24999), */
515 0x81, 0x02, /* Input (Variable), */
516 0xB4, /* Pop, */
517 0x09, 0x30, /* Usage (Tip Pressure), */
518 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
519 0x81, 0x02, /* Input (Variable), */
520 0xC0, /* End Collection, */
521 0xC0 /* End Collection */
522};
523
524/* Fixed TWHA60 report descriptor, interface 1 (frame buttons) */
525static __u8 twha60_rdesc_fixed1[] = {
526 0x05, 0x01, /* Usage Page (Desktop), */
527 0x09, 0x06, /* Usage (Keyboard), */
528 0xA1, 0x01, /* Collection (Application), */
529 0x85, 0x05, /* Report ID (5), */
530 0x05, 0x07, /* Usage Page (Keyboard), */
531 0x14, /* Logical Minimum (0), */
532 0x25, 0x01, /* Logical Maximum (1), */
533 0x75, 0x01, /* Report Size (1), */
534 0x95, 0x08, /* Report Count (8), */
535 0x81, 0x01, /* Input (Constant), */
536 0x95, 0x0C, /* Report Count (12), */
537 0x19, 0x3A, /* Usage Minimum (KB F1), */
538 0x29, 0x45, /* Usage Maximum (KB F12), */
539 0x81, 0x02, /* Input (Variable), */
540 0x95, 0x0C, /* Report Count (12), */
541 0x19, 0x68, /* Usage Minimum (KB F13), */
542 0x29, 0x73, /* Usage Maximum (KB F24), */
543 0x81, 0x02, /* Input (Variable), */
544 0x95, 0x08, /* Report Count (8), */
545 0x81, 0x01, /* Input (Constant), */
546 0xC0 /* End Collection */
547};
548
469static __u8 *uclogic_report_fixup(struct hid_device *hdev, __u8 *rdesc, 549static __u8 *uclogic_report_fixup(struct hid_device *hdev, __u8 *rdesc,
470 unsigned int *rsize) 550 unsigned int *rsize)
471{ 551{
@@ -525,6 +605,22 @@ static __u8 *uclogic_report_fixup(struct hid_device *hdev, __u8 *rdesc,
525 break; 605 break;
526 } 606 }
527 break; 607 break;
608 case USB_DEVICE_ID_UCLOGIC_TABLET_TWHA60:
609 switch (iface_num) {
610 case 0:
611 if (*rsize == TWHA60_RDESC_ORIG_SIZE0) {
612 rdesc = twha60_rdesc_fixed0;
613 *rsize = sizeof(twha60_rdesc_fixed0);
614 }
615 break;
616 case 1:
617 if (*rsize == TWHA60_RDESC_ORIG_SIZE1) {
618 rdesc = twha60_rdesc_fixed1;
619 *rsize = sizeof(twha60_rdesc_fixed1);
620 }
621 break;
622 }
623 break;
528 } 624 }
529 625
530 return rdesc; 626 return rdesc;
@@ -543,6 +639,8 @@ static const struct hid_device_id uclogic_devices[] = {
543 USB_DEVICE_ID_UCLOGIC_TABLET_WP1062) }, 639 USB_DEVICE_ID_UCLOGIC_TABLET_WP1062) },
544 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, 640 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
545 USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850) }, 641 USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850) },
642 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
643 USB_DEVICE_ID_UCLOGIC_TABLET_TWHA60) },
546 { } 644 { }
547}; 645};
548MODULE_DEVICE_TABLE(hid, uclogic_devices); 646MODULE_DEVICE_TABLE(hid, uclogic_devices);
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c
index fe23a1eb586b..75b970f116ee 100644
--- a/drivers/hid/hid-wacom.c
+++ b/drivers/hid/hid-wacom.c
@@ -33,6 +33,8 @@
33#define PAD_DEVICE_ID 0x0F 33#define PAD_DEVICE_ID 0x0F
34 34
35#define WAC_CMD_LED_CONTROL 0x20 35#define WAC_CMD_LED_CONTROL 0x20
36#define WAC_CMD_ICON_START_STOP 0x21
37#define WAC_CMD_ICON_TRANSFER 0x26
36 38
37struct wacom_data { 39struct wacom_data {
38 __u16 tool; 40 __u16 tool;
@@ -69,6 +71,91 @@ static enum power_supply_property wacom_ac_props[] = {
69 POWER_SUPPLY_PROP_SCOPE, 71 POWER_SUPPLY_PROP_SCOPE,
70}; 72};
71 73
74static void wacom_scramble(__u8 *image)
75{
76 __u16 mask;
77 __u16 s1;
78 __u16 s2;
79 __u16 r1 ;
80 __u16 r2 ;
81 __u16 r;
82 __u8 buf[256];
83 int i, w, x, y, z;
84
85 for (x = 0; x < 32; x++) {
86 for (y = 0; y < 8; y++)
87 buf[(8 * x) + (7 - y)] = image[(8 * x) + y];
88 }
89
90 /* Change 76543210 into GECA6420 as required by Intuos4 WL
91 * HGFEDCBA HFDB7531
92 */
93 for (x = 0; x < 4; x++) {
94 for (y = 0; y < 4; y++) {
95 for (z = 0; z < 8; z++) {
96 mask = 0x0001;
97 r1 = 0;
98 r2 = 0;
99 i = (x << 6) + (y << 4) + z;
100 s1 = buf[i];
101 s2 = buf[i+8];
102 for (w = 0; w < 8; w++) {
103 r1 |= (s1 & mask);
104 r2 |= (s2 & mask);
105 s1 <<= 1;
106 s2 <<= 1;
107 mask <<= 2;
108 }
109 r = r1 | (r2 << 1);
110 i = (x << 6) + (y << 4) + (z << 1);
111 image[i] = 0xFF & r;
112 image[i+1] = (0xFF00 & r) >> 8;
113 }
114 }
115 }
116}
117
118static void wacom_set_image(struct hid_device *hdev, const char *image,
119 __u8 icon_no)
120{
121 __u8 rep_data[68];
122 __u8 p[256];
123 int ret, i, j;
124
125 for (i = 0; i < 256; i++)
126 p[i] = image[i];
127
128 rep_data[0] = WAC_CMD_ICON_START_STOP;
129 rep_data[1] = 0;
130 ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
131 HID_FEATURE_REPORT);
132 if (ret < 0)
133 goto err;
134
135 rep_data[0] = WAC_CMD_ICON_TRANSFER;
136 rep_data[1] = icon_no & 0x07;
137
138 wacom_scramble(p);
139
140 for (i = 0; i < 4; i++) {
141 for (j = 0; j < 64; j++)
142 rep_data[j + 3] = p[(i << 6) + j];
143
144 rep_data[2] = i;
145 ret = hdev->hid_output_raw_report(hdev, rep_data, 67,
146 HID_FEATURE_REPORT);
147 }
148
149 rep_data[0] = WAC_CMD_ICON_START_STOP;
150 rep_data[1] = 0;
151
152 ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
153 HID_FEATURE_REPORT);
154
155err:
156 return;
157}
158
72static void wacom_leds_set_brightness(struct led_classdev *led_dev, 159static void wacom_leds_set_brightness(struct led_classdev *led_dev,
73 enum led_brightness value) 160 enum led_brightness value)
74{ 161{
@@ -91,7 +178,10 @@ static void wacom_leds_set_brightness(struct led_classdev *led_dev,
91 if (buf) { 178 if (buf) {
92 buf[0] = WAC_CMD_LED_CONTROL; 179 buf[0] = WAC_CMD_LED_CONTROL;
93 buf[1] = led; 180 buf[1] = led;
94 buf[2] = value; 181 buf[2] = value >> 2;
182 buf[3] = value;
183 /* use fixed brightness for OLEDs */
184 buf[4] = 0x08;
95 hdev->hid_output_raw_report(hdev, buf, 9, HID_FEATURE_REPORT); 185 hdev->hid_output_raw_report(hdev, buf, 9, HID_FEATURE_REPORT);
96 kfree(buf); 186 kfree(buf);
97 } 187 }
@@ -317,6 +407,34 @@ static ssize_t wacom_store_speed(struct device *dev,
317static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR | S_IWGRP, 407static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR | S_IWGRP,
318 wacom_show_speed, wacom_store_speed); 408 wacom_show_speed, wacom_store_speed);
319 409
410#define WACOM_STORE(OLED_ID) \
411static ssize_t wacom_oled##OLED_ID##_store(struct device *dev, \
412 struct device_attribute *attr, \
413 const char *buf, size_t count) \
414{ \
415 struct hid_device *hdev = container_of(dev, struct hid_device, \
416 dev); \
417 \
418 if (count != 256) \
419 return -EINVAL; \
420 \
421 wacom_set_image(hdev, buf, OLED_ID); \
422 \
423 return count; \
424} \
425 \
426static DEVICE_ATTR(oled##OLED_ID##_img, S_IWUSR | S_IWGRP, NULL, \
427 wacom_oled##OLED_ID##_store)
428
429WACOM_STORE(0);
430WACOM_STORE(1);
431WACOM_STORE(2);
432WACOM_STORE(3);
433WACOM_STORE(4);
434WACOM_STORE(5);
435WACOM_STORE(6);
436WACOM_STORE(7);
437
320static int wacom_gr_parse_report(struct hid_device *hdev, 438static int wacom_gr_parse_report(struct hid_device *hdev,
321 struct wacom_data *wdata, 439 struct wacom_data *wdata,
322 struct input_dev *input, unsigned char *data) 440 struct input_dev *input, unsigned char *data)
@@ -717,17 +835,33 @@ static int wacom_probe(struct hid_device *hdev,
717 hid_warn(hdev, 835 hid_warn(hdev,
718 "can't create sysfs speed attribute err: %d\n", ret); 836 "can't create sysfs speed attribute err: %d\n", ret);
719 837
838#define OLED_INIT(OLED_ID) \
839 do { \
840 ret = device_create_file(&hdev->dev, \
841 &dev_attr_oled##OLED_ID##_img); \
842 if (ret) \
843 hid_warn(hdev, \
844 "can't create sysfs oled attribute, err: %d\n", ret);\
845 } while (0)
846
847OLED_INIT(0);
848OLED_INIT(1);
849OLED_INIT(2);
850OLED_INIT(3);
851OLED_INIT(4);
852OLED_INIT(5);
853OLED_INIT(6);
854OLED_INIT(7);
855
720 wdata->features = 0; 856 wdata->features = 0;
721 wacom_set_features(hdev, 1); 857 wacom_set_features(hdev, 1);
722 858
723 if (hdev->product == USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) { 859 if (hdev->product == USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) {
724 sprintf(hdev->name, "%s", "Wacom Intuos4 WL"); 860 sprintf(hdev->name, "%s", "Wacom Intuos4 WL");
725 ret = wacom_initialize_leds(hdev); 861 ret = wacom_initialize_leds(hdev);
726 if (ret) { 862 if (ret)
727 hid_warn(hdev, 863 hid_warn(hdev,
728 "can't create led attribute, err: %d\n", ret); 864 "can't create led attribute, err: %d\n", ret);
729 goto destroy_leds;
730 }
731 } 865 }
732 866
733 wdata->battery.properties = wacom_battery_props; 867 wdata->battery.properties = wacom_battery_props;
@@ -740,8 +874,8 @@ static int wacom_probe(struct hid_device *hdev,
740 874
741 ret = power_supply_register(&hdev->dev, &wdata->battery); 875 ret = power_supply_register(&hdev->dev, &wdata->battery);
742 if (ret) { 876 if (ret) {
743 hid_warn(hdev, "can't create sysfs battery attribute, err: %d\n", 877 hid_err(hdev, "can't create sysfs battery attribute, err: %d\n",
744 ret); 878 ret);
745 goto err_battery; 879 goto err_battery;
746 } 880 }
747 881
@@ -756,8 +890,8 @@ static int wacom_probe(struct hid_device *hdev,
756 890
757 ret = power_supply_register(&hdev->dev, &wdata->ac); 891 ret = power_supply_register(&hdev->dev, &wdata->ac);
758 if (ret) { 892 if (ret) {
759 hid_warn(hdev, 893 hid_err(hdev,
760 "can't create ac battery attribute, err: %d\n", ret); 894 "can't create ac battery attribute, err: %d\n", ret);
761 goto err_ac; 895 goto err_ac;
762 } 896 }
763 897
@@ -767,10 +901,17 @@ static int wacom_probe(struct hid_device *hdev,
767err_ac: 901err_ac:
768 power_supply_unregister(&wdata->battery); 902 power_supply_unregister(&wdata->battery);
769err_battery: 903err_battery:
904 wacom_destroy_leds(hdev);
905 device_remove_file(&hdev->dev, &dev_attr_oled0_img);
906 device_remove_file(&hdev->dev, &dev_attr_oled1_img);
907 device_remove_file(&hdev->dev, &dev_attr_oled2_img);
908 device_remove_file(&hdev->dev, &dev_attr_oled3_img);
909 device_remove_file(&hdev->dev, &dev_attr_oled4_img);
910 device_remove_file(&hdev->dev, &dev_attr_oled5_img);
911 device_remove_file(&hdev->dev, &dev_attr_oled6_img);
912 device_remove_file(&hdev->dev, &dev_attr_oled7_img);
770 device_remove_file(&hdev->dev, &dev_attr_speed); 913 device_remove_file(&hdev->dev, &dev_attr_speed);
771 hid_hw_stop(hdev); 914 hid_hw_stop(hdev);
772destroy_leds:
773 wacom_destroy_leds(hdev);
774err_free: 915err_free:
775 kfree(wdata); 916 kfree(wdata);
776 return ret; 917 return ret;
@@ -781,6 +922,14 @@ static void wacom_remove(struct hid_device *hdev)
781 struct wacom_data *wdata = hid_get_drvdata(hdev); 922 struct wacom_data *wdata = hid_get_drvdata(hdev);
782 923
783 wacom_destroy_leds(hdev); 924 wacom_destroy_leds(hdev);
925 device_remove_file(&hdev->dev, &dev_attr_oled0_img);
926 device_remove_file(&hdev->dev, &dev_attr_oled1_img);
927 device_remove_file(&hdev->dev, &dev_attr_oled2_img);
928 device_remove_file(&hdev->dev, &dev_attr_oled3_img);
929 device_remove_file(&hdev->dev, &dev_attr_oled4_img);
930 device_remove_file(&hdev->dev, &dev_attr_oled5_img);
931 device_remove_file(&hdev->dev, &dev_attr_oled6_img);
932 device_remove_file(&hdev->dev, &dev_attr_oled7_img);
784 device_remove_file(&hdev->dev, &dev_attr_speed); 933 device_remove_file(&hdev->dev, &dev_attr_speed);
785 hid_hw_stop(hdev); 934 hid_hw_stop(hdev);
786 935
diff --git a/drivers/hid/hid-wiimote-ext.c b/drivers/hid/hid-wiimote-ext.c
index 0a1805c9b0e5..bc85bf29062e 100644
--- a/drivers/hid/hid-wiimote-ext.c
+++ b/drivers/hid/hid-wiimote-ext.c
@@ -28,12 +28,14 @@ struct wiimote_ext {
28 bool mp_plugged; 28 bool mp_plugged;
29 bool motionp; 29 bool motionp;
30 __u8 ext_type; 30 __u8 ext_type;
31 __u16 calib[4][3];
31}; 32};
32 33
33enum wiiext_type { 34enum wiiext_type {
34 WIIEXT_NONE, /* placeholder */ 35 WIIEXT_NONE, /* placeholder */
35 WIIEXT_CLASSIC, /* Nintendo classic controller */ 36 WIIEXT_CLASSIC, /* Nintendo classic controller */
36 WIIEXT_NUNCHUCK, /* Nintendo nunchuck controller */ 37 WIIEXT_NUNCHUCK, /* Nintendo nunchuck controller */
38 WIIEXT_BALANCE_BOARD, /* Nintendo balance board controller */
37}; 39};
38 40
39enum wiiext_keys { 41enum wiiext_keys {
@@ -126,6 +128,7 @@ error:
126static __u8 ext_read(struct wiimote_ext *ext) 128static __u8 ext_read(struct wiimote_ext *ext)
127{ 129{
128 ssize_t ret; 130 ssize_t ret;
131 __u8 buf[24], i, j, offs = 0;
129 __u8 rmem[2], wmem; 132 __u8 rmem[2], wmem;
130 __u8 type = WIIEXT_NONE; 133 __u8 type = WIIEXT_NONE;
131 134
@@ -151,6 +154,28 @@ static __u8 ext_read(struct wiimote_ext *ext)
151 type = WIIEXT_NUNCHUCK; 154 type = WIIEXT_NUNCHUCK;
152 else if (rmem[0] == 0x01 && rmem[1] == 0x01) 155 else if (rmem[0] == 0x01 && rmem[1] == 0x01)
153 type = WIIEXT_CLASSIC; 156 type = WIIEXT_CLASSIC;
157 else if (rmem[0] == 0x04 && rmem[1] == 0x02)
158 type = WIIEXT_BALANCE_BOARD;
159 }
160
161 /* get balance board calibration data */
162 if (type == WIIEXT_BALANCE_BOARD) {
163 ret = wiimote_cmd_read(ext->wdata, 0xa40024, buf, 12);
164 ret += wiimote_cmd_read(ext->wdata, 0xa40024 + 12,
165 buf + 12, 12);
166
167 if (ret != 24) {
168 type = WIIEXT_NONE;
169 } else {
170 for (i = 0; i < 3; i++) {
171 for (j = 0; j < 4; j++) {
172 ext->calib[j][i] = buf[offs];
173 ext->calib[j][i] <<= 8;
174 ext->calib[j][i] |= buf[offs + 1];
175 offs += 2;
176 }
177 }
178 }
154 } 179 }
155 180
156 wiimote_cmd_release(ext->wdata); 181 wiimote_cmd_release(ext->wdata);
@@ -509,6 +534,71 @@ static void handler_classic(struct wiimote_ext *ext, const __u8 *payload)
509 input_sync(ext->input); 534 input_sync(ext->input);
510} 535}
511 536
537static void handler_balance_board(struct wiimote_ext *ext, const __u8 *payload)
538{
539 __s32 val[4], tmp;
540 unsigned int i;
541
542 /* Byte | 8 7 6 5 4 3 2 1 |
543 * -----+--------------------------+
544 * 1 | Top Right <15:8> |
545 * 2 | Top Right <7:0> |
546 * -----+--------------------------+
547 * 3 | Bottom Right <15:8> |
548 * 4 | Bottom Right <7:0> |
549 * -----+--------------------------+
550 * 5 | Top Left <15:8> |
551 * 6 | Top Left <7:0> |
552 * -----+--------------------------+
553 * 7 | Bottom Left <15:8> |
554 * 8 | Bottom Left <7:0> |
555 * -----+--------------------------+
556 *
557 * These values represent the weight-measurements of the Wii-balance
558 * board with 16bit precision.
559 *
560 * The balance-board is never reported interleaved with motionp.
561 */
562
563 val[0] = payload[0];
564 val[0] <<= 8;
565 val[0] |= payload[1];
566
567 val[1] = payload[2];
568 val[1] <<= 8;
569 val[1] |= payload[3];
570
571 val[2] = payload[4];
572 val[2] <<= 8;
573 val[2] |= payload[5];
574
575 val[3] = payload[6];
576 val[3] <<= 8;
577 val[3] |= payload[7];
578
579 /* apply calibration data */
580 for (i = 0; i < 4; i++) {
581 if (val[i] < ext->calib[i][1]) {
582 tmp = val[i] - ext->calib[i][0];
583 tmp *= 1700;
584 tmp /= ext->calib[i][1] - ext->calib[i][0];
585 } else {
586 tmp = val[i] - ext->calib[i][1];
587 tmp *= 1700;
588 tmp /= ext->calib[i][2] - ext->calib[i][1];
589 tmp += 1700;
590 }
591 val[i] = tmp;
592 }
593
594 input_report_abs(ext->input, ABS_HAT0X, val[0]);
595 input_report_abs(ext->input, ABS_HAT0Y, val[1]);
596 input_report_abs(ext->input, ABS_HAT1X, val[2]);
597 input_report_abs(ext->input, ABS_HAT1Y, val[3]);
598
599 input_sync(ext->input);
600}
601
512/* call this with state.lock spinlock held */ 602/* call this with state.lock spinlock held */
513void wiiext_handle(struct wiimote_data *wdata, const __u8 *payload) 603void wiiext_handle(struct wiimote_data *wdata, const __u8 *payload)
514{ 604{
@@ -523,6 +613,8 @@ void wiiext_handle(struct wiimote_data *wdata, const __u8 *payload)
523 handler_nunchuck(ext, payload); 613 handler_nunchuck(ext, payload);
524 } else if (ext->ext_type == WIIEXT_CLASSIC) { 614 } else if (ext->ext_type == WIIEXT_CLASSIC) {
525 handler_classic(ext, payload); 615 handler_classic(ext, payload);
616 } else if (ext->ext_type == WIIEXT_BALANCE_BOARD) {
617 handler_balance_board(ext, payload);
526 } 618 }
527} 619}
528 620
@@ -551,6 +643,11 @@ static ssize_t wiiext_show(struct device *dev, struct device_attribute *attr,
551 return sprintf(buf, "motionp+classic\n"); 643 return sprintf(buf, "motionp+classic\n");
552 else 644 else
553 return sprintf(buf, "classic\n"); 645 return sprintf(buf, "classic\n");
646 } else if (type == WIIEXT_BALANCE_BOARD) {
647 if (motionp)
648 return sprintf(buf, "motionp+balanceboard\n");
649 else
650 return sprintf(buf, "balanceboard\n");
554 } else { 651 } else {
555 if (motionp) 652 if (motionp)
556 return sprintf(buf, "motionp\n"); 653 return sprintf(buf, "motionp\n");
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 3b6f7bf5a77e..c46c5f1037f4 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -42,6 +42,7 @@ static struct cdev hidraw_cdev;
42static struct class *hidraw_class; 42static struct class *hidraw_class;
43static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES]; 43static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES];
44static DEFINE_MUTEX(minors_lock); 44static DEFINE_MUTEX(minors_lock);
45static void drop_ref(struct hidraw *hid, int exists_bit);
45 46
46static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) 47static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
47{ 48{
@@ -113,7 +114,7 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer,
113 __u8 *buf; 114 __u8 *buf;
114 int ret = 0; 115 int ret = 0;
115 116
116 if (!hidraw_table[minor]) { 117 if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
117 ret = -ENODEV; 118 ret = -ENODEV;
118 goto out; 119 goto out;
119 } 120 }
@@ -261,7 +262,7 @@ static int hidraw_open(struct inode *inode, struct file *file)
261 } 262 }
262 263
263 mutex_lock(&minors_lock); 264 mutex_lock(&minors_lock);
264 if (!hidraw_table[minor]) { 265 if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
265 err = -ENODEV; 266 err = -ENODEV;
266 goto out_unlock; 267 goto out_unlock;
267 } 268 }
@@ -298,36 +299,12 @@ out:
298static int hidraw_release(struct inode * inode, struct file * file) 299static int hidraw_release(struct inode * inode, struct file * file)
299{ 300{
300 unsigned int minor = iminor(inode); 301 unsigned int minor = iminor(inode);
301 struct hidraw *dev;
302 struct hidraw_list *list = file->private_data; 302 struct hidraw_list *list = file->private_data;
303 int ret;
304 int i;
305
306 mutex_lock(&minors_lock);
307 if (!hidraw_table[minor]) {
308 ret = -ENODEV;
309 goto unlock;
310 }
311 303
304 drop_ref(hidraw_table[minor], 0);
312 list_del(&list->node); 305 list_del(&list->node);
313 dev = hidraw_table[minor];
314 if (!--dev->open) {
315 if (list->hidraw->exist) {
316 hid_hw_power(dev->hid, PM_HINT_NORMAL);
317 hid_hw_close(dev->hid);
318 } else {
319 kfree(list->hidraw);
320 }
321 }
322
323 for (i = 0; i < HIDRAW_BUFFER_SIZE; ++i)
324 kfree(list->buffer[i].value);
325 kfree(list); 306 kfree(list);
326 ret = 0; 307 return 0;
327unlock:
328 mutex_unlock(&minors_lock);
329
330 return ret;
331} 308}
332 309
333static long hidraw_ioctl(struct file *file, unsigned int cmd, 310static long hidraw_ioctl(struct file *file, unsigned int cmd,
@@ -529,21 +506,7 @@ EXPORT_SYMBOL_GPL(hidraw_connect);
529void hidraw_disconnect(struct hid_device *hid) 506void hidraw_disconnect(struct hid_device *hid)
530{ 507{
531 struct hidraw *hidraw = hid->hidraw; 508 struct hidraw *hidraw = hid->hidraw;
532 509 drop_ref(hidraw, 1);
533 mutex_lock(&minors_lock);
534 hidraw->exist = 0;
535
536 device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
537
538 hidraw_table[hidraw->minor] = NULL;
539
540 if (hidraw->open) {
541 hid_hw_close(hid);
542 wake_up_interruptible(&hidraw->wait);
543 } else {
544 kfree(hidraw);
545 }
546 mutex_unlock(&minors_lock);
547} 510}
548EXPORT_SYMBOL_GPL(hidraw_disconnect); 511EXPORT_SYMBOL_GPL(hidraw_disconnect);
549 512
@@ -585,3 +548,23 @@ void hidraw_exit(void)
585 unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES); 548 unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES);
586 549
587} 550}
551
552static void drop_ref(struct hidraw *hidraw, int exists_bit)
553{
554 mutex_lock(&minors_lock);
555 if (exists_bit) {
556 hid_hw_close(hidraw->hid);
557 hidraw->exist = 0;
558 if (hidraw->open)
559 wake_up_interruptible(&hidraw->wait);
560 } else {
561 --hidraw->open;
562 }
563
564 if (!hidraw->open && !hidraw->exist) {
565 device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
566 hidraw_table[hidraw->minor] = NULL;
567 kfree(hidraw);
568 }
569 mutex_unlock(&minors_lock);
570}