Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branches 'ntrig', 'picolcd', 'prodikeys' and 'roccat-kone' into for-linus

Conflicts:
drivers/hid/Makefile

+5554 -9
+43
Documentation/ABI/testing/sysfs-driver-hid-picolcd
··· 1 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/operation_mode 2 + Date: March 2010 3 + Contact: Bruno Prémont <bonbons@linux-vserver.org> 4 + Description: Make it possible to switch the PicoLCD device between LCD 5 + (firmware) and bootloader (flasher) operation modes. 6 + 7 + Reading: returns list of available modes, the active mode being 8 + enclosed in brackets ('[' and ']') 9 + 10 + Writing: causes operation mode switch. Permitted values are 11 + the non-active mode names listed when read. 12 + 13 + Note: when switching mode the current PicoLCD HID device gets 14 + disconnected and reconnects after above delay (see attribute 15 + operation_mode_delay for its value). 16 + 17 + 18 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/operation_mode_delay 19 + Date: April 2010 20 + Contact: Bruno Prémont <bonbons@linux-vserver.org> 21 + Description: Delay PicoLCD waits before restarting in new mode when 22 + operation_mode has changed. 23 + 24 + Reading/Writing: It is expressed in ms and permitted range is 25 + 0..30000ms. 26 + 27 + 28 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/fb_update_rate 29 + Date: March 2010 30 + Contact: Bruno Prémont <bonbons@linux-vserver.org> 31 + Description: Make it possible to adjust defio refresh rate. 32 + 33 + Reading: returns list of available refresh rates (expressed in Hz), 34 + the active refresh rate being enclosed in brackets ('[' and ']') 35 + 36 + Writing: accepts new refresh rate expressed in integer Hz 37 + within permitted rates. 38 + 39 + Note: As device can barely do 2 complete refreshes a second 40 + it only makes sense to adjust this value if only one or two 41 + tiles get changed and it's not appropriate to expect the application 42 + to flush it's tiny changes explicitely at higher than default rate. 43 +
+29
Documentation/ABI/testing/sysfs-driver-hid-prodikeys
··· 1 + What: /sys/bus/hid/drivers/prodikeys/.../channel 2 + Date: April 2010 3 + KernelVersion: 2.6.34 4 + Contact: Don Prince <dhprince.devel@yahoo.co.uk> 5 + Description: 6 + Allows control (via software) the midi channel to which 7 + that the pc-midi keyboard will output.midi data. 8 + Range: 0..15 9 + Type: Read/write 10 + What: /sys/bus/hid/drivers/prodikeys/.../sustain 11 + Date: April 2010 12 + KernelVersion: 2.6.34 13 + Contact: Don Prince <dhprince.devel@yahoo.co.uk> 14 + Description: 15 + Allows control (via software) the sustain duration of a 16 + note held by the pc-midi driver. 17 + 0 means sustain mode is disabled. 18 + Range: 0..5000 (milliseconds) 19 + Type: Read/write 20 + What: /sys/bus/hid/drivers/prodikeys/.../octave 21 + Date: April 2010 22 + KernelVersion: 2.6.34 23 + Contact: Don Prince <dhprince.devel@yahoo.co.uk> 24 + Description: 25 + Controls the octave shift modifier in the pc-midi driver. 26 + The octave can be shifted via software up/down 2 octaves. 27 + 0 means the no ocatve shift. 28 + Range: -2..2 (minus 2 to plus 2) 29 + Type: Read/Write
+111
Documentation/ABI/testing/sysfs-driver-hid-roccat-kone
··· 1 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/actual_dpi 2 + Date: March 2010 3 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 4 + Description: It is possible to switch the dpi setting of the mouse with the 5 + press of a button. 6 + When read, this file returns the raw number of the actual dpi 7 + setting reported by the mouse. This number has to be further 8 + processed to receive the real dpi value. 9 + 10 + VALUE DPI 11 + 1 800 12 + 2 1200 13 + 3 1600 14 + 4 2000 15 + 5 2400 16 + 6 3200 17 + 18 + This file is readonly. 19 + 20 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/actual_profile 21 + Date: March 2010 22 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 23 + Description: When read, this file returns the number of the actual profile. 24 + This file is readonly. 25 + 26 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/firmware_version 27 + Date: March 2010 28 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 29 + Description: When read, this file returns the raw integer version number of the 30 + firmware reported by the mouse. Using the integer value eases 31 + further usage in other programs. To receive the real version 32 + number the decimal point has to be shifted 2 positions to the 33 + left. E.g. a returned value of 138 means 1.38 34 + This file is readonly. 35 + 36 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/kone_driver_version 37 + Date: March 2010 38 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 39 + Description: When read, this file returns the driver version. 40 + The format of the string is "v<major>.<minor>.<patchlevel>". 41 + This attribute is used by the userland tools to find the sysfs- 42 + paths of installed kone-mice and determine the capabilites of 43 + the driver. Versions of this driver for old kernels replace 44 + usbhid instead of generic-usb. The way to scan for this file 45 + has been chosen to provide a consistent way for all supported 46 + kernel versions. 47 + This file is readonly. 48 + 49 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile[1-5] 50 + Date: March 2010 51 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 52 + Description: The mouse can store 5 profiles which can be switched by the 53 + press of a button. A profile holds informations like button 54 + mappings, sensitivity, the colors of the 5 leds and light 55 + effects. 56 + When read, these files return the respective profile. The 57 + returned data is 975 bytes in size. 58 + When written, this file lets one write the respective profile 59 + data back to the mouse. The data has to be 975 bytes long. 60 + The mouse will reject invalid data, whereas the profile number 61 + stored in the profile doesn't need to fit the number of the 62 + store. 63 + 64 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/settings 65 + Date: March 2010 66 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 67 + Description: When read, this file returns the settings stored in the mouse. 68 + The size of the data is 36 bytes and holds information like the 69 + startup_profile, tcu state and calibration_data. 70 + When written, this file lets write settings back to the mouse. 71 + The data has to be 36 bytes long. The mouse will reject invalid 72 + data. 73 + 74 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/startup_profile 75 + Date: March 2010 76 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 77 + Description: The integer value of this attribute ranges from 1 to 5. 78 + When read, this attribute returns the number of the profile 79 + that's active when the mouse is powered on. 80 + When written, this file sets the number of the startup profile 81 + and the mouse activates this profile immediately. 82 + 83 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/tcu 84 + Date: March 2010 85 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 86 + Description: The mouse has a "Tracking Control Unit" which lets the user 87 + calibrate the laser power to fit the mousepad surface. 88 + When read, this file returns the current state of the TCU, 89 + where 0 means off and 1 means on. 90 + Writing 0 in this file will switch the TCU off. 91 + Writing 1 in this file will start the calibration which takes 92 + around 6 seconds to complete and activates the TCU. 93 + 94 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/weight 95 + Date: March 2010 96 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 97 + Description: The mouse can be equipped with one of four supplied weights 98 + ranging from 5 to 20 grams which are recognized by the mouse 99 + and its value can be read out. When read, this file returns the 100 + raw value returned by the mouse which eases further processing 101 + in other software. 102 + The values map to the weights as follows: 103 + 104 + VALUE WEIGHT 105 + 0 none 106 + 1 5g 107 + 2 10g 108 + 3 15g 109 + 4 20g 110 + 111 + This file is readonly.
+79
drivers/hid/Kconfig
··· 106 106 ---help--- 107 107 Support for Chicony Tactical pad. 108 108 109 + config HID_PRODIKEYS 110 + tristate "Prodikeys PC-MIDI Keyboard support" 111 + depends on USB_HID && SND 112 + select SND_RAWMIDI 113 + ---help--- 114 + Support for Prodikeys PC-MIDI Keyboard device support. 115 + Say Y here to enable support for this device. 116 + - Prodikeys PC-MIDI keyboard. 117 + The Prodikeys PC-MIDI acts as a USB Audio device, with one MIDI 118 + input and one MIDI output. These MIDI jacks appear as 119 + a sound "card" in the ALSA sound system. 120 + Note: if you say N here, this device will still function as a basic 121 + multimedia keyboard, but will lack support for the musical keyboard 122 + and some additional multimedia keys. 123 + 109 124 config HID_CYPRESS 110 125 tristate "Cypress" if EMBEDDED 111 126 depends on USB_HID ··· 289 274 ---help--- 290 275 Support for Petalynx Maxter remote control. 291 276 277 + config HID_PICOLCD 278 + tristate "PicoLCD (graphic version)" 279 + depends on USB_HID 280 + ---help--- 281 + This provides support for Minibox PicoLCD devices, currently 282 + only the graphical ones are supported. 283 + 284 + This includes support for the following device features: 285 + - Keypad 286 + - Switching between Firmware and Flash mode 287 + - EEProm / Flash access (via debugfs) 288 + Features selectively enabled: 289 + - Framebuffer for monochrome 256x64 display 290 + - Backlight control 291 + - Contrast control 292 + - General purpose outputs 293 + Features that are not (yet) supported: 294 + - IR 295 + 296 + config HID_PICOLCD_FB 297 + bool "Framebuffer support" if EMBEDDED 298 + default !EMBEDDED 299 + depends on HID_PICOLCD 300 + depends on HID_PICOLCD=FB || FB=y 301 + select FB_DEFERRED_IO 302 + select FB_SYS_FILLRECT 303 + select FB_SYS_COPYAREA 304 + select FB_SYS_IMAGEBLIT 305 + select FB_SYS_FOPS 306 + ---help--- 307 + Provide access to PicoLCD's 256x64 monochrome display via a 308 + frambuffer device. 309 + 310 + config HID_PICOLCD_BACKLIGHT 311 + bool "Backlight control" if EMBEDDED 312 + default !EMBEDDED 313 + depends on HID_PICOLCD 314 + depends on HID_PICOLCD=BACKLIGHT_CLASS_DEVICE || BACKLIGHT_CLASS_DEVICE=y 315 + ---help--- 316 + Provide access to PicoLCD's backlight control via backlight 317 + class. 318 + 319 + config HID_PICOLCD_LCD 320 + bool "Contrast control" if EMBEDDED 321 + default !EMBEDDED 322 + depends on HID_PICOLCD 323 + depends on HID_PICOLCD=LCD_CLASS_DEVICE || LCD_CLASS_DEVICE=y 324 + ---help--- 325 + Provide access to PicoLCD's LCD contrast via lcd class. 326 + 327 + config HID_PICOLCD_LEDS 328 + bool "GPO via leds class" if EMBEDDED 329 + default !EMBEDDED 330 + depends on HID_PICOLCD 331 + depends on HID_PICOLCD=LEDS_CLASS || LEDS_CLASS=y 332 + ---help--- 333 + Provide access to PicoLCD's GPO pins via leds class. 334 + 292 335 config HID_QUANTA 293 336 tristate "Quanta Optical Touch" 294 337 depends on USB_HID 295 338 ---help--- 296 339 Support for Quanta Optical Touch dual-touch panels. 340 + 341 + config HID_ROCCAT_KONE 342 + tristate "Roccat Kone Mouse support" 343 + depends on USB_HID 344 + ---help--- 345 + Support for Roccat Kone mouse. 297 346 298 347 config HID_SAMSUNG 299 348 tristate "Samsung" if EMBEDDED
+3
drivers/hid/Makefile
··· 43 43 obj-$(CONFIG_HID_MOSART) += hid-mosart.o 44 44 obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o 45 45 obj-$(CONFIG_HID_ORTEK) += hid-ortek.o 46 + obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o 46 47 obj-$(CONFIG_HID_QUANTA) += hid-quanta.o 47 48 obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o 48 49 obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o 50 + obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o 51 + obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o 49 52 obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o 50 53 obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o 51 54 obj-$(CONFIG_HID_SONY) += hid-sony.o
+4
drivers/hid/hid-core.c
··· 1287 1287 { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, 1288 1288 { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, 1289 1289 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, 1290 + { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, 1290 1291 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, 1291 1292 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, 1292 1293 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) }, ··· 1327 1326 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, 1328 1327 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) }, 1329 1328 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) }, 1329 + { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) }, 1330 + { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) }, 1330 1331 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, 1331 1332 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) }, 1332 1333 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) }, ··· 1340 1337 { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, 1341 1338 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, 1342 1339 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, 1340 + { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) }, 1343 1341 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, 1344 1342 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, 1345 1343 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
+8
drivers/hid/hid-ids.h
··· 156 156 #define USB_DEVICE_ID_CODEMERCS_IOW_FIRST 0x1500 157 157 #define USB_DEVICE_ID_CODEMERCS_IOW_LAST 0x15ff 158 158 159 + #define USB_VENDOR_ID_CREATIVELABS 0x041e 160 + #define USB_DEVICE_ID_PRODIKEYS_PCMIDI 0x2801 161 + 159 162 #define USB_VENDOR_ID_CYGNAL 0x10c4 160 163 #define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a 161 164 ··· 357 354 #define USB_VENDOR_ID_MICROCHIP 0x04d8 358 355 #define USB_DEVICE_ID_PICKIT1 0x0032 359 356 #define USB_DEVICE_ID_PICKIT2 0x0033 357 + #define USB_DEVICE_ID_PICOLCD 0xc002 358 + #define USB_DEVICE_ID_PICOLCD_BOOTLOADER 0xf002 360 359 361 360 #define USB_VENDOR_ID_MICROSOFT 0x045e 362 361 #define USB_DEVICE_ID_SIDEWINDER_GV 0x003b ··· 416 411 417 412 #define USB_VENDOR_ID_PRODIGE 0x05af 418 413 #define USB_DEVICE_ID_PRODIGE_CORDLESS 0x3062 414 + 415 + #define USB_VENDOR_ID_ROCCAT 0x1e7d 416 + #define USB_DEVICE_ID_ROCCAT_KONE 0x2ced 419 417 420 418 #define USB_VENDOR_ID_SAITEK 0x06a3 421 419 #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
+517 -9
drivers/hid/hid-ntrig.c
··· 24 24 25 25 #define NTRIG_DUPLICATE_USAGES 0x001 26 26 27 + static unsigned int min_width; 28 + module_param(min_width, uint, 0644); 29 + MODULE_PARM_DESC(min_width, "Minimum touch contact width to accept."); 30 + 31 + static unsigned int min_height; 32 + module_param(min_height, uint, 0644); 33 + MODULE_PARM_DESC(min_height, "Minimum touch contact height to accept."); 34 + 35 + static unsigned int activate_slack = 1; 36 + module_param(activate_slack, uint, 0644); 37 + MODULE_PARM_DESC(activate_slack, "Number of touch frames to ignore at " 38 + "the start of touch input."); 39 + 40 + static unsigned int deactivate_slack = 4; 41 + module_param(deactivate_slack, uint, 0644); 42 + MODULE_PARM_DESC(deactivate_slack, "Number of empty frames to ignore before " 43 + "deactivating touch."); 44 + 45 + static unsigned int activation_width = 64; 46 + module_param(activation_width, uint, 0644); 47 + MODULE_PARM_DESC(activation_width, "Width threshold to immediately start " 48 + "processing touch events."); 49 + 50 + static unsigned int activation_height = 32; 51 + module_param(activation_height, uint, 0644); 52 + MODULE_PARM_DESC(activation_height, "Height threshold to immediately start " 53 + "processing touch events."); 54 + 27 55 struct ntrig_data { 28 56 /* Incoming raw values for a single contact */ 29 57 __u16 x, y, w, h; ··· 65 37 66 38 __u8 mt_footer[4]; 67 39 __u8 mt_foot_count; 40 + 41 + /* The current activation state. */ 42 + __s8 act_state; 43 + 44 + /* Empty frames to ignore before recognizing the end of activity */ 45 + __s8 deactivate_slack; 46 + 47 + /* Frames to ignore before acknowledging the start of activity */ 48 + __s8 activate_slack; 49 + 50 + /* Minimum size contact to accept */ 51 + __u16 min_width; 52 + __u16 min_height; 53 + 54 + /* Threshold to override activation slack */ 55 + __u16 activation_width; 56 + __u16 activation_height; 57 + 58 + __u16 sensor_logical_width; 59 + __u16 sensor_logical_height; 60 + __u16 sensor_physical_width; 61 + __u16 sensor_physical_height; 62 + }; 63 + 64 + 65 + static ssize_t show_phys_width(struct device *dev, 66 + struct device_attribute *attr, 67 + char *buf) 68 + { 69 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 70 + struct ntrig_data *nd = hid_get_drvdata(hdev); 71 + 72 + return sprintf(buf, "%d\n", nd->sensor_physical_width); 73 + } 74 + 75 + static DEVICE_ATTR(sensor_physical_width, S_IRUGO, show_phys_width, NULL); 76 + 77 + static ssize_t show_phys_height(struct device *dev, 78 + struct device_attribute *attr, 79 + char *buf) 80 + { 81 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 82 + struct ntrig_data *nd = hid_get_drvdata(hdev); 83 + 84 + return sprintf(buf, "%d\n", nd->sensor_physical_height); 85 + } 86 + 87 + static DEVICE_ATTR(sensor_physical_height, S_IRUGO, show_phys_height, NULL); 88 + 89 + static ssize_t show_log_width(struct device *dev, 90 + struct device_attribute *attr, 91 + char *buf) 92 + { 93 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 94 + struct ntrig_data *nd = hid_get_drvdata(hdev); 95 + 96 + return sprintf(buf, "%d\n", nd->sensor_logical_width); 97 + } 98 + 99 + static DEVICE_ATTR(sensor_logical_width, S_IRUGO, show_log_width, NULL); 100 + 101 + static ssize_t show_log_height(struct device *dev, 102 + struct device_attribute *attr, 103 + char *buf) 104 + { 105 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 106 + struct ntrig_data *nd = hid_get_drvdata(hdev); 107 + 108 + return sprintf(buf, "%d\n", nd->sensor_logical_height); 109 + } 110 + 111 + static DEVICE_ATTR(sensor_logical_height, S_IRUGO, show_log_height, NULL); 112 + 113 + static ssize_t show_min_width(struct device *dev, 114 + struct device_attribute *attr, 115 + char *buf) 116 + { 117 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 118 + struct ntrig_data *nd = hid_get_drvdata(hdev); 119 + 120 + return sprintf(buf, "%d\n", nd->min_width * 121 + nd->sensor_physical_width / 122 + nd->sensor_logical_width); 123 + } 124 + 125 + static ssize_t set_min_width(struct device *dev, 126 + struct device_attribute *attr, 127 + const char *buf, size_t count) 128 + { 129 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 130 + struct ntrig_data *nd = hid_get_drvdata(hdev); 131 + 132 + unsigned long val; 133 + 134 + if (strict_strtoul(buf, 0, &val)) 135 + return -EINVAL; 136 + 137 + if (val > nd->sensor_physical_width) 138 + return -EINVAL; 139 + 140 + nd->min_width = val * nd->sensor_logical_width / 141 + nd->sensor_physical_width; 142 + 143 + return count; 144 + } 145 + 146 + static DEVICE_ATTR(min_width, S_IWUSR | S_IRUGO, show_min_width, set_min_width); 147 + 148 + static ssize_t show_min_height(struct device *dev, 149 + struct device_attribute *attr, 150 + char *buf) 151 + { 152 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 153 + struct ntrig_data *nd = hid_get_drvdata(hdev); 154 + 155 + return sprintf(buf, "%d\n", nd->min_height * 156 + nd->sensor_physical_height / 157 + nd->sensor_logical_height); 158 + } 159 + 160 + static ssize_t set_min_height(struct device *dev, 161 + struct device_attribute *attr, 162 + const char *buf, size_t count) 163 + { 164 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 165 + struct ntrig_data *nd = hid_get_drvdata(hdev); 166 + 167 + unsigned long val; 168 + 169 + if (strict_strtoul(buf, 0, &val)) 170 + return -EINVAL; 171 + 172 + if (val > nd->sensor_physical_height) 173 + return -EINVAL; 174 + 175 + nd->min_height = val * nd->sensor_logical_height / 176 + nd->sensor_physical_height; 177 + 178 + return count; 179 + } 180 + 181 + static DEVICE_ATTR(min_height, S_IWUSR | S_IRUGO, show_min_height, 182 + set_min_height); 183 + 184 + static ssize_t show_activate_slack(struct device *dev, 185 + struct device_attribute *attr, 186 + char *buf) 187 + { 188 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 189 + struct ntrig_data *nd = hid_get_drvdata(hdev); 190 + 191 + return sprintf(buf, "%d\n", nd->activate_slack); 192 + } 193 + 194 + static ssize_t set_activate_slack(struct device *dev, 195 + struct device_attribute *attr, 196 + const char *buf, size_t count) 197 + { 198 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 199 + struct ntrig_data *nd = hid_get_drvdata(hdev); 200 + 201 + unsigned long val; 202 + 203 + if (strict_strtoul(buf, 0, &val)) 204 + return -EINVAL; 205 + 206 + if (val > 0x7f) 207 + return -EINVAL; 208 + 209 + nd->activate_slack = val; 210 + 211 + return count; 212 + } 213 + 214 + static DEVICE_ATTR(activate_slack, S_IWUSR | S_IRUGO, show_activate_slack, 215 + set_activate_slack); 216 + 217 + static ssize_t show_activation_width(struct device *dev, 218 + struct device_attribute *attr, 219 + char *buf) 220 + { 221 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 222 + struct ntrig_data *nd = hid_get_drvdata(hdev); 223 + 224 + return sprintf(buf, "%d\n", nd->activation_width * 225 + nd->sensor_physical_width / 226 + nd->sensor_logical_width); 227 + } 228 + 229 + static ssize_t set_activation_width(struct device *dev, 230 + struct device_attribute *attr, 231 + const char *buf, size_t count) 232 + { 233 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 234 + struct ntrig_data *nd = hid_get_drvdata(hdev); 235 + 236 + unsigned long val; 237 + 238 + if (strict_strtoul(buf, 0, &val)) 239 + return -EINVAL; 240 + 241 + if (val > nd->sensor_physical_width) 242 + return -EINVAL; 243 + 244 + nd->activation_width = val * nd->sensor_logical_width / 245 + nd->sensor_physical_width; 246 + 247 + return count; 248 + } 249 + 250 + static DEVICE_ATTR(activation_width, S_IWUSR | S_IRUGO, show_activation_width, 251 + set_activation_width); 252 + 253 + static ssize_t show_activation_height(struct device *dev, 254 + struct device_attribute *attr, 255 + char *buf) 256 + { 257 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 258 + struct ntrig_data *nd = hid_get_drvdata(hdev); 259 + 260 + return sprintf(buf, "%d\n", nd->activation_height * 261 + nd->sensor_physical_height / 262 + nd->sensor_logical_height); 263 + } 264 + 265 + static ssize_t set_activation_height(struct device *dev, 266 + struct device_attribute *attr, 267 + const char *buf, size_t count) 268 + { 269 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 270 + struct ntrig_data *nd = hid_get_drvdata(hdev); 271 + 272 + unsigned long val; 273 + 274 + if (strict_strtoul(buf, 0, &val)) 275 + return -EINVAL; 276 + 277 + if (val > nd->sensor_physical_height) 278 + return -EINVAL; 279 + 280 + nd->activation_height = val * nd->sensor_logical_height / 281 + nd->sensor_physical_height; 282 + 283 + return count; 284 + } 285 + 286 + static DEVICE_ATTR(activation_height, S_IWUSR | S_IRUGO, 287 + show_activation_height, set_activation_height); 288 + 289 + static ssize_t show_deactivate_slack(struct device *dev, 290 + struct device_attribute *attr, 291 + char *buf) 292 + { 293 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 294 + struct ntrig_data *nd = hid_get_drvdata(hdev); 295 + 296 + return sprintf(buf, "%d\n", -nd->deactivate_slack); 297 + } 298 + 299 + static ssize_t set_deactivate_slack(struct device *dev, 300 + struct device_attribute *attr, 301 + const char *buf, size_t count) 302 + { 303 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 304 + struct ntrig_data *nd = hid_get_drvdata(hdev); 305 + 306 + unsigned long val; 307 + 308 + if (strict_strtoul(buf, 0, &val)) 309 + return -EINVAL; 310 + 311 + /* 312 + * No more than 8 terminal frames have been observed so far 313 + * and higher slack is highly likely to leave the single 314 + * touch emulation stuck down. 315 + */ 316 + if (val > 7) 317 + return -EINVAL; 318 + 319 + nd->deactivate_slack = -val; 320 + 321 + return count; 322 + } 323 + 324 + static DEVICE_ATTR(deactivate_slack, S_IWUSR | S_IRUGO, show_deactivate_slack, 325 + set_deactivate_slack); 326 + 327 + static struct attribute *sysfs_attrs[] = { 328 + &dev_attr_sensor_physical_width.attr, 329 + &dev_attr_sensor_physical_height.attr, 330 + &dev_attr_sensor_logical_width.attr, 331 + &dev_attr_sensor_logical_height.attr, 332 + &dev_attr_min_height.attr, 333 + &dev_attr_min_width.attr, 334 + &dev_attr_activate_slack.attr, 335 + &dev_attr_activation_width.attr, 336 + &dev_attr_activation_height.attr, 337 + &dev_attr_deactivate_slack.attr, 338 + NULL 339 + }; 340 + 341 + static struct attribute_group ntrig_attribute_group = { 342 + .attrs = sysfs_attrs 68 343 }; 69 344 70 345 /* ··· 380 49 struct hid_field *field, struct hid_usage *usage, 381 50 unsigned long **bit, int *max) 382 51 { 52 + struct ntrig_data *nd = hid_get_drvdata(hdev); 53 + 383 54 /* No special mappings needed for the pen and single touch */ 384 55 if (field->physical) 385 56 return 0; ··· 395 62 input_set_abs_params(hi->input, ABS_X, 396 63 field->logical_minimum, 397 64 field->logical_maximum, 0, 0); 65 + 66 + if (!nd->sensor_logical_width) { 67 + nd->sensor_logical_width = 68 + field->logical_maximum - 69 + field->logical_minimum; 70 + nd->sensor_physical_width = 71 + field->physical_maximum - 72 + field->physical_minimum; 73 + nd->activation_width = activation_width * 74 + nd->sensor_logical_width / 75 + nd->sensor_physical_width; 76 + nd->min_width = min_width * 77 + nd->sensor_logical_width / 78 + nd->sensor_physical_width; 79 + } 398 80 return 1; 399 81 case HID_GD_Y: 400 82 hid_map_usage(hi, usage, bit, max, ··· 417 69 input_set_abs_params(hi->input, ABS_Y, 418 70 field->logical_minimum, 419 71 field->logical_maximum, 0, 0); 72 + 73 + if (!nd->sensor_logical_height) { 74 + nd->sensor_logical_height = 75 + field->logical_maximum - 76 + field->logical_minimum; 77 + nd->sensor_physical_height = 78 + field->physical_maximum - 79 + field->physical_minimum; 80 + nd->activation_height = activation_height * 81 + nd->sensor_logical_height / 82 + nd->sensor_physical_height; 83 + nd->min_height = min_height * 84 + nd->sensor_logical_height / 85 + nd->sensor_physical_height; 86 + } 420 87 return 1; 421 88 } 422 89 return 0; ··· 564 201 if (nd->mt_foot_count != 4) 565 202 break; 566 203 567 - /* Pen activity signal, trigger end of touch. */ 204 + /* Pen activity signal. */ 568 205 if (nd->mt_footer[2]) { 206 + /* 207 + * When the pen deactivates touch, we see a 208 + * bogus frame with ContactCount > 0. 209 + * We can 210 + * save a bit of work by ensuring act_state < 0 211 + * even if deactivation slack is turned off. 212 + */ 213 + nd->act_state = deactivate_slack - 1; 569 214 nd->confidence = 0; 570 215 break; 571 216 } 572 217 573 - /* If the contact was invalid */ 574 - if (!(nd->confidence && nd->mt_footer[0]) 575 - || nd->w <= 250 576 - || nd->h <= 190) { 577 - nd->confidence = 0; 218 + /* 219 + * The first footer value indicates the presence of a 220 + * finger. 221 + */ 222 + if (nd->mt_footer[0]) { 223 + /* 224 + * We do not want to process contacts under 225 + * the size threshold, but do not want to 226 + * ignore them for activation state 227 + */ 228 + if (nd->w < nd->min_width || 229 + nd->h < nd->min_height) 230 + nd->confidence = 0; 231 + } else 578 232 break; 233 + 234 + if (nd->act_state > 0) { 235 + /* 236 + * Contact meets the activation size threshold 237 + */ 238 + if (nd->w >= nd->activation_width && 239 + nd->h >= nd->activation_height) { 240 + if (nd->id) 241 + /* 242 + * first contact, activate now 243 + */ 244 + nd->act_state = 0; 245 + else { 246 + /* 247 + * avoid corrupting this frame 248 + * but ensure next frame will 249 + * be active 250 + */ 251 + nd->act_state = 1; 252 + break; 253 + } 254 + } else 255 + /* 256 + * Defer adjusting the activation state 257 + * until the end of the frame. 258 + */ 259 + break; 579 260 } 261 + 262 + /* Discarding this contact */ 263 + if (!nd->confidence) 264 + break; 580 265 581 266 /* emit a normal (X, Y) for the first point only */ 582 267 if (nd->id == 0) { ··· 638 227 input_event(input, EV_ABS, ABS_X, nd->x); 639 228 input_event(input, EV_ABS, ABS_Y, nd->y); 640 229 } 230 + 231 + /* Emit MT events */ 641 232 input_event(input, EV_ABS, ABS_MT_POSITION_X, nd->x); 642 233 input_event(input, EV_ABS, ABS_MT_POSITION_Y, nd->y); 234 + 235 + /* 236 + * Translate from height and width to size 237 + * and orientation. 238 + */ 643 239 if (nd->w > nd->h) { 644 240 input_event(input, EV_ABS, 645 241 ABS_MT_ORIENTATION, 1); ··· 666 248 break; 667 249 668 250 case HID_DG_CONTACTCOUNT: /* End of a multitouch group */ 669 - if (!nd->reading_mt) 251 + if (!nd->reading_mt) /* Just to be sure */ 670 252 break; 671 253 672 254 nd->reading_mt = 0; 673 255 674 - if (nd->first_contact_touch) { 256 + 257 + /* 258 + * Activation state machine logic: 259 + * 260 + * Fundamental states: 261 + * state > 0: Inactive 262 + * state <= 0: Active 263 + * state < -deactivate_slack: 264 + * Pen termination of touch 265 + * 266 + * Specific values of interest 267 + * state == activate_slack 268 + * no valid input since the last reset 269 + * 270 + * state == 0 271 + * general operational state 272 + * 273 + * state == -deactivate_slack 274 + * read sufficient empty frames to accept 275 + * the end of input and reset 276 + */ 277 + 278 + if (nd->act_state > 0) { /* Currently inactive */ 279 + if (value) 280 + /* 281 + * Consider each live contact as 282 + * evidence of intentional activity. 283 + */ 284 + nd->act_state = (nd->act_state > value) 285 + ? nd->act_state - value 286 + : 0; 287 + else 288 + /* 289 + * Empty frame before we hit the 290 + * activity threshold, reset. 291 + */ 292 + nd->act_state = nd->activate_slack; 293 + 294 + /* 295 + * Entered this block inactive and no 296 + * coordinates sent this frame, so hold off 297 + * on button state. 298 + */ 299 + break; 300 + } else { /* Currently active */ 301 + if (value && nd->act_state >= 302 + nd->deactivate_slack) 303 + /* 304 + * Live point: clear accumulated 305 + * deactivation count. 306 + */ 307 + nd->act_state = 0; 308 + else if (nd->act_state <= nd->deactivate_slack) 309 + /* 310 + * We've consumed the deactivation 311 + * slack, time to deactivate and reset. 312 + */ 313 + nd->act_state = 314 + nd->activate_slack; 315 + else { /* Move towards deactivation */ 316 + nd->act_state--; 317 + break; 318 + } 319 + } 320 + 321 + if (nd->first_contact_touch && nd->act_state <= 0) { 322 + /* 323 + * Check to see if we're ready to start 324 + * emitting touch events. 325 + * 326 + * Note: activation slack will decrease over 327 + * the course of the frame, and it will be 328 + * inconsistent from the start to the end of 329 + * the frame. However if the frame starts 330 + * with slack, first_contact_touch will still 331 + * be 0 and we will not get to this point. 332 + */ 675 333 input_report_key(input, BTN_TOOL_DOUBLETAP, 1); 676 334 input_report_key(input, BTN_TOUCH, 1); 677 335 } else { ··· 757 263 break; 758 264 759 265 default: 760 - /* fallback to the generic hidinput handling */ 266 + /* fall-back to the generic hidinput handling */ 761 267 return 0; 762 268 } 763 269 } ··· 787 293 } 788 294 789 295 nd->reading_mt = 0; 296 + nd->min_width = 0; 297 + nd->min_height = 0; 298 + nd->activate_slack = activate_slack; 299 + nd->act_state = activate_slack; 300 + nd->deactivate_slack = -deactivate_slack; 301 + nd->sensor_logical_width = 0; 302 + nd->sensor_logical_height = 0; 303 + nd->sensor_physical_width = 0; 304 + nd->sensor_physical_height = 0; 305 + 790 306 hid_set_drvdata(hdev, nd); 791 307 792 308 ret = hid_parse(hdev); ··· 848 344 if (report) 849 345 usbhid_submit_report(hdev, report, USB_DIR_OUT); 850 346 347 + ret = sysfs_create_group(&hdev->dev.kobj, 348 + &ntrig_attribute_group); 851 349 852 350 return 0; 853 351 err_free: ··· 859 353 860 354 static void ntrig_remove(struct hid_device *hdev) 861 355 { 356 + sysfs_remove_group(&hdev->dev.kobj, 357 + &ntrig_attribute_group); 862 358 hid_hw_stop(hdev); 863 359 kfree(hid_get_drvdata(hdev)); 864 360 }
+2631
drivers/hid/hid-picolcd.c
··· 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 + 40 + #define PICOLCD_NAME "PicoLCD (graphic)" 41 + 42 + /* Report numbers */ 43 + #define REPORT_ERROR_CODE 0x10 /* LCD: IN[16] */ 44 + #define ERR_SUCCESS 0x00 45 + #define ERR_PARAMETER_MISSING 0x01 46 + #define ERR_DATA_MISSING 0x02 47 + #define ERR_BLOCK_READ_ONLY 0x03 48 + #define ERR_BLOCK_NOT_ERASABLE 0x04 49 + #define ERR_BLOCK_TOO_BIG 0x05 50 + #define ERR_SECTION_OVERFLOW 0x06 51 + #define ERR_INVALID_CMD_LEN 0x07 52 + #define ERR_INVALID_DATA_LEN 0x08 53 + #define REPORT_KEY_STATE 0x11 /* LCD: IN[2] */ 54 + #define REPORT_IR_DATA 0x21 /* LCD: IN[63] */ 55 + #define REPORT_EE_DATA 0x32 /* LCD: IN[63] */ 56 + #define REPORT_MEMORY 0x41 /* LCD: IN[63] */ 57 + #define REPORT_LED_STATE 0x81 /* LCD: OUT[1] */ 58 + #define REPORT_BRIGHTNESS 0x91 /* LCD: OUT[1] */ 59 + #define REPORT_CONTRAST 0x92 /* LCD: OUT[1] */ 60 + #define REPORT_RESET 0x93 /* LCD: OUT[2] */ 61 + #define REPORT_LCD_CMD 0x94 /* LCD: OUT[63] */ 62 + #define REPORT_LCD_DATA 0x95 /* LCD: OUT[63] */ 63 + #define REPORT_LCD_CMD_DATA 0x96 /* LCD: OUT[63] */ 64 + #define REPORT_EE_READ 0xa3 /* LCD: OUT[63] */ 65 + #define REPORT_EE_WRITE 0xa4 /* LCD: OUT[63] */ 66 + #define REPORT_ERASE_MEMORY 0xb2 /* LCD: OUT[2] */ 67 + #define REPORT_READ_MEMORY 0xb3 /* LCD: OUT[3] */ 68 + #define REPORT_WRITE_MEMORY 0xb4 /* LCD: OUT[63] */ 69 + #define REPORT_SPLASH_RESTART 0xc1 /* LCD: OUT[1] */ 70 + #define REPORT_EXIT_KEYBOARD 0xef /* LCD: OUT[2] */ 71 + #define REPORT_VERSION 0xf1 /* LCD: IN[2],OUT[1] Bootloader: IN[2],OUT[1] */ 72 + #define REPORT_BL_ERASE_MEMORY 0xf2 /* Bootloader: IN[36],OUT[4] */ 73 + #define REPORT_BL_READ_MEMORY 0xf3 /* Bootloader: IN[36],OUT[4] */ 74 + #define REPORT_BL_WRITE_MEMORY 0xf4 /* Bootloader: IN[36],OUT[36] */ 75 + #define REPORT_DEVID 0xf5 /* LCD: IN[5], OUT[1] Bootloader: IN[5],OUT[1] */ 76 + #define REPORT_SPLASH_SIZE 0xf6 /* LCD: IN[4], OUT[1] */ 77 + #define REPORT_HOOK_VERSION 0xf7 /* LCD: IN[2], OUT[1] */ 78 + #define REPORT_EXIT_FLASHER 0xff /* Bootloader: OUT[2] */ 79 + 80 + #ifdef CONFIG_HID_PICOLCD_FB 81 + /* Framebuffer 82 + * 83 + * The PicoLCD use a Topway LCD module of 256x64 pixel 84 + * This display area is tiled over 4 controllers with 8 tiles 85 + * each. Each tile has 8x64 pixel, each data byte representing 86 + * a 1-bit wide vertical line of the tile. 87 + * 88 + * The display can be updated at a tile granularity. 89 + * 90 + * Chip 1 Chip 2 Chip 3 Chip 4 91 + * +----------------+----------------+----------------+----------------+ 92 + * | Tile 1 | Tile 1 | Tile 1 | Tile 1 | 93 + * +----------------+----------------+----------------+----------------+ 94 + * | Tile 2 | Tile 2 | Tile 2 | Tile 2 | 95 + * +----------------+----------------+----------------+----------------+ 96 + * ... 97 + * +----------------+----------------+----------------+----------------+ 98 + * | Tile 8 | Tile 8 | Tile 8 | Tile 8 | 99 + * +----------------+----------------+----------------+----------------+ 100 + */ 101 + #define PICOLCDFB_NAME "picolcdfb" 102 + #define PICOLCDFB_WIDTH (256) 103 + #define PICOLCDFB_HEIGHT (64) 104 + #define PICOLCDFB_SIZE (PICOLCDFB_WIDTH * PICOLCDFB_HEIGHT / 8) 105 + 106 + #define PICOLCDFB_UPDATE_RATE_LIMIT 10 107 + #define PICOLCDFB_UPDATE_RATE_DEFAULT 2 108 + 109 + /* Framebuffer visual structures */ 110 + static const struct fb_fix_screeninfo picolcdfb_fix = { 111 + .id = PICOLCDFB_NAME, 112 + .type = FB_TYPE_PACKED_PIXELS, 113 + .visual = FB_VISUAL_MONO01, 114 + .xpanstep = 0, 115 + .ypanstep = 0, 116 + .ywrapstep = 0, 117 + .line_length = PICOLCDFB_WIDTH / 8, 118 + .accel = FB_ACCEL_NONE, 119 + }; 120 + 121 + static const struct fb_var_screeninfo picolcdfb_var = { 122 + .xres = PICOLCDFB_WIDTH, 123 + .yres = PICOLCDFB_HEIGHT, 124 + .xres_virtual = PICOLCDFB_WIDTH, 125 + .yres_virtual = PICOLCDFB_HEIGHT, 126 + .width = 103, 127 + .height = 26, 128 + .bits_per_pixel = 1, 129 + .grayscale = 1, 130 + }; 131 + #endif /* CONFIG_HID_PICOLCD_FB */ 132 + 133 + /* Input device 134 + * 135 + * The PicoLCD has an IR receiver header, a built-in keypad with 5 keys 136 + * and header for 4x4 key matrix. The built-in keys are part of the matrix. 137 + */ 138 + static const unsigned short def_keymap[] = { 139 + KEY_RESERVED, /* none */ 140 + KEY_BACK, /* col 4 + row 1 */ 141 + KEY_HOMEPAGE, /* col 3 + row 1 */ 142 + KEY_RESERVED, /* col 2 + row 1 */ 143 + KEY_RESERVED, /* col 1 + row 1 */ 144 + KEY_SCROLLUP, /* col 4 + row 2 */ 145 + KEY_OK, /* col 3 + row 2 */ 146 + KEY_SCROLLDOWN, /* col 2 + row 2 */ 147 + KEY_RESERVED, /* col 1 + row 2 */ 148 + KEY_RESERVED, /* col 4 + row 3 */ 149 + KEY_RESERVED, /* col 3 + row 3 */ 150 + KEY_RESERVED, /* col 2 + row 3 */ 151 + KEY_RESERVED, /* col 1 + row 3 */ 152 + KEY_RESERVED, /* col 4 + row 4 */ 153 + KEY_RESERVED, /* col 3 + row 4 */ 154 + KEY_RESERVED, /* col 2 + row 4 */ 155 + KEY_RESERVED, /* col 1 + row 4 */ 156 + }; 157 + #define PICOLCD_KEYS ARRAY_SIZE(def_keymap) 158 + 159 + /* Description of in-progress IO operation, used for operations 160 + * that trigger response from device */ 161 + struct picolcd_pending { 162 + struct hid_report *out_report; 163 + struct hid_report *in_report; 164 + struct completion ready; 165 + int raw_size; 166 + u8 raw_data[64]; 167 + }; 168 + 169 + /* Per device data structure */ 170 + struct picolcd_data { 171 + struct hid_device *hdev; 172 + #ifdef CONFIG_DEBUG_FS 173 + struct dentry *debug_reset; 174 + struct dentry *debug_eeprom; 175 + struct dentry *debug_flash; 176 + struct mutex mutex_flash; 177 + int addr_sz; 178 + #endif 179 + u8 version[2]; 180 + unsigned short opmode_delay; 181 + /* input stuff */ 182 + u8 pressed_keys[2]; 183 + struct input_dev *input_keys; 184 + struct input_dev *input_cir; 185 + unsigned short keycode[PICOLCD_KEYS]; 186 + 187 + #ifdef CONFIG_HID_PICOLCD_FB 188 + /* Framebuffer stuff */ 189 + u8 fb_update_rate; 190 + u8 fb_bpp; 191 + u8 *fb_vbitmap; /* local copy of what was sent to PicoLCD */ 192 + u8 *fb_bitmap; /* framebuffer */ 193 + struct fb_info *fb_info; 194 + struct fb_deferred_io fb_defio; 195 + #endif /* CONFIG_HID_PICOLCD_FB */ 196 + #ifdef CONFIG_HID_PICOLCD_LCD 197 + struct lcd_device *lcd; 198 + u8 lcd_contrast; 199 + #endif /* CONFIG_HID_PICOLCD_LCD */ 200 + #ifdef CONFIG_HID_PICOLCD_BACKLIGHT 201 + struct backlight_device *backlight; 202 + u8 lcd_brightness; 203 + u8 lcd_power; 204 + #endif /* CONFIG_HID_PICOLCD_BACKLIGHT */ 205 + #ifdef CONFIG_HID_PICOLCD_LEDS 206 + /* LED stuff */ 207 + u8 led_state; 208 + struct led_classdev *led[8]; 209 + #endif /* CONFIG_HID_PICOLCD_LEDS */ 210 + 211 + /* Housekeeping stuff */ 212 + spinlock_t lock; 213 + struct mutex mutex; 214 + struct picolcd_pending *pending; 215 + int status; 216 + #define PICOLCD_BOOTLOADER 1 217 + #define PICOLCD_FAILED 2 218 + #define PICOLCD_READY_FB 4 219 + }; 220 + 221 + 222 + /* Find a given report */ 223 + #define picolcd_in_report(id, dev) picolcd_report(id, dev, HID_INPUT_REPORT) 224 + #define picolcd_out_report(id, dev) picolcd_report(id, dev, HID_OUTPUT_REPORT) 225 + 226 + static struct hid_report *picolcd_report(int id, struct hid_device *hdev, int dir) 227 + { 228 + struct list_head *feature_report_list = &hdev->report_enum[dir].report_list; 229 + struct hid_report *report = NULL; 230 + 231 + list_for_each_entry(report, feature_report_list, list) { 232 + if (report->id == id) 233 + return report; 234 + } 235 + dev_warn(&hdev->dev, "No report with id 0x%x found\n", id); 236 + return NULL; 237 + } 238 + 239 + #ifdef CONFIG_DEBUG_FS 240 + static void picolcd_debug_out_report(struct picolcd_data *data, 241 + struct hid_device *hdev, struct hid_report *report); 242 + #define usbhid_submit_report(a, b, c) \ 243 + do { \ 244 + picolcd_debug_out_report(hid_get_drvdata(a), a, b); \ 245 + usbhid_submit_report(a, b, c); \ 246 + } while (0) 247 + #endif 248 + 249 + /* Submit a report and wait for a reply from device - if device fades away 250 + * or does not respond in time, return NULL */ 251 + static struct picolcd_pending *picolcd_send_and_wait(struct hid_device *hdev, 252 + int report_id, const u8 *raw_data, int size) 253 + { 254 + struct picolcd_data *data = hid_get_drvdata(hdev); 255 + struct picolcd_pending *work; 256 + struct hid_report *report = picolcd_out_report(report_id, hdev); 257 + unsigned long flags; 258 + int i, j, k; 259 + 260 + if (!report || !data) 261 + return NULL; 262 + if (data->status & PICOLCD_FAILED) 263 + return NULL; 264 + work = kzalloc(sizeof(*work), GFP_KERNEL); 265 + if (!work) 266 + return NULL; 267 + 268 + init_completion(&work->ready); 269 + work->out_report = report; 270 + work->in_report = NULL; 271 + work->raw_size = 0; 272 + 273 + mutex_lock(&data->mutex); 274 + spin_lock_irqsave(&data->lock, flags); 275 + for (i = k = 0; i < report->maxfield; i++) 276 + for (j = 0; j < report->field[i]->report_count; j++) { 277 + hid_set_field(report->field[i], j, k < size ? raw_data[k] : 0); 278 + k++; 279 + } 280 + data->pending = work; 281 + usbhid_submit_report(data->hdev, report, USB_DIR_OUT); 282 + spin_unlock_irqrestore(&data->lock, flags); 283 + wait_for_completion_interruptible_timeout(&work->ready, HZ*2); 284 + spin_lock_irqsave(&data->lock, flags); 285 + data->pending = NULL; 286 + spin_unlock_irqrestore(&data->lock, flags); 287 + mutex_unlock(&data->mutex); 288 + return work; 289 + } 290 + 291 + #ifdef CONFIG_HID_PICOLCD_FB 292 + /* Send a given tile to PicoLCD */ 293 + static int picolcd_fb_send_tile(struct hid_device *hdev, int chip, int tile) 294 + { 295 + struct picolcd_data *data = hid_get_drvdata(hdev); 296 + struct hid_report *report1 = picolcd_out_report(REPORT_LCD_CMD_DATA, hdev); 297 + struct hid_report *report2 = picolcd_out_report(REPORT_LCD_DATA, hdev); 298 + unsigned long flags; 299 + u8 *tdata; 300 + int i; 301 + 302 + if (!report1 || report1->maxfield != 1 || !report2 || report2->maxfield != 1) 303 + return -ENODEV; 304 + 305 + spin_lock_irqsave(&data->lock, flags); 306 + hid_set_field(report1->field[0], 0, chip << 2); 307 + hid_set_field(report1->field[0], 1, 0x02); 308 + hid_set_field(report1->field[0], 2, 0x00); 309 + hid_set_field(report1->field[0], 3, 0x00); 310 + hid_set_field(report1->field[0], 4, 0xb8 | tile); 311 + hid_set_field(report1->field[0], 5, 0x00); 312 + hid_set_field(report1->field[0], 6, 0x00); 313 + hid_set_field(report1->field[0], 7, 0x40); 314 + hid_set_field(report1->field[0], 8, 0x00); 315 + hid_set_field(report1->field[0], 9, 0x00); 316 + hid_set_field(report1->field[0], 10, 32); 317 + 318 + hid_set_field(report2->field[0], 0, (chip << 2) | 0x01); 319 + hid_set_field(report2->field[0], 1, 0x00); 320 + hid_set_field(report2->field[0], 2, 0x00); 321 + hid_set_field(report2->field[0], 3, 32); 322 + 323 + tdata = data->fb_vbitmap + (tile * 4 + chip) * 64; 324 + for (i = 0; i < 64; i++) 325 + if (i < 32) 326 + hid_set_field(report1->field[0], 11 + i, tdata[i]); 327 + else 328 + hid_set_field(report2->field[0], 4 + i - 32, tdata[i]); 329 + 330 + usbhid_submit_report(data->hdev, report1, USB_DIR_OUT); 331 + usbhid_submit_report(data->hdev, report2, USB_DIR_OUT); 332 + spin_unlock_irqrestore(&data->lock, flags); 333 + return 0; 334 + } 335 + 336 + /* Translate a single tile*/ 337 + static int picolcd_fb_update_tile(u8 *vbitmap, const u8 *bitmap, int bpp, 338 + int chip, int tile) 339 + { 340 + int i, b, changed = 0; 341 + u8 tdata[64]; 342 + u8 *vdata = vbitmap + (tile * 4 + chip) * 64; 343 + 344 + if (bpp == 1) { 345 + for (b = 7; b >= 0; b--) { 346 + const u8 *bdata = bitmap + tile * 256 + chip * 8 + b * 32; 347 + for (i = 0; i < 64; i++) { 348 + tdata[i] <<= 1; 349 + tdata[i] |= (bdata[i/8] >> (7 - i % 8)) & 0x01; 350 + } 351 + } 352 + } else if (bpp == 8) { 353 + for (b = 7; b >= 0; b--) { 354 + const u8 *bdata = bitmap + (tile * 256 + chip * 8 + b * 32) * 8; 355 + for (i = 0; i < 64; i++) { 356 + tdata[i] <<= 1; 357 + tdata[i] |= (bdata[i] & 0x80) ? 0x01 : 0x00; 358 + } 359 + } 360 + } else { 361 + /* Oops, we should never get here! */ 362 + WARN_ON(1); 363 + return 0; 364 + } 365 + 366 + for (i = 0; i < 64; i++) 367 + if (tdata[i] != vdata[i]) { 368 + changed = 1; 369 + vdata[i] = tdata[i]; 370 + } 371 + return changed; 372 + } 373 + 374 + /* Reconfigure LCD display */ 375 + static int picolcd_fb_reset(struct picolcd_data *data, int clear) 376 + { 377 + struct hid_report *report = picolcd_out_report(REPORT_LCD_CMD, data->hdev); 378 + int i, j; 379 + unsigned long flags; 380 + static const u8 mapcmd[8] = { 0x00, 0x02, 0x00, 0x64, 0x3f, 0x00, 0x64, 0xc0 }; 381 + 382 + if (!report || report->maxfield != 1) 383 + return -ENODEV; 384 + 385 + spin_lock_irqsave(&data->lock, flags); 386 + for (i = 0; i < 4; i++) { 387 + for (j = 0; j < report->field[0]->maxusage; j++) 388 + if (j == 0) 389 + hid_set_field(report->field[0], j, i << 2); 390 + else if (j < sizeof(mapcmd)) 391 + hid_set_field(report->field[0], j, mapcmd[j]); 392 + else 393 + hid_set_field(report->field[0], j, 0); 394 + usbhid_submit_report(data->hdev, report, USB_DIR_OUT); 395 + } 396 + 397 + data->status |= PICOLCD_READY_FB; 398 + spin_unlock_irqrestore(&data->lock, flags); 399 + 400 + if (data->fb_bitmap) { 401 + if (clear) { 402 + memset(data->fb_vbitmap, 0xff, PICOLCDFB_SIZE); 403 + memset(data->fb_bitmap, 0, PICOLCDFB_SIZE*data->fb_bpp); 404 + } else { 405 + /* invert 1 byte in each tile to force resend */ 406 + for (i = 0; i < PICOLCDFB_SIZE; i += 64) 407 + data->fb_vbitmap[i] = ~data->fb_vbitmap[i]; 408 + } 409 + } 410 + 411 + /* schedule first output of framebuffer */ 412 + if (data->fb_info) 413 + schedule_delayed_work(&data->fb_info->deferred_work, 0); 414 + 415 + return 0; 416 + } 417 + 418 + /* Update fb_vbitmap from the screen_base and send changed tiles to device */ 419 + static void picolcd_fb_update(struct picolcd_data *data) 420 + { 421 + int chip, tile, n; 422 + unsigned long flags; 423 + 424 + spin_lock_irqsave(&data->lock, flags); 425 + if (!(data->status & PICOLCD_READY_FB)) { 426 + spin_unlock_irqrestore(&data->lock, flags); 427 + picolcd_fb_reset(data, 0); 428 + } else { 429 + spin_unlock_irqrestore(&data->lock, flags); 430 + } 431 + 432 + /* 433 + * Translate the framebuffer into the format needed by the PicoLCD. 434 + * See display layout above. 435 + * Do this one tile after the other and push those tiles that changed. 436 + * 437 + * Wait for our IO to complete as otherwise we might flood the queue! 438 + */ 439 + n = 0; 440 + for (chip = 0; chip < 4; chip++) 441 + for (tile = 0; tile < 8; tile++) 442 + if (picolcd_fb_update_tile(data->fb_vbitmap, 443 + data->fb_bitmap, data->fb_bpp, chip, tile)) { 444 + n += 2; 445 + if (n >= HID_OUTPUT_FIFO_SIZE / 2) { 446 + usbhid_wait_io(data->hdev); 447 + n = 0; 448 + } 449 + picolcd_fb_send_tile(data->hdev, chip, tile); 450 + } 451 + if (n) 452 + usbhid_wait_io(data->hdev); 453 + } 454 + 455 + /* Stub to call the system default and update the image on the picoLCD */ 456 + static void picolcd_fb_fillrect(struct fb_info *info, 457 + const struct fb_fillrect *rect) 458 + { 459 + if (!info->par) 460 + return; 461 + sys_fillrect(info, rect); 462 + 463 + schedule_delayed_work(&info->deferred_work, 0); 464 + } 465 + 466 + /* Stub to call the system default and update the image on the picoLCD */ 467 + static void picolcd_fb_copyarea(struct fb_info *info, 468 + const struct fb_copyarea *area) 469 + { 470 + if (!info->par) 471 + return; 472 + sys_copyarea(info, area); 473 + 474 + schedule_delayed_work(&info->deferred_work, 0); 475 + } 476 + 477 + /* Stub to call the system default and update the image on the picoLCD */ 478 + static void picolcd_fb_imageblit(struct fb_info *info, const struct fb_image *image) 479 + { 480 + if (!info->par) 481 + return; 482 + sys_imageblit(info, image); 483 + 484 + schedule_delayed_work(&info->deferred_work, 0); 485 + } 486 + 487 + /* 488 + * this is the slow path from userspace. they can seek and write to 489 + * the fb. it's inefficient to do anything less than a full screen draw 490 + */ 491 + static ssize_t picolcd_fb_write(struct fb_info *info, const char __user *buf, 492 + size_t count, loff_t *ppos) 493 + { 494 + ssize_t ret; 495 + if (!info->par) 496 + return -ENODEV; 497 + ret = fb_sys_write(info, buf, count, ppos); 498 + if (ret >= 0) 499 + schedule_delayed_work(&info->deferred_work, 0); 500 + return ret; 501 + } 502 + 503 + static int picolcd_fb_blank(int blank, struct fb_info *info) 504 + { 505 + if (!info->par) 506 + return -ENODEV; 507 + /* We let fb notification do this for us via lcd/backlight device */ 508 + return 0; 509 + } 510 + 511 + static void picolcd_fb_destroy(struct fb_info *info) 512 + { 513 + struct picolcd_data *data = info->par; 514 + info->par = NULL; 515 + if (data) 516 + data->fb_info = NULL; 517 + fb_deferred_io_cleanup(info); 518 + framebuffer_release(info); 519 + } 520 + 521 + static int picolcd_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 522 + { 523 + __u32 bpp = var->bits_per_pixel; 524 + __u32 activate = var->activate; 525 + 526 + /* only allow 1/8 bit depth (8-bit is grayscale) */ 527 + *var = picolcdfb_var; 528 + var->activate = activate; 529 + if (bpp >= 8) 530 + var->bits_per_pixel = 8; 531 + else 532 + var->bits_per_pixel = 1; 533 + return 0; 534 + } 535 + 536 + static int picolcd_set_par(struct fb_info *info) 537 + { 538 + struct picolcd_data *data = info->par; 539 + u8 *o_fb, *n_fb; 540 + if (info->var.bits_per_pixel == data->fb_bpp) 541 + return 0; 542 + /* switch between 1/8 bit depths */ 543 + if (info->var.bits_per_pixel != 1 && info->var.bits_per_pixel != 8) 544 + return -EINVAL; 545 + 546 + o_fb = data->fb_bitmap; 547 + n_fb = vmalloc(PICOLCDFB_SIZE*info->var.bits_per_pixel); 548 + if (!n_fb) 549 + return -ENOMEM; 550 + 551 + fb_deferred_io_cleanup(info); 552 + /* translate FB content to new bits-per-pixel */ 553 + if (info->var.bits_per_pixel == 1) { 554 + int i, b; 555 + for (i = 0; i < PICOLCDFB_SIZE; i++) { 556 + u8 p = 0; 557 + for (b = 0; b < 8; b++) { 558 + p <<= 1; 559 + p |= o_fb[i*8+b] ? 0x01 : 0x00; 560 + } 561 + } 562 + info->fix.visual = FB_VISUAL_MONO01; 563 + info->fix.line_length = PICOLCDFB_WIDTH / 8; 564 + } else { 565 + int i; 566 + for (i = 0; i < PICOLCDFB_SIZE * 8; i++) 567 + n_fb[i] = o_fb[i/8] & (0x01 << (7 - i % 8)) ? 0xff : 0x00; 568 + info->fix.visual = FB_VISUAL_TRUECOLOR; 569 + info->fix.line_length = PICOLCDFB_WIDTH; 570 + } 571 + 572 + data->fb_bitmap = n_fb; 573 + data->fb_bpp = info->var.bits_per_pixel; 574 + info->screen_base = (char __force __iomem *)n_fb; 575 + info->fix.smem_start = (unsigned long)n_fb; 576 + info->fix.smem_len = PICOLCDFB_SIZE*data->fb_bpp; 577 + fb_deferred_io_init(info); 578 + vfree(o_fb); 579 + return 0; 580 + } 581 + 582 + /* Note this can't be const because of struct fb_info definition */ 583 + static struct fb_ops picolcdfb_ops = { 584 + .owner = THIS_MODULE, 585 + .fb_destroy = picolcd_fb_destroy, 586 + .fb_read = fb_sys_read, 587 + .fb_write = picolcd_fb_write, 588 + .fb_blank = picolcd_fb_blank, 589 + .fb_fillrect = picolcd_fb_fillrect, 590 + .fb_copyarea = picolcd_fb_copyarea, 591 + .fb_imageblit = picolcd_fb_imageblit, 592 + .fb_check_var = picolcd_fb_check_var, 593 + .fb_set_par = picolcd_set_par, 594 + }; 595 + 596 + 597 + /* Callback from deferred IO workqueue */ 598 + static void picolcd_fb_deferred_io(struct fb_info *info, struct list_head *pagelist) 599 + { 600 + picolcd_fb_update(info->par); 601 + } 602 + 603 + static const struct fb_deferred_io picolcd_fb_defio = { 604 + .delay = HZ / PICOLCDFB_UPDATE_RATE_DEFAULT, 605 + .deferred_io = picolcd_fb_deferred_io, 606 + }; 607 + 608 + 609 + /* 610 + * The "fb_update_rate" sysfs attribute 611 + */ 612 + static ssize_t picolcd_fb_update_rate_show(struct device *dev, 613 + struct device_attribute *attr, char *buf) 614 + { 615 + struct picolcd_data *data = dev_get_drvdata(dev); 616 + unsigned i, fb_update_rate = data->fb_update_rate; 617 + size_t ret = 0; 618 + 619 + for (i = 1; i <= PICOLCDFB_UPDATE_RATE_LIMIT; i++) 620 + if (ret >= PAGE_SIZE) 621 + break; 622 + else if (i == fb_update_rate) 623 + ret += snprintf(buf+ret, PAGE_SIZE-ret, "[%u] ", i); 624 + else 625 + ret += snprintf(buf+ret, PAGE_SIZE-ret, "%u ", i); 626 + if (ret > 0) 627 + buf[min(ret, (size_t)PAGE_SIZE)-1] = '\n'; 628 + return ret; 629 + } 630 + 631 + static ssize_t picolcd_fb_update_rate_store(struct device *dev, 632 + struct device_attribute *attr, const char *buf, size_t count) 633 + { 634 + struct picolcd_data *data = dev_get_drvdata(dev); 635 + int i; 636 + unsigned u; 637 + 638 + if (count < 1 || count > 10) 639 + return -EINVAL; 640 + 641 + i = sscanf(buf, "%u", &u); 642 + if (i != 1) 643 + return -EINVAL; 644 + 645 + if (u > PICOLCDFB_UPDATE_RATE_LIMIT) 646 + return -ERANGE; 647 + else if (u == 0) 648 + u = PICOLCDFB_UPDATE_RATE_DEFAULT; 649 + 650 + data->fb_update_rate = u; 651 + data->fb_defio.delay = HZ / data->fb_update_rate; 652 + return count; 653 + } 654 + 655 + static DEVICE_ATTR(fb_update_rate, 0666, picolcd_fb_update_rate_show, 656 + picolcd_fb_update_rate_store); 657 + 658 + /* initialize Framebuffer device */ 659 + static int picolcd_init_framebuffer(struct picolcd_data *data) 660 + { 661 + struct device *dev = &data->hdev->dev; 662 + struct fb_info *info = NULL; 663 + int error = -ENOMEM; 664 + u8 *fb_vbitmap = NULL; 665 + u8 *fb_bitmap = NULL; 666 + 667 + fb_bitmap = vmalloc(PICOLCDFB_SIZE*picolcdfb_var.bits_per_pixel); 668 + if (fb_bitmap == NULL) { 669 + dev_err(dev, "can't get a free page for framebuffer\n"); 670 + goto err_nomem; 671 + } 672 + 673 + fb_vbitmap = kmalloc(PICOLCDFB_SIZE, GFP_KERNEL); 674 + if (fb_vbitmap == NULL) { 675 + dev_err(dev, "can't alloc vbitmap image buffer\n"); 676 + goto err_nomem; 677 + } 678 + 679 + data->fb_update_rate = PICOLCDFB_UPDATE_RATE_DEFAULT; 680 + data->fb_defio = picolcd_fb_defio; 681 + info = framebuffer_alloc(0, dev); 682 + if (info == NULL) { 683 + dev_err(dev, "failed to allocate a framebuffer\n"); 684 + goto err_nomem; 685 + } 686 + 687 + info->fbdefio = &data->fb_defio; 688 + info->screen_base = (char __force __iomem *)fb_bitmap; 689 + info->fbops = &picolcdfb_ops; 690 + info->var = picolcdfb_var; 691 + info->fix = picolcdfb_fix; 692 + info->fix.smem_len = PICOLCDFB_SIZE; 693 + info->fix.smem_start = (unsigned long)fb_bitmap; 694 + info->par = data; 695 + info->flags = FBINFO_FLAG_DEFAULT; 696 + 697 + data->fb_vbitmap = fb_vbitmap; 698 + data->fb_bitmap = fb_bitmap; 699 + data->fb_bpp = picolcdfb_var.bits_per_pixel; 700 + error = picolcd_fb_reset(data, 1); 701 + if (error) { 702 + dev_err(dev, "failed to configure display\n"); 703 + goto err_cleanup; 704 + } 705 + error = device_create_file(dev, &dev_attr_fb_update_rate); 706 + if (error) { 707 + dev_err(dev, "failed to create sysfs attributes\n"); 708 + goto err_cleanup; 709 + } 710 + data->fb_info = info; 711 + error = register_framebuffer(info); 712 + if (error) { 713 + dev_err(dev, "failed to register framebuffer\n"); 714 + goto err_sysfs; 715 + } 716 + fb_deferred_io_init(info); 717 + /* schedule first output of framebuffer */ 718 + schedule_delayed_work(&info->deferred_work, 0); 719 + return 0; 720 + 721 + err_sysfs: 722 + device_remove_file(dev, &dev_attr_fb_update_rate); 723 + err_cleanup: 724 + data->fb_vbitmap = NULL; 725 + data->fb_bitmap = NULL; 726 + data->fb_bpp = 0; 727 + data->fb_info = NULL; 728 + 729 + err_nomem: 730 + framebuffer_release(info); 731 + vfree(fb_bitmap); 732 + kfree(fb_vbitmap); 733 + return error; 734 + } 735 + 736 + static void picolcd_exit_framebuffer(struct picolcd_data *data) 737 + { 738 + struct fb_info *info = data->fb_info; 739 + u8 *fb_vbitmap = data->fb_vbitmap; 740 + u8 *fb_bitmap = data->fb_bitmap; 741 + 742 + if (!info) 743 + return; 744 + 745 + data->fb_vbitmap = NULL; 746 + data->fb_bitmap = NULL; 747 + data->fb_bpp = 0; 748 + data->fb_info = NULL; 749 + device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate); 750 + fb_deferred_io_cleanup(info); 751 + unregister_framebuffer(info); 752 + vfree(fb_bitmap); 753 + kfree(fb_vbitmap); 754 + } 755 + 756 + #define picolcd_fbinfo(d) ((d)->fb_info) 757 + #else 758 + static inline int picolcd_fb_reset(struct picolcd_data *data, int clear) 759 + { 760 + return 0; 761 + } 762 + static inline int picolcd_init_framebuffer(struct picolcd_data *data) 763 + { 764 + return 0; 765 + } 766 + static inline void picolcd_exit_framebuffer(struct picolcd_data *data) 767 + { 768 + } 769 + #define picolcd_fbinfo(d) NULL 770 + #endif /* CONFIG_HID_PICOLCD_FB */ 771 + 772 + #ifdef CONFIG_HID_PICOLCD_BACKLIGHT 773 + /* 774 + * backlight class device 775 + */ 776 + static int picolcd_get_brightness(struct backlight_device *bdev) 777 + { 778 + struct picolcd_data *data = bl_get_data(bdev); 779 + return data->lcd_brightness; 780 + } 781 + 782 + static int picolcd_set_brightness(struct backlight_device *bdev) 783 + { 784 + struct picolcd_data *data = bl_get_data(bdev); 785 + struct hid_report *report = picolcd_out_report(REPORT_BRIGHTNESS, data->hdev); 786 + unsigned long flags; 787 + 788 + if (!report || report->maxfield != 1 || report->field[0]->report_count != 1) 789 + return -ENODEV; 790 + 791 + data->lcd_brightness = bdev->props.brightness & 0x0ff; 792 + data->lcd_power = bdev->props.power; 793 + spin_lock_irqsave(&data->lock, flags); 794 + hid_set_field(report->field[0], 0, data->lcd_power == FB_BLANK_UNBLANK ? data->lcd_brightness : 0); 795 + usbhid_submit_report(data->hdev, report, USB_DIR_OUT); 796 + spin_unlock_irqrestore(&data->lock, flags); 797 + return 0; 798 + } 799 + 800 + static int picolcd_check_bl_fb(struct backlight_device *bdev, struct fb_info *fb) 801 + { 802 + return fb && fb == picolcd_fbinfo((struct picolcd_data *)bl_get_data(bdev)); 803 + } 804 + 805 + static const struct backlight_ops picolcd_blops = { 806 + .update_status = picolcd_set_brightness, 807 + .get_brightness = picolcd_get_brightness, 808 + .check_fb = picolcd_check_bl_fb, 809 + }; 810 + 811 + static int picolcd_init_backlight(struct picolcd_data *data, struct hid_report *report) 812 + { 813 + struct device *dev = &data->hdev->dev; 814 + struct backlight_device *bdev; 815 + struct backlight_properties props; 816 + if (!report) 817 + return -ENODEV; 818 + if (report->maxfield != 1 || report->field[0]->report_count != 1 || 819 + report->field[0]->report_size != 8) { 820 + dev_err(dev, "unsupported BRIGHTNESS report"); 821 + return -EINVAL; 822 + } 823 + 824 + memset(&props, 0, sizeof(props)); 825 + props.max_brightness = 0xff; 826 + bdev = backlight_device_register(dev_name(dev), dev, data, 827 + &picolcd_blops, &props); 828 + if (IS_ERR(bdev)) { 829 + dev_err(dev, "failed to register backlight\n"); 830 + return PTR_ERR(bdev); 831 + } 832 + bdev->props.brightness = 0xff; 833 + data->lcd_brightness = 0xff; 834 + data->backlight = bdev; 835 + picolcd_set_brightness(bdev); 836 + return 0; 837 + } 838 + 839 + static void picolcd_exit_backlight(struct picolcd_data *data) 840 + { 841 + struct backlight_device *bdev = data->backlight; 842 + 843 + data->backlight = NULL; 844 + if (bdev) 845 + backlight_device_unregister(bdev); 846 + } 847 + 848 + static inline int picolcd_resume_backlight(struct picolcd_data *data) 849 + { 850 + if (!data->backlight) 851 + return 0; 852 + return picolcd_set_brightness(data->backlight); 853 + } 854 + 855 + #ifdef CONFIG_PM 856 + static void picolcd_suspend_backlight(struct picolcd_data *data) 857 + { 858 + int bl_power = data->lcd_power; 859 + if (!data->backlight) 860 + return; 861 + 862 + data->backlight->props.power = FB_BLANK_POWERDOWN; 863 + picolcd_set_brightness(data->backlight); 864 + data->lcd_power = data->backlight->props.power = bl_power; 865 + } 866 + #endif /* CONFIG_PM */ 867 + #else 868 + static inline int picolcd_init_backlight(struct picolcd_data *data, 869 + struct hid_report *report) 870 + { 871 + return 0; 872 + } 873 + static inline void picolcd_exit_backlight(struct picolcd_data *data) 874 + { 875 + } 876 + static inline int picolcd_resume_backlight(struct picolcd_data *data) 877 + { 878 + return 0; 879 + } 880 + static inline void picolcd_suspend_backlight(struct picolcd_data *data) 881 + { 882 + } 883 + #endif /* CONFIG_HID_PICOLCD_BACKLIGHT */ 884 + 885 + #ifdef CONFIG_HID_PICOLCD_LCD 886 + /* 887 + * lcd class device 888 + */ 889 + static int picolcd_get_contrast(struct lcd_device *ldev) 890 + { 891 + struct picolcd_data *data = lcd_get_data(ldev); 892 + return data->lcd_contrast; 893 + } 894 + 895 + static int picolcd_set_contrast(struct lcd_device *ldev, int contrast) 896 + { 897 + struct picolcd_data *data = lcd_get_data(ldev); 898 + struct hid_report *report = picolcd_out_report(REPORT_CONTRAST, data->hdev); 899 + unsigned long flags; 900 + 901 + if (!report || report->maxfield != 1 || report->field[0]->report_count != 1) 902 + return -ENODEV; 903 + 904 + data->lcd_contrast = contrast & 0x0ff; 905 + spin_lock_irqsave(&data->lock, flags); 906 + hid_set_field(report->field[0], 0, data->lcd_contrast); 907 + usbhid_submit_report(data->hdev, report, USB_DIR_OUT); 908 + spin_unlock_irqrestore(&data->lock, flags); 909 + return 0; 910 + } 911 + 912 + static int picolcd_check_lcd_fb(struct lcd_device *ldev, struct fb_info *fb) 913 + { 914 + return fb && fb == picolcd_fbinfo((struct picolcd_data *)lcd_get_data(ldev)); 915 + } 916 + 917 + static struct lcd_ops picolcd_lcdops = { 918 + .get_contrast = picolcd_get_contrast, 919 + .set_contrast = picolcd_set_contrast, 920 + .check_fb = picolcd_check_lcd_fb, 921 + }; 922 + 923 + static int picolcd_init_lcd(struct picolcd_data *data, struct hid_report *report) 924 + { 925 + struct device *dev = &data->hdev->dev; 926 + struct lcd_device *ldev; 927 + 928 + if (!report) 929 + return -ENODEV; 930 + if (report->maxfield != 1 || report->field[0]->report_count != 1 || 931 + report->field[0]->report_size != 8) { 932 + dev_err(dev, "unsupported CONTRAST report"); 933 + return -EINVAL; 934 + } 935 + 936 + ldev = lcd_device_register(dev_name(dev), dev, data, &picolcd_lcdops); 937 + if (IS_ERR(ldev)) { 938 + dev_err(dev, "failed to register LCD\n"); 939 + return PTR_ERR(ldev); 940 + } 941 + ldev->props.max_contrast = 0x0ff; 942 + data->lcd_contrast = 0xe5; 943 + data->lcd = ldev; 944 + picolcd_set_contrast(ldev, 0xe5); 945 + return 0; 946 + } 947 + 948 + static void picolcd_exit_lcd(struct picolcd_data *data) 949 + { 950 + struct lcd_device *ldev = data->lcd; 951 + 952 + data->lcd = NULL; 953 + if (ldev) 954 + lcd_device_unregister(ldev); 955 + } 956 + 957 + static inline int picolcd_resume_lcd(struct picolcd_data *data) 958 + { 959 + if (!data->lcd) 960 + return 0; 961 + return picolcd_set_contrast(data->lcd, data->lcd_contrast); 962 + } 963 + #else 964 + static inline int picolcd_init_lcd(struct picolcd_data *data, 965 + struct hid_report *report) 966 + { 967 + return 0; 968 + } 969 + static inline void picolcd_exit_lcd(struct picolcd_data *data) 970 + { 971 + } 972 + static inline int picolcd_resume_lcd(struct picolcd_data *data) 973 + { 974 + return 0; 975 + } 976 + #endif /* CONFIG_HID_PICOLCD_LCD */ 977 + 978 + #ifdef CONFIG_HID_PICOLCD_LEDS 979 + /** 980 + * LED class device 981 + */ 982 + static void picolcd_leds_set(struct picolcd_data *data) 983 + { 984 + struct hid_report *report; 985 + unsigned long flags; 986 + 987 + if (!data->led[0]) 988 + return; 989 + report = picolcd_out_report(REPORT_LED_STATE, data->hdev); 990 + if (!report || report->maxfield != 1 || report->field[0]->report_count != 1) 991 + return; 992 + 993 + spin_lock_irqsave(&data->lock, flags); 994 + hid_set_field(report->field[0], 0, data->led_state); 995 + usbhid_submit_report(data->hdev, report, USB_DIR_OUT); 996 + spin_unlock_irqrestore(&data->lock, flags); 997 + } 998 + 999 + static void picolcd_led_set_brightness(struct led_classdev *led_cdev, 1000 + enum led_brightness value) 1001 + { 1002 + struct device *dev; 1003 + struct hid_device *hdev; 1004 + struct picolcd_data *data; 1005 + int i, state = 0; 1006 + 1007 + dev = led_cdev->dev->parent; 1008 + hdev = container_of(dev, struct hid_device, dev); 1009 + data = hid_get_drvdata(hdev); 1010 + for (i = 0; i < 8; i++) { 1011 + if (led_cdev != data->led[i]) 1012 + continue; 1013 + state = (data->led_state >> i) & 1; 1014 + if (value == LED_OFF && state) { 1015 + data->led_state &= ~(1 << i); 1016 + picolcd_leds_set(data); 1017 + } else if (value != LED_OFF && !state) { 1018 + data->led_state |= 1 << i; 1019 + picolcd_leds_set(data); 1020 + } 1021 + break; 1022 + } 1023 + } 1024 + 1025 + static enum led_brightness picolcd_led_get_brightness(struct led_classdev *led_cdev) 1026 + { 1027 + struct device *dev; 1028 + struct hid_device *hdev; 1029 + struct picolcd_data *data; 1030 + int i, value = 0; 1031 + 1032 + dev = led_cdev->dev->parent; 1033 + hdev = container_of(dev, struct hid_device, dev); 1034 + data = hid_get_drvdata(hdev); 1035 + for (i = 0; i < 8; i++) 1036 + if (led_cdev == data->led[i]) { 1037 + value = (data->led_state >> i) & 1; 1038 + break; 1039 + } 1040 + return value ? LED_FULL : LED_OFF; 1041 + } 1042 + 1043 + static int picolcd_init_leds(struct picolcd_data *data, struct hid_report *report) 1044 + { 1045 + struct device *dev = &data->hdev->dev; 1046 + struct led_classdev *led; 1047 + size_t name_sz = strlen(dev_name(dev)) + 8; 1048 + char *name; 1049 + int i, ret = 0; 1050 + 1051 + if (!report) 1052 + return -ENODEV; 1053 + if (report->maxfield != 1 || report->field[0]->report_count != 1 || 1054 + report->field[0]->report_size != 8) { 1055 + dev_err(dev, "unsupported LED_STATE report"); 1056 + return -EINVAL; 1057 + } 1058 + 1059 + for (i = 0; i < 8; i++) { 1060 + led = kzalloc(sizeof(struct led_classdev)+name_sz, GFP_KERNEL); 1061 + if (!led) { 1062 + dev_err(dev, "can't allocate memory for LED %d\n", i); 1063 + ret = -ENOMEM; 1064 + goto err; 1065 + } 1066 + name = (void *)(&led[1]); 1067 + snprintf(name, name_sz, "%s::GPO%d", dev_name(dev), i); 1068 + led->name = name; 1069 + led->brightness = 0; 1070 + led->max_brightness = 1; 1071 + led->brightness_get = picolcd_led_get_brightness; 1072 + led->brightness_set = picolcd_led_set_brightness; 1073 + 1074 + data->led[i] = led; 1075 + ret = led_classdev_register(dev, data->led[i]); 1076 + if (ret) { 1077 + data->led[i] = NULL; 1078 + kfree(led); 1079 + dev_err(dev, "can't register LED %d\n", i); 1080 + goto err; 1081 + } 1082 + } 1083 + return 0; 1084 + err: 1085 + for (i = 0; i < 8; i++) 1086 + if (data->led[i]) { 1087 + led = data->led[i]; 1088 + data->led[i] = NULL; 1089 + led_classdev_unregister(led); 1090 + kfree(led); 1091 + } 1092 + return ret; 1093 + } 1094 + 1095 + static void picolcd_exit_leds(struct picolcd_data *data) 1096 + { 1097 + struct led_classdev *led; 1098 + int i; 1099 + 1100 + for (i = 0; i < 8; i++) { 1101 + led = data->led[i]; 1102 + data->led[i] = NULL; 1103 + if (!led) 1104 + continue; 1105 + led_classdev_unregister(led); 1106 + kfree(led); 1107 + } 1108 + } 1109 + 1110 + #else 1111 + static inline int picolcd_init_leds(struct picolcd_data *data, 1112 + struct hid_report *report) 1113 + { 1114 + return 0; 1115 + } 1116 + static inline void picolcd_exit_leds(struct picolcd_data *data) 1117 + { 1118 + } 1119 + static inline int picolcd_leds_set(struct picolcd_data *data) 1120 + { 1121 + return 0; 1122 + } 1123 + #endif /* CONFIG_HID_PICOLCD_LEDS */ 1124 + 1125 + /* 1126 + * input class device 1127 + */ 1128 + static int picolcd_raw_keypad(struct picolcd_data *data, 1129 + struct hid_report *report, u8 *raw_data, int size) 1130 + { 1131 + /* 1132 + * Keypad event 1133 + * First and second data bytes list currently pressed keys, 1134 + * 0x00 means no key and at most 2 keys may be pressed at same time 1135 + */ 1136 + int i, j; 1137 + 1138 + /* determine newly pressed keys */ 1139 + for (i = 0; i < size; i++) { 1140 + unsigned int key_code; 1141 + if (raw_data[i] == 0) 1142 + continue; 1143 + for (j = 0; j < sizeof(data->pressed_keys); j++) 1144 + if (data->pressed_keys[j] == raw_data[i]) 1145 + goto key_already_down; 1146 + for (j = 0; j < sizeof(data->pressed_keys); j++) 1147 + if (data->pressed_keys[j] == 0) { 1148 + data->pressed_keys[j] = raw_data[i]; 1149 + break; 1150 + } 1151 + input_event(data->input_keys, EV_MSC, MSC_SCAN, raw_data[i]); 1152 + if (raw_data[i] < PICOLCD_KEYS) 1153 + key_code = data->keycode[raw_data[i]]; 1154 + else 1155 + key_code = KEY_UNKNOWN; 1156 + if (key_code != KEY_UNKNOWN) { 1157 + dbg_hid(PICOLCD_NAME " got key press for %u:%d", 1158 + raw_data[i], key_code); 1159 + input_report_key(data->input_keys, key_code, 1); 1160 + } 1161 + input_sync(data->input_keys); 1162 + key_already_down: 1163 + continue; 1164 + } 1165 + 1166 + /* determine newly released keys */ 1167 + for (j = 0; j < sizeof(data->pressed_keys); j++) { 1168 + unsigned int key_code; 1169 + if (data->pressed_keys[j] == 0) 1170 + continue; 1171 + for (i = 0; i < size; i++) 1172 + if (data->pressed_keys[j] == raw_data[i]) 1173 + goto key_still_down; 1174 + input_event(data->input_keys, EV_MSC, MSC_SCAN, data->pressed_keys[j]); 1175 + if (data->pressed_keys[j] < PICOLCD_KEYS) 1176 + key_code = data->keycode[data->pressed_keys[j]]; 1177 + else 1178 + key_code = KEY_UNKNOWN; 1179 + if (key_code != KEY_UNKNOWN) { 1180 + dbg_hid(PICOLCD_NAME " got key release for %u:%d", 1181 + data->pressed_keys[j], key_code); 1182 + input_report_key(data->input_keys, key_code, 0); 1183 + } 1184 + input_sync(data->input_keys); 1185 + data->pressed_keys[j] = 0; 1186 + key_still_down: 1187 + continue; 1188 + } 1189 + return 1; 1190 + } 1191 + 1192 + static int picolcd_raw_cir(struct picolcd_data *data, 1193 + struct hid_report *report, u8 *raw_data, int size) 1194 + { 1195 + /* Need understanding of CIR data format to implement ... */ 1196 + return 1; 1197 + } 1198 + 1199 + static int picolcd_check_version(struct hid_device *hdev) 1200 + { 1201 + struct picolcd_data *data = hid_get_drvdata(hdev); 1202 + struct picolcd_pending *verinfo; 1203 + int ret = 0; 1204 + 1205 + if (!data) 1206 + return -ENODEV; 1207 + 1208 + verinfo = picolcd_send_and_wait(hdev, REPORT_VERSION, NULL, 0); 1209 + if (!verinfo) { 1210 + dev_err(&hdev->dev, "no version response from PicoLCD"); 1211 + return -ENODEV; 1212 + } 1213 + 1214 + if (verinfo->raw_size == 2) { 1215 + data->version[0] = verinfo->raw_data[1]; 1216 + data->version[1] = verinfo->raw_data[0]; 1217 + if (data->status & PICOLCD_BOOTLOADER) { 1218 + dev_info(&hdev->dev, "PicoLCD, bootloader version %d.%d\n", 1219 + verinfo->raw_data[1], verinfo->raw_data[0]); 1220 + } else { 1221 + dev_info(&hdev->dev, "PicoLCD, firmware version %d.%d\n", 1222 + verinfo->raw_data[1], verinfo->raw_data[0]); 1223 + } 1224 + } else { 1225 + dev_err(&hdev->dev, "confused, got unexpected version response from PicoLCD\n"); 1226 + ret = -EINVAL; 1227 + } 1228 + kfree(verinfo); 1229 + return ret; 1230 + } 1231 + 1232 + /* 1233 + * Reset our device and wait for answer to VERSION request 1234 + */ 1235 + static int picolcd_reset(struct hid_device *hdev) 1236 + { 1237 + struct picolcd_data *data = hid_get_drvdata(hdev); 1238 + struct hid_report *report = picolcd_out_report(REPORT_RESET, hdev); 1239 + unsigned long flags; 1240 + int error; 1241 + 1242 + if (!data || !report || report->maxfield != 1) 1243 + return -ENODEV; 1244 + 1245 + spin_lock_irqsave(&data->lock, flags); 1246 + if (hdev->product == USB_DEVICE_ID_PICOLCD_BOOTLOADER) 1247 + data->status |= PICOLCD_BOOTLOADER; 1248 + 1249 + /* perform the reset */ 1250 + hid_set_field(report->field[0], 0, 1); 1251 + usbhid_submit_report(hdev, report, USB_DIR_OUT); 1252 + spin_unlock_irqrestore(&data->lock, flags); 1253 + 1254 + error = picolcd_check_version(hdev); 1255 + if (error) 1256 + return error; 1257 + 1258 + picolcd_resume_lcd(data); 1259 + picolcd_resume_backlight(data); 1260 + #ifdef CONFIG_HID_PICOLCD_FB 1261 + if (data->fb_info) 1262 + schedule_delayed_work(&data->fb_info->deferred_work, 0); 1263 + #endif /* CONFIG_HID_PICOLCD_FB */ 1264 + 1265 + picolcd_leds_set(data); 1266 + return 0; 1267 + } 1268 + 1269 + /* 1270 + * The "operation_mode" sysfs attribute 1271 + */ 1272 + static ssize_t picolcd_operation_mode_show(struct device *dev, 1273 + struct device_attribute *attr, char *buf) 1274 + { 1275 + struct picolcd_data *data = dev_get_drvdata(dev); 1276 + 1277 + if (data->status & PICOLCD_BOOTLOADER) 1278 + return snprintf(buf, PAGE_SIZE, "[bootloader] lcd\n"); 1279 + else 1280 + return snprintf(buf, PAGE_SIZE, "bootloader [lcd]\n"); 1281 + } 1282 + 1283 + static ssize_t picolcd_operation_mode_store(struct device *dev, 1284 + struct device_attribute *attr, const char *buf, size_t count) 1285 + { 1286 + struct picolcd_data *data = dev_get_drvdata(dev); 1287 + struct hid_report *report = NULL; 1288 + size_t cnt = count; 1289 + int timeout = data->opmode_delay; 1290 + unsigned long flags; 1291 + 1292 + if (cnt >= 3 && strncmp("lcd", buf, 3) == 0) { 1293 + if (data->status & PICOLCD_BOOTLOADER) 1294 + report = picolcd_out_report(REPORT_EXIT_FLASHER, data->hdev); 1295 + buf += 3; 1296 + cnt -= 3; 1297 + } else if (cnt >= 10 && strncmp("bootloader", buf, 10) == 0) { 1298 + if (!(data->status & PICOLCD_BOOTLOADER)) 1299 + report = picolcd_out_report(REPORT_EXIT_KEYBOARD, data->hdev); 1300 + buf += 10; 1301 + cnt -= 10; 1302 + } 1303 + if (!report) 1304 + return -EINVAL; 1305 + 1306 + while (cnt > 0 && (buf[cnt-1] == '\n' || buf[cnt-1] == '\r')) 1307 + cnt--; 1308 + if (cnt != 0) 1309 + return -EINVAL; 1310 + 1311 + spin_lock_irqsave(&data->lock, flags); 1312 + hid_set_field(report->field[0], 0, timeout & 0xff); 1313 + hid_set_field(report->field[0], 1, (timeout >> 8) & 0xff); 1314 + usbhid_submit_report(data->hdev, report, USB_DIR_OUT); 1315 + spin_unlock_irqrestore(&data->lock, flags); 1316 + return count; 1317 + } 1318 + 1319 + static DEVICE_ATTR(operation_mode, 0644, picolcd_operation_mode_show, 1320 + picolcd_operation_mode_store); 1321 + 1322 + /* 1323 + * The "operation_mode_delay" sysfs attribute 1324 + */ 1325 + static ssize_t picolcd_operation_mode_delay_show(struct device *dev, 1326 + struct device_attribute *attr, char *buf) 1327 + { 1328 + struct picolcd_data *data = dev_get_drvdata(dev); 1329 + 1330 + return snprintf(buf, PAGE_SIZE, "%hu\n", data->opmode_delay); 1331 + } 1332 + 1333 + static ssize_t picolcd_operation_mode_delay_store(struct device *dev, 1334 + struct device_attribute *attr, const char *buf, size_t count) 1335 + { 1336 + struct picolcd_data *data = dev_get_drvdata(dev); 1337 + unsigned u; 1338 + if (sscanf(buf, "%u", &u) != 1) 1339 + return -EINVAL; 1340 + if (u > 30000) 1341 + return -EINVAL; 1342 + else 1343 + data->opmode_delay = u; 1344 + return count; 1345 + } 1346 + 1347 + static DEVICE_ATTR(operation_mode_delay, 0644, picolcd_operation_mode_delay_show, 1348 + picolcd_operation_mode_delay_store); 1349 + 1350 + 1351 + #ifdef CONFIG_DEBUG_FS 1352 + /* 1353 + * The "reset" file 1354 + */ 1355 + static int picolcd_debug_reset_show(struct seq_file *f, void *p) 1356 + { 1357 + if (picolcd_fbinfo((struct picolcd_data *)f->private)) 1358 + seq_printf(f, "all fb\n"); 1359 + else 1360 + seq_printf(f, "all\n"); 1361 + return 0; 1362 + } 1363 + 1364 + static int picolcd_debug_reset_open(struct inode *inode, struct file *f) 1365 + { 1366 + return single_open(f, picolcd_debug_reset_show, inode->i_private); 1367 + } 1368 + 1369 + static ssize_t picolcd_debug_reset_write(struct file *f, const char __user *user_buf, 1370 + size_t count, loff_t *ppos) 1371 + { 1372 + struct picolcd_data *data = ((struct seq_file *)f->private_data)->private; 1373 + char buf[32]; 1374 + size_t cnt = min(count, sizeof(buf)-1); 1375 + if (copy_from_user(buf, user_buf, cnt)) 1376 + return -EFAULT; 1377 + 1378 + while (cnt > 0 && (buf[cnt-1] == ' ' || buf[cnt-1] == '\n')) 1379 + cnt--; 1380 + buf[cnt] = '\0'; 1381 + if (strcmp(buf, "all") == 0) { 1382 + picolcd_reset(data->hdev); 1383 + picolcd_fb_reset(data, 1); 1384 + } else if (strcmp(buf, "fb") == 0) { 1385 + picolcd_fb_reset(data, 1); 1386 + } else { 1387 + return -EINVAL; 1388 + } 1389 + return count; 1390 + } 1391 + 1392 + static const struct file_operations picolcd_debug_reset_fops = { 1393 + .owner = THIS_MODULE, 1394 + .open = picolcd_debug_reset_open, 1395 + .read = seq_read, 1396 + .llseek = seq_lseek, 1397 + .write = picolcd_debug_reset_write, 1398 + .release = single_release, 1399 + }; 1400 + 1401 + /* 1402 + * The "eeprom" file 1403 + */ 1404 + static int picolcd_debug_eeprom_open(struct inode *i, struct file *f) 1405 + { 1406 + f->private_data = i->i_private; 1407 + return 0; 1408 + } 1409 + 1410 + static ssize_t picolcd_debug_eeprom_read(struct file *f, char __user *u, 1411 + size_t s, loff_t *off) 1412 + { 1413 + struct picolcd_data *data = f->private_data; 1414 + struct picolcd_pending *resp; 1415 + u8 raw_data[3]; 1416 + ssize_t ret = -EIO; 1417 + 1418 + if (s == 0) 1419 + return -EINVAL; 1420 + if (*off > 0x0ff) 1421 + return 0; 1422 + 1423 + /* prepare buffer with info about what we want to read (addr & len) */ 1424 + raw_data[0] = *off & 0xff; 1425 + raw_data[1] = (*off >> 8) && 0xff; 1426 + raw_data[2] = s < 20 ? s : 20; 1427 + if (*off + raw_data[2] > 0xff) 1428 + raw_data[2] = 0x100 - *off; 1429 + resp = picolcd_send_and_wait(data->hdev, REPORT_EE_READ, raw_data, 1430 + sizeof(raw_data)); 1431 + if (!resp) 1432 + return -EIO; 1433 + 1434 + if (resp->in_report && resp->in_report->id == REPORT_EE_DATA) { 1435 + /* successful read :) */ 1436 + ret = resp->raw_data[2]; 1437 + if (ret > s) 1438 + ret = s; 1439 + if (copy_to_user(u, resp->raw_data+3, ret)) 1440 + ret = -EFAULT; 1441 + else 1442 + *off += ret; 1443 + } /* anything else is some kind of IO error */ 1444 + 1445 + kfree(resp); 1446 + return ret; 1447 + } 1448 + 1449 + static ssize_t picolcd_debug_eeprom_write(struct file *f, const char __user *u, 1450 + size_t s, loff_t *off) 1451 + { 1452 + struct picolcd_data *data = f->private_data; 1453 + struct picolcd_pending *resp; 1454 + ssize_t ret = -EIO; 1455 + u8 raw_data[23]; 1456 + 1457 + if (s == 0) 1458 + return -EINVAL; 1459 + if (*off > 0x0ff) 1460 + return -ENOSPC; 1461 + 1462 + memset(raw_data, 0, sizeof(raw_data)); 1463 + raw_data[0] = *off & 0xff; 1464 + raw_data[1] = (*off >> 8) && 0xff; 1465 + raw_data[2] = s < 20 ? s : 20; 1466 + if (*off + raw_data[2] > 0xff) 1467 + raw_data[2] = 0x100 - *off; 1468 + 1469 + if (copy_from_user(raw_data+3, u, raw_data[2])) 1470 + return -EFAULT; 1471 + resp = picolcd_send_and_wait(data->hdev, REPORT_EE_WRITE, raw_data, 1472 + sizeof(raw_data)); 1473 + 1474 + if (!resp) 1475 + return -EIO; 1476 + 1477 + if (resp->in_report && resp->in_report->id == REPORT_EE_DATA) { 1478 + /* check if written data matches */ 1479 + if (memcmp(raw_data, resp->raw_data, 3+raw_data[2]) == 0) { 1480 + *off += raw_data[2]; 1481 + ret = raw_data[2]; 1482 + } 1483 + } 1484 + kfree(resp); 1485 + return ret; 1486 + } 1487 + 1488 + /* 1489 + * Notes: 1490 + * - read/write happens in chunks of at most 20 bytes, it's up to userspace 1491 + * to loop in order to get more data. 1492 + * - on write errors on otherwise correct write request the bytes 1493 + * that should have been written are in undefined state. 1494 + */ 1495 + static const struct file_operations picolcd_debug_eeprom_fops = { 1496 + .owner = THIS_MODULE, 1497 + .open = picolcd_debug_eeprom_open, 1498 + .read = picolcd_debug_eeprom_read, 1499 + .write = picolcd_debug_eeprom_write, 1500 + .llseek = generic_file_llseek, 1501 + }; 1502 + 1503 + /* 1504 + * The "flash" file 1505 + */ 1506 + static int picolcd_debug_flash_open(struct inode *i, struct file *f) 1507 + { 1508 + f->private_data = i->i_private; 1509 + return 0; 1510 + } 1511 + 1512 + /* record a flash address to buf (bounds check to be done by caller) */ 1513 + static int _picolcd_flash_setaddr(struct picolcd_data *data, u8 *buf, long off) 1514 + { 1515 + buf[0] = off & 0xff; 1516 + buf[1] = (off >> 8) & 0xff; 1517 + if (data->addr_sz == 3) 1518 + buf[2] = (off >> 16) & 0xff; 1519 + return data->addr_sz == 2 ? 2 : 3; 1520 + } 1521 + 1522 + /* read a given size of data (bounds check to be done by caller) */ 1523 + static ssize_t _picolcd_flash_read(struct picolcd_data *data, int report_id, 1524 + char __user *u, size_t s, loff_t *off) 1525 + { 1526 + struct picolcd_pending *resp; 1527 + u8 raw_data[4]; 1528 + ssize_t ret = 0; 1529 + int len_off, err = -EIO; 1530 + 1531 + while (s > 0) { 1532 + err = -EIO; 1533 + len_off = _picolcd_flash_setaddr(data, raw_data, *off); 1534 + raw_data[len_off] = s > 32 ? 32 : s; 1535 + resp = picolcd_send_and_wait(data->hdev, report_id, raw_data, len_off+1); 1536 + if (!resp || !resp->in_report) 1537 + goto skip; 1538 + if (resp->in_report->id == REPORT_MEMORY || 1539 + resp->in_report->id == REPORT_BL_READ_MEMORY) { 1540 + if (memcmp(raw_data, resp->raw_data, len_off+1) != 0) 1541 + goto skip; 1542 + if (copy_to_user(u+ret, resp->raw_data+len_off+1, raw_data[len_off])) { 1543 + err = -EFAULT; 1544 + goto skip; 1545 + } 1546 + *off += raw_data[len_off]; 1547 + s -= raw_data[len_off]; 1548 + ret += raw_data[len_off]; 1549 + err = 0; 1550 + } 1551 + skip: 1552 + kfree(resp); 1553 + if (err) 1554 + return ret > 0 ? ret : err; 1555 + } 1556 + return ret; 1557 + } 1558 + 1559 + static ssize_t picolcd_debug_flash_read(struct file *f, char __user *u, 1560 + size_t s, loff_t *off) 1561 + { 1562 + struct picolcd_data *data = f->private_data; 1563 + 1564 + if (s == 0) 1565 + return -EINVAL; 1566 + if (*off > 0x05fff) 1567 + return 0; 1568 + if (*off + s > 0x05fff) 1569 + s = 0x06000 - *off; 1570 + 1571 + if (data->status & PICOLCD_BOOTLOADER) 1572 + return _picolcd_flash_read(data, REPORT_BL_READ_MEMORY, u, s, off); 1573 + else 1574 + return _picolcd_flash_read(data, REPORT_READ_MEMORY, u, s, off); 1575 + } 1576 + 1577 + /* erase block aligned to 64bytes boundary */ 1578 + static ssize_t _picolcd_flash_erase64(struct picolcd_data *data, int report_id, 1579 + loff_t *off) 1580 + { 1581 + struct picolcd_pending *resp; 1582 + u8 raw_data[3]; 1583 + int len_off; 1584 + ssize_t ret = -EIO; 1585 + 1586 + if (*off & 0x3f) 1587 + return -EINVAL; 1588 + 1589 + len_off = _picolcd_flash_setaddr(data, raw_data, *off); 1590 + resp = picolcd_send_and_wait(data->hdev, report_id, raw_data, len_off); 1591 + if (!resp || !resp->in_report) 1592 + goto skip; 1593 + if (resp->in_report->id == REPORT_MEMORY || 1594 + resp->in_report->id == REPORT_BL_ERASE_MEMORY) { 1595 + if (memcmp(raw_data, resp->raw_data, len_off) != 0) 1596 + goto skip; 1597 + ret = 0; 1598 + } 1599 + skip: 1600 + kfree(resp); 1601 + return ret; 1602 + } 1603 + 1604 + /* write a given size of data (bounds check to be done by caller) */ 1605 + static ssize_t _picolcd_flash_write(struct picolcd_data *data, int report_id, 1606 + const char __user *u, size_t s, loff_t *off) 1607 + { 1608 + struct picolcd_pending *resp; 1609 + u8 raw_data[36]; 1610 + ssize_t ret = 0; 1611 + int len_off, err = -EIO; 1612 + 1613 + while (s > 0) { 1614 + err = -EIO; 1615 + len_off = _picolcd_flash_setaddr(data, raw_data, *off); 1616 + raw_data[len_off] = s > 32 ? 32 : s; 1617 + if (copy_from_user(raw_data+len_off+1, u, raw_data[len_off])) { 1618 + err = -EFAULT; 1619 + break; 1620 + } 1621 + resp = picolcd_send_and_wait(data->hdev, report_id, raw_data, 1622 + len_off+1+raw_data[len_off]); 1623 + if (!resp || !resp->in_report) 1624 + goto skip; 1625 + if (resp->in_report->id == REPORT_MEMORY || 1626 + resp->in_report->id == REPORT_BL_WRITE_MEMORY) { 1627 + if (memcmp(raw_data, resp->raw_data, len_off+1+raw_data[len_off]) != 0) 1628 + goto skip; 1629 + *off += raw_data[len_off]; 1630 + s -= raw_data[len_off]; 1631 + ret += raw_data[len_off]; 1632 + err = 0; 1633 + } 1634 + skip: 1635 + kfree(resp); 1636 + if (err) 1637 + break; 1638 + } 1639 + return ret > 0 ? ret : err; 1640 + } 1641 + 1642 + static ssize_t picolcd_debug_flash_write(struct file *f, const char __user *u, 1643 + size_t s, loff_t *off) 1644 + { 1645 + struct picolcd_data *data = f->private_data; 1646 + ssize_t err, ret = 0; 1647 + int report_erase, report_write; 1648 + 1649 + if (s == 0) 1650 + return -EINVAL; 1651 + if (*off > 0x5fff) 1652 + return -ENOSPC; 1653 + if (s & 0x3f) 1654 + return -EINVAL; 1655 + if (*off & 0x3f) 1656 + return -EINVAL; 1657 + 1658 + if (data->status & PICOLCD_BOOTLOADER) { 1659 + report_erase = REPORT_BL_ERASE_MEMORY; 1660 + report_write = REPORT_BL_WRITE_MEMORY; 1661 + } else { 1662 + report_erase = REPORT_ERASE_MEMORY; 1663 + report_write = REPORT_WRITE_MEMORY; 1664 + } 1665 + mutex_lock(&data->mutex_flash); 1666 + while (s > 0) { 1667 + err = _picolcd_flash_erase64(data, report_erase, off); 1668 + if (err) 1669 + break; 1670 + err = _picolcd_flash_write(data, report_write, u, 64, off); 1671 + if (err < 0) 1672 + break; 1673 + ret += err; 1674 + *off += err; 1675 + s -= err; 1676 + if (err != 64) 1677 + break; 1678 + } 1679 + mutex_unlock(&data->mutex_flash); 1680 + return ret > 0 ? ret : err; 1681 + } 1682 + 1683 + /* 1684 + * Notes: 1685 + * - concurrent writing is prevented by mutex and all writes must be 1686 + * n*64 bytes and 64-byte aligned, each write being preceeded by an 1687 + * ERASE which erases a 64byte block. 1688 + * If less than requested was written or an error is returned for an 1689 + * otherwise correct write request the next 64-byte block which should 1690 + * have been written is in undefined state (mostly: original, erased, 1691 + * (half-)written with write error) 1692 + * - reading can happend without special restriction 1693 + */ 1694 + static const struct file_operations picolcd_debug_flash_fops = { 1695 + .owner = THIS_MODULE, 1696 + .open = picolcd_debug_flash_open, 1697 + .read = picolcd_debug_flash_read, 1698 + .write = picolcd_debug_flash_write, 1699 + .llseek = generic_file_llseek, 1700 + }; 1701 + 1702 + 1703 + /* 1704 + * Helper code for HID report level dumping/debugging 1705 + */ 1706 + static const char *error_codes[] = { 1707 + "success", "parameter missing", "data_missing", "block readonly", 1708 + "block not erasable", "block too big", "section overflow", 1709 + "invalid command length", "invalid data length", 1710 + }; 1711 + 1712 + static void dump_buff_as_hex(char *dst, size_t dst_sz, const u8 *data, 1713 + const size_t data_len) 1714 + { 1715 + int i, j; 1716 + for (i = j = 0; i < data_len && j + 3 < dst_sz; i++) { 1717 + dst[j++] = hex_asc[(data[i] >> 4) & 0x0f]; 1718 + dst[j++] = hex_asc[data[i] & 0x0f]; 1719 + dst[j++] = ' '; 1720 + } 1721 + if (j < dst_sz) { 1722 + dst[j--] = '\0'; 1723 + dst[j] = '\n'; 1724 + } else 1725 + dst[j] = '\0'; 1726 + } 1727 + 1728 + static void picolcd_debug_out_report(struct picolcd_data *data, 1729 + struct hid_device *hdev, struct hid_report *report) 1730 + { 1731 + u8 raw_data[70]; 1732 + int raw_size = (report->size >> 3) + 1; 1733 + char *buff; 1734 + #define BUFF_SZ 256 1735 + 1736 + /* Avoid unnecessary overhead if debugfs is disabled */ 1737 + if (!hdev->debug_events) 1738 + return; 1739 + 1740 + buff = kmalloc(BUFF_SZ, GFP_ATOMIC); 1741 + if (!buff) 1742 + return; 1743 + 1744 + snprintf(buff, BUFF_SZ, "\nout report %d (size %d) = ", 1745 + report->id, raw_size); 1746 + hid_debug_event(hdev, buff); 1747 + if (raw_size + 5 > sizeof(raw_data)) { 1748 + hid_debug_event(hdev, " TOO BIG\n"); 1749 + return; 1750 + } else { 1751 + raw_data[0] = report->id; 1752 + hid_output_report(report, raw_data); 1753 + dump_buff_as_hex(buff, BUFF_SZ, raw_data, raw_size); 1754 + hid_debug_event(hdev, buff); 1755 + } 1756 + 1757 + switch (report->id) { 1758 + case REPORT_LED_STATE: 1759 + /* 1 data byte with GPO state */ 1760 + snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 1761 + "REPORT_LED_STATE", report->id, raw_size-1); 1762 + hid_debug_event(hdev, buff); 1763 + snprintf(buff, BUFF_SZ, "\tGPO state: 0x%02x\n", raw_data[1]); 1764 + hid_debug_event(hdev, buff); 1765 + break; 1766 + case REPORT_BRIGHTNESS: 1767 + /* 1 data byte with brightness */ 1768 + snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 1769 + "REPORT_BRIGHTNESS", report->id, raw_size-1); 1770 + hid_debug_event(hdev, buff); 1771 + snprintf(buff, BUFF_SZ, "\tBrightness: 0x%02x\n", raw_data[1]); 1772 + hid_debug_event(hdev, buff); 1773 + break; 1774 + case REPORT_CONTRAST: 1775 + /* 1 data byte with contrast */ 1776 + snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 1777 + "REPORT_CONTRAST", report->id, raw_size-1); 1778 + hid_debug_event(hdev, buff); 1779 + snprintf(buff, BUFF_SZ, "\tContrast: 0x%02x\n", raw_data[1]); 1780 + hid_debug_event(hdev, buff); 1781 + break; 1782 + case REPORT_RESET: 1783 + /* 2 data bytes with reset duration in ms */ 1784 + snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 1785 + "REPORT_RESET", report->id, raw_size-1); 1786 + hid_debug_event(hdev, buff); 1787 + snprintf(buff, BUFF_SZ, "\tDuration: 0x%02x%02x (%dms)\n", 1788 + raw_data[2], raw_data[1], raw_data[2] << 8 | raw_data[1]); 1789 + hid_debug_event(hdev, buff); 1790 + break; 1791 + case REPORT_LCD_CMD: 1792 + /* 63 data bytes with LCD commands */ 1793 + snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 1794 + "REPORT_LCD_CMD", report->id, raw_size-1); 1795 + hid_debug_event(hdev, buff); 1796 + /* TODO: format decoding */ 1797 + break; 1798 + case REPORT_LCD_DATA: 1799 + /* 63 data bytes with LCD data */ 1800 + snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 1801 + "REPORT_LCD_CMD", report->id, raw_size-1); 1802 + /* TODO: format decoding */ 1803 + hid_debug_event(hdev, buff); 1804 + break; 1805 + case REPORT_LCD_CMD_DATA: 1806 + /* 63 data bytes with LCD commands and data */ 1807 + snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 1808 + "REPORT_LCD_CMD", report->id, raw_size-1); 1809 + /* TODO: format decoding */ 1810 + hid_debug_event(hdev, buff); 1811 + break; 1812 + case REPORT_EE_READ: 1813 + /* 3 data bytes with read area description */ 1814 + snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 1815 + "REPORT_EE_READ", report->id, raw_size-1); 1816 + hid_debug_event(hdev, buff); 1817 + snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n", 1818 + raw_data[2], raw_data[1]); 1819 + hid_debug_event(hdev, buff); 1820 + snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]); 1821 + hid_debug_event(hdev, buff); 1822 + break; 1823 + case REPORT_EE_WRITE: 1824 + /* 3+1..20 data bytes with write area description */ 1825 + snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 1826 + "REPORT_EE_WRITE", report->id, raw_size-1); 1827 + hid_debug_event(hdev, buff); 1828 + snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n", 1829 + raw_data[2], raw_data[1]); 1830 + hid_debug_event(hdev, buff); 1831 + snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]); 1832 + hid_debug_event(hdev, buff); 1833 + if (raw_data[3] == 0) { 1834 + snprintf(buff, BUFF_SZ, "\tNo data\n"); 1835 + } else if (raw_data[3] + 4 <= raw_size) { 1836 + snprintf(buff, BUFF_SZ, "\tData: "); 1837 + hid_debug_event(hdev, buff); 1838 + dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]); 1839 + } else { 1840 + snprintf(buff, BUFF_SZ, "\tData overflowed\n"); 1841 + } 1842 + hid_debug_event(hdev, buff); 1843 + break; 1844 + case REPORT_ERASE_MEMORY: 1845 + case REPORT_BL_ERASE_MEMORY: 1846 + /* 3 data bytes with pointer inside erase block */ 1847 + snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 1848 + "REPORT_ERASE_MEMORY", report->id, raw_size-1); 1849 + hid_debug_event(hdev, buff); 1850 + switch (data->addr_sz) { 1851 + case 2: 1852 + snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x\n", 1853 + raw_data[2], raw_data[1]); 1854 + break; 1855 + case 3: 1856 + snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x%02x\n", 1857 + raw_data[3], raw_data[2], raw_data[1]); 1858 + break; 1859 + default: 1860 + snprintf(buff, BUFF_SZ, "\tNot supported\n"); 1861 + } 1862 + hid_debug_event(hdev, buff); 1863 + break; 1864 + case REPORT_READ_MEMORY: 1865 + case REPORT_BL_READ_MEMORY: 1866 + /* 4 data bytes with read area description */ 1867 + snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 1868 + "REPORT_READ_MEMORY", report->id, raw_size-1); 1869 + hid_debug_event(hdev, buff); 1870 + switch (data->addr_sz) { 1871 + case 2: 1872 + snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n", 1873 + raw_data[2], raw_data[1]); 1874 + hid_debug_event(hdev, buff); 1875 + snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]); 1876 + break; 1877 + case 3: 1878 + snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n", 1879 + raw_data[3], raw_data[2], raw_data[1]); 1880 + hid_debug_event(hdev, buff); 1881 + snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]); 1882 + break; 1883 + default: 1884 + snprintf(buff, BUFF_SZ, "\tNot supported\n"); 1885 + } 1886 + hid_debug_event(hdev, buff); 1887 + break; 1888 + case REPORT_WRITE_MEMORY: 1889 + case REPORT_BL_WRITE_MEMORY: 1890 + /* 4+1..32 data bytes with write adrea description */ 1891 + snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 1892 + "REPORT_WRITE_MEMORY", report->id, raw_size-1); 1893 + hid_debug_event(hdev, buff); 1894 + switch (data->addr_sz) { 1895 + case 2: 1896 + snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n", 1897 + raw_data[2], raw_data[1]); 1898 + hid_debug_event(hdev, buff); 1899 + snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]); 1900 + hid_debug_event(hdev, buff); 1901 + if (raw_data[3] == 0) { 1902 + snprintf(buff, BUFF_SZ, "\tNo data\n"); 1903 + } else if (raw_data[3] + 4 <= raw_size) { 1904 + snprintf(buff, BUFF_SZ, "\tData: "); 1905 + hid_debug_event(hdev, buff); 1906 + dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]); 1907 + } else { 1908 + snprintf(buff, BUFF_SZ, "\tData overflowed\n"); 1909 + } 1910 + break; 1911 + case 3: 1912 + snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n", 1913 + raw_data[3], raw_data[2], raw_data[1]); 1914 + hid_debug_event(hdev, buff); 1915 + snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]); 1916 + hid_debug_event(hdev, buff); 1917 + if (raw_data[4] == 0) { 1918 + snprintf(buff, BUFF_SZ, "\tNo data\n"); 1919 + } else if (raw_data[4] + 5 <= raw_size) { 1920 + snprintf(buff, BUFF_SZ, "\tData: "); 1921 + hid_debug_event(hdev, buff); 1922 + dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]); 1923 + } else { 1924 + snprintf(buff, BUFF_SZ, "\tData overflowed\n"); 1925 + } 1926 + break; 1927 + default: 1928 + snprintf(buff, BUFF_SZ, "\tNot supported\n"); 1929 + } 1930 + hid_debug_event(hdev, buff); 1931 + break; 1932 + case REPORT_SPLASH_RESTART: 1933 + /* TODO */ 1934 + break; 1935 + case REPORT_EXIT_KEYBOARD: 1936 + snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 1937 + "REPORT_EXIT_KEYBOARD", report->id, raw_size-1); 1938 + hid_debug_event(hdev, buff); 1939 + snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n", 1940 + raw_data[1] | (raw_data[2] << 8), 1941 + raw_data[2], raw_data[1]); 1942 + hid_debug_event(hdev, buff); 1943 + break; 1944 + case REPORT_VERSION: 1945 + snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 1946 + "REPORT_VERSION", report->id, raw_size-1); 1947 + hid_debug_event(hdev, buff); 1948 + break; 1949 + case REPORT_DEVID: 1950 + snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 1951 + "REPORT_DEVID", report->id, raw_size-1); 1952 + hid_debug_event(hdev, buff); 1953 + break; 1954 + case REPORT_SPLASH_SIZE: 1955 + snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 1956 + "REPORT_SPLASH_SIZE", report->id, raw_size-1); 1957 + hid_debug_event(hdev, buff); 1958 + break; 1959 + case REPORT_HOOK_VERSION: 1960 + snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 1961 + "REPORT_HOOK_VERSION", report->id, raw_size-1); 1962 + hid_debug_event(hdev, buff); 1963 + break; 1964 + case REPORT_EXIT_FLASHER: 1965 + snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 1966 + "REPORT_VERSION", report->id, raw_size-1); 1967 + hid_debug_event(hdev, buff); 1968 + snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n", 1969 + raw_data[1] | (raw_data[2] << 8), 1970 + raw_data[2], raw_data[1]); 1971 + hid_debug_event(hdev, buff); 1972 + break; 1973 + default: 1974 + snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 1975 + "<unknown>", report->id, raw_size-1); 1976 + hid_debug_event(hdev, buff); 1977 + break; 1978 + } 1979 + wake_up_interruptible(&hdev->debug_wait); 1980 + kfree(buff); 1981 + } 1982 + 1983 + static void picolcd_debug_raw_event(struct picolcd_data *data, 1984 + struct hid_device *hdev, struct hid_report *report, 1985 + u8 *raw_data, int size) 1986 + { 1987 + char *buff; 1988 + 1989 + #define BUFF_SZ 256 1990 + /* Avoid unnecessary overhead if debugfs is disabled */ 1991 + if (!hdev->debug_events) 1992 + return; 1993 + 1994 + buff = kmalloc(BUFF_SZ, GFP_ATOMIC); 1995 + if (!buff) 1996 + return; 1997 + 1998 + switch (report->id) { 1999 + case REPORT_ERROR_CODE: 2000 + /* 2 data bytes with affected report and error code */ 2001 + snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n", 2002 + "REPORT_ERROR_CODE", report->id, size-1); 2003 + hid_debug_event(hdev, buff); 2004 + if (raw_data[2] < ARRAY_SIZE(error_codes)) 2005 + snprintf(buff, BUFF_SZ, "\tError code 0x%02x (%s) in reply to report 0x%02x\n", 2006 + raw_data[2], error_codes[raw_data[2]], raw_data[1]); 2007 + else 2008 + snprintf(buff, BUFF_SZ, "\tError code 0x%02x in reply to report 0x%02x\n", 2009 + raw_data[2], raw_data[1]); 2010 + hid_debug_event(hdev, buff); 2011 + break; 2012 + case REPORT_KEY_STATE: 2013 + /* 2 data bytes with key state */ 2014 + snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n", 2015 + "REPORT_KEY_STATE", report->id, size-1); 2016 + hid_debug_event(hdev, buff); 2017 + if (raw_data[1] == 0) 2018 + snprintf(buff, BUFF_SZ, "\tNo key pressed\n"); 2019 + else if (raw_data[2] == 0) 2020 + snprintf(buff, BUFF_SZ, "\tOne key pressed: 0x%02x (%d)\n", 2021 + raw_data[1], raw_data[1]); 2022 + else 2023 + snprintf(buff, BUFF_SZ, "\tTwo keys pressed: 0x%02x (%d), 0x%02x (%d)\n", 2024 + raw_data[1], raw_data[1], raw_data[2], raw_data[2]); 2025 + hid_debug_event(hdev, buff); 2026 + break; 2027 + case REPORT_IR_DATA: 2028 + /* Up to 20 byes of IR scancode data */ 2029 + snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n", 2030 + "REPORT_IR_DATA", report->id, size-1); 2031 + hid_debug_event(hdev, buff); 2032 + if (raw_data[1] == 0) { 2033 + snprintf(buff, BUFF_SZ, "\tUnexpectedly 0 data length\n"); 2034 + hid_debug_event(hdev, buff); 2035 + } else if (raw_data[1] + 1 <= size) { 2036 + snprintf(buff, BUFF_SZ, "\tData length: %d\n\tIR Data: ", 2037 + raw_data[1]-1); 2038 + hid_debug_event(hdev, buff); 2039 + dump_buff_as_hex(buff, BUFF_SZ, raw_data+2, raw_data[1]-1); 2040 + hid_debug_event(hdev, buff); 2041 + } else { 2042 + snprintf(buff, BUFF_SZ, "\tOverflowing data length: %d\n", 2043 + raw_data[1]-1); 2044 + hid_debug_event(hdev, buff); 2045 + } 2046 + break; 2047 + case REPORT_EE_DATA: 2048 + /* Data buffer in response to REPORT_EE_READ or REPORT_EE_WRITE */ 2049 + snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n", 2050 + "REPORT_EE_DATA", report->id, size-1); 2051 + hid_debug_event(hdev, buff); 2052 + snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n", 2053 + raw_data[2], raw_data[1]); 2054 + hid_debug_event(hdev, buff); 2055 + snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]); 2056 + hid_debug_event(hdev, buff); 2057 + if (raw_data[3] == 0) { 2058 + snprintf(buff, BUFF_SZ, "\tNo data\n"); 2059 + hid_debug_event(hdev, buff); 2060 + } else if (raw_data[3] + 4 <= size) { 2061 + snprintf(buff, BUFF_SZ, "\tData: "); 2062 + hid_debug_event(hdev, buff); 2063 + dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]); 2064 + hid_debug_event(hdev, buff); 2065 + } else { 2066 + snprintf(buff, BUFF_SZ, "\tData overflowed\n"); 2067 + hid_debug_event(hdev, buff); 2068 + } 2069 + break; 2070 + case REPORT_MEMORY: 2071 + /* Data buffer in response to REPORT_READ_MEMORY or REPORT_WRTIE_MEMORY */ 2072 + snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n", 2073 + "REPORT_MEMORY", report->id, size-1); 2074 + hid_debug_event(hdev, buff); 2075 + switch (data->addr_sz) { 2076 + case 2: 2077 + snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n", 2078 + raw_data[2], raw_data[1]); 2079 + hid_debug_event(hdev, buff); 2080 + snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]); 2081 + hid_debug_event(hdev, buff); 2082 + if (raw_data[3] == 0) { 2083 + snprintf(buff, BUFF_SZ, "\tNo data\n"); 2084 + } else if (raw_data[3] + 4 <= size) { 2085 + snprintf(buff, BUFF_SZ, "\tData: "); 2086 + hid_debug_event(hdev, buff); 2087 + dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]); 2088 + } else { 2089 + snprintf(buff, BUFF_SZ, "\tData overflowed\n"); 2090 + } 2091 + break; 2092 + case 3: 2093 + snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n", 2094 + raw_data[3], raw_data[2], raw_data[1]); 2095 + hid_debug_event(hdev, buff); 2096 + snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]); 2097 + hid_debug_event(hdev, buff); 2098 + if (raw_data[4] == 0) { 2099 + snprintf(buff, BUFF_SZ, "\tNo data\n"); 2100 + } else if (raw_data[4] + 5 <= size) { 2101 + snprintf(buff, BUFF_SZ, "\tData: "); 2102 + hid_debug_event(hdev, buff); 2103 + dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]); 2104 + } else { 2105 + snprintf(buff, BUFF_SZ, "\tData overflowed\n"); 2106 + } 2107 + break; 2108 + default: 2109 + snprintf(buff, BUFF_SZ, "\tNot supported\n"); 2110 + } 2111 + hid_debug_event(hdev, buff); 2112 + break; 2113 + case REPORT_VERSION: 2114 + snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n", 2115 + "REPORT_VERSION", report->id, size-1); 2116 + hid_debug_event(hdev, buff); 2117 + snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n", 2118 + raw_data[2], raw_data[1]); 2119 + hid_debug_event(hdev, buff); 2120 + break; 2121 + case REPORT_BL_ERASE_MEMORY: 2122 + snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n", 2123 + "REPORT_BL_ERASE_MEMORY", report->id, size-1); 2124 + hid_debug_event(hdev, buff); 2125 + /* TODO */ 2126 + break; 2127 + case REPORT_BL_READ_MEMORY: 2128 + snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n", 2129 + "REPORT_BL_READ_MEMORY", report->id, size-1); 2130 + hid_debug_event(hdev, buff); 2131 + /* TODO */ 2132 + break; 2133 + case REPORT_BL_WRITE_MEMORY: 2134 + snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n", 2135 + "REPORT_BL_WRITE_MEMORY", report->id, size-1); 2136 + hid_debug_event(hdev, buff); 2137 + /* TODO */ 2138 + break; 2139 + case REPORT_DEVID: 2140 + snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n", 2141 + "REPORT_DEVID", report->id, size-1); 2142 + hid_debug_event(hdev, buff); 2143 + snprintf(buff, BUFF_SZ, "\tSerial: 0x%02x%02x%02x%02x\n", 2144 + raw_data[1], raw_data[2], raw_data[3], raw_data[4]); 2145 + hid_debug_event(hdev, buff); 2146 + snprintf(buff, BUFF_SZ, "\tType: 0x%02x\n", 2147 + raw_data[5]); 2148 + hid_debug_event(hdev, buff); 2149 + break; 2150 + case REPORT_SPLASH_SIZE: 2151 + snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n", 2152 + "REPORT_SPLASH_SIZE", report->id, size-1); 2153 + hid_debug_event(hdev, buff); 2154 + snprintf(buff, BUFF_SZ, "\tTotal splash space: %d\n", 2155 + (raw_data[2] << 8) | raw_data[1]); 2156 + hid_debug_event(hdev, buff); 2157 + snprintf(buff, BUFF_SZ, "\tUsed splash space: %d\n", 2158 + (raw_data[4] << 8) | raw_data[3]); 2159 + hid_debug_event(hdev, buff); 2160 + break; 2161 + case REPORT_HOOK_VERSION: 2162 + snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n", 2163 + "REPORT_HOOK_VERSION", report->id, size-1); 2164 + hid_debug_event(hdev, buff); 2165 + snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n", 2166 + raw_data[1], raw_data[2]); 2167 + hid_debug_event(hdev, buff); 2168 + break; 2169 + default: 2170 + snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n", 2171 + "<unknown>", report->id, size-1); 2172 + hid_debug_event(hdev, buff); 2173 + break; 2174 + } 2175 + wake_up_interruptible(&hdev->debug_wait); 2176 + kfree(buff); 2177 + } 2178 + 2179 + static void picolcd_init_devfs(struct picolcd_data *data, 2180 + struct hid_report *eeprom_r, struct hid_report *eeprom_w, 2181 + struct hid_report *flash_r, struct hid_report *flash_w, 2182 + struct hid_report *reset) 2183 + { 2184 + struct hid_device *hdev = data->hdev; 2185 + 2186 + mutex_init(&data->mutex_flash); 2187 + 2188 + /* reset */ 2189 + if (reset) 2190 + data->debug_reset = debugfs_create_file("reset", 0600, 2191 + hdev->debug_dir, data, &picolcd_debug_reset_fops); 2192 + 2193 + /* eeprom */ 2194 + if (eeprom_r || eeprom_w) 2195 + data->debug_eeprom = debugfs_create_file("eeprom", 2196 + (eeprom_w ? S_IWUSR : 0) | (eeprom_r ? S_IRUSR : 0), 2197 + hdev->debug_dir, data, &picolcd_debug_eeprom_fops); 2198 + 2199 + /* flash */ 2200 + if (flash_r && flash_r->maxfield == 1 && flash_r->field[0]->report_size == 8) 2201 + data->addr_sz = flash_r->field[0]->report_count - 1; 2202 + else 2203 + data->addr_sz = -1; 2204 + if (data->addr_sz == 2 || data->addr_sz == 3) { 2205 + data->debug_flash = debugfs_create_file("flash", 2206 + (flash_w ? S_IWUSR : 0) | (flash_r ? S_IRUSR : 0), 2207 + hdev->debug_dir, data, &picolcd_debug_flash_fops); 2208 + } else if (flash_r || flash_w) 2209 + dev_warn(&hdev->dev, "Unexpected FLASH access reports, " 2210 + "please submit rdesc for review\n"); 2211 + } 2212 + 2213 + static void picolcd_exit_devfs(struct picolcd_data *data) 2214 + { 2215 + struct dentry *dent; 2216 + 2217 + dent = data->debug_reset; 2218 + data->debug_reset = NULL; 2219 + if (dent) 2220 + debugfs_remove(dent); 2221 + dent = data->debug_eeprom; 2222 + data->debug_eeprom = NULL; 2223 + if (dent) 2224 + debugfs_remove(dent); 2225 + dent = data->debug_flash; 2226 + data->debug_flash = NULL; 2227 + if (dent) 2228 + debugfs_remove(dent); 2229 + mutex_destroy(&data->mutex_flash); 2230 + } 2231 + #else 2232 + static inline void picolcd_debug_raw_event(struct picolcd_data *data, 2233 + struct hid_device *hdev, struct hid_report *report, 2234 + u8 *raw_data, int size) 2235 + { 2236 + } 2237 + static inline void picolcd_init_devfs(struct picolcd_data *data, 2238 + struct hid_report *eeprom_r, struct hid_report *eeprom_w, 2239 + struct hid_report *flash_r, struct hid_report *flash_w, 2240 + struct hid_report *reset) 2241 + { 2242 + } 2243 + static inline void picolcd_exit_devfs(struct picolcd_data *data) 2244 + { 2245 + } 2246 + #endif /* CONFIG_DEBUG_FS */ 2247 + 2248 + /* 2249 + * Handle raw report as sent by device 2250 + */ 2251 + static int picolcd_raw_event(struct hid_device *hdev, 2252 + struct hid_report *report, u8 *raw_data, int size) 2253 + { 2254 + struct picolcd_data *data = hid_get_drvdata(hdev); 2255 + unsigned long flags; 2256 + int ret = 0; 2257 + 2258 + if (!data) 2259 + return 1; 2260 + 2261 + if (report->id == REPORT_KEY_STATE) { 2262 + if (data->input_keys) 2263 + ret = picolcd_raw_keypad(data, report, raw_data+1, size-1); 2264 + } else if (report->id == REPORT_IR_DATA) { 2265 + if (data->input_cir) 2266 + ret = picolcd_raw_cir(data, report, raw_data+1, size-1); 2267 + } else { 2268 + spin_lock_irqsave(&data->lock, flags); 2269 + /* 2270 + * We let the caller of picolcd_send_and_wait() check if the 2271 + * report we got is one of the expected ones or not. 2272 + */ 2273 + if (data->pending) { 2274 + memcpy(data->pending->raw_data, raw_data+1, size-1); 2275 + data->pending->raw_size = size-1; 2276 + data->pending->in_report = report; 2277 + complete(&data->pending->ready); 2278 + } 2279 + spin_unlock_irqrestore(&data->lock, flags); 2280 + } 2281 + 2282 + picolcd_debug_raw_event(data, hdev, report, raw_data, size); 2283 + return 1; 2284 + } 2285 + 2286 + #ifdef CONFIG_PM 2287 + static int picolcd_suspend(struct hid_device *hdev, pm_message_t message) 2288 + { 2289 + if (message.event & PM_EVENT_AUTO) 2290 + return 0; 2291 + 2292 + picolcd_suspend_backlight(hid_get_drvdata(hdev)); 2293 + dbg_hid(PICOLCD_NAME " device ready for suspend\n"); 2294 + return 0; 2295 + } 2296 + 2297 + static int picolcd_resume(struct hid_device *hdev) 2298 + { 2299 + int ret; 2300 + ret = picolcd_resume_backlight(hid_get_drvdata(hdev)); 2301 + if (ret) 2302 + dbg_hid(PICOLCD_NAME " restoring backlight failed: %d\n", ret); 2303 + return 0; 2304 + } 2305 + 2306 + static int picolcd_reset_resume(struct hid_device *hdev) 2307 + { 2308 + int ret; 2309 + ret = picolcd_reset(hdev); 2310 + if (ret) 2311 + dbg_hid(PICOLCD_NAME " resetting our device failed: %d\n", ret); 2312 + ret = picolcd_fb_reset(hid_get_drvdata(hdev), 0); 2313 + if (ret) 2314 + dbg_hid(PICOLCD_NAME " restoring framebuffer content failed: %d\n", ret); 2315 + ret = picolcd_resume_lcd(hid_get_drvdata(hdev)); 2316 + if (ret) 2317 + dbg_hid(PICOLCD_NAME " restoring lcd failed: %d\n", ret); 2318 + ret = picolcd_resume_backlight(hid_get_drvdata(hdev)); 2319 + if (ret) 2320 + dbg_hid(PICOLCD_NAME " restoring backlight failed: %d\n", ret); 2321 + picolcd_leds_set(hid_get_drvdata(hdev)); 2322 + return 0; 2323 + } 2324 + #endif 2325 + 2326 + /* initialize keypad input device */ 2327 + static int picolcd_init_keys(struct picolcd_data *data, 2328 + struct hid_report *report) 2329 + { 2330 + struct hid_device *hdev = data->hdev; 2331 + struct input_dev *idev; 2332 + int error, i; 2333 + 2334 + if (!report) 2335 + return -ENODEV; 2336 + if (report->maxfield != 1 || report->field[0]->report_count != 2 || 2337 + report->field[0]->report_size != 8) { 2338 + dev_err(&hdev->dev, "unsupported KEY_STATE report"); 2339 + return -EINVAL; 2340 + } 2341 + 2342 + idev = input_allocate_device(); 2343 + if (idev == NULL) { 2344 + dev_err(&hdev->dev, "failed to allocate input device"); 2345 + return -ENOMEM; 2346 + } 2347 + input_set_drvdata(idev, hdev); 2348 + memcpy(data->keycode, def_keymap, sizeof(def_keymap)); 2349 + idev->name = hdev->name; 2350 + idev->phys = hdev->phys; 2351 + idev->uniq = hdev->uniq; 2352 + idev->id.bustype = hdev->bus; 2353 + idev->id.vendor = hdev->vendor; 2354 + idev->id.product = hdev->product; 2355 + idev->id.version = hdev->version; 2356 + idev->dev.parent = hdev->dev.parent; 2357 + idev->keycode = &data->keycode; 2358 + idev->keycodemax = PICOLCD_KEYS; 2359 + idev->keycodesize = sizeof(data->keycode[0]); 2360 + input_set_capability(idev, EV_MSC, MSC_SCAN); 2361 + set_bit(EV_REP, idev->evbit); 2362 + for (i = 0; i < PICOLCD_KEYS; i++) 2363 + input_set_capability(idev, EV_KEY, data->keycode[i]); 2364 + error = input_register_device(idev); 2365 + if (error) { 2366 + dev_err(&hdev->dev, "error registering the input device"); 2367 + input_free_device(idev); 2368 + return error; 2369 + } 2370 + data->input_keys = idev; 2371 + return 0; 2372 + } 2373 + 2374 + static void picolcd_exit_keys(struct picolcd_data *data) 2375 + { 2376 + struct input_dev *idev = data->input_keys; 2377 + 2378 + data->input_keys = NULL; 2379 + if (idev) 2380 + input_unregister_device(idev); 2381 + } 2382 + 2383 + /* initialize CIR input device */ 2384 + static inline int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report) 2385 + { 2386 + /* support not implemented yet */ 2387 + return 0; 2388 + } 2389 + 2390 + static inline void picolcd_exit_cir(struct picolcd_data *data) 2391 + { 2392 + } 2393 + 2394 + static int picolcd_probe_lcd(struct hid_device *hdev, struct picolcd_data *data) 2395 + { 2396 + int error; 2397 + 2398 + error = picolcd_check_version(hdev); 2399 + if (error) 2400 + return error; 2401 + 2402 + if (data->version[0] != 0 && data->version[1] != 3) 2403 + dev_info(&hdev->dev, "Device with untested firmware revision, " 2404 + "please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n", 2405 + dev_name(&hdev->dev)); 2406 + 2407 + /* Setup keypad input device */ 2408 + error = picolcd_init_keys(data, picolcd_in_report(REPORT_KEY_STATE, hdev)); 2409 + if (error) 2410 + goto err; 2411 + 2412 + /* Setup CIR input device */ 2413 + error = picolcd_init_cir(data, picolcd_in_report(REPORT_IR_DATA, hdev)); 2414 + if (error) 2415 + goto err; 2416 + 2417 + /* Set up the framebuffer device */ 2418 + error = picolcd_init_framebuffer(data); 2419 + if (error) 2420 + goto err; 2421 + 2422 + /* Setup lcd class device */ 2423 + error = picolcd_init_lcd(data, picolcd_out_report(REPORT_CONTRAST, hdev)); 2424 + if (error) 2425 + goto err; 2426 + 2427 + /* Setup backlight class device */ 2428 + error = picolcd_init_backlight(data, picolcd_out_report(REPORT_BRIGHTNESS, hdev)); 2429 + if (error) 2430 + goto err; 2431 + 2432 + /* Setup the LED class devices */ 2433 + error = picolcd_init_leds(data, picolcd_out_report(REPORT_LED_STATE, hdev)); 2434 + if (error) 2435 + goto err; 2436 + 2437 + picolcd_init_devfs(data, picolcd_out_report(REPORT_EE_READ, hdev), 2438 + picolcd_out_report(REPORT_EE_WRITE, hdev), 2439 + picolcd_out_report(REPORT_READ_MEMORY, hdev), 2440 + picolcd_out_report(REPORT_WRITE_MEMORY, hdev), 2441 + picolcd_out_report(REPORT_RESET, hdev)); 2442 + return 0; 2443 + err: 2444 + picolcd_exit_leds(data); 2445 + picolcd_exit_backlight(data); 2446 + picolcd_exit_lcd(data); 2447 + picolcd_exit_framebuffer(data); 2448 + picolcd_exit_cir(data); 2449 + picolcd_exit_keys(data); 2450 + return error; 2451 + } 2452 + 2453 + static int picolcd_probe_bootloader(struct hid_device *hdev, struct picolcd_data *data) 2454 + { 2455 + int error; 2456 + 2457 + error = picolcd_check_version(hdev); 2458 + if (error) 2459 + return error; 2460 + 2461 + if (data->version[0] != 1 && data->version[1] != 0) 2462 + dev_info(&hdev->dev, "Device with untested bootloader revision, " 2463 + "please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n", 2464 + dev_name(&hdev->dev)); 2465 + 2466 + picolcd_init_devfs(data, NULL, NULL, 2467 + picolcd_out_report(REPORT_BL_READ_MEMORY, hdev), 2468 + picolcd_out_report(REPORT_BL_WRITE_MEMORY, hdev), NULL); 2469 + return 0; 2470 + } 2471 + 2472 + static int picolcd_probe(struct hid_device *hdev, 2473 + const struct hid_device_id *id) 2474 + { 2475 + struct picolcd_data *data; 2476 + int error = -ENOMEM; 2477 + 2478 + dbg_hid(PICOLCD_NAME " hardware probe...\n"); 2479 + 2480 + /* 2481 + * Let's allocate the picolcd data structure, set some reasonable 2482 + * defaults, and associate it with the device 2483 + */ 2484 + data = kzalloc(sizeof(struct picolcd_data), GFP_KERNEL); 2485 + if (data == NULL) { 2486 + dev_err(&hdev->dev, "can't allocate space for Minibox PicoLCD device data\n"); 2487 + error = -ENOMEM; 2488 + goto err_no_cleanup; 2489 + } 2490 + 2491 + spin_lock_init(&data->lock); 2492 + mutex_init(&data->mutex); 2493 + data->hdev = hdev; 2494 + data->opmode_delay = 5000; 2495 + if (hdev->product == USB_DEVICE_ID_PICOLCD_BOOTLOADER) 2496 + data->status |= PICOLCD_BOOTLOADER; 2497 + hid_set_drvdata(hdev, data); 2498 + 2499 + /* Parse the device reports and start it up */ 2500 + error = hid_parse(hdev); 2501 + if (error) { 2502 + dev_err(&hdev->dev, "device report parse failed\n"); 2503 + goto err_cleanup_data; 2504 + } 2505 + 2506 + /* We don't use hidinput but hid_hw_start() fails if nothing is 2507 + * claimed. So spoof claimed input. */ 2508 + hdev->claimed = HID_CLAIMED_INPUT; 2509 + error = hid_hw_start(hdev, 0); 2510 + hdev->claimed = 0; 2511 + if (error) { 2512 + dev_err(&hdev->dev, "hardware start failed\n"); 2513 + goto err_cleanup_data; 2514 + } 2515 + 2516 + error = hdev->ll_driver->open(hdev); 2517 + if (error) { 2518 + dev_err(&hdev->dev, "failed to open input interrupt pipe for key and IR events\n"); 2519 + goto err_cleanup_hid_hw; 2520 + } 2521 + 2522 + error = device_create_file(&hdev->dev, &dev_attr_operation_mode_delay); 2523 + if (error) { 2524 + dev_err(&hdev->dev, "failed to create sysfs attributes\n"); 2525 + goto err_cleanup_hid_ll; 2526 + } 2527 + 2528 + error = device_create_file(&hdev->dev, &dev_attr_operation_mode); 2529 + if (error) { 2530 + dev_err(&hdev->dev, "failed to create sysfs attributes\n"); 2531 + goto err_cleanup_sysfs1; 2532 + } 2533 + 2534 + if (data->status & PICOLCD_BOOTLOADER) 2535 + error = picolcd_probe_bootloader(hdev, data); 2536 + else 2537 + error = picolcd_probe_lcd(hdev, data); 2538 + if (error) 2539 + goto err_cleanup_sysfs2; 2540 + 2541 + dbg_hid(PICOLCD_NAME " activated and initialized\n"); 2542 + return 0; 2543 + 2544 + err_cleanup_sysfs2: 2545 + device_remove_file(&hdev->dev, &dev_attr_operation_mode); 2546 + err_cleanup_sysfs1: 2547 + device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay); 2548 + err_cleanup_hid_ll: 2549 + hdev->ll_driver->close(hdev); 2550 + err_cleanup_hid_hw: 2551 + hid_hw_stop(hdev); 2552 + err_cleanup_data: 2553 + kfree(data); 2554 + err_no_cleanup: 2555 + hid_set_drvdata(hdev, NULL); 2556 + 2557 + return error; 2558 + } 2559 + 2560 + static void picolcd_remove(struct hid_device *hdev) 2561 + { 2562 + struct picolcd_data *data = hid_get_drvdata(hdev); 2563 + unsigned long flags; 2564 + 2565 + dbg_hid(PICOLCD_NAME " hardware remove...\n"); 2566 + spin_lock_irqsave(&data->lock, flags); 2567 + data->status |= PICOLCD_FAILED; 2568 + spin_unlock_irqrestore(&data->lock, flags); 2569 + 2570 + picolcd_exit_devfs(data); 2571 + device_remove_file(&hdev->dev, &dev_attr_operation_mode); 2572 + device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay); 2573 + hdev->ll_driver->close(hdev); 2574 + hid_hw_stop(hdev); 2575 + hid_set_drvdata(hdev, NULL); 2576 + 2577 + /* Shortcut potential pending reply that will never arrive */ 2578 + spin_lock_irqsave(&data->lock, flags); 2579 + if (data->pending) 2580 + complete(&data->pending->ready); 2581 + spin_unlock_irqrestore(&data->lock, flags); 2582 + 2583 + /* Cleanup LED */ 2584 + picolcd_exit_leds(data); 2585 + /* Clean up the framebuffer */ 2586 + picolcd_exit_backlight(data); 2587 + picolcd_exit_lcd(data); 2588 + picolcd_exit_framebuffer(data); 2589 + /* Cleanup input */ 2590 + picolcd_exit_cir(data); 2591 + picolcd_exit_keys(data); 2592 + 2593 + mutex_destroy(&data->mutex); 2594 + /* Finally, clean up the picolcd data itself */ 2595 + kfree(data); 2596 + } 2597 + 2598 + static const struct hid_device_id picolcd_devices[] = { 2599 + { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) }, 2600 + { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) }, 2601 + { } 2602 + }; 2603 + MODULE_DEVICE_TABLE(hid, picolcd_devices); 2604 + 2605 + static struct hid_driver picolcd_driver = { 2606 + .name = "hid-picolcd", 2607 + .id_table = picolcd_devices, 2608 + .probe = picolcd_probe, 2609 + .remove = picolcd_remove, 2610 + .raw_event = picolcd_raw_event, 2611 + #ifdef CONFIG_PM 2612 + .suspend = picolcd_suspend, 2613 + .resume = picolcd_resume, 2614 + .reset_resume = picolcd_reset_resume, 2615 + #endif 2616 + }; 2617 + 2618 + static int __init picolcd_init(void) 2619 + { 2620 + return hid_register_driver(&picolcd_driver); 2621 + } 2622 + 2623 + static void __exit picolcd_exit(void) 2624 + { 2625 + hid_unregister_driver(&picolcd_driver); 2626 + } 2627 + 2628 + module_init(picolcd_init); 2629 + module_exit(picolcd_exit); 2630 + MODULE_DESCRIPTION("Minibox graphics PicoLCD Driver"); 2631 + MODULE_LICENSE("GPL v2");
+910
drivers/hid/hid-prodikeys.c
··· 1 + /* 2 + * HID driver for the Prodikeys PC-MIDI Keyboard 3 + * providing midi & extra multimedia keys functionality 4 + * 5 + * Copyright (c) 2009 Don Prince <dhprince.devel@yahoo.co.uk> 6 + * 7 + * Controls for Octave Shift Up/Down, Channel, and 8 + * Sustain Duration available via sysfs. 9 + * 10 + */ 11 + 12 + /* 13 + * This program is free software; you can redistribute it and/or modify it 14 + * under the terms of the GNU General Public License as published by the Free 15 + * Software Foundation; either version 2 of the License, or (at your option) 16 + * any later version. 17 + */ 18 + 19 + #include <linux/device.h> 20 + #include <linux/module.h> 21 + #include <linux/usb.h> 22 + #include <linux/mutex.h> 23 + #include <linux/hid.h> 24 + #include <sound/core.h> 25 + #include <sound/initval.h> 26 + #include <sound/rawmidi.h> 27 + #include "usbhid/usbhid.h" 28 + #include "hid-ids.h" 29 + 30 + 31 + #define pk_debug(format, arg...) \ 32 + pr_debug("hid-prodikeys: " format "\n" , ## arg) 33 + #define pk_error(format, arg...) \ 34 + pr_err("hid-prodikeys: " format "\n" , ## arg) 35 + 36 + struct pcmidi_snd; 37 + 38 + struct pk_device { 39 + unsigned long quirks; 40 + 41 + struct hid_device *hdev; 42 + struct pcmidi_snd *pm; /* pcmidi device context */ 43 + }; 44 + 45 + struct pcmidi_snd; 46 + 47 + struct pcmidi_sustain { 48 + unsigned long in_use; 49 + struct pcmidi_snd *pm; 50 + struct timer_list timer; 51 + unsigned char status; 52 + unsigned char note; 53 + unsigned char velocity; 54 + }; 55 + 56 + #define PCMIDI_SUSTAINED_MAX 32 57 + struct pcmidi_snd { 58 + struct pk_device *pk; 59 + unsigned short ifnum; 60 + struct hid_report *pcmidi_report6; 61 + struct input_dev *input_ep82; 62 + unsigned short midi_mode; 63 + unsigned short midi_sustain_mode; 64 + unsigned short midi_sustain; 65 + unsigned short midi_channel; 66 + short midi_octave; 67 + struct pcmidi_sustain sustained_notes[PCMIDI_SUSTAINED_MAX]; 68 + unsigned short fn_state; 69 + unsigned short last_key[24]; 70 + spinlock_t rawmidi_in_lock; 71 + struct snd_card *card; 72 + struct snd_rawmidi *rwmidi; 73 + struct snd_rawmidi_substream *in_substream; 74 + struct snd_rawmidi_substream *out_substream; 75 + unsigned long in_triggered; 76 + unsigned long out_active; 77 + }; 78 + 79 + #define PK_QUIRK_NOGET 0x00010000 80 + #define PCMIDI_MIDDLE_C 60 81 + #define PCMIDI_CHANNEL_MIN 0 82 + #define PCMIDI_CHANNEL_MAX 15 83 + #define PCMIDI_OCTAVE_MIN (-2) 84 + #define PCMIDI_OCTAVE_MAX 2 85 + #define PCMIDI_SUSTAIN_MIN 0 86 + #define PCMIDI_SUSTAIN_MAX 5000 87 + 88 + static const char shortname[] = "PC-MIDI"; 89 + static const char longname[] = "Prodikeys PC-MIDI Keyboard"; 90 + 91 + static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 92 + static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 93 + static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 94 + 95 + module_param_array(index, int, NULL, 0444); 96 + module_param_array(id, charp, NULL, 0444); 97 + module_param_array(enable, bool, NULL, 0444); 98 + MODULE_PARM_DESC(index, "Index value for the PC-MIDI virtual audio driver"); 99 + MODULE_PARM_DESC(id, "ID string for the PC-MIDI virtual audio driver"); 100 + MODULE_PARM_DESC(enable, "Enable for the PC-MIDI virtual audio driver"); 101 + 102 + 103 + /* Output routine for the sysfs channel file */ 104 + static ssize_t show_channel(struct device *dev, 105 + struct device_attribute *attr, char *buf) 106 + { 107 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 108 + struct pk_device *pk = (struct pk_device *)hid_get_drvdata(hdev); 109 + 110 + dbg_hid("pcmidi sysfs read channel=%u\n", pk->pm->midi_channel); 111 + 112 + return sprintf(buf, "%u (min:%u, max:%u)\n", pk->pm->midi_channel, 113 + PCMIDI_CHANNEL_MIN, PCMIDI_CHANNEL_MAX); 114 + } 115 + 116 + /* Input routine for the sysfs channel file */ 117 + static ssize_t store_channel(struct device *dev, 118 + struct device_attribute *attr, const char *buf, size_t count) 119 + { 120 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 121 + struct pk_device *pk = (struct pk_device *)hid_get_drvdata(hdev); 122 + 123 + unsigned channel = 0; 124 + 125 + if (sscanf(buf, "%u", &channel) > 0 && channel <= PCMIDI_CHANNEL_MAX) { 126 + dbg_hid("pcmidi sysfs write channel=%u\n", channel); 127 + pk->pm->midi_channel = channel; 128 + return strlen(buf); 129 + } 130 + return -EINVAL; 131 + } 132 + 133 + static DEVICE_ATTR(channel, S_IRUGO | S_IWUGO, show_channel, 134 + store_channel); 135 + 136 + static struct device_attribute *sysfs_device_attr_channel = { 137 + &dev_attr_channel, 138 + }; 139 + 140 + /* Output routine for the sysfs sustain file */ 141 + static ssize_t show_sustain(struct device *dev, 142 + struct device_attribute *attr, char *buf) 143 + { 144 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 145 + struct pk_device *pk = (struct pk_device *)hid_get_drvdata(hdev); 146 + 147 + dbg_hid("pcmidi sysfs read sustain=%u\n", pk->pm->midi_sustain); 148 + 149 + return sprintf(buf, "%u (off:%u, max:%u (ms))\n", pk->pm->midi_sustain, 150 + PCMIDI_SUSTAIN_MIN, PCMIDI_SUSTAIN_MAX); 151 + } 152 + 153 + /* Input routine for the sysfs sustain file */ 154 + static ssize_t store_sustain(struct device *dev, 155 + struct device_attribute *attr, const char *buf, size_t count) 156 + { 157 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 158 + struct pk_device *pk = (struct pk_device *)hid_get_drvdata(hdev); 159 + 160 + unsigned sustain = 0; 161 + 162 + if (sscanf(buf, "%u", &sustain) > 0 && sustain <= PCMIDI_SUSTAIN_MAX) { 163 + dbg_hid("pcmidi sysfs write sustain=%u\n", sustain); 164 + pk->pm->midi_sustain = sustain; 165 + pk->pm->midi_sustain_mode = 166 + (0 == sustain || !pk->pm->midi_mode) ? 0 : 1; 167 + return strlen(buf); 168 + } 169 + return -EINVAL; 170 + } 171 + 172 + static DEVICE_ATTR(sustain, S_IRUGO | S_IWUGO, show_sustain, 173 + store_sustain); 174 + 175 + static struct device_attribute *sysfs_device_attr_sustain = { 176 + &dev_attr_sustain, 177 + }; 178 + 179 + /* Output routine for the sysfs octave file */ 180 + static ssize_t show_octave(struct device *dev, 181 + struct device_attribute *attr, char *buf) 182 + { 183 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 184 + struct pk_device *pk = (struct pk_device *)hid_get_drvdata(hdev); 185 + 186 + dbg_hid("pcmidi sysfs read octave=%d\n", pk->pm->midi_octave); 187 + 188 + return sprintf(buf, "%d (min:%d, max:%d)\n", pk->pm->midi_octave, 189 + PCMIDI_OCTAVE_MIN, PCMIDI_OCTAVE_MAX); 190 + } 191 + 192 + /* Input routine for the sysfs octave file */ 193 + static ssize_t store_octave(struct device *dev, 194 + struct device_attribute *attr, const char *buf, size_t count) 195 + { 196 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 197 + struct pk_device *pk = (struct pk_device *)hid_get_drvdata(hdev); 198 + 199 + int octave = 0; 200 + 201 + if (sscanf(buf, "%d", &octave) > 0 && 202 + octave >= PCMIDI_OCTAVE_MIN && octave <= PCMIDI_OCTAVE_MAX) { 203 + dbg_hid("pcmidi sysfs write octave=%d\n", octave); 204 + pk->pm->midi_octave = octave; 205 + return strlen(buf); 206 + } 207 + return -EINVAL; 208 + } 209 + 210 + static DEVICE_ATTR(octave, S_IRUGO | S_IWUGO, show_octave, 211 + store_octave); 212 + 213 + static struct device_attribute *sysfs_device_attr_octave = { 214 + &dev_attr_octave, 215 + }; 216 + 217 + 218 + static void pcmidi_send_note(struct pcmidi_snd *pm, 219 + unsigned char status, unsigned char note, unsigned char velocity) 220 + { 221 + unsigned long flags; 222 + unsigned char buffer[3]; 223 + 224 + buffer[0] = status; 225 + buffer[1] = note; 226 + buffer[2] = velocity; 227 + 228 + spin_lock_irqsave(&pm->rawmidi_in_lock, flags); 229 + 230 + if (!pm->in_substream) 231 + goto drop_note; 232 + if (!test_bit(pm->in_substream->number, &pm->in_triggered)) 233 + goto drop_note; 234 + 235 + snd_rawmidi_receive(pm->in_substream, buffer, 3); 236 + 237 + drop_note: 238 + spin_unlock_irqrestore(&pm->rawmidi_in_lock, flags); 239 + 240 + return; 241 + } 242 + 243 + void pcmidi_sustained_note_release(unsigned long data) 244 + { 245 + struct pcmidi_sustain *pms = (struct pcmidi_sustain *)data; 246 + 247 + pcmidi_send_note(pms->pm, pms->status, pms->note, pms->velocity); 248 + pms->in_use = 0; 249 + } 250 + 251 + void init_sustain_timers(struct pcmidi_snd *pm) 252 + { 253 + struct pcmidi_sustain *pms; 254 + unsigned i; 255 + 256 + for (i = 0; i < PCMIDI_SUSTAINED_MAX; i++) { 257 + pms = &pm->sustained_notes[i]; 258 + pms->in_use = 0; 259 + pms->pm = pm; 260 + setup_timer(&pms->timer, pcmidi_sustained_note_release, 261 + (unsigned long)pms); 262 + } 263 + } 264 + 265 + void stop_sustain_timers(struct pcmidi_snd *pm) 266 + { 267 + struct pcmidi_sustain *pms; 268 + unsigned i; 269 + 270 + for (i = 0; i < PCMIDI_SUSTAINED_MAX; i++) { 271 + pms = &pm->sustained_notes[i]; 272 + pms->in_use = 1; 273 + del_timer_sync(&pms->timer); 274 + } 275 + } 276 + 277 + static int pcmidi_get_output_report(struct pcmidi_snd *pm) 278 + { 279 + struct hid_device *hdev = pm->pk->hdev; 280 + struct hid_report *report; 281 + 282 + list_for_each_entry(report, 283 + &hdev->report_enum[HID_OUTPUT_REPORT].report_list, list) { 284 + if (!(6 == report->id)) 285 + continue; 286 + 287 + if (report->maxfield < 1) { 288 + dev_err(&hdev->dev, "output report is empty\n"); 289 + break; 290 + } 291 + if (report->field[0]->report_count != 2) { 292 + dev_err(&hdev->dev, "field count too low\n"); 293 + break; 294 + } 295 + pm->pcmidi_report6 = report; 296 + return 0; 297 + } 298 + /* should never get here */ 299 + return -ENODEV; 300 + } 301 + 302 + static void pcmidi_submit_output_report(struct pcmidi_snd *pm, int state) 303 + { 304 + struct hid_device *hdev = pm->pk->hdev; 305 + struct hid_report *report = pm->pcmidi_report6; 306 + report->field[0]->value[0] = 0x01; 307 + report->field[0]->value[1] = state; 308 + 309 + usbhid_submit_report(hdev, report, USB_DIR_OUT); 310 + } 311 + 312 + static int pcmidi_handle_report1(struct pcmidi_snd *pm, u8 *data) 313 + { 314 + u32 bit_mask; 315 + 316 + bit_mask = data[1]; 317 + bit_mask = (bit_mask << 8) | data[2]; 318 + bit_mask = (bit_mask << 8) | data[3]; 319 + 320 + dbg_hid("pcmidi mode: %d\n", pm->midi_mode); 321 + 322 + /*KEY_MAIL or octave down*/ 323 + if (pm->midi_mode && bit_mask == 0x004000) { 324 + /* octave down */ 325 + pm->midi_octave--; 326 + if (pm->midi_octave < -2) 327 + pm->midi_octave = -2; 328 + dbg_hid("pcmidi mode: %d octave: %d\n", 329 + pm->midi_mode, pm->midi_octave); 330 + return 1; 331 + } 332 + /*KEY_WWW or sustain*/ 333 + else if (pm->midi_mode && bit_mask == 0x000004) { 334 + /* sustain on/off*/ 335 + pm->midi_sustain_mode ^= 0x1; 336 + return 1; 337 + } 338 + 339 + return 0; /* continue key processing */ 340 + } 341 + 342 + static int pcmidi_handle_report3(struct pcmidi_snd *pm, u8 *data, int size) 343 + { 344 + struct pcmidi_sustain *pms; 345 + unsigned i, j; 346 + unsigned char status, note, velocity; 347 + 348 + unsigned num_notes = (size-1)/2; 349 + for (j = 0; j < num_notes; j++) { 350 + note = data[j*2+1]; 351 + velocity = data[j*2+2]; 352 + 353 + if (note < 0x81) { /* note on */ 354 + status = 128 + 16 + pm->midi_channel; /* 1001nnnn */ 355 + note = note - 0x54 + PCMIDI_MIDDLE_C + 356 + (pm->midi_octave * 12); 357 + if (0 == velocity) 358 + velocity = 1; /* force note on */ 359 + } else { /* note off */ 360 + status = 128 + pm->midi_channel; /* 1000nnnn */ 361 + note = note - 0x94 + PCMIDI_MIDDLE_C + 362 + (pm->midi_octave*12); 363 + 364 + if (pm->midi_sustain_mode) { 365 + for (i = 0; i < PCMIDI_SUSTAINED_MAX; i++) { 366 + pms = &pm->sustained_notes[i]; 367 + if (!pms->in_use) { 368 + pms->status = status; 369 + pms->note = note; 370 + pms->velocity = velocity; 371 + pms->in_use = 1; 372 + 373 + mod_timer(&pms->timer, 374 + jiffies + 375 + msecs_to_jiffies(pm->midi_sustain)); 376 + return 1; 377 + } 378 + } 379 + } 380 + } 381 + pcmidi_send_note(pm, status, note, velocity); 382 + } 383 + 384 + return 1; 385 + } 386 + 387 + static int pcmidi_handle_report4(struct pcmidi_snd *pm, u8 *data) 388 + { 389 + unsigned key; 390 + u32 bit_mask; 391 + u32 bit_index; 392 + 393 + bit_mask = data[1]; 394 + bit_mask = (bit_mask << 8) | data[2]; 395 + bit_mask = (bit_mask << 8) | data[3]; 396 + 397 + /* break keys */ 398 + for (bit_index = 0; bit_index < 24; bit_index++) { 399 + key = pm->last_key[bit_index]; 400 + if (!((0x01 << bit_index) & bit_mask)) { 401 + input_event(pm->input_ep82, EV_KEY, 402 + pm->last_key[bit_index], 0); 403 + pm->last_key[bit_index] = 0; 404 + } 405 + } 406 + 407 + /* make keys */ 408 + for (bit_index = 0; bit_index < 24; bit_index++) { 409 + key = 0; 410 + switch ((0x01 << bit_index) & bit_mask) { 411 + case 0x000010: /* Fn lock*/ 412 + pm->fn_state ^= 0x000010; 413 + if (pm->fn_state) 414 + pcmidi_submit_output_report(pm, 0xc5); 415 + else 416 + pcmidi_submit_output_report(pm, 0xc6); 417 + continue; 418 + case 0x020000: /* midi launcher..send a key (qwerty) or not? */ 419 + pcmidi_submit_output_report(pm, 0xc1); 420 + pm->midi_mode ^= 0x01; 421 + 422 + dbg_hid("pcmidi mode: %d\n", pm->midi_mode); 423 + continue; 424 + case 0x100000: /* KEY_MESSENGER or octave up */ 425 + dbg_hid("pcmidi mode: %d\n", pm->midi_mode); 426 + if (pm->midi_mode) { 427 + pm->midi_octave++; 428 + if (pm->midi_octave > 2) 429 + pm->midi_octave = 2; 430 + dbg_hid("pcmidi mode: %d octave: %d\n", 431 + pm->midi_mode, pm->midi_octave); 432 + continue; 433 + } else 434 + key = KEY_MESSENGER; 435 + break; 436 + case 0x400000: 437 + key = KEY_CALENDAR; 438 + break; 439 + case 0x080000: 440 + key = KEY_ADDRESSBOOK; 441 + break; 442 + case 0x040000: 443 + key = KEY_DOCUMENTS; 444 + break; 445 + case 0x800000: 446 + key = KEY_WORDPROCESSOR; 447 + break; 448 + case 0x200000: 449 + key = KEY_SPREADSHEET; 450 + break; 451 + case 0x010000: 452 + key = KEY_COFFEE; 453 + break; 454 + case 0x000100: 455 + key = KEY_HELP; 456 + break; 457 + case 0x000200: 458 + key = KEY_SEND; 459 + break; 460 + case 0x000400: 461 + key = KEY_REPLY; 462 + break; 463 + case 0x000800: 464 + key = KEY_FORWARDMAIL; 465 + break; 466 + case 0x001000: 467 + key = KEY_NEW; 468 + break; 469 + case 0x002000: 470 + key = KEY_OPEN; 471 + break; 472 + case 0x004000: 473 + key = KEY_CLOSE; 474 + break; 475 + case 0x008000: 476 + key = KEY_SAVE; 477 + break; 478 + case 0x000001: 479 + key = KEY_UNDO; 480 + break; 481 + case 0x000002: 482 + key = KEY_REDO; 483 + break; 484 + case 0x000004: 485 + key = KEY_SPELLCHECK; 486 + break; 487 + case 0x000008: 488 + key = KEY_PRINT; 489 + break; 490 + } 491 + if (key) { 492 + input_event(pm->input_ep82, EV_KEY, key, 1); 493 + pm->last_key[bit_index] = key; 494 + } 495 + } 496 + 497 + return 1; 498 + } 499 + 500 + int pcmidi_handle_report( 501 + struct pcmidi_snd *pm, unsigned report_id, u8 *data, int size) 502 + { 503 + int ret = 0; 504 + 505 + switch (report_id) { 506 + case 0x01: /* midi keys (qwerty)*/ 507 + ret = pcmidi_handle_report1(pm, data); 508 + break; 509 + case 0x03: /* midi keyboard (musical)*/ 510 + ret = pcmidi_handle_report3(pm, data, size); 511 + break; 512 + case 0x04: /* multimedia/midi keys (qwerty)*/ 513 + ret = pcmidi_handle_report4(pm, data); 514 + break; 515 + } 516 + return ret; 517 + } 518 + 519 + void pcmidi_setup_extra_keys(struct pcmidi_snd *pm, struct input_dev *input) 520 + { 521 + /* reassigned functionality for N/A keys 522 + MY PICTURES => KEY_WORDPROCESSOR 523 + MY MUSIC=> KEY_SPREADSHEET 524 + */ 525 + unsigned int keys[] = { 526 + KEY_FN, 527 + KEY_MESSENGER, KEY_CALENDAR, 528 + KEY_ADDRESSBOOK, KEY_DOCUMENTS, 529 + KEY_WORDPROCESSOR, 530 + KEY_SPREADSHEET, 531 + KEY_COFFEE, 532 + KEY_HELP, KEY_SEND, 533 + KEY_REPLY, KEY_FORWARDMAIL, 534 + KEY_NEW, KEY_OPEN, 535 + KEY_CLOSE, KEY_SAVE, 536 + KEY_UNDO, KEY_REDO, 537 + KEY_SPELLCHECK, KEY_PRINT, 538 + 0 539 + }; 540 + 541 + unsigned int *pkeys = &keys[0]; 542 + unsigned short i; 543 + 544 + if (pm->ifnum != 1) /* only set up ONCE for interace 1 */ 545 + return; 546 + 547 + pm->input_ep82 = input; 548 + 549 + for (i = 0; i < 24; i++) 550 + pm->last_key[i] = 0; 551 + 552 + while (*pkeys != 0) { 553 + set_bit(*pkeys, pm->input_ep82->keybit); 554 + ++pkeys; 555 + } 556 + } 557 + 558 + static int pcmidi_set_operational(struct pcmidi_snd *pm) 559 + { 560 + if (pm->ifnum != 1) 561 + return 0; /* only set up ONCE for interace 1 */ 562 + 563 + pcmidi_get_output_report(pm); 564 + pcmidi_submit_output_report(pm, 0xc1); 565 + return 0; 566 + } 567 + 568 + static int pcmidi_snd_free(struct snd_device *dev) 569 + { 570 + return 0; 571 + } 572 + 573 + static int pcmidi_in_open(struct snd_rawmidi_substream *substream) 574 + { 575 + struct pcmidi_snd *pm = substream->rmidi->private_data; 576 + 577 + dbg_hid("pcmidi in open\n"); 578 + pm->in_substream = substream; 579 + return 0; 580 + } 581 + 582 + static int pcmidi_in_close(struct snd_rawmidi_substream *substream) 583 + { 584 + dbg_hid("pcmidi in close\n"); 585 + return 0; 586 + } 587 + 588 + static void pcmidi_in_trigger(struct snd_rawmidi_substream *substream, int up) 589 + { 590 + struct pcmidi_snd *pm = substream->rmidi->private_data; 591 + 592 + dbg_hid("pcmidi in trigger %d\n", up); 593 + 594 + pm->in_triggered = up; 595 + } 596 + 597 + static struct snd_rawmidi_ops pcmidi_in_ops = { 598 + .open = pcmidi_in_open, 599 + .close = pcmidi_in_close, 600 + .trigger = pcmidi_in_trigger 601 + }; 602 + 603 + int pcmidi_snd_initialise(struct pcmidi_snd *pm) 604 + { 605 + static int dev; 606 + struct snd_card *card; 607 + struct snd_rawmidi *rwmidi; 608 + int err; 609 + 610 + static struct snd_device_ops ops = { 611 + .dev_free = pcmidi_snd_free, 612 + }; 613 + 614 + if (pm->ifnum != 1) 615 + return 0; /* only set up midi device ONCE for interace 1 */ 616 + 617 + if (dev >= SNDRV_CARDS) 618 + return -ENODEV; 619 + 620 + if (!enable[dev]) { 621 + dev++; 622 + return -ENOENT; 623 + } 624 + 625 + /* Setup sound card */ 626 + 627 + err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); 628 + if (err < 0) { 629 + pk_error("failed to create pc-midi sound card\n"); 630 + err = -ENOMEM; 631 + goto fail; 632 + } 633 + pm->card = card; 634 + 635 + /* Setup sound device */ 636 + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, pm, &ops); 637 + if (err < 0) { 638 + pk_error("failed to create pc-midi sound device: error %d\n", 639 + err); 640 + goto fail; 641 + } 642 + 643 + strncpy(card->driver, shortname, sizeof(card->driver)); 644 + strncpy(card->shortname, shortname, sizeof(card->shortname)); 645 + strncpy(card->longname, longname, sizeof(card->longname)); 646 + 647 + /* Set up rawmidi */ 648 + err = snd_rawmidi_new(card, card->shortname, 0, 649 + 0, 1, &rwmidi); 650 + if (err < 0) { 651 + pk_error("failed to create pc-midi rawmidi device: error %d\n", 652 + err); 653 + goto fail; 654 + } 655 + pm->rwmidi = rwmidi; 656 + strncpy(rwmidi->name, card->shortname, sizeof(rwmidi->name)); 657 + rwmidi->info_flags = SNDRV_RAWMIDI_INFO_INPUT; 658 + rwmidi->private_data = pm; 659 + 660 + snd_rawmidi_set_ops(rwmidi, SNDRV_RAWMIDI_STREAM_INPUT, 661 + &pcmidi_in_ops); 662 + 663 + snd_card_set_dev(card, &pm->pk->hdev->dev); 664 + 665 + /* create sysfs variables */ 666 + err = device_create_file(&pm->pk->hdev->dev, 667 + sysfs_device_attr_channel); 668 + if (err < 0) { 669 + pk_error("failed to create sysfs attribute channel: error %d\n", 670 + err); 671 + goto fail; 672 + } 673 + 674 + err = device_create_file(&pm->pk->hdev->dev, 675 + sysfs_device_attr_sustain); 676 + if (err < 0) { 677 + pk_error("failed to create sysfs attribute sustain: error %d\n", 678 + err); 679 + goto fail_attr_sustain; 680 + } 681 + 682 + err = device_create_file(&pm->pk->hdev->dev, 683 + sysfs_device_attr_octave); 684 + if (err < 0) { 685 + pk_error("failed to create sysfs attribute octave: error %d\n", 686 + err); 687 + goto fail_attr_octave; 688 + } 689 + 690 + spin_lock_init(&pm->rawmidi_in_lock); 691 + 692 + init_sustain_timers(pm); 693 + pcmidi_set_operational(pm); 694 + 695 + /* register it */ 696 + err = snd_card_register(card); 697 + if (err < 0) { 698 + pk_error("failed to register pc-midi sound card: error %d\n", 699 + err); 700 + goto fail_register; 701 + } 702 + 703 + dbg_hid("pcmidi_snd_initialise finished ok\n"); 704 + return 0; 705 + 706 + fail_register: 707 + stop_sustain_timers(pm); 708 + device_remove_file(&pm->pk->hdev->dev, sysfs_device_attr_octave); 709 + fail_attr_octave: 710 + device_remove_file(&pm->pk->hdev->dev, sysfs_device_attr_sustain); 711 + fail_attr_sustain: 712 + device_remove_file(&pm->pk->hdev->dev, sysfs_device_attr_channel); 713 + fail: 714 + if (pm->card) { 715 + snd_card_free(pm->card); 716 + pm->card = NULL; 717 + } 718 + return err; 719 + } 720 + 721 + int pcmidi_snd_terminate(struct pcmidi_snd *pm) 722 + { 723 + if (pm->card) { 724 + stop_sustain_timers(pm); 725 + 726 + device_remove_file(&pm->pk->hdev->dev, 727 + sysfs_device_attr_channel); 728 + device_remove_file(&pm->pk->hdev->dev, 729 + sysfs_device_attr_sustain); 730 + device_remove_file(&pm->pk->hdev->dev, 731 + sysfs_device_attr_octave); 732 + 733 + snd_card_disconnect(pm->card); 734 + snd_card_free_when_closed(pm->card); 735 + } 736 + 737 + return 0; 738 + } 739 + 740 + /* 741 + * PC-MIDI report descriptor for report id is wrong. 742 + */ 743 + static void pk_report_fixup(struct hid_device *hdev, __u8 *rdesc, 744 + unsigned int rsize) 745 + { 746 + if (rsize == 178 && 747 + rdesc[111] == 0x06 && rdesc[112] == 0x00 && 748 + rdesc[113] == 0xff) { 749 + dev_info(&hdev->dev, "fixing up pc-midi keyboard report " 750 + "descriptor\n"); 751 + 752 + rdesc[144] = 0x18; /* report 4: was 0x10 report count */ 753 + } 754 + } 755 + 756 + static int pk_input_mapping(struct hid_device *hdev, struct hid_input *hi, 757 + struct hid_field *field, struct hid_usage *usage, 758 + unsigned long **bit, int *max) 759 + { 760 + struct pk_device *pk = (struct pk_device *)hid_get_drvdata(hdev); 761 + struct pcmidi_snd *pm; 762 + 763 + pm = pk->pm; 764 + 765 + if (HID_UP_MSVENDOR == (usage->hid & HID_USAGE_PAGE) && 766 + 1 == pm->ifnum) { 767 + pcmidi_setup_extra_keys(pm, hi->input); 768 + return 0; 769 + } 770 + 771 + return 0; 772 + } 773 + 774 + 775 + static int pk_raw_event(struct hid_device *hdev, struct hid_report *report, 776 + u8 *data, int size) 777 + { 778 + struct pk_device *pk = (struct pk_device *)hid_get_drvdata(hdev); 779 + int ret = 0; 780 + 781 + if (1 == pk->pm->ifnum) { 782 + if (report->id == data[0]) 783 + switch (report->id) { 784 + case 0x01: /* midi keys (qwerty)*/ 785 + case 0x03: /* midi keyboard (musical)*/ 786 + case 0x04: /* extra/midi keys (qwerty)*/ 787 + ret = pcmidi_handle_report(pk->pm, 788 + report->id, data, size); 789 + break; 790 + } 791 + } 792 + 793 + return ret; 794 + } 795 + 796 + static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) 797 + { 798 + int ret; 799 + struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 800 + unsigned short ifnum = intf->cur_altsetting->desc.bInterfaceNumber; 801 + unsigned long quirks = id->driver_data; 802 + struct pk_device *pk; 803 + struct pcmidi_snd *pm = NULL; 804 + 805 + pk = kzalloc(sizeof(*pk), GFP_KERNEL); 806 + if (pk == NULL) { 807 + dev_err(&hdev->dev, "prodikeys: can't alloc descriptor\n"); 808 + return -ENOMEM; 809 + } 810 + 811 + pk->hdev = hdev; 812 + 813 + pm = kzalloc(sizeof(*pm), GFP_KERNEL); 814 + if (pm == NULL) { 815 + dev_err(&hdev->dev, 816 + "prodikeys: can't alloc descriptor\n"); 817 + ret = -ENOMEM; 818 + goto err_free; 819 + } 820 + 821 + pm->pk = pk; 822 + pk->pm = pm; 823 + pm->ifnum = ifnum; 824 + 825 + hid_set_drvdata(hdev, pk); 826 + 827 + ret = hid_parse(hdev); 828 + if (ret) { 829 + dev_err(&hdev->dev, "prodikeys: hid parse failed\n"); 830 + goto err_free; 831 + } 832 + 833 + if (quirks & PK_QUIRK_NOGET) { /* hid_parse cleared all the quirks */ 834 + hdev->quirks |= HID_QUIRK_NOGET; 835 + } 836 + 837 + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 838 + if (ret) { 839 + dev_err(&hdev->dev, "prodikeys: hw start failed\n"); 840 + goto err_free; 841 + } 842 + 843 + ret = pcmidi_snd_initialise(pm); 844 + if (ret < 0) 845 + goto err_stop; 846 + 847 + return 0; 848 + err_stop: 849 + hid_hw_stop(hdev); 850 + err_free: 851 + if (pm != NULL) 852 + kfree(pm); 853 + 854 + kfree(pk); 855 + return ret; 856 + } 857 + 858 + static void pk_remove(struct hid_device *hdev) 859 + { 860 + struct pk_device *pk = (struct pk_device *)hid_get_drvdata(hdev); 861 + struct pcmidi_snd *pm; 862 + 863 + pm = pk->pm; 864 + if (pm) { 865 + pcmidi_snd_terminate(pm); 866 + kfree(pm); 867 + } 868 + 869 + hid_hw_stop(hdev); 870 + 871 + kfree(pk); 872 + } 873 + 874 + static const struct hid_device_id pk_devices[] = { 875 + {HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, 876 + USB_DEVICE_ID_PRODIKEYS_PCMIDI), 877 + .driver_data = PK_QUIRK_NOGET}, 878 + { } 879 + }; 880 + MODULE_DEVICE_TABLE(hid, pk_devices); 881 + 882 + static struct hid_driver pk_driver = { 883 + .name = "prodikeys", 884 + .id_table = pk_devices, 885 + .report_fixup = pk_report_fixup, 886 + .input_mapping = pk_input_mapping, 887 + .raw_event = pk_raw_event, 888 + .probe = pk_probe, 889 + .remove = pk_remove, 890 + }; 891 + 892 + static int pk_init(void) 893 + { 894 + int ret; 895 + 896 + ret = hid_register_driver(&pk_driver); 897 + if (ret) 898 + printk(KERN_ERR "can't register prodikeys driver\n"); 899 + 900 + return ret; 901 + } 902 + 903 + static void pk_exit(void) 904 + { 905 + hid_unregister_driver(&pk_driver); 906 + } 907 + 908 + module_init(pk_init); 909 + module_exit(pk_exit); 910 + MODULE_LICENSE("GPL");
+994
drivers/hid/hid-roccat-kone.c
··· 1 + /* 2 + * Roccat Kone driver for Linux 3 + * 4 + * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net> 5 + */ 6 + 7 + /* 8 + * This program is free software; you can redistribute it and/or modify it 9 + * under the terms of the GNU General Public License as published by the Free 10 + * Software Foundation; either version 2 of the License, or (at your option) 11 + * any later version. 12 + */ 13 + 14 + /* 15 + * Roccat Kone is a gamer mouse which consists of a mouse part and a keyboard 16 + * part. The keyboard part enables the mouse to execute stored macros with mixed 17 + * key- and button-events. 18 + * 19 + * TODO implement on-the-fly polling-rate change 20 + * The windows driver has the ability to change the polling rate of the 21 + * device on the press of a mousebutton. 22 + * Is it possible to remove and reinstall the urb in raw-event- or any 23 + * other handler, or to defer this action to be executed somewhere else? 24 + * 25 + * TODO implement notification mechanism for overlong macro execution 26 + * If user wants to execute an overlong macro only the names of macroset 27 + * and macro are given. Should userland tap hidraw or is there an 28 + * additional streaming mechanism? 29 + * 30 + * TODO is it possible to overwrite group for sysfs attributes via udev? 31 + */ 32 + 33 + #include <linux/device.h> 34 + #include <linux/input.h> 35 + #include <linux/hid.h> 36 + #include <linux/usb.h> 37 + #include <linux/module.h> 38 + #include <linux/slab.h> 39 + #include "hid-ids.h" 40 + #include "hid-roccat-kone.h" 41 + 42 + static void kone_set_settings_checksum(struct kone_settings *settings) 43 + { 44 + uint16_t checksum = 0; 45 + unsigned char *address = (unsigned char *)settings; 46 + int i; 47 + 48 + for (i = 0; i < sizeof(struct kone_settings) - 2; ++i, ++address) 49 + checksum += *address; 50 + settings->checksum = cpu_to_le16(checksum); 51 + } 52 + 53 + /* 54 + * Checks success after writing data to mouse 55 + * On success returns 0 56 + * On failure returns errno 57 + */ 58 + static int kone_check_write(struct usb_device *usb_dev) 59 + { 60 + int len; 61 + unsigned char *data; 62 + 63 + data = kmalloc(1, GFP_KERNEL); 64 + if (!data) 65 + return -ENOMEM; 66 + 67 + do { 68 + /* 69 + * Mouse needs 50 msecs until it says ok, but there are 70 + * 30 more msecs needed for next write to work. 71 + */ 72 + msleep(80); 73 + 74 + len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 75 + USB_REQ_CLEAR_FEATURE, 76 + USB_TYPE_CLASS | USB_RECIP_INTERFACE | 77 + USB_DIR_IN, 78 + kone_command_confirm_write, 0, data, 1, 79 + USB_CTRL_SET_TIMEOUT); 80 + 81 + if (len != 1) { 82 + kfree(data); 83 + return -EIO; 84 + } 85 + 86 + /* 87 + * value of 3 seems to mean something like 88 + * "not finished yet, but it looks good" 89 + * So check again after a moment. 90 + */ 91 + } while (*data == 3); 92 + 93 + if (*data == 1) { /* everything alright */ 94 + kfree(data); 95 + return 0; 96 + } else { /* unknown answer */ 97 + dev_err(&usb_dev->dev, "got retval %d when checking write\n", 98 + *data); 99 + kfree(data); 100 + return -EIO; 101 + } 102 + } 103 + 104 + /* 105 + * Reads settings from mouse and stores it in @buf 106 + * @buf has to be alloced with GFP_KERNEL 107 + * On success returns 0 108 + * On failure returns errno 109 + */ 110 + static int kone_get_settings(struct usb_device *usb_dev, 111 + struct kone_settings *buf) 112 + { 113 + int len; 114 + 115 + len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 116 + USB_REQ_CLEAR_FEATURE, 117 + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 118 + kone_command_settings, 0, buf, 119 + sizeof(struct kone_settings), USB_CTRL_SET_TIMEOUT); 120 + 121 + if (len != sizeof(struct kone_settings)) 122 + return -EIO; 123 + 124 + return 0; 125 + } 126 + 127 + /* 128 + * Writes settings from @buf to mouse 129 + * On success returns 0 130 + * On failure returns errno 131 + */ 132 + static int kone_set_settings(struct usb_device *usb_dev, 133 + struct kone_settings const *settings) 134 + { 135 + int len; 136 + 137 + len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 138 + USB_REQ_SET_CONFIGURATION, 139 + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, 140 + kone_command_settings, 0, (char *)settings, 141 + sizeof(struct kone_settings), 142 + USB_CTRL_SET_TIMEOUT); 143 + 144 + if (len != sizeof(struct kone_settings)) 145 + return -EIO; 146 + 147 + if (kone_check_write(usb_dev)) 148 + return -EIO; 149 + 150 + return 0; 151 + } 152 + 153 + /* 154 + * Reads profile data from mouse and stores it in @buf 155 + * @number: profile number to read 156 + * On success returns 0 157 + * On failure returns errno 158 + */ 159 + static int kone_get_profile(struct usb_device *usb_dev, 160 + struct kone_profile *buf, int number) 161 + { 162 + int len; 163 + 164 + if (number < 1 || number > 5) 165 + return -EINVAL; 166 + 167 + len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 168 + USB_REQ_CLEAR_FEATURE, 169 + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 170 + kone_command_profile, number, buf, 171 + sizeof(struct kone_profile), USB_CTRL_SET_TIMEOUT); 172 + 173 + if (len != sizeof(struct kone_profile)) 174 + return -EIO; 175 + 176 + return 0; 177 + } 178 + 179 + /* 180 + * Writes profile data to mouse. 181 + * @number: profile number to write 182 + * On success returns 0 183 + * On failure returns errno 184 + */ 185 + static int kone_set_profile(struct usb_device *usb_dev, 186 + struct kone_profile const *profile, int number) 187 + { 188 + int len; 189 + 190 + if (number < 1 || number > 5) 191 + return -EINVAL; 192 + 193 + len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 194 + USB_REQ_SET_CONFIGURATION, 195 + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, 196 + kone_command_profile, number, (char *)profile, 197 + sizeof(struct kone_profile), 198 + USB_CTRL_SET_TIMEOUT); 199 + 200 + if (len != sizeof(struct kone_profile)) 201 + return len; 202 + 203 + if (kone_check_write(usb_dev)) 204 + return -EIO; 205 + 206 + return 0; 207 + } 208 + 209 + /* 210 + * Reads value of "fast-clip-weight" and stores it in @result 211 + * On success returns 0 212 + * On failure returns errno 213 + */ 214 + static int kone_get_weight(struct usb_device *usb_dev, int *result) 215 + { 216 + int len; 217 + uint8_t *data; 218 + 219 + data = kmalloc(1, GFP_KERNEL); 220 + if (!data) 221 + return -ENOMEM; 222 + 223 + len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 224 + USB_REQ_CLEAR_FEATURE, 225 + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 226 + kone_command_weight, 0, data, 1, USB_CTRL_SET_TIMEOUT); 227 + 228 + if (len != 1) { 229 + kfree(data); 230 + return -EIO; 231 + } 232 + *result = (int)*data; 233 + kfree(data); 234 + return 0; 235 + } 236 + 237 + /* 238 + * Reads firmware_version of mouse and stores it in @result 239 + * On success returns 0 240 + * On failure returns errno 241 + */ 242 + static int kone_get_firmware_version(struct usb_device *usb_dev, int *result) 243 + { 244 + int len; 245 + unsigned char *data; 246 + 247 + data = kmalloc(2, GFP_KERNEL); 248 + if (!data) 249 + return -ENOMEM; 250 + 251 + len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 252 + USB_REQ_CLEAR_FEATURE, 253 + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 254 + kone_command_firmware_version, 0, data, 2, 255 + USB_CTRL_SET_TIMEOUT); 256 + 257 + if (len != 2) { 258 + kfree(data); 259 + return -EIO; 260 + } 261 + *result = le16_to_cpu(*data); 262 + kfree(data); 263 + return 0; 264 + } 265 + 266 + static ssize_t kone_sysfs_read_settings(struct kobject *kobj, 267 + struct bin_attribute *attr, char *buf, 268 + loff_t off, size_t count) { 269 + struct device *dev = container_of(kobj, struct device, kobj); 270 + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); 271 + 272 + if (off >= sizeof(struct kone_settings)) 273 + return 0; 274 + 275 + if (off + count > sizeof(struct kone_settings)) 276 + count = sizeof(struct kone_settings) - off; 277 + 278 + mutex_lock(&kone->kone_lock); 279 + memcpy(buf, &kone->settings + off, count); 280 + mutex_unlock(&kone->kone_lock); 281 + 282 + return count; 283 + } 284 + 285 + /* 286 + * Writing settings automatically activates startup_profile. 287 + * This function keeps values in kone_device up to date and assumes that in 288 + * case of error the old data is still valid 289 + */ 290 + static ssize_t kone_sysfs_write_settings(struct kobject *kobj, 291 + struct bin_attribute *attr, char *buf, 292 + loff_t off, size_t count) { 293 + struct device *dev = container_of(kobj, struct device, kobj); 294 + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); 295 + struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 296 + int retval = 0, difference; 297 + 298 + /* I need to get my data in one piece */ 299 + if (off != 0 || count != sizeof(struct kone_settings)) 300 + return -EINVAL; 301 + 302 + mutex_lock(&kone->kone_lock); 303 + difference = memcmp(buf, &kone->settings, sizeof(struct kone_settings)); 304 + if (difference) { 305 + retval = kone_set_settings(usb_dev, 306 + (struct kone_settings const *)buf); 307 + if (!retval) 308 + memcpy(&kone->settings, buf, 309 + sizeof(struct kone_settings)); 310 + } 311 + mutex_unlock(&kone->kone_lock); 312 + 313 + if (retval) 314 + return retval; 315 + 316 + /* 317 + * If we get here, treat settings as okay and update actual values 318 + * according to startup_profile 319 + */ 320 + kone->actual_profile = kone->settings.startup_profile; 321 + kone->actual_dpi = kone->profiles[kone->actual_profile - 1].startup_dpi; 322 + 323 + return sizeof(struct kone_settings); 324 + } 325 + 326 + static ssize_t kone_sysfs_read_profilex(struct kobject *kobj, 327 + struct bin_attribute *attr, char *buf, 328 + loff_t off, size_t count, int number) { 329 + struct device *dev = container_of(kobj, struct device, kobj); 330 + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); 331 + 332 + if (off >= sizeof(struct kone_profile)) 333 + return 0; 334 + 335 + if (off + count > sizeof(struct kone_profile)) 336 + count = sizeof(struct kone_profile) - off; 337 + 338 + mutex_lock(&kone->kone_lock); 339 + memcpy(buf, &kone->profiles[number - 1], sizeof(struct kone_profile)); 340 + mutex_unlock(&kone->kone_lock); 341 + 342 + return count; 343 + } 344 + 345 + static ssize_t kone_sysfs_read_profile1(struct kobject *kobj, 346 + struct bin_attribute *attr, char *buf, 347 + loff_t off, size_t count) { 348 + return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 1); 349 + } 350 + 351 + static ssize_t kone_sysfs_read_profile2(struct kobject *kobj, 352 + struct bin_attribute *attr, char *buf, 353 + loff_t off, size_t count) { 354 + return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 2); 355 + } 356 + 357 + static ssize_t kone_sysfs_read_profile3(struct kobject *kobj, 358 + struct bin_attribute *attr, char *buf, 359 + loff_t off, size_t count) { 360 + return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 3); 361 + } 362 + 363 + static ssize_t kone_sysfs_read_profile4(struct kobject *kobj, 364 + struct bin_attribute *attr, char *buf, 365 + loff_t off, size_t count) { 366 + return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 4); 367 + } 368 + 369 + static ssize_t kone_sysfs_read_profile5(struct kobject *kobj, 370 + struct bin_attribute *attr, char *buf, 371 + loff_t off, size_t count) { 372 + return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 5); 373 + } 374 + 375 + /* Writes data only if different to stored data */ 376 + static ssize_t kone_sysfs_write_profilex(struct kobject *kobj, 377 + struct bin_attribute *attr, char *buf, 378 + loff_t off, size_t count, int number) { 379 + struct device *dev = container_of(kobj, struct device, kobj); 380 + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); 381 + struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 382 + struct kone_profile *profile; 383 + int retval = 0, difference; 384 + 385 + /* I need to get my data in one piece */ 386 + if (off != 0 || count != sizeof(struct kone_profile)) 387 + return -EINVAL; 388 + 389 + profile = &kone->profiles[number - 1]; 390 + 391 + mutex_lock(&kone->kone_lock); 392 + difference = memcmp(buf, profile, sizeof(struct kone_profile)); 393 + if (difference) { 394 + retval = kone_set_profile(usb_dev, 395 + (struct kone_profile const *)buf, number); 396 + if (!retval) 397 + memcpy(profile, buf, sizeof(struct kone_profile)); 398 + } 399 + mutex_unlock(&kone->kone_lock); 400 + 401 + if (retval) 402 + return retval; 403 + 404 + return sizeof(struct kone_profile); 405 + } 406 + 407 + static ssize_t kone_sysfs_write_profile1(struct kobject *kobj, 408 + struct bin_attribute *attr, char *buf, 409 + loff_t off, size_t count) { 410 + return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 1); 411 + } 412 + 413 + static ssize_t kone_sysfs_write_profile2(struct kobject *kobj, 414 + struct bin_attribute *attr, char *buf, 415 + loff_t off, size_t count) { 416 + return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 2); 417 + } 418 + 419 + static ssize_t kone_sysfs_write_profile3(struct kobject *kobj, 420 + struct bin_attribute *attr, char *buf, 421 + loff_t off, size_t count) { 422 + return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 3); 423 + } 424 + 425 + static ssize_t kone_sysfs_write_profile4(struct kobject *kobj, 426 + struct bin_attribute *attr, char *buf, 427 + loff_t off, size_t count) { 428 + return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 4); 429 + } 430 + 431 + static ssize_t kone_sysfs_write_profile5(struct kobject *kobj, 432 + struct bin_attribute *attr, char *buf, 433 + loff_t off, size_t count) { 434 + return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 5); 435 + } 436 + 437 + static ssize_t kone_sysfs_show_actual_profile(struct device *dev, 438 + struct device_attribute *attr, char *buf) 439 + { 440 + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); 441 + return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_profile); 442 + } 443 + 444 + static ssize_t kone_sysfs_show_actual_dpi(struct device *dev, 445 + struct device_attribute *attr, char *buf) 446 + { 447 + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); 448 + return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_dpi); 449 + } 450 + 451 + /* weight is read each time, since we don't get informed when it's changed */ 452 + static ssize_t kone_sysfs_show_weight(struct device *dev, 453 + struct device_attribute *attr, char *buf) 454 + { 455 + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); 456 + struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 457 + int weight = 0; 458 + int retval; 459 + 460 + mutex_lock(&kone->kone_lock); 461 + retval = kone_get_weight(usb_dev, &weight); 462 + mutex_unlock(&kone->kone_lock); 463 + 464 + if (retval) 465 + return retval; 466 + return snprintf(buf, PAGE_SIZE, "%d\n", weight); 467 + } 468 + 469 + static ssize_t kone_sysfs_show_firmware_version(struct device *dev, 470 + struct device_attribute *attr, char *buf) 471 + { 472 + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); 473 + return snprintf(buf, PAGE_SIZE, "%d\n", kone->firmware_version); 474 + } 475 + 476 + static ssize_t kone_sysfs_show_tcu(struct device *dev, 477 + struct device_attribute *attr, char *buf) 478 + { 479 + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); 480 + return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.tcu); 481 + } 482 + 483 + static int kone_tcu_command(struct usb_device *usb_dev, int number) 484 + { 485 + int len; 486 + char *value; 487 + 488 + value = kmalloc(1, GFP_KERNEL); 489 + if (!value) 490 + return -ENOMEM; 491 + 492 + *value = number; 493 + 494 + len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 495 + USB_REQ_SET_CONFIGURATION, 496 + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, 497 + kone_command_calibrate, 0, value, 1, 498 + USB_CTRL_SET_TIMEOUT); 499 + 500 + kfree(value); 501 + return ((len != 1) ? -EIO : 0); 502 + } 503 + 504 + /* 505 + * Calibrating the tcu is the only action that changes settings data inside the 506 + * mouse, so this data needs to be reread 507 + */ 508 + static ssize_t kone_sysfs_set_tcu(struct device *dev, 509 + struct device_attribute *attr, char const *buf, size_t size) 510 + { 511 + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); 512 + struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 513 + int retval; 514 + unsigned long state; 515 + 516 + retval = strict_strtoul(buf, 10, &state); 517 + if (retval) 518 + return retval; 519 + 520 + if (state != 0 && state != 1) 521 + return -EINVAL; 522 + 523 + mutex_lock(&kone->kone_lock); 524 + 525 + if (state == 1) { /* state activate */ 526 + retval = kone_tcu_command(usb_dev, 1); 527 + if (retval) 528 + goto exit_unlock; 529 + retval = kone_tcu_command(usb_dev, 2); 530 + if (retval) 531 + goto exit_unlock; 532 + ssleep(5); /* tcu needs this time for calibration */ 533 + retval = kone_tcu_command(usb_dev, 3); 534 + if (retval) 535 + goto exit_unlock; 536 + retval = kone_tcu_command(usb_dev, 0); 537 + if (retval) 538 + goto exit_unlock; 539 + retval = kone_tcu_command(usb_dev, 4); 540 + if (retval) 541 + goto exit_unlock; 542 + /* 543 + * Kone needs this time to settle things. 544 + * Reading settings too early will result in invalid data. 545 + * Roccat's driver waits 1 sec, maybe this time could be 546 + * shortened. 547 + */ 548 + ssleep(1); 549 + } 550 + 551 + /* calibration changes values in settings, so reread */ 552 + retval = kone_get_settings(usb_dev, &kone->settings); 553 + if (retval) 554 + goto exit_no_settings; 555 + 556 + /* only write settings back if activation state is different */ 557 + if (kone->settings.tcu != state) { 558 + kone->settings.tcu = state; 559 + kone_set_settings_checksum(&kone->settings); 560 + 561 + retval = kone_set_settings(usb_dev, &kone->settings); 562 + if (retval) { 563 + dev_err(&usb_dev->dev, "couldn't set tcu state\n"); 564 + /* 565 + * try to reread valid settings into buffer overwriting 566 + * first error code 567 + */ 568 + retval = kone_get_settings(usb_dev, &kone->settings); 569 + if (retval) 570 + goto exit_no_settings; 571 + goto exit_unlock; 572 + } 573 + } 574 + 575 + retval = size; 576 + exit_no_settings: 577 + dev_err(&usb_dev->dev, "couldn't read settings\n"); 578 + exit_unlock: 579 + mutex_unlock(&kone->kone_lock); 580 + return retval; 581 + } 582 + 583 + static ssize_t kone_sysfs_show_startup_profile(struct device *dev, 584 + struct device_attribute *attr, char *buf) 585 + { 586 + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); 587 + return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.startup_profile); 588 + } 589 + 590 + static ssize_t kone_sysfs_set_startup_profile(struct device *dev, 591 + struct device_attribute *attr, char const *buf, size_t size) 592 + { 593 + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); 594 + struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 595 + int retval; 596 + unsigned long new_startup_profile; 597 + 598 + retval = strict_strtoul(buf, 10, &new_startup_profile); 599 + if (retval) 600 + return retval; 601 + 602 + if (new_startup_profile < 1 || new_startup_profile > 5) 603 + return -EINVAL; 604 + 605 + mutex_lock(&kone->kone_lock); 606 + 607 + kone->settings.startup_profile = new_startup_profile; 608 + kone_set_settings_checksum(&kone->settings); 609 + 610 + retval = kone_set_settings(usb_dev, &kone->settings); 611 + 612 + mutex_unlock(&kone->kone_lock); 613 + 614 + if (retval) 615 + return retval; 616 + 617 + /* changing the startup profile immediately activates this profile */ 618 + kone->actual_profile = new_startup_profile; 619 + kone->actual_dpi = kone->profiles[kone->actual_profile - 1].startup_dpi; 620 + 621 + return size; 622 + } 623 + 624 + /* 625 + * This file is used by userland software to find devices that are handled by 626 + * this driver. This provides a consistent way for actual and older kernels 627 + * where this driver replaced usbhid instead of generic-usb. 628 + * Driver capabilities are determined by version number. 629 + */ 630 + static ssize_t kone_sysfs_show_driver_version(struct device *dev, 631 + struct device_attribute *attr, char *buf) 632 + { 633 + return snprintf(buf, PAGE_SIZE, ROCCAT_KONE_DRIVER_VERSION "\n"); 634 + } 635 + 636 + /* 637 + * Read actual dpi settings. 638 + * Returns raw value for further processing. Refer to enum kone_polling_rates to 639 + * get real value. 640 + */ 641 + static DEVICE_ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL); 642 + 643 + static DEVICE_ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL); 644 + 645 + /* 646 + * The mouse can be equipped with one of four supplied weights from 5 to 20 647 + * grams which are recognized and its value can be read out. 648 + * This returns the raw value reported by the mouse for easy evaluation by 649 + * software. Refer to enum kone_weights to get corresponding real weight. 650 + */ 651 + static DEVICE_ATTR(weight, 0440, kone_sysfs_show_weight, NULL); 652 + 653 + /* 654 + * Prints firmware version stored in mouse as integer. 655 + * The raw value reported by the mouse is returned for easy evaluation, to get 656 + * the real version number the decimal point has to be shifted 2 positions to 657 + * the left. E.g. a value of 138 means 1.38. 658 + */ 659 + static DEVICE_ATTR(firmware_version, 0440, 660 + kone_sysfs_show_firmware_version, NULL); 661 + 662 + /* 663 + * Prints state of Tracking Control Unit as number where 0 = off and 1 = on 664 + * Writing 0 deactivates tcu and writing 1 calibrates and activates the tcu 665 + */ 666 + static DEVICE_ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu); 667 + 668 + /* Prints and takes the number of the profile the mouse starts with */ 669 + static DEVICE_ATTR(startup_profile, 0660, 670 + kone_sysfs_show_startup_profile, 671 + kone_sysfs_set_startup_profile); 672 + 673 + static DEVICE_ATTR(kone_driver_version, 0440, 674 + kone_sysfs_show_driver_version, NULL); 675 + 676 + static struct attribute *kone_attributes[] = { 677 + &dev_attr_actual_dpi.attr, 678 + &dev_attr_actual_profile.attr, 679 + &dev_attr_weight.attr, 680 + &dev_attr_firmware_version.attr, 681 + &dev_attr_tcu.attr, 682 + &dev_attr_startup_profile.attr, 683 + &dev_attr_kone_driver_version.attr, 684 + NULL 685 + }; 686 + 687 + static struct attribute_group kone_attribute_group = { 688 + .attrs = kone_attributes 689 + }; 690 + 691 + static struct bin_attribute kone_settings_attr = { 692 + .attr = { .name = "settings", .mode = 0660 }, 693 + .size = sizeof(struct kone_settings), 694 + .read = kone_sysfs_read_settings, 695 + .write = kone_sysfs_write_settings 696 + }; 697 + 698 + static struct bin_attribute kone_profile1_attr = { 699 + .attr = { .name = "profile1", .mode = 0660 }, 700 + .size = sizeof(struct kone_profile), 701 + .read = kone_sysfs_read_profile1, 702 + .write = kone_sysfs_write_profile1 703 + }; 704 + 705 + static struct bin_attribute kone_profile2_attr = { 706 + .attr = { .name = "profile2", .mode = 0660 }, 707 + .size = sizeof(struct kone_profile), 708 + .read = kone_sysfs_read_profile2, 709 + .write = kone_sysfs_write_profile2 710 + }; 711 + 712 + static struct bin_attribute kone_profile3_attr = { 713 + .attr = { .name = "profile3", .mode = 0660 }, 714 + .size = sizeof(struct kone_profile), 715 + .read = kone_sysfs_read_profile3, 716 + .write = kone_sysfs_write_profile3 717 + }; 718 + 719 + static struct bin_attribute kone_profile4_attr = { 720 + .attr = { .name = "profile4", .mode = 0660 }, 721 + .size = sizeof(struct kone_profile), 722 + .read = kone_sysfs_read_profile4, 723 + .write = kone_sysfs_write_profile4 724 + }; 725 + 726 + static struct bin_attribute kone_profile5_attr = { 727 + .attr = { .name = "profile5", .mode = 0660 }, 728 + .size = sizeof(struct kone_profile), 729 + .read = kone_sysfs_read_profile5, 730 + .write = kone_sysfs_write_profile5 731 + }; 732 + 733 + static int kone_create_sysfs_attributes(struct usb_interface *intf) 734 + { 735 + int retval; 736 + 737 + retval = sysfs_create_group(&intf->dev.kobj, &kone_attribute_group); 738 + if (retval) 739 + goto exit_1; 740 + 741 + retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_settings_attr); 742 + if (retval) 743 + goto exit_2; 744 + 745 + retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile1_attr); 746 + if (retval) 747 + goto exit_3; 748 + 749 + retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile2_attr); 750 + if (retval) 751 + goto exit_4; 752 + 753 + retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile3_attr); 754 + if (retval) 755 + goto exit_5; 756 + 757 + retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile4_attr); 758 + if (retval) 759 + goto exit_6; 760 + 761 + retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile5_attr); 762 + if (retval) 763 + goto exit_7; 764 + 765 + return 0; 766 + 767 + exit_7: 768 + sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile4_attr); 769 + exit_6: 770 + sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile3_attr); 771 + exit_5: 772 + sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile2_attr); 773 + exit_4: 774 + sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile1_attr); 775 + exit_3: 776 + sysfs_remove_bin_file(&intf->dev.kobj, &kone_settings_attr); 777 + exit_2: 778 + sysfs_remove_group(&intf->dev.kobj, &kone_attribute_group); 779 + exit_1: 780 + return retval; 781 + } 782 + 783 + static void kone_remove_sysfs_attributes(struct usb_interface *intf) 784 + { 785 + sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile5_attr); 786 + sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile4_attr); 787 + sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile3_attr); 788 + sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile2_attr); 789 + sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile1_attr); 790 + sysfs_remove_bin_file(&intf->dev.kobj, &kone_settings_attr); 791 + sysfs_remove_group(&intf->dev.kobj, &kone_attribute_group); 792 + } 793 + 794 + static int kone_init_kone_device_struct(struct usb_device *usb_dev, 795 + struct kone_device *kone) 796 + { 797 + uint i; 798 + int retval; 799 + 800 + mutex_init(&kone->kone_lock); 801 + 802 + for (i = 0; i < 5; ++i) { 803 + retval = kone_get_profile(usb_dev, &kone->profiles[i], i + 1); 804 + if (retval) 805 + return retval; 806 + } 807 + 808 + retval = kone_get_settings(usb_dev, &kone->settings); 809 + if (retval) 810 + return retval; 811 + 812 + retval = kone_get_firmware_version(usb_dev, &kone->firmware_version); 813 + if (retval) 814 + return retval; 815 + 816 + kone->actual_profile = kone->settings.startup_profile; 817 + kone->actual_dpi = kone->profiles[kone->actual_profile].startup_dpi; 818 + 819 + return 0; 820 + } 821 + 822 + /* 823 + * Since IGNORE_MOUSE quirk moved to hid-apple, there is no way to bind only to 824 + * mousepart if usb_hid is compiled into the kernel and kone is compiled as 825 + * module. 826 + * Secial behaviour is bound only to mousepart since only mouseevents contain 827 + * additional notifications. 828 + */ 829 + static int kone_init_specials(struct hid_device *hdev) 830 + { 831 + struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 832 + struct usb_device *usb_dev = interface_to_usbdev(intf); 833 + struct kone_device *kone; 834 + int retval; 835 + 836 + if (intf->cur_altsetting->desc.bInterfaceProtocol 837 + == USB_INTERFACE_PROTOCOL_MOUSE) { 838 + 839 + kone = kzalloc(sizeof(*kone), GFP_KERNEL); 840 + if (!kone) { 841 + dev_err(&hdev->dev, "can't alloc device descriptor\n"); 842 + return -ENOMEM; 843 + } 844 + hid_set_drvdata(hdev, kone); 845 + 846 + retval = kone_init_kone_device_struct(usb_dev, kone); 847 + if (retval) { 848 + dev_err(&hdev->dev, 849 + "couldn't init struct kone_device\n"); 850 + goto exit_free; 851 + } 852 + retval = kone_create_sysfs_attributes(intf); 853 + if (retval) { 854 + dev_err(&hdev->dev, "cannot create sysfs files\n"); 855 + goto exit_free; 856 + } 857 + } else { 858 + hid_set_drvdata(hdev, NULL); 859 + } 860 + 861 + return 0; 862 + exit_free: 863 + kfree(kone); 864 + return retval; 865 + } 866 + 867 + 868 + static void kone_remove_specials(struct hid_device *hdev) 869 + { 870 + struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 871 + 872 + if (intf->cur_altsetting->desc.bInterfaceProtocol 873 + == USB_INTERFACE_PROTOCOL_MOUSE) { 874 + kone_remove_sysfs_attributes(intf); 875 + kfree(hid_get_drvdata(hdev)); 876 + } 877 + } 878 + 879 + static int kone_probe(struct hid_device *hdev, const struct hid_device_id *id) 880 + { 881 + int retval; 882 + 883 + retval = hid_parse(hdev); 884 + if (retval) { 885 + dev_err(&hdev->dev, "parse failed\n"); 886 + goto exit; 887 + } 888 + 889 + retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 890 + if (retval) { 891 + dev_err(&hdev->dev, "hw start failed\n"); 892 + goto exit; 893 + } 894 + 895 + retval = kone_init_specials(hdev); 896 + if (retval) { 897 + dev_err(&hdev->dev, "couldn't install mouse\n"); 898 + goto exit_stop; 899 + } 900 + 901 + return 0; 902 + 903 + exit_stop: 904 + hid_hw_stop(hdev); 905 + exit: 906 + return retval; 907 + } 908 + 909 + static void kone_remove(struct hid_device *hdev) 910 + { 911 + kone_remove_specials(hdev); 912 + hid_hw_stop(hdev); 913 + } 914 + 915 + /* handle special events and keep actual profile and dpi values up to date */ 916 + static void kone_keep_values_up_to_date(struct kone_device *kone, 917 + struct kone_mouse_event const *event) 918 + { 919 + switch (event->event) { 920 + case kone_mouse_event_switch_profile: 921 + case kone_mouse_event_osd_profile: 922 + kone->actual_profile = event->value; 923 + kone->actual_dpi = kone->profiles[kone->actual_profile - 1]. 924 + startup_dpi; 925 + break; 926 + case kone_mouse_event_switch_dpi: 927 + case kone_mouse_event_osd_dpi: 928 + kone->actual_dpi = event->value; 929 + break; 930 + } 931 + } 932 + 933 + /* 934 + * Is called for keyboard- and mousepart. 935 + * Only mousepart gets informations about special events in its extended event 936 + * structure. 937 + */ 938 + static int kone_raw_event(struct hid_device *hdev, struct hid_report *report, 939 + u8 *data, int size) 940 + { 941 + struct kone_device *kone = hid_get_drvdata(hdev); 942 + struct kone_mouse_event *event = (struct kone_mouse_event *)data; 943 + 944 + /* keyboard events are always processed by default handler */ 945 + if (size != sizeof(struct kone_mouse_event)) 946 + return 0; 947 + 948 + /* 949 + * Firmware 1.38 introduced new behaviour for tilt and special buttons. 950 + * Pressed button is reported in each movement event. 951 + * Workaround sends only one event per press. 952 + */ 953 + if (memcmp(&kone->last_mouse_event.tilt, &event->tilt, 5)) 954 + memcpy(&kone->last_mouse_event, event, 955 + sizeof(struct kone_mouse_event)); 956 + else 957 + memset(&event->tilt, 0, 5); 958 + 959 + kone_keep_values_up_to_date(kone, event); 960 + 961 + return 0; /* always do further processing */ 962 + } 963 + 964 + static const struct hid_device_id kone_devices[] = { 965 + { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) }, 966 + { } 967 + }; 968 + 969 + MODULE_DEVICE_TABLE(hid, kone_devices); 970 + 971 + static struct hid_driver kone_driver = { 972 + .name = "kone", 973 + .id_table = kone_devices, 974 + .probe = kone_probe, 975 + .remove = kone_remove, 976 + .raw_event = kone_raw_event 977 + }; 978 + 979 + static int __init kone_init(void) 980 + { 981 + return hid_register_driver(&kone_driver); 982 + } 983 + 984 + static void __exit kone_exit(void) 985 + { 986 + hid_unregister_driver(&kone_driver); 987 + } 988 + 989 + module_init(kone_init); 990 + module_exit(kone_exit); 991 + 992 + MODULE_AUTHOR("Stefan Achatz"); 993 + MODULE_DESCRIPTION("USB Roccat Kone driver"); 994 + MODULE_LICENSE("GPL v2");
+224
drivers/hid/hid-roccat-kone.h
··· 1 + #ifndef __HID_ROCCAT_KONE_H 2 + #define __HID_ROCCAT_KONE_H 3 + 4 + /* 5 + * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net> 6 + */ 7 + 8 + /* 9 + * This program is free software; you can redistribute it and/or modify it 10 + * under the terms of the GNU General Public License as published by the Free 11 + * Software Foundation; either version 2 of the License, or (at your option) 12 + * any later version. 13 + */ 14 + 15 + #include <linux/types.h> 16 + 17 + #define ROCCAT_KONE_DRIVER_VERSION "v0.3.1" 18 + 19 + #pragma pack(push) 20 + #pragma pack(1) 21 + 22 + struct kone_keystroke { 23 + uint8_t key; 24 + uint8_t action; 25 + uint16_t period; /* in milliseconds */ 26 + }; 27 + 28 + enum kone_keystroke_buttons { 29 + kone_keystroke_button_1 = 0xf0, /* left mouse button */ 30 + kone_keystroke_button_2 = 0xf1, /* right mouse button */ 31 + kone_keystroke_button_3 = 0xf2, /* wheel */ 32 + kone_keystroke_button_9 = 0xf3, /* side button up */ 33 + kone_keystroke_button_8 = 0xf4 /* side button down */ 34 + }; 35 + 36 + enum kone_keystroke_actions { 37 + kone_keystroke_action_press = 0, 38 + kone_keystroke_action_release = 1 39 + }; 40 + 41 + struct kone_button_info { 42 + uint8_t number; /* range 1-8 */ 43 + uint8_t type; 44 + uint8_t macro_type; /* 0 = short, 1 = overlong */ 45 + uint8_t macro_set_name[16]; /* can be max 15 chars long */ 46 + uint8_t macro_name[16]; /* can be max 15 chars long */ 47 + uint8_t count; 48 + struct kone_keystroke keystrokes[20]; 49 + }; 50 + 51 + enum kone_button_info_types { 52 + /* valid button types until firmware 1.32 */ 53 + kone_button_info_type_button_1 = 0x1, /* click (left mouse button) */ 54 + kone_button_info_type_button_2 = 0x2, /* menu (right mouse button)*/ 55 + kone_button_info_type_button_3 = 0x3, /* scroll (wheel) */ 56 + kone_button_info_type_double_click = 0x4, 57 + kone_button_info_type_key = 0x5, 58 + kone_button_info_type_macro = 0x6, 59 + kone_button_info_type_off = 0x7, 60 + /* TODO clarify function and rename */ 61 + kone_button_info_type_osd_xy_prescaling = 0x8, 62 + kone_button_info_type_osd_dpi = 0x9, 63 + kone_button_info_type_osd_profile = 0xa, 64 + kone_button_info_type_button_9 = 0xb, /* ie forward */ 65 + kone_button_info_type_button_8 = 0xc, /* ie backward */ 66 + kone_button_info_type_dpi_up = 0xd, /* internal */ 67 + kone_button_info_type_dpi_down = 0xe, /* internal */ 68 + kone_button_info_type_button_7 = 0xf, /* tilt left */ 69 + kone_button_info_type_button_6 = 0x10, /* tilt right */ 70 + kone_button_info_type_profile_up = 0x11, /* internal */ 71 + kone_button_info_type_profile_down = 0x12, /* internal */ 72 + /* additional valid button types since firmware 1.38 */ 73 + kone_button_info_type_multimedia_open_player = 0x20, 74 + kone_button_info_type_multimedia_next_track = 0x21, 75 + kone_button_info_type_multimedia_prev_track = 0x22, 76 + kone_button_info_type_multimedia_play_pause = 0x23, 77 + kone_button_info_type_multimedia_stop = 0x24, 78 + kone_button_info_type_multimedia_mute = 0x25, 79 + kone_button_info_type_multimedia_volume_up = 0x26, 80 + kone_button_info_type_multimedia_volume_down = 0x27 81 + }; 82 + 83 + enum kone_button_info_numbers { 84 + kone_button_top = 1, 85 + kone_button_wheel_tilt_left = 2, 86 + kone_button_wheel_tilt_right = 3, 87 + kone_button_forward = 4, 88 + kone_button_backward = 5, 89 + kone_button_middle = 6, 90 + kone_button_plus = 7, 91 + kone_button_minus = 8, 92 + }; 93 + 94 + struct kone_light_info { 95 + uint8_t number; /* number of light 1-5 */ 96 + uint8_t mod; /* 1 = on, 2 = off */ 97 + uint8_t red; /* range 0x00-0xff */ 98 + uint8_t green; /* range 0x00-0xff */ 99 + uint8_t blue; /* range 0x00-0xff */ 100 + }; 101 + 102 + struct kone_profile { 103 + uint16_t size; /* always 975 */ 104 + uint16_t unused; /* always 0 */ 105 + 106 + /* 107 + * range 1-5 108 + * This number does not need to correspond with location where profile 109 + * saved 110 + */ 111 + uint8_t profile; /* range 1-5 */ 112 + 113 + uint16_t main_sensitivity; /* range 100-1000 */ 114 + uint8_t xy_sensitivity_enabled; /* 1 = on, 2 = off */ 115 + uint16_t x_sensitivity; /* range 100-1000 */ 116 + uint16_t y_sensitivity; /* range 100-1000 */ 117 + uint8_t dpi_rate; /* bit 1 = 800, ... */ 118 + uint8_t startup_dpi; /* range 1-6 */ 119 + uint8_t polling_rate; /* 1 = 125Hz, 2 = 500Hz, 3 = 1000Hz */ 120 + /* kone has no dcu 121 + * value is always 2 in firmwares <= 1.32 and 122 + * 1 in firmwares > 1.32 123 + */ 124 + uint8_t dcu_flag; 125 + uint8_t light_effect_1; /* range 1-3 */ 126 + uint8_t light_effect_2; /* range 1-5 */ 127 + uint8_t light_effect_3; /* range 1-4 */ 128 + uint8_t light_effect_speed; /* range 0-255 */ 129 + 130 + struct kone_light_info light_infos[5]; 131 + /* offset is kone_button_info_numbers - 1 */ 132 + struct kone_button_info button_infos[8]; 133 + 134 + uint16_t checksum; /* \brief holds checksum of struct */ 135 + }; 136 + 137 + enum kone_polling_rates { 138 + kone_polling_rate_125 = 1, 139 + kone_polling_rate_500 = 2, 140 + kone_polling_rate_1000 = 3 141 + }; 142 + 143 + struct kone_settings { 144 + uint16_t size; /* always 36 */ 145 + uint8_t startup_profile; /* 1-5 */ 146 + uint8_t unknown1; 147 + uint8_t tcu; /* 0 = off, 1 = on */ 148 + uint8_t unknown2[23]; 149 + uint8_t calibration_data[4]; 150 + uint8_t unknown3[2]; 151 + uint16_t checksum; 152 + }; 153 + 154 + /* 155 + * 12 byte mouse event read by interrupt_read 156 + */ 157 + struct kone_mouse_event { 158 + uint8_t report_number; /* always 1 */ 159 + uint8_t button; 160 + uint16_t x; 161 + uint16_t y; 162 + uint8_t wheel; /* up = 1, down = -1 */ 163 + uint8_t tilt; /* right = 1, left = -1 */ 164 + uint8_t unknown; 165 + uint8_t event; 166 + uint8_t value; /* press = 0, release = 1 */ 167 + uint8_t macro_key; /* 0 to 8 */ 168 + }; 169 + 170 + enum kone_mouse_events { 171 + /* osd events are thought to be display on screen */ 172 + kone_mouse_event_osd_dpi = 0xa0, 173 + kone_mouse_event_osd_profile = 0xb0, 174 + /* TODO clarify meaning and occurence of kone_mouse_event_calibration */ 175 + kone_mouse_event_calibration = 0xc0, 176 + kone_mouse_event_call_overlong_macro = 0xe0, 177 + /* switch events notify if user changed values with mousebutton click */ 178 + kone_mouse_event_switch_dpi = 0xf0, 179 + kone_mouse_event_switch_profile = 0xf1 180 + }; 181 + 182 + enum kone_commands { 183 + kone_command_profile = 0x5a, 184 + kone_command_settings = 0x15a, 185 + kone_command_firmware_version = 0x25a, 186 + kone_command_weight = 0x45a, 187 + kone_command_calibrate = 0x55a, 188 + kone_command_confirm_write = 0x65a, 189 + kone_command_firmware = 0xe5a 190 + }; 191 + 192 + #pragma pack(pop) 193 + 194 + struct kone_device { 195 + /* 196 + * Storing actual values when we get informed about changes since there 197 + * is no way of getting this information from the device on demand 198 + */ 199 + int actual_profile, actual_dpi; 200 + /* Used for neutralizing abnormal button behaviour */ 201 + struct kone_mouse_event last_mouse_event; 202 + 203 + /* 204 + * It's unlikely that multiple sysfs attributes are accessed at a time, 205 + * so only one mutex is used to secure hardware access and profiles and 206 + * settings of this struct. 207 + */ 208 + struct mutex kone_lock; 209 + 210 + /* 211 + * Storing the data here reduces IO and ensures that data is available 212 + * when its needed (E.g. interrupt handler). 213 + */ 214 + struct kone_profile profiles[5]; 215 + struct kone_settings settings; 216 + 217 + /* 218 + * firmware doesn't change unless firmware update is implemented, 219 + * so it's read only once 220 + */ 221 + int firmware_version; 222 + }; 223 + 224 + #endif
+1
drivers/hid/usbhid/hid-core.c
··· 623 623 624 624 return 0; 625 625 } 626 + EXPORT_SYMBOL_GPL(usbhid_wait_io); 626 627 627 628 static int hid_set_idle(struct usb_device *dev, int ifnum, int report, int idle) 628 629 {