blob: 517677305ef9a967aa87f061ddbf493996555c59 [file] [log] [blame]
Bruno Prémont236db472010-03-30 22:33:50 +02001/***************************************************************************
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
Bruno Prémontb8c21cf2010-03-30 22:34:30 +020027#include <linux/fb.h>
28#include <linux/vmalloc.h>
Bruno Prémontf1c21762010-03-30 22:35:27 +020029#include <linux/backlight.h>
Bruno Prémonte8d931b2010-03-30 22:36:07 +020030#include <linux/lcd.h>
Bruno Prémontb8c21cf2010-03-30 22:34:30 +020031
Bruno Prémont467d6522010-03-30 22:36:49 +020032#include <linux/leds.h>
33
Bruno Prémont236db472010-03-30 22:33:50 +020034#include <linux/seq_file.h>
35#include <linux/debugfs.h>
36
37#include <linux/completion.h>
38
39#define PICOLCD_NAME "PicoLCD (graphic)"
40
41/* Report numbers */
42#define REPORT_ERROR_CODE 0x10 /* LCD: IN[16] */
43#define ERR_SUCCESS 0x00
44#define ERR_PARAMETER_MISSING 0x01
45#define ERR_DATA_MISSING 0x02
46#define ERR_BLOCK_READ_ONLY 0x03
47#define ERR_BLOCK_NOT_ERASABLE 0x04
48#define ERR_BLOCK_TOO_BIG 0x05
49#define ERR_SECTION_OVERFLOW 0x06
50#define ERR_INVALID_CMD_LEN 0x07
51#define ERR_INVALID_DATA_LEN 0x08
52#define REPORT_KEY_STATE 0x11 /* LCD: IN[2] */
53#define REPORT_IR_DATA 0x21 /* LCD: IN[63] */
54#define REPORT_EE_DATA 0x32 /* LCD: IN[63] */
55#define REPORT_MEMORY 0x41 /* LCD: IN[63] */
56#define REPORT_LED_STATE 0x81 /* LCD: OUT[1] */
57#define REPORT_BRIGHTNESS 0x91 /* LCD: OUT[1] */
58#define REPORT_CONTRAST 0x92 /* LCD: OUT[1] */
59#define REPORT_RESET 0x93 /* LCD: OUT[2] */
60#define REPORT_LCD_CMD 0x94 /* LCD: OUT[63] */
61#define REPORT_LCD_DATA 0x95 /* LCD: OUT[63] */
62#define REPORT_LCD_CMD_DATA 0x96 /* LCD: OUT[63] */
63#define REPORT_EE_READ 0xa3 /* LCD: OUT[63] */
64#define REPORT_EE_WRITE 0xa4 /* LCD: OUT[63] */
65#define REPORT_ERASE_MEMORY 0xb2 /* LCD: OUT[2] */
66#define REPORT_READ_MEMORY 0xb3 /* LCD: OUT[3] */
67#define REPORT_WRITE_MEMORY 0xb4 /* LCD: OUT[63] */
68#define REPORT_SPLASH_RESTART 0xc1 /* LCD: OUT[1] */
69#define REPORT_EXIT_KEYBOARD 0xef /* LCD: OUT[2] */
70#define REPORT_VERSION 0xf1 /* LCD: IN[2],OUT[1] Bootloader: IN[2],OUT[1] */
71#define REPORT_BL_ERASE_MEMORY 0xf2 /* Bootloader: IN[36],OUT[4] */
72#define REPORT_BL_READ_MEMORY 0xf3 /* Bootloader: IN[36],OUT[4] */
73#define REPORT_BL_WRITE_MEMORY 0xf4 /* Bootloader: IN[36],OUT[36] */
74#define REPORT_DEVID 0xf5 /* LCD: IN[5], OUT[1] Bootloader: IN[5],OUT[1] */
75#define REPORT_SPLASH_SIZE 0xf6 /* LCD: IN[4], OUT[1] */
76#define REPORT_HOOK_VERSION 0xf7 /* LCD: IN[2], OUT[1] */
77#define REPORT_EXIT_FLASHER 0xff /* Bootloader: OUT[2] */
78
Bruno Prémontb8c21cf2010-03-30 22:34:30 +020079#if defined(CONFIG_FB) || defined(CONFIG_FB_MODULE)
80/* Framebuffer
81 *
82 * The PicoLCD use a Topway LCD module of 256x64 pixel
83 * This display area is tiled over 4 controllers with 8 tiles
84 * each. Each tile has 8x64 pixel, each data byte representing
85 * a 1-bit wide vertical line of the tile.
86 *
87 * The display can be updated at a tile granularity.
88 *
89 * Chip 1 Chip 2 Chip 3 Chip 4
90 * +----------------+----------------+----------------+----------------+
91 * | Tile 1 | Tile 1 | Tile 1 | Tile 1 |
92 * +----------------+----------------+----------------+----------------+
93 * | Tile 2 | Tile 2 | Tile 2 | Tile 2 |
94 * +----------------+----------------+----------------+----------------+
95 * ...
96 * +----------------+----------------+----------------+----------------+
97 * | Tile 8 | Tile 8 | Tile 8 | Tile 8 |
98 * +----------------+----------------+----------------+----------------+
99 */
100#define PICOLCDFB_NAME "picolcdfb"
101#define PICOLCDFB_WIDTH (256)
102#define PICOLCDFB_HEIGHT (64)
103#define PICOLCDFB_SIZE (PICOLCDFB_WIDTH * PICOLCDFB_HEIGHT / 8)
104
105#define PICOLCDFB_UPDATE_RATE_LIMIT 10
106#define PICOLCDFB_UPDATE_RATE_DEFAULT 2
107
108/* Framebuffer visual structures */
109static const struct fb_fix_screeninfo picolcdfb_fix = {
110 .id = PICOLCDFB_NAME,
111 .type = FB_TYPE_PACKED_PIXELS,
112 .visual = FB_VISUAL_MONO01,
113 .xpanstep = 0,
114 .ypanstep = 0,
115 .ywrapstep = 0,
116 .line_length = PICOLCDFB_WIDTH / 8,
117 .accel = FB_ACCEL_NONE,
118};
119
120static const struct fb_var_screeninfo picolcdfb_var = {
121 .xres = PICOLCDFB_WIDTH,
122 .yres = PICOLCDFB_HEIGHT,
123 .xres_virtual = PICOLCDFB_WIDTH,
124 .yres_virtual = PICOLCDFB_HEIGHT,
125 .width = 103,
126 .height = 26,
127 .bits_per_pixel = 1,
128 .grayscale = 1,
129};
130#endif /* CONFIG_FB */
131
Bruno Prémont236db472010-03-30 22:33:50 +0200132/* Input device
133 *
134 * The PicoLCD has an IR receiver header, a built-in keypad with 5 keys
135 * and header for 4x4 key matrix. The built-in keys are part of the matrix.
136 */
137static const unsigned short def_keymap[] = {
138 KEY_RESERVED, /* none */
139 KEY_BACK, /* col 4 + row 1 */
140 KEY_HOMEPAGE, /* col 3 + row 1 */
141 KEY_RESERVED, /* col 2 + row 1 */
142 KEY_RESERVED, /* col 1 + row 1 */
143 KEY_SCROLLUP, /* col 4 + row 2 */
144 KEY_OK, /* col 3 + row 2 */
145 KEY_SCROLLDOWN, /* col 2 + row 2 */
146 KEY_RESERVED, /* col 1 + row 2 */
147 KEY_RESERVED, /* col 4 + row 3 */
148 KEY_RESERVED, /* col 3 + row 3 */
149 KEY_RESERVED, /* col 2 + row 3 */
150 KEY_RESERVED, /* col 1 + row 3 */
151 KEY_RESERVED, /* col 4 + row 4 */
152 KEY_RESERVED, /* col 3 + row 4 */
153 KEY_RESERVED, /* col 2 + row 4 */
154 KEY_RESERVED, /* col 1 + row 4 */
155};
156#define PICOLCD_KEYS ARRAY_SIZE(def_keymap)
157
158/* Description of in-progress IO operation, used for operations
159 * that trigger response from device */
160struct picolcd_pending {
161 struct hid_report *out_report;
162 struct hid_report *in_report;
163 struct completion ready;
164 int raw_size;
165 u8 raw_data[64];
166};
167
168/* Per device data structure */
169struct picolcd_data {
170 struct hid_device *hdev;
171#ifdef CONFIG_DEBUG_FS
172 int addr_sz;
173#endif
174 u8 version[2];
175 /* input stuff */
176 u8 pressed_keys[2];
177 struct input_dev *input_keys;
178 struct input_dev *input_cir;
179 unsigned short keycode[PICOLCD_KEYS];
180
Bruno Prémontb8c21cf2010-03-30 22:34:30 +0200181#if defined(CONFIG_FB) || defined(CONFIG_FB_MODULE)
182 /* Framebuffer stuff */
183 u8 fb_update_rate;
184 u8 fb_bpp;
185 u8 *fb_vbitmap; /* local copy of what was sent to PicoLCD */
186 u8 *fb_bitmap; /* framebuffer */
187 struct fb_info *fb_info;
188 struct fb_deferred_io fb_defio;
189#endif /* CONFIG_FB */
Bruno Prémonte8d931b2010-03-30 22:36:07 +0200190#if defined(CONFIG_LCD_CLASS_DEVICE) || defined(CONFIG_LCD_CLASS_DEVICE_MODULE)
191 struct lcd_device *lcd;
192 u8 lcd_contrast;
193#endif
Bruno Prémontf1c21762010-03-30 22:35:27 +0200194#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
195 struct backlight_device *backlight;
196 u8 lcd_brightness;
197 u8 lcd_power;
198#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
Bruno Prémont467d6522010-03-30 22:36:49 +0200199#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
200 /* LED stuff */
201 u8 led_state;
202 struct led_classdev *led[8];
203#endif /* CONFIG_LEDS_CLASS */
Bruno Prémontb8c21cf2010-03-30 22:34:30 +0200204
Bruno Prémont236db472010-03-30 22:33:50 +0200205 /* Housekeeping stuff */
206 spinlock_t lock;
207 struct mutex mutex;
208 struct picolcd_pending *pending;
209 int status;
210#define PICOLCD_BOOTLOADER 1
211#define PICOLCD_FAILED 2
Bruno Prémontb8c21cf2010-03-30 22:34:30 +0200212#define PICOLCD_READY_FB 4
Bruno Prémont236db472010-03-30 22:33:50 +0200213};
214
215
216/* Find a given report */
217#define picolcd_in_report(id, dev) picolcd_report(id, dev, HID_INPUT_REPORT)
218#define picolcd_out_report(id, dev) picolcd_report(id, dev, HID_OUTPUT_REPORT)
219
220static struct hid_report *picolcd_report(int id, struct hid_device *hdev, int dir)
221{
222 struct list_head *feature_report_list = &hdev->report_enum[dir].report_list;
223 struct hid_report *report = NULL;
224
225 list_for_each_entry(report, feature_report_list, list) {
226 if (report->id == id)
227 return report;
228 }
229 dev_warn(&hdev->dev, "No report with id 0x%x found\n", id);
230 return NULL;
231}
232
233#ifdef CONFIG_DEBUG_FS
234static void picolcd_debug_out_report(struct picolcd_data *data,
235 struct hid_device *hdev, struct hid_report *report);
236#define usbhid_submit_report(a, b, c) \
237 do { \
238 picolcd_debug_out_report(hid_get_drvdata(a), a, b); \
239 usbhid_submit_report(a, b, c); \
240 } while (0)
241#endif
242
243/* Submit a report and wait for a reply from device - if device fades away
244 * or does not respond in time, return NULL */
245static struct picolcd_pending *picolcd_send_and_wait(struct hid_device *hdev,
246 int report_id, const u8 *raw_data, int size)
247{
248 struct picolcd_data *data = hid_get_drvdata(hdev);
249 struct picolcd_pending *work;
250 struct hid_report *report = picolcd_out_report(report_id, hdev);
251 unsigned long flags;
252 int i, j, k;
253
254 if (!report || !data)
255 return NULL;
256 if (data->status & PICOLCD_FAILED)
257 return NULL;
258 work = kzalloc(sizeof(*work), GFP_KERNEL);
259 if (!work)
260 return NULL;
261
262 init_completion(&work->ready);
263 work->out_report = report;
264 work->in_report = NULL;
265 work->raw_size = 0;
266
267 mutex_lock(&data->mutex);
268 spin_lock_irqsave(&data->lock, flags);
269 for (i = k = 0; i < report->maxfield; i++)
270 for (j = 0; j < report->field[i]->report_count; j++) {
271 hid_set_field(report->field[i], j, k < size ? raw_data[k] : 0);
272 k++;
273 }
274 data->pending = work;
275 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
276 spin_unlock_irqrestore(&data->lock, flags);
277 wait_for_completion_interruptible_timeout(&work->ready, HZ*2);
278 spin_lock_irqsave(&data->lock, flags);
279 data->pending = NULL;
280 spin_unlock_irqrestore(&data->lock, flags);
281 mutex_unlock(&data->mutex);
282 return work;
283}
284
Bruno Prémontb8c21cf2010-03-30 22:34:30 +0200285#if defined(CONFIG_FB) || defined(CONFIG_FB_MODULE)
286/* Send a given tile to PicoLCD */
287static int picolcd_fb_send_tile(struct hid_device *hdev, int chip, int tile)
288{
289 struct picolcd_data *data = hid_get_drvdata(hdev);
290 struct hid_report *report1 = picolcd_out_report(REPORT_LCD_CMD_DATA, hdev);
291 struct hid_report *report2 = picolcd_out_report(REPORT_LCD_DATA, hdev);
292 unsigned long flags;
293 u8 *tdata;
294 int i;
295
296 if (!report1 || report1->maxfield != 1 || !report2 || report2->maxfield != 1)
297 return -ENODEV;
298
299 spin_lock_irqsave(&data->lock, flags);
300 hid_set_field(report1->field[0], 0, chip << 2);
301 hid_set_field(report1->field[0], 1, 0x02);
302 hid_set_field(report1->field[0], 2, 0x00);
303 hid_set_field(report1->field[0], 3, 0x00);
304 hid_set_field(report1->field[0], 4, 0xb8 | tile);
305 hid_set_field(report1->field[0], 5, 0x00);
306 hid_set_field(report1->field[0], 6, 0x00);
307 hid_set_field(report1->field[0], 7, 0x40);
308 hid_set_field(report1->field[0], 8, 0x00);
309 hid_set_field(report1->field[0], 9, 0x00);
310 hid_set_field(report1->field[0], 10, 32);
311
312 hid_set_field(report2->field[0], 0, (chip << 2) | 0x01);
313 hid_set_field(report2->field[0], 1, 0x00);
314 hid_set_field(report2->field[0], 2, 0x00);
315 hid_set_field(report2->field[0], 3, 32);
316
317 tdata = data->fb_vbitmap + (tile * 4 + chip) * 64;
318 for (i = 0; i < 64; i++)
319 if (i < 32)
320 hid_set_field(report1->field[0], 11 + i, tdata[i]);
321 else
322 hid_set_field(report2->field[0], 4 + i - 32, tdata[i]);
323
324 usbhid_submit_report(data->hdev, report1, USB_DIR_OUT);
325 usbhid_submit_report(data->hdev, report2, USB_DIR_OUT);
326 spin_unlock_irqrestore(&data->lock, flags);
327 return 0;
328}
329
330/* Translate a single tile*/
331static int picolcd_fb_update_tile(u8 *vbitmap, const u8 *bitmap, int bpp,
332 int chip, int tile)
333{
334 int i, b, changed = 0;
335 u8 tdata[64];
336 u8 *vdata = vbitmap + (tile * 4 + chip) * 64;
337
338 if (bpp == 1) {
339 for (b = 7; b >= 0; b--) {
340 const u8 *bdata = bitmap + tile * 256 + chip * 8 + b * 32;
341 for (i = 0; i < 64; i++) {
342 tdata[i] <<= 1;
343 tdata[i] |= (bdata[i/8] >> (7 - i % 8)) & 0x01;
344 }
345 }
346 } else if (bpp == 8) {
347 for (b = 7; b >= 0; b--) {
348 const u8 *bdata = bitmap + (tile * 256 + chip * 8 + b * 32) * 8;
349 for (i = 0; i < 64; i++) {
350 tdata[i] <<= 1;
351 tdata[i] |= (bdata[i] & 0x80) ? 0x01 : 0x00;
352 }
353 }
354 } else {
355 /* Oops, we should never get here! */
356 WARN_ON(1);
357 return 0;
358 }
359
360 for (i = 0; i < 64; i++)
361 if (tdata[i] != vdata[i]) {
362 changed = 1;
363 vdata[i] = tdata[i];
364 }
365 return changed;
366}
367
368/* Reconfigure LCD display */
369static int picolcd_fb_reset(struct picolcd_data *data, int clear)
370{
371 struct hid_report *report = picolcd_out_report(REPORT_LCD_CMD, data->hdev);
372 int i, j;
373 unsigned long flags;
374 static const u8 mapcmd[8] = { 0x00, 0x02, 0x00, 0x64, 0x3f, 0x00, 0x64, 0xc0 };
375
376 if (!report || report->maxfield != 1)
377 return -ENODEV;
378
379 spin_lock_irqsave(&data->lock, flags);
380 for (i = 0; i < 4; i++) {
381 for (j = 0; j < report->field[0]->maxusage; j++)
382 if (j == 0)
383 hid_set_field(report->field[0], j, i << 2);
384 else if (j < sizeof(mapcmd))
385 hid_set_field(report->field[0], j, mapcmd[j]);
386 else
387 hid_set_field(report->field[0], j, 0);
388 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
389 }
390
391 data->status |= PICOLCD_READY_FB;
392 spin_unlock_irqrestore(&data->lock, flags);
393
394 if (data->fb_bitmap) {
395 if (clear) {
396 memset(data->fb_vbitmap, 0xff, PICOLCDFB_SIZE);
397 memset(data->fb_bitmap, 0, PICOLCDFB_SIZE*data->fb_bpp);
398 } else {
399 /* invert 1 byte in each tile to force resend */
400 for (i = 0; i < PICOLCDFB_SIZE; i += 64)
401 data->fb_vbitmap[i] = ~data->fb_vbitmap[i];
402 }
403 }
404
405 /* schedule first output of framebuffer */
406 if (data->fb_info)
407 schedule_delayed_work(&data->fb_info->deferred_work, 0);
408
409 return 0;
410}
411
412/* Update fb_vbitmap from the screen_base and send changed tiles to device */
413static void picolcd_fb_update(struct picolcd_data *data)
414{
415 int chip, tile, n;
416 unsigned long flags;
417
418 spin_lock_irqsave(&data->lock, flags);
419 if (!(data->status & PICOLCD_READY_FB)) {
420 spin_unlock_irqrestore(&data->lock, flags);
421 picolcd_fb_reset(data, 0);
422 } else {
423 spin_unlock_irqrestore(&data->lock, flags);
424 }
425
426 /*
427 * Translate the framebuffer into the format needed by the PicoLCD.
428 * See display layout above.
429 * Do this one tile after the other and push those tiles that changed.
430 *
431 * Wait for our IO to complete as otherwise we might flood the queue!
432 */
433 n = 0;
434 for (chip = 0; chip < 4; chip++)
435 for (tile = 0; tile < 8; tile++)
436 if (picolcd_fb_update_tile(data->fb_vbitmap,
437 data->fb_bitmap, data->fb_bpp, chip, tile)) {
438 n += 2;
439 if (n >= HID_OUTPUT_FIFO_SIZE / 2) {
440 usbhid_wait_io(data->hdev);
441 n = 0;
442 }
443 picolcd_fb_send_tile(data->hdev, chip, tile);
444 }
445 if (n)
446 usbhid_wait_io(data->hdev);
447}
448
449/* Stub to call the system default and update the image on the picoLCD */
450static void picolcd_fb_fillrect(struct fb_info *info,
451 const struct fb_fillrect *rect)
452{
453 if (!info->par)
454 return;
455 sys_fillrect(info, rect);
456
457 schedule_delayed_work(&info->deferred_work, 0);
458}
459
460/* Stub to call the system default and update the image on the picoLCD */
461static void picolcd_fb_copyarea(struct fb_info *info,
462 const struct fb_copyarea *area)
463{
464 if (!info->par)
465 return;
466 sys_copyarea(info, area);
467
468 schedule_delayed_work(&info->deferred_work, 0);
469}
470
471/* Stub to call the system default and update the image on the picoLCD */
472static void picolcd_fb_imageblit(struct fb_info *info, const struct fb_image *image)
473{
474 if (!info->par)
475 return;
476 sys_imageblit(info, image);
477
478 schedule_delayed_work(&info->deferred_work, 0);
479}
480
481/*
482 * this is the slow path from userspace. they can seek and write to
483 * the fb. it's inefficient to do anything less than a full screen draw
484 */
485static ssize_t picolcd_fb_write(struct fb_info *info, const char __user *buf,
486 size_t count, loff_t *ppos)
487{
488 ssize_t ret;
489 if (!info->par)
490 return -ENODEV;
491 ret = fb_sys_write(info, buf, count, ppos);
492 if (ret >= 0)
493 schedule_delayed_work(&info->deferred_work, 0);
494 return ret;
495}
496
497static int picolcd_fb_blank(int blank, struct fb_info *info)
498{
499 if (!info->par)
500 return -ENODEV;
501 /* We let fb notification do this for us via lcd/backlight device */
502 return 0;
503}
504
505static void picolcd_fb_destroy(struct fb_info *info)
506{
507 struct picolcd_data *data = info->par;
508 info->par = NULL;
509 if (data)
510 data->fb_info = NULL;
511 fb_deferred_io_cleanup(info);
512 framebuffer_release(info);
513}
514
515static int picolcd_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
516{
517 __u32 bpp = var->bits_per_pixel;
518 __u32 activate = var->activate;
519
520 /* only allow 1/8 bit depth (8-bit is grayscale) */
521 *var = picolcdfb_var;
522 var->activate = activate;
523 if (bpp >= 8)
524 var->bits_per_pixel = 8;
525 else
526 var->bits_per_pixel = 1;
527 return 0;
528}
529
530static int picolcd_set_par(struct fb_info *info)
531{
532 struct picolcd_data *data = info->par;
533 u8 *o_fb, *n_fb;
534 if (info->var.bits_per_pixel == data->fb_bpp)
535 return 0;
536 /* switch between 1/8 bit depths */
537 if (info->var.bits_per_pixel != 1 && info->var.bits_per_pixel != 8)
538 return -EINVAL;
539
540 o_fb = data->fb_bitmap;
541 n_fb = vmalloc(PICOLCDFB_SIZE*info->var.bits_per_pixel);
542 if (!n_fb)
543 return -ENOMEM;
544
545 fb_deferred_io_cleanup(info);
546 /* translate FB content to new bits-per-pixel */
547 if (info->var.bits_per_pixel == 1) {
548 int i, b;
549 for (i = 0; i < PICOLCDFB_SIZE; i++) {
550 u8 p = 0;
551 for (b = 0; b < 8; b++) {
552 p <<= 1;
553 p |= o_fb[i*8+b] ? 0x01 : 0x00;
554 }
555 }
556 info->fix.visual = FB_VISUAL_MONO01;
557 info->fix.line_length = PICOLCDFB_WIDTH / 8;
558 } else {
559 int i;
560 for (i = 0; i < PICOLCDFB_SIZE * 8; i++)
561 n_fb[i] = o_fb[i/8] & (0x01 << (7 - i % 8)) ? 0xff : 0x00;
562 info->fix.visual = FB_VISUAL_TRUECOLOR;
563 info->fix.line_length = PICOLCDFB_WIDTH;
564 }
565
566 data->fb_bitmap = n_fb;
567 data->fb_bpp = info->var.bits_per_pixel;
568 info->screen_base = (char __force __iomem *)n_fb;
569 info->fix.smem_start = (unsigned long)n_fb;
570 info->fix.smem_len = PICOLCDFB_SIZE*data->fb_bpp;
571 fb_deferred_io_init(info);
572 vfree(o_fb);
573 return 0;
574}
575
576/* Note this can't be const because of struct fb_info definition */
577static struct fb_ops picolcdfb_ops = {
578 .owner = THIS_MODULE,
579 .fb_destroy = picolcd_fb_destroy,
580 .fb_read = fb_sys_read,
581 .fb_write = picolcd_fb_write,
582 .fb_blank = picolcd_fb_blank,
583 .fb_fillrect = picolcd_fb_fillrect,
584 .fb_copyarea = picolcd_fb_copyarea,
585 .fb_imageblit = picolcd_fb_imageblit,
586 .fb_check_var = picolcd_fb_check_var,
587 .fb_set_par = picolcd_set_par,
588};
589
590
591/* Callback from deferred IO workqueue */
592static void picolcd_fb_deferred_io(struct fb_info *info, struct list_head *pagelist)
593{
594 picolcd_fb_update(info->par);
595}
596
597static const struct fb_deferred_io picolcd_fb_defio = {
598 .delay = HZ / PICOLCDFB_UPDATE_RATE_DEFAULT,
599 .deferred_io = picolcd_fb_deferred_io,
600};
601
602
603/*
604 * The "fb_update_rate" sysfs attribute
605 */
606static ssize_t picolcd_fb_update_rate_show(struct device *dev,
607 struct device_attribute *attr, char *buf)
608{
609 struct picolcd_data *data = dev_get_drvdata(dev);
610 unsigned i, fb_update_rate = data->fb_update_rate;
611 size_t ret = 0;
612
613 for (i = 1; i <= PICOLCDFB_UPDATE_RATE_LIMIT; i++)
614 if (ret >= PAGE_SIZE)
615 break;
616 else if (i == fb_update_rate)
617 ret += snprintf(buf+ret, PAGE_SIZE-ret, "[%u] ", i);
618 else
619 ret += snprintf(buf+ret, PAGE_SIZE-ret, "%u ", i);
620 if (ret > 0)
621 buf[min(ret, (size_t)PAGE_SIZE)-1] = '\n';
622 return ret;
623}
624
625static ssize_t picolcd_fb_update_rate_store(struct device *dev,
626 struct device_attribute *attr, const char *buf, size_t count)
627{
628 struct picolcd_data *data = dev_get_drvdata(dev);
629 int i;
630 unsigned u;
631
632 if (count < 1 || count > 10)
633 return -EINVAL;
634
635 i = sscanf(buf, "%u", &u);
636 if (i != 1)
637 return -EINVAL;
638
639 if (u > PICOLCDFB_UPDATE_RATE_LIMIT)
640 return -ERANGE;
641 else if (u == 0)
642 u = PICOLCDFB_UPDATE_RATE_DEFAULT;
643
644 data->fb_update_rate = u;
645 data->fb_defio.delay = HZ / data->fb_update_rate;
646 return count;
647}
648
649static DEVICE_ATTR(fb_update_rate, 0666, picolcd_fb_update_rate_show,
650 picolcd_fb_update_rate_store);
651
652/* initialize Framebuffer device */
653static int picolcd_init_framebuffer(struct picolcd_data *data)
654{
655 struct device *dev = &data->hdev->dev;
656 struct fb_info *info = NULL;
657 int error = -ENOMEM;
658 u8 *fb_vbitmap = NULL;
659 u8 *fb_bitmap = NULL;
660
661 fb_bitmap = vmalloc(PICOLCDFB_SIZE*picolcdfb_var.bits_per_pixel);
662 if (fb_bitmap == NULL) {
663 dev_err(dev, "can't get a free page for framebuffer\n");
664 goto err_nomem;
665 }
666
667 fb_vbitmap = kmalloc(PICOLCDFB_SIZE, GFP_KERNEL);
668 if (fb_vbitmap == NULL) {
669 dev_err(dev, "can't alloc vbitmap image buffer\n");
670 goto err_nomem;
671 }
672
673 data->fb_update_rate = PICOLCDFB_UPDATE_RATE_DEFAULT;
674 data->fb_defio = picolcd_fb_defio;
675 info = framebuffer_alloc(0, dev);
676 if (info == NULL) {
677 dev_err(dev, "failed to allocate a framebuffer\n");
678 goto err_nomem;
679 }
680
681 info->fbdefio = &data->fb_defio;
682 info->screen_base = (char __force __iomem *)fb_bitmap;
683 info->fbops = &picolcdfb_ops;
684 info->var = picolcdfb_var;
685 info->fix = picolcdfb_fix;
686 info->fix.smem_len = PICOLCDFB_SIZE;
687 info->fix.smem_start = (unsigned long)fb_bitmap;
688 info->par = data;
689 info->flags = FBINFO_FLAG_DEFAULT;
690
691 data->fb_vbitmap = fb_vbitmap;
692 data->fb_bitmap = fb_bitmap;
693 data->fb_bpp = picolcdfb_var.bits_per_pixel;
694 error = picolcd_fb_reset(data, 1);
695 if (error) {
696 dev_err(dev, "failed to configure display\n");
697 goto err_cleanup;
698 }
699 error = device_create_file(dev, &dev_attr_fb_update_rate);
700 if (error) {
701 dev_err(dev, "failed to create sysfs attributes\n");
702 goto err_cleanup;
703 }
704 data->fb_info = info;
705 error = register_framebuffer(info);
706 if (error) {
707 dev_err(dev, "failed to register framebuffer\n");
708 goto err_sysfs;
709 }
710 fb_deferred_io_init(info);
711 /* schedule first output of framebuffer */
712 schedule_delayed_work(&info->deferred_work, 0);
713 return 0;
714
715err_sysfs:
716 device_remove_file(dev, &dev_attr_fb_update_rate);
717err_cleanup:
718 data->fb_vbitmap = NULL;
719 data->fb_bitmap = NULL;
720 data->fb_bpp = 0;
721 data->fb_info = NULL;
722
723err_nomem:
724 framebuffer_release(info);
725 vfree(fb_bitmap);
726 kfree(fb_vbitmap);
727 return error;
728}
729
730static void picolcd_exit_framebuffer(struct picolcd_data *data)
731{
732 struct fb_info *info = data->fb_info;
733 u8 *fb_vbitmap = data->fb_vbitmap;
734 u8 *fb_bitmap = data->fb_bitmap;
735
736 if (!info)
737 return;
738
739 data->fb_vbitmap = NULL;
740 data->fb_bitmap = NULL;
741 data->fb_bpp = 0;
742 data->fb_info = NULL;
743 device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate);
744 fb_deferred_io_cleanup(info);
745 unregister_framebuffer(info);
746 vfree(fb_bitmap);
747 kfree(fb_vbitmap);
748}
749
Bruno Prémontf1c21762010-03-30 22:35:27 +0200750#define picolcd_fbinfo(d) ((d)->fb_info)
Bruno Prémontb8c21cf2010-03-30 22:34:30 +0200751#else
752static inline int picolcd_fb_reset(struct picolcd_data *data, int clear)
753{
754 return 0;
755}
756static inline int picolcd_init_framebuffer(struct picolcd_data *data)
757{
758 return 0;
759}
760static void picolcd_exit_framebuffer(struct picolcd_data *data)
761{
762}
Bruno Prémontf1c21762010-03-30 22:35:27 +0200763#define picolcd_fbinfo(d) NULL
Bruno Prémontb8c21cf2010-03-30 22:34:30 +0200764#endif /* CONFIG_FB */
765
Bruno Prémontf1c21762010-03-30 22:35:27 +0200766#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
767/*
768 * backlight class device
769 */
770static int picolcd_get_brightness(struct backlight_device *bdev)
771{
772 struct picolcd_data *data = bl_get_data(bdev);
773 return data->lcd_brightness;
774}
775
776static int picolcd_set_brightness(struct backlight_device *bdev)
777{
778 struct picolcd_data *data = bl_get_data(bdev);
779 struct hid_report *report = picolcd_out_report(REPORT_BRIGHTNESS, data->hdev);
780 unsigned long flags;
781
782 if (!report || report->maxfield != 1 || report->field[0]->report_count != 1)
783 return -ENODEV;
784
785 data->lcd_brightness = bdev->props.brightness & 0x0ff;
786 data->lcd_power = bdev->props.power;
787 spin_lock_irqsave(&data->lock, flags);
788 hid_set_field(report->field[0], 0, data->lcd_power == FB_BLANK_UNBLANK ? data->lcd_brightness : 0);
789 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
790 spin_unlock_irqrestore(&data->lock, flags);
791 return 0;
792}
793
794static int picolcd_check_bl_fb(struct backlight_device *bdev, struct fb_info *fb)
795{
796 return fb && fb == picolcd_fbinfo((struct picolcd_data *)bl_get_data(bdev));
797}
798
799static const struct backlight_ops picolcd_blops = {
800 .update_status = picolcd_set_brightness,
801 .get_brightness = picolcd_get_brightness,
802 .check_fb = picolcd_check_bl_fb,
803};
804
805static int picolcd_init_backlight(struct picolcd_data *data, struct hid_report *report)
806{
807 struct device *dev = &data->hdev->dev;
808 struct backlight_device *bdev;
809 struct backlight_properties props;
810 if (!report)
811 return -ENODEV;
812 if (report->maxfield != 1 || report->field[0]->report_count != 1 ||
813 report->field[0]->report_size != 8) {
814 dev_err(dev, "unsupported BRIGHTNESS report");
815 return -EINVAL;
816 }
817
818 memset(&props, 0, sizeof(props));
819 props.max_brightness = 0xff;
820 bdev = backlight_device_register(dev_name(dev), dev, data,
821 &picolcd_blops, &props);
822 if (IS_ERR(bdev)) {
823 dev_err(dev, "failed to register backlight\n");
824 return PTR_ERR(bdev);
825 }
826 bdev->props.brightness = 0xff;
827 data->lcd_brightness = 0xff;
828 data->backlight = bdev;
829 picolcd_set_brightness(bdev);
830 return 0;
831}
832
833static void picolcd_exit_backlight(struct picolcd_data *data)
834{
835 struct backlight_device *bdev = data->backlight;
836
837 data->backlight = NULL;
838 if (bdev)
839 backlight_device_unregister(bdev);
840}
841
842static inline int picolcd_resume_backlight(struct picolcd_data *data)
843{
844 if (!data->backlight)
845 return 0;
846 return picolcd_set_brightness(data->backlight);
847}
848
849#else
850static inline int picolcd_init_backlight(struct picolcd_data *data,
851 struct hid_report *report)
852{
853 return 0;
854}
855static inline void picolcd_exit_backlight(struct picolcd_data *data)
856{
857}
858static inline int picolcd_resume_backlight(struct picolcd_data *data)
859{
860 return 0;
861}
862#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
863
Bruno Prémonte8d931b2010-03-30 22:36:07 +0200864#if defined(CONFIG_LCD_CLASS_DEVICE) || defined(CONFIG_LCD_CLASS_DEVICE_MODULE)
865/*
866 * lcd class device
867 */
868static int picolcd_get_contrast(struct lcd_device *ldev)
869{
870 struct picolcd_data *data = lcd_get_data(ldev);
871 return data->lcd_contrast;
872}
873
874static int picolcd_set_contrast(struct lcd_device *ldev, int contrast)
875{
876 struct picolcd_data *data = lcd_get_data(ldev);
877 struct hid_report *report = picolcd_out_report(REPORT_CONTRAST, data->hdev);
878 unsigned long flags;
879
880 if (!report || report->maxfield != 1 || report->field[0]->report_count != 1)
881 return -ENODEV;
882
883 data->lcd_contrast = contrast & 0x0ff;
884 spin_lock_irqsave(&data->lock, flags);
885 hid_set_field(report->field[0], 0, data->lcd_contrast);
886 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
887 spin_unlock_irqrestore(&data->lock, flags);
888 return 0;
889}
890
891static int picolcd_check_lcd_fb(struct lcd_device *ldev, struct fb_info *fb)
892{
893 return fb && fb == picolcd_fbinfo((struct picolcd_data *)lcd_get_data(ldev));
894}
895
896static struct lcd_ops picolcd_lcdops = {
897 .get_contrast = picolcd_get_contrast,
898 .set_contrast = picolcd_set_contrast,
899 .check_fb = picolcd_check_lcd_fb,
900};
901
902static int picolcd_init_lcd(struct picolcd_data *data, struct hid_report *report)
903{
904 struct device *dev = &data->hdev->dev;
905 struct lcd_device *ldev;
906
907 if (!report)
908 return -ENODEV;
909 if (report->maxfield != 1 || report->field[0]->report_count != 1 ||
910 report->field[0]->report_size != 8) {
911 dev_err(dev, "unsupported CONTRAST report");
912 return -EINVAL;
913 }
914
915 ldev = lcd_device_register(dev_name(dev), dev, data, &picolcd_lcdops);
916 if (IS_ERR(ldev)) {
917 dev_err(dev, "failed to register LCD\n");
918 return PTR_ERR(ldev);
919 }
920 ldev->props.max_contrast = 0x0ff;
921 data->lcd_contrast = 0xe5;
922 data->lcd = ldev;
923 picolcd_set_contrast(ldev, 0xe5);
924 return 0;
925}
926
927static void picolcd_exit_lcd(struct picolcd_data *data)
928{
929 struct lcd_device *ldev = data->lcd;
930
931 data->lcd = NULL;
932 if (ldev)
933 lcd_device_unregister(ldev);
934}
935
936static inline int picolcd_resume_lcd(struct picolcd_data *data)
937{
938 if (!data->lcd)
939 return 0;
940 return picolcd_set_contrast(data->lcd, data->lcd_contrast);
941}
942#else
943static inline int picolcd_init_lcd(struct picolcd_data *data,
944 struct hid_report *report)
945{
946 return 0;
947}
948static inline void picolcd_exit_lcd(struct picolcd_data *data)
949{
950}
951static inline int picolcd_resume_lcd(struct picolcd_data *data)
952{
953 return 0;
954}
955#endif /* CONFIG_LCD_CLASS_DEVICE */
956
Bruno Prémont467d6522010-03-30 22:36:49 +0200957#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
958/**
959 * LED class device
960 */
961static void picolcd_leds_set(struct picolcd_data *data)
962{
963 struct hid_report *report;
964 unsigned long flags;
965
966 if (!data->led[0])
967 return;
968 report = picolcd_out_report(REPORT_LED_STATE, data->hdev);
969 if (!report || report->maxfield != 1 || report->field[0]->report_count != 1)
970 return;
971
972 spin_lock_irqsave(&data->lock, flags);
973 hid_set_field(report->field[0], 0, data->led_state);
974 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
975 spin_unlock_irqrestore(&data->lock, flags);
976}
977
978static void picolcd_led_set_brightness(struct led_classdev *led_cdev,
979 enum led_brightness value)
980{
981 struct device *dev;
982 struct hid_device *hdev;
983 struct picolcd_data *data;
984 int i, state = 0;
985
986 dev = led_cdev->dev->parent;
987 hdev = container_of(dev, struct hid_device, dev);
988 data = hid_get_drvdata(hdev);
989 for (i = 0; i < 8; i++) {
990 if (led_cdev != data->led[i])
991 continue;
992 state = (data->led_state >> i) & 1;
993 if (value == LED_OFF && state) {
994 data->led_state &= ~(1 << i);
995 picolcd_leds_set(data);
996 } else if (value != LED_OFF && !state) {
997 data->led_state |= 1 << i;
998 picolcd_leds_set(data);
999 }
1000 break;
1001 }
1002}
1003
1004static enum led_brightness picolcd_led_get_brightness(struct led_classdev *led_cdev)
1005{
1006 struct device *dev;
1007 struct hid_device *hdev;
1008 struct picolcd_data *data;
1009 int i, value = 0;
1010
1011 dev = led_cdev->dev->parent;
1012 hdev = container_of(dev, struct hid_device, dev);
1013 data = hid_get_drvdata(hdev);
1014 for (i = 0; i < 8; i++)
1015 if (led_cdev == data->led[i]) {
1016 value = (data->led_state >> i) & 1;
1017 break;
1018 }
1019 return value ? LED_FULL : LED_OFF;
1020}
1021
1022static int picolcd_init_leds(struct picolcd_data *data, struct hid_report *report)
1023{
1024 struct device *dev = &data->hdev->dev;
1025 struct led_classdev *led;
1026 size_t name_sz = strlen(dev_name(dev)) + 8;
1027 char *name;
1028 int i, ret = 0;
1029
1030 if (!report)
1031 return -ENODEV;
1032 if (report->maxfield != 1 || report->field[0]->report_count != 1 ||
1033 report->field[0]->report_size != 8) {
1034 dev_err(dev, "unsupported LED_STATE report");
1035 return -EINVAL;
1036 }
1037
1038 for (i = 0; i < 8; i++) {
1039 led = kzalloc(sizeof(struct led_classdev)+name_sz, GFP_KERNEL);
1040 if (!led) {
1041 dev_err(dev, "can't allocate memory for LED %d\n", i);
1042 ret = -ENOMEM;
1043 goto err;
1044 }
1045 name = (void *)(&led[1]);
1046 snprintf(name, name_sz, "%s::GPO%d", dev_name(dev), i);
1047 led->name = name;
1048 led->brightness = 0;
1049 led->max_brightness = 1;
1050 led->brightness_get = picolcd_led_get_brightness;
1051 led->brightness_set = picolcd_led_set_brightness;
1052
1053 data->led[i] = led;
1054 ret = led_classdev_register(dev, data->led[i]);
1055 if (ret) {
1056 data->led[i] = NULL;
1057 kfree(led);
1058 dev_err(dev, "can't register LED %d\n", i);
1059 goto err;
1060 }
1061 }
1062 return 0;
1063err:
1064 for (i = 0; i < 8; i++)
1065 if (data->led[i]) {
1066 led = data->led[i];
1067 data->led[i] = NULL;
1068 led_classdev_unregister(led);
1069 kfree(led);
1070 }
1071 return ret;
1072}
1073
1074static void picolcd_exit_leds(struct picolcd_data *data)
1075{
1076 struct led_classdev *led;
1077 int i;
1078
1079 for (i = 0; i < 8; i++) {
1080 led = data->led[i];
1081 data->led[i] = NULL;
1082 if (!led)
1083 continue;
1084 led_classdev_unregister(led);
1085 kfree(led);
1086 }
1087}
1088
1089#else
1090static inline int picolcd_init_leds(struct picolcd_data *data,
1091 struct hid_report *report)
1092{
1093 return 0;
1094}
1095static void picolcd_exit_leds(struct picolcd_data *data)
1096{
1097}
1098static inline int picolcd_leds_set(struct picolcd_data *data)
1099{
1100 return 0;
1101}
1102#endif /* CONFIG_LEDS_CLASS */
1103
Bruno Prémont236db472010-03-30 22:33:50 +02001104/*
1105 * input class device
1106 */
1107static int picolcd_raw_keypad(struct picolcd_data *data,
1108 struct hid_report *report, u8 *raw_data, int size)
1109{
1110 /*
1111 * Keypad event
1112 * First and second data bytes list currently pressed keys,
1113 * 0x00 means no key and at most 2 keys may be pressed at same time
1114 */
1115 int i, j;
1116
1117 /* determine newly pressed keys */
1118 for (i = 0; i < size; i++) {
1119 unsigned int key_code;
1120 if (raw_data[i] == 0)
1121 continue;
1122 for (j = 0; j < sizeof(data->pressed_keys); j++)
1123 if (data->pressed_keys[j] == raw_data[i])
1124 goto key_already_down;
1125 for (j = 0; j < sizeof(data->pressed_keys); j++)
1126 if (data->pressed_keys[j] == 0) {
1127 data->pressed_keys[j] = raw_data[i];
1128 break;
1129 }
1130 input_event(data->input_keys, EV_MSC, MSC_SCAN, raw_data[i]);
1131 if (raw_data[i] < PICOLCD_KEYS)
1132 key_code = data->keycode[raw_data[i]];
1133 else
1134 key_code = KEY_UNKNOWN;
1135 if (key_code != KEY_UNKNOWN) {
1136 dbg_hid(PICOLCD_NAME " got key press for %u:%d",
1137 raw_data[i], key_code);
1138 input_report_key(data->input_keys, key_code, 1);
1139 }
1140 input_sync(data->input_keys);
1141key_already_down:
1142 continue;
1143 }
1144
1145 /* determine newly released keys */
1146 for (j = 0; j < sizeof(data->pressed_keys); j++) {
1147 unsigned int key_code;
1148 if (data->pressed_keys[j] == 0)
1149 continue;
1150 for (i = 0; i < size; i++)
1151 if (data->pressed_keys[j] == raw_data[i])
1152 goto key_still_down;
1153 input_event(data->input_keys, EV_MSC, MSC_SCAN, data->pressed_keys[j]);
1154 if (data->pressed_keys[j] < PICOLCD_KEYS)
1155 key_code = data->keycode[data->pressed_keys[j]];
1156 else
1157 key_code = KEY_UNKNOWN;
1158 if (key_code != KEY_UNKNOWN) {
1159 dbg_hid(PICOLCD_NAME " got key release for %u:%d",
1160 data->pressed_keys[j], key_code);
1161 input_report_key(data->input_keys, key_code, 0);
1162 }
1163 input_sync(data->input_keys);
1164 data->pressed_keys[j] = 0;
1165key_still_down:
1166 continue;
1167 }
1168 return 1;
1169}
1170
1171static int picolcd_raw_cir(struct picolcd_data *data,
1172 struct hid_report *report, u8 *raw_data, int size)
1173{
1174 /* Need understanding of CIR data format to implement ... */
1175 return 1;
1176}
1177
1178static int picolcd_check_version(struct hid_device *hdev)
1179{
1180 struct picolcd_data *data = hid_get_drvdata(hdev);
1181 struct picolcd_pending *verinfo;
1182 int ret = 0;
1183
1184 if (!data)
1185 return -ENODEV;
1186
1187 verinfo = picolcd_send_and_wait(hdev, REPORT_VERSION, NULL, 0);
1188 if (!verinfo) {
1189 dev_err(&hdev->dev, "no version response from PicoLCD");
1190 return -ENODEV;
1191 }
1192
1193 if (verinfo->raw_size == 2) {
1194 if (data->status & PICOLCD_BOOTLOADER) {
1195 dev_info(&hdev->dev, "PicoLCD, bootloader version %d.%d\n",
1196 verinfo->raw_data[0], verinfo->raw_data[1]);
1197 data->version[0] = verinfo->raw_data[0];
1198 data->version[1] = verinfo->raw_data[1];
1199 } else {
1200 dev_info(&hdev->dev, "PicoLCD, firmware version %d.%d\n",
1201 verinfo->raw_data[1], verinfo->raw_data[0]);
1202 data->version[0] = verinfo->raw_data[1];
1203 data->version[1] = verinfo->raw_data[0];
1204 }
1205 } else {
1206 dev_err(&hdev->dev, "confused, got unexpected version response from PicoLCD\n");
1207 ret = -EINVAL;
1208 }
1209 kfree(verinfo);
1210 return ret;
1211}
1212
1213/*
1214 * Reset our device and wait for answer to VERSION request
1215 */
1216static int picolcd_reset(struct hid_device *hdev)
1217{
1218 struct picolcd_data *data = hid_get_drvdata(hdev);
1219 struct hid_report *report = picolcd_out_report(REPORT_RESET, hdev);
1220 unsigned long flags;
Bruno Prémontb8c21cf2010-03-30 22:34:30 +02001221 int error;
Bruno Prémont236db472010-03-30 22:33:50 +02001222
1223 if (!data || !report || report->maxfield != 1)
1224 return -ENODEV;
1225
1226 spin_lock_irqsave(&data->lock, flags);
1227 if (hdev->product == USB_DEVICE_ID_PICOLCD_BOOTLOADER)
1228 data->status |= PICOLCD_BOOTLOADER;
1229
1230 /* perform the reset */
1231 hid_set_field(report->field[0], 0, 1);
1232 usbhid_submit_report(hdev, report, USB_DIR_OUT);
1233 spin_unlock_irqrestore(&data->lock, flags);
1234
Bruno Prémontb8c21cf2010-03-30 22:34:30 +02001235 error = picolcd_check_version(hdev);
1236 if (error)
1237 return error;
1238
Bruno Prémonte8d931b2010-03-30 22:36:07 +02001239 picolcd_resume_lcd(data);
Bruno Prémontf1c21762010-03-30 22:35:27 +02001240 picolcd_resume_backlight(data);
Bruno Prémontb8c21cf2010-03-30 22:34:30 +02001241#if defined(CONFIG_FB) || defined(CONFIG_FB_MODULE)
1242 if (data->fb_info)
1243 schedule_delayed_work(&data->fb_info->deferred_work, 0);
1244#endif /* CONFIG_FB */
1245
Bruno Prémont467d6522010-03-30 22:36:49 +02001246 picolcd_leds_set(data);
Bruno Prémontb8c21cf2010-03-30 22:34:30 +02001247 return 0;
Bruno Prémont236db472010-03-30 22:33:50 +02001248}
1249
1250/*
1251 * The "operation_mode" sysfs attribute
1252 */
1253static ssize_t picolcd_operation_mode_show(struct device *dev,
1254 struct device_attribute *attr, char *buf)
1255{
1256 struct picolcd_data *data = dev_get_drvdata(dev);
1257
1258 if (data->status & PICOLCD_BOOTLOADER)
1259 return snprintf(buf, PAGE_SIZE, "[bootloader] lcd\n");
1260 else
1261 return snprintf(buf, PAGE_SIZE, "bootloader [lcd]\n");
1262}
1263
1264static ssize_t picolcd_operation_mode_store(struct device *dev,
1265 struct device_attribute *attr, const char *buf, size_t count)
1266{
1267 struct picolcd_data *data = dev_get_drvdata(dev);
1268 struct hid_report *report = NULL;
1269 size_t cnt = count;
1270 int timeout = 5000;
1271 unsigned u;
1272 unsigned long flags;
1273
1274 if (cnt >= 3 && strncmp("lcd", buf, 3) == 0) {
1275 if (data->status & PICOLCD_BOOTLOADER)
1276 report = picolcd_out_report(REPORT_EXIT_FLASHER, data->hdev);
1277 buf += 3;
1278 cnt -= 3;
1279 } else if (cnt >= 10 && strncmp("bootloader", buf, 10) == 0) {
1280 if (!(data->status & PICOLCD_BOOTLOADER))
1281 report = picolcd_out_report(REPORT_EXIT_KEYBOARD, data->hdev);
1282 buf += 10;
1283 cnt -= 10;
1284 }
1285 if (!report)
1286 return -EINVAL;
1287
1288 while (cnt > 0 && (*buf == ' ' || *buf == '\t')) {
1289 buf++;
1290 cnt--;
1291 }
1292 while (cnt > 0 && (buf[cnt-1] == '\n' || buf[cnt-1] == '\r'))
1293 cnt--;
1294 if (cnt > 0) {
1295 if (sscanf(buf, "%u", &u) != 1)
1296 return -EINVAL;
1297 if (u > 30000)
1298 return -EINVAL;
1299 else
1300 timeout = u;
1301 }
1302
1303 spin_lock_irqsave(&data->lock, flags);
1304 hid_set_field(report->field[0], 0, timeout & 0xff);
1305 hid_set_field(report->field[0], 1, (timeout >> 8) & 0xff);
1306 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
1307 spin_unlock_irqrestore(&data->lock, flags);
1308 return count;
1309}
1310
1311static DEVICE_ATTR(operation_mode, 0644, picolcd_operation_mode_show,
1312 picolcd_operation_mode_store);
1313
1314
1315#ifdef CONFIG_DEBUG_FS
1316/*
1317 * Helper code for HID report level dumping/debugging
1318 */
1319static const char *error_codes[] = {
1320 "success", "parameter missing", "data_missing", "block readonly",
1321 "block not erasable", "block too big", "section overflow",
1322 "invalid command length", "invalid data length",
1323};
1324
1325static void dump_buff_as_hex(char *dst, size_t dst_sz, const u8 *data,
1326 const size_t data_len)
1327{
1328 int i, j;
1329 for (i = j = 0; i < data_len && j + 3 < dst_sz; i++) {
1330 dst[j++] = hex_asc[(data[i] >> 4) & 0x0f];
1331 dst[j++] = hex_asc[data[i] & 0x0f];
1332 dst[j++] = ' ';
1333 }
1334 if (j < dst_sz) {
1335 dst[j--] = '\0';
1336 dst[j] = '\n';
1337 } else
1338 dst[j] = '\0';
1339}
1340
1341static void picolcd_debug_out_report(struct picolcd_data *data,
1342 struct hid_device *hdev, struct hid_report *report)
1343{
1344 u8 raw_data[70];
1345 int raw_size = (report->size >> 3) + 1;
1346 char *buff;
1347#define BUFF_SZ 256
1348
1349 /* Avoid unnecessary overhead if debugfs is disabled */
1350 if (!hdev->debug_events)
1351 return;
1352
1353 buff = kmalloc(BUFF_SZ, GFP_ATOMIC);
1354 if (!buff)
1355 return;
1356
1357 snprintf(buff, BUFF_SZ, "\nout report %d (size %d) = ",
1358 report->id, raw_size);
1359 hid_debug_event(hdev, buff);
1360 if (raw_size + 5 > sizeof(raw_data)) {
1361 hid_debug_event(hdev, " TOO BIG\n");
1362 return;
1363 } else {
1364 raw_data[0] = report->id;
1365 hid_output_report(report, raw_data);
1366 dump_buff_as_hex(buff, BUFF_SZ, raw_data, raw_size);
1367 hid_debug_event(hdev, buff);
1368 }
1369
1370 switch (report->id) {
1371 case REPORT_LED_STATE:
1372 /* 1 data byte with GPO state */
1373 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1374 "REPORT_LED_STATE", report->id, raw_size-1);
1375 hid_debug_event(hdev, buff);
1376 snprintf(buff, BUFF_SZ, "\tGPO state: 0x%02x\n", raw_data[1]);
1377 hid_debug_event(hdev, buff);
1378 break;
1379 case REPORT_BRIGHTNESS:
1380 /* 1 data byte with brightness */
1381 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1382 "REPORT_BRIGHTNESS", report->id, raw_size-1);
1383 hid_debug_event(hdev, buff);
1384 snprintf(buff, BUFF_SZ, "\tBrightness: 0x%02x\n", raw_data[1]);
1385 hid_debug_event(hdev, buff);
1386 break;
1387 case REPORT_CONTRAST:
1388 /* 1 data byte with contrast */
1389 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1390 "REPORT_CONTRAST", report->id, raw_size-1);
1391 hid_debug_event(hdev, buff);
1392 snprintf(buff, BUFF_SZ, "\tContrast: 0x%02x\n", raw_data[1]);
1393 hid_debug_event(hdev, buff);
1394 break;
1395 case REPORT_RESET:
1396 /* 2 data bytes with reset duration in ms */
1397 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1398 "REPORT_RESET", report->id, raw_size-1);
1399 hid_debug_event(hdev, buff);
1400 snprintf(buff, BUFF_SZ, "\tDuration: 0x%02x%02x (%dms)\n",
1401 raw_data[2], raw_data[1], raw_data[2] << 8 | raw_data[1]);
1402 hid_debug_event(hdev, buff);
1403 break;
1404 case REPORT_LCD_CMD:
1405 /* 63 data bytes with LCD commands */
1406 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1407 "REPORT_LCD_CMD", report->id, raw_size-1);
1408 hid_debug_event(hdev, buff);
1409 /* TODO: format decoding */
1410 break;
1411 case REPORT_LCD_DATA:
1412 /* 63 data bytes with LCD data */
1413 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1414 "REPORT_LCD_CMD", report->id, raw_size-1);
1415 /* TODO: format decoding */
1416 hid_debug_event(hdev, buff);
1417 break;
1418 case REPORT_LCD_CMD_DATA:
1419 /* 63 data bytes with LCD commands and data */
1420 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1421 "REPORT_LCD_CMD", report->id, raw_size-1);
1422 /* TODO: format decoding */
1423 hid_debug_event(hdev, buff);
1424 break;
1425 case REPORT_EE_READ:
1426 /* 3 data bytes with read area description */
1427 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1428 "REPORT_EE_READ", report->id, raw_size-1);
1429 hid_debug_event(hdev, buff);
1430 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
1431 raw_data[2], raw_data[1]);
1432 hid_debug_event(hdev, buff);
1433 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
1434 hid_debug_event(hdev, buff);
1435 break;
1436 case REPORT_EE_WRITE:
1437 /* 3+1..20 data bytes with write area description */
1438 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1439 "REPORT_EE_WRITE", report->id, raw_size-1);
1440 hid_debug_event(hdev, buff);
1441 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
1442 raw_data[2], raw_data[1]);
1443 hid_debug_event(hdev, buff);
1444 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
1445 hid_debug_event(hdev, buff);
1446 if (raw_data[3] == 0) {
1447 snprintf(buff, BUFF_SZ, "\tNo data\n");
1448 } else if (raw_data[3] + 4 <= raw_size) {
1449 snprintf(buff, BUFF_SZ, "\tData: ");
1450 hid_debug_event(hdev, buff);
1451 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
1452 } else {
1453 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
1454 }
1455 hid_debug_event(hdev, buff);
1456 break;
1457 case REPORT_ERASE_MEMORY:
1458 case REPORT_BL_ERASE_MEMORY:
1459 /* 3 data bytes with pointer inside erase block */
1460 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1461 "REPORT_ERASE_MEMORY", report->id, raw_size-1);
1462 hid_debug_event(hdev, buff);
1463 switch (data->addr_sz) {
1464 case 2:
1465 snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x\n",
1466 raw_data[2], raw_data[1]);
1467 break;
1468 case 3:
1469 snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x%02x\n",
1470 raw_data[3], raw_data[2], raw_data[1]);
1471 break;
1472 default:
1473 snprintf(buff, BUFF_SZ, "\tNot supported\n");
1474 }
1475 hid_debug_event(hdev, buff);
1476 break;
1477 case REPORT_READ_MEMORY:
1478 case REPORT_BL_READ_MEMORY:
1479 /* 4 data bytes with read area description */
1480 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1481 "REPORT_READ_MEMORY", report->id, raw_size-1);
1482 hid_debug_event(hdev, buff);
1483 switch (data->addr_sz) {
1484 case 2:
1485 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
1486 raw_data[2], raw_data[1]);
1487 hid_debug_event(hdev, buff);
1488 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
1489 break;
1490 case 3:
1491 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
1492 raw_data[3], raw_data[2], raw_data[1]);
1493 hid_debug_event(hdev, buff);
1494 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
1495 break;
1496 default:
1497 snprintf(buff, BUFF_SZ, "\tNot supported\n");
1498 }
1499 hid_debug_event(hdev, buff);
1500 break;
1501 case REPORT_WRITE_MEMORY:
1502 case REPORT_BL_WRITE_MEMORY:
1503 /* 4+1..32 data bytes with write adrea description */
1504 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1505 "REPORT_WRITE_MEMORY", report->id, raw_size-1);
1506 hid_debug_event(hdev, buff);
1507 switch (data->addr_sz) {
1508 case 2:
1509 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
1510 raw_data[2], raw_data[1]);
1511 hid_debug_event(hdev, buff);
1512 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
1513 hid_debug_event(hdev, buff);
1514 if (raw_data[3] == 0) {
1515 snprintf(buff, BUFF_SZ, "\tNo data\n");
1516 } else if (raw_data[3] + 4 <= raw_size) {
1517 snprintf(buff, BUFF_SZ, "\tData: ");
1518 hid_debug_event(hdev, buff);
1519 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
1520 } else {
1521 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
1522 }
1523 break;
1524 case 3:
1525 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
1526 raw_data[3], raw_data[2], raw_data[1]);
1527 hid_debug_event(hdev, buff);
1528 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
1529 hid_debug_event(hdev, buff);
1530 if (raw_data[4] == 0) {
1531 snprintf(buff, BUFF_SZ, "\tNo data\n");
1532 } else if (raw_data[4] + 5 <= raw_size) {
1533 snprintf(buff, BUFF_SZ, "\tData: ");
1534 hid_debug_event(hdev, buff);
1535 dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]);
1536 } else {
1537 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
1538 }
1539 break;
1540 default:
1541 snprintf(buff, BUFF_SZ, "\tNot supported\n");
1542 }
1543 hid_debug_event(hdev, buff);
1544 break;
1545 case REPORT_SPLASH_RESTART:
1546 /* TODO */
1547 break;
1548 case REPORT_EXIT_KEYBOARD:
1549 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1550 "REPORT_EXIT_KEYBOARD", report->id, raw_size-1);
1551 hid_debug_event(hdev, buff);
1552 snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n",
1553 raw_data[1] | (raw_data[2] << 8),
1554 raw_data[2], raw_data[1]);
1555 hid_debug_event(hdev, buff);
1556 break;
1557 case REPORT_VERSION:
1558 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1559 "REPORT_VERSION", report->id, raw_size-1);
1560 hid_debug_event(hdev, buff);
1561 break;
1562 case REPORT_DEVID:
1563 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1564 "REPORT_DEVID", report->id, raw_size-1);
1565 hid_debug_event(hdev, buff);
1566 break;
1567 case REPORT_SPLASH_SIZE:
1568 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1569 "REPORT_SPLASH_SIZE", report->id, raw_size-1);
1570 hid_debug_event(hdev, buff);
1571 break;
1572 case REPORT_HOOK_VERSION:
1573 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1574 "REPORT_HOOK_VERSION", report->id, raw_size-1);
1575 hid_debug_event(hdev, buff);
1576 break;
1577 case REPORT_EXIT_FLASHER:
1578 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1579 "REPORT_VERSION", report->id, raw_size-1);
1580 hid_debug_event(hdev, buff);
1581 snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n",
1582 raw_data[1] | (raw_data[2] << 8),
1583 raw_data[2], raw_data[1]);
1584 hid_debug_event(hdev, buff);
1585 break;
1586 default:
1587 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
1588 "<unknown>", report->id, raw_size-1);
1589 hid_debug_event(hdev, buff);
1590 break;
1591 }
1592 wake_up_interruptible(&hdev->debug_wait);
1593 kfree(buff);
1594}
1595
1596static void picolcd_debug_raw_event(struct picolcd_data *data,
1597 struct hid_device *hdev, struct hid_report *report,
1598 u8 *raw_data, int size)
1599{
1600 char *buff;
1601
1602#define BUFF_SZ 256
1603 /* Avoid unnecessary overhead if debugfs is disabled */
1604 if (!hdev->debug_events)
1605 return;
1606
1607 buff = kmalloc(BUFF_SZ, GFP_ATOMIC);
1608 if (!buff)
1609 return;
1610
1611 switch (report->id) {
1612 case REPORT_ERROR_CODE:
1613 /* 2 data bytes with affected report and error code */
1614 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
1615 "REPORT_ERROR_CODE", report->id, size-1);
1616 hid_debug_event(hdev, buff);
1617 if (raw_data[2] < ARRAY_SIZE(error_codes))
1618 snprintf(buff, BUFF_SZ, "\tError code 0x%02x (%s) in reply to report 0x%02x\n",
1619 raw_data[2], error_codes[raw_data[2]], raw_data[1]);
1620 else
1621 snprintf(buff, BUFF_SZ, "\tError code 0x%02x in reply to report 0x%02x\n",
1622 raw_data[2], raw_data[1]);
1623 hid_debug_event(hdev, buff);
1624 break;
1625 case REPORT_KEY_STATE:
1626 /* 2 data bytes with key state */
1627 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
1628 "REPORT_KEY_STATE", report->id, size-1);
1629 hid_debug_event(hdev, buff);
1630 if (raw_data[1] == 0)
1631 snprintf(buff, BUFF_SZ, "\tNo key pressed\n");
1632 else if (raw_data[2] == 0)
1633 snprintf(buff, BUFF_SZ, "\tOne key pressed: 0x%02x (%d)\n",
1634 raw_data[1], raw_data[1]);
1635 else
1636 snprintf(buff, BUFF_SZ, "\tTwo keys pressed: 0x%02x (%d), 0x%02x (%d)\n",
1637 raw_data[1], raw_data[1], raw_data[2], raw_data[2]);
1638 hid_debug_event(hdev, buff);
1639 break;
1640 case REPORT_IR_DATA:
1641 /* Up to 20 byes of IR scancode data */
1642 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
1643 "REPORT_IR_DATA", report->id, size-1);
1644 hid_debug_event(hdev, buff);
1645 if (raw_data[1] == 0) {
1646 snprintf(buff, BUFF_SZ, "\tUnexpectedly 0 data length\n");
1647 hid_debug_event(hdev, buff);
1648 } else if (raw_data[1] + 1 <= size) {
1649 snprintf(buff, BUFF_SZ, "\tData length: %d\n\tIR Data: ",
1650 raw_data[1]-1);
1651 hid_debug_event(hdev, buff);
1652 dump_buff_as_hex(buff, BUFF_SZ, raw_data+2, raw_data[1]-1);
1653 hid_debug_event(hdev, buff);
1654 } else {
1655 snprintf(buff, BUFF_SZ, "\tOverflowing data length: %d\n",
1656 raw_data[1]-1);
1657 hid_debug_event(hdev, buff);
1658 }
1659 break;
1660 case REPORT_EE_DATA:
1661 /* Data buffer in response to REPORT_EE_READ or REPORT_EE_WRITE */
1662 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
1663 "REPORT_EE_DATA", report->id, size-1);
1664 hid_debug_event(hdev, buff);
1665 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
1666 raw_data[2], raw_data[1]);
1667 hid_debug_event(hdev, buff);
1668 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
1669 hid_debug_event(hdev, buff);
1670 if (raw_data[3] == 0) {
1671 snprintf(buff, BUFF_SZ, "\tNo data\n");
1672 hid_debug_event(hdev, buff);
1673 } else if (raw_data[3] + 4 <= size) {
1674 snprintf(buff, BUFF_SZ, "\tData: ");
1675 hid_debug_event(hdev, buff);
1676 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
1677 hid_debug_event(hdev, buff);
1678 } else {
1679 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
1680 hid_debug_event(hdev, buff);
1681 }
1682 break;
1683 case REPORT_MEMORY:
1684 /* Data buffer in response to REPORT_READ_MEMORY or REPORT_WRTIE_MEMORY */
1685 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
1686 "REPORT_MEMORY", report->id, size-1);
1687 hid_debug_event(hdev, buff);
1688 switch (data->addr_sz) {
1689 case 2:
1690 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
1691 raw_data[2], raw_data[1]);
1692 hid_debug_event(hdev, buff);
1693 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
1694 hid_debug_event(hdev, buff);
1695 if (raw_data[3] == 0) {
1696 snprintf(buff, BUFF_SZ, "\tNo data\n");
1697 } else if (raw_data[3] + 4 <= size) {
1698 snprintf(buff, BUFF_SZ, "\tData: ");
1699 hid_debug_event(hdev, buff);
1700 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
1701 } else {
1702 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
1703 }
1704 break;
1705 case 3:
1706 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
1707 raw_data[3], raw_data[2], raw_data[1]);
1708 hid_debug_event(hdev, buff);
1709 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
1710 hid_debug_event(hdev, buff);
1711 if (raw_data[4] == 0) {
1712 snprintf(buff, BUFF_SZ, "\tNo data\n");
1713 } else if (raw_data[4] + 5 <= size) {
1714 snprintf(buff, BUFF_SZ, "\tData: ");
1715 hid_debug_event(hdev, buff);
1716 dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]);
1717 } else {
1718 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
1719 }
1720 break;
1721 default:
1722 snprintf(buff, BUFF_SZ, "\tNot supported\n");
1723 }
1724 hid_debug_event(hdev, buff);
1725 break;
1726 case REPORT_VERSION:
1727 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
1728 "REPORT_VERSION", report->id, size-1);
1729 hid_debug_event(hdev, buff);
1730 snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n",
1731 raw_data[2], raw_data[1]);
1732 hid_debug_event(hdev, buff);
1733 break;
1734 case REPORT_BL_ERASE_MEMORY:
1735 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
1736 "REPORT_BL_ERASE_MEMORY", report->id, size-1);
1737 hid_debug_event(hdev, buff);
1738 /* TODO */
1739 break;
1740 case REPORT_BL_READ_MEMORY:
1741 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
1742 "REPORT_BL_READ_MEMORY", report->id, size-1);
1743 hid_debug_event(hdev, buff);
1744 /* TODO */
1745 break;
1746 case REPORT_BL_WRITE_MEMORY:
1747 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
1748 "REPORT_BL_WRITE_MEMORY", report->id, size-1);
1749 hid_debug_event(hdev, buff);
1750 /* TODO */
1751 break;
1752 case REPORT_DEVID:
1753 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
1754 "REPORT_DEVID", report->id, size-1);
1755 hid_debug_event(hdev, buff);
1756 snprintf(buff, BUFF_SZ, "\tSerial: 0x%02x%02x%02x%02x\n",
1757 raw_data[1], raw_data[2], raw_data[3], raw_data[4]);
1758 hid_debug_event(hdev, buff);
1759 snprintf(buff, BUFF_SZ, "\tType: 0x%02x\n",
1760 raw_data[5]);
1761 hid_debug_event(hdev, buff);
1762 break;
1763 case REPORT_SPLASH_SIZE:
1764 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
1765 "REPORT_SPLASH_SIZE", report->id, size-1);
1766 hid_debug_event(hdev, buff);
1767 snprintf(buff, BUFF_SZ, "\tTotal splash space: %d\n",
1768 (raw_data[2] << 8) | raw_data[1]);
1769 hid_debug_event(hdev, buff);
1770 snprintf(buff, BUFF_SZ, "\tUsed splash space: %d\n",
1771 (raw_data[4] << 8) | raw_data[3]);
1772 hid_debug_event(hdev, buff);
1773 break;
1774 case REPORT_HOOK_VERSION:
1775 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
1776 "REPORT_HOOK_VERSION", report->id, size-1);
1777 hid_debug_event(hdev, buff);
1778 snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n",
1779 raw_data[1], raw_data[2]);
1780 hid_debug_event(hdev, buff);
1781 break;
1782 default:
1783 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
1784 "<unknown>", report->id, size-1);
1785 hid_debug_event(hdev, buff);
1786 break;
1787 }
1788 wake_up_interruptible(&hdev->debug_wait);
1789 kfree(buff);
1790}
1791#else
1792#define picolcd_debug_raw_event(data, hdev, report, raw_data, size)
1793#endif
1794
1795/*
1796 * Handle raw report as sent by device
1797 */
1798static int picolcd_raw_event(struct hid_device *hdev,
1799 struct hid_report *report, u8 *raw_data, int size)
1800{
1801 struct picolcd_data *data = hid_get_drvdata(hdev);
1802 unsigned long flags;
1803 int ret = 0;
1804
1805 if (!data)
1806 return 1;
1807
1808 if (report->id == REPORT_KEY_STATE) {
1809 if (data->input_keys)
1810 ret = picolcd_raw_keypad(data, report, raw_data+1, size-1);
1811 } else if (report->id == REPORT_IR_DATA) {
1812 if (data->input_cir)
1813 ret = picolcd_raw_cir(data, report, raw_data+1, size-1);
1814 } else {
1815 spin_lock_irqsave(&data->lock, flags);
1816 /*
1817 * We let the caller of picolcd_send_and_wait() check if the
1818 * report we got is one of the expected ones or not.
1819 */
1820 if (data->pending) {
1821 memcpy(data->pending->raw_data, raw_data+1, size-1);
1822 data->pending->raw_size = size-1;
1823 data->pending->in_report = report;
1824 complete(&data->pending->ready);
1825 }
1826 spin_unlock_irqrestore(&data->lock, flags);
1827 }
1828
1829 picolcd_debug_raw_event(data, hdev, report, raw_data, size);
1830 return 1;
1831}
1832
1833/* initialize keypad input device */
1834static int picolcd_init_keys(struct picolcd_data *data,
1835 struct hid_report *report)
1836{
1837 struct hid_device *hdev = data->hdev;
1838 struct input_dev *idev;
1839 int error, i;
1840
1841 if (!report)
1842 return -ENODEV;
1843 if (report->maxfield != 1 || report->field[0]->report_count != 2 ||
1844 report->field[0]->report_size != 8) {
1845 dev_err(&hdev->dev, "unsupported KEY_STATE report");
1846 return -EINVAL;
1847 }
1848
1849 idev = input_allocate_device();
1850 if (idev == NULL) {
1851 dev_err(&hdev->dev, "failed to allocate input device");
1852 return -ENOMEM;
1853 }
1854 input_set_drvdata(idev, hdev);
1855 memcpy(data->keycode, def_keymap, sizeof(def_keymap));
1856 idev->name = hdev->name;
1857 idev->phys = hdev->phys;
1858 idev->uniq = hdev->uniq;
1859 idev->id.bustype = hdev->bus;
1860 idev->id.vendor = hdev->vendor;
1861 idev->id.product = hdev->product;
1862 idev->id.version = hdev->version;
1863 idev->dev.parent = hdev->dev.parent;
1864 idev->keycode = &data->keycode;
1865 idev->keycodemax = PICOLCD_KEYS;
1866 idev->keycodesize = sizeof(data->keycode[0]);
1867 input_set_capability(idev, EV_MSC, MSC_SCAN);
1868 set_bit(EV_REP, idev->evbit);
1869 for (i = 0; i < PICOLCD_KEYS; i++)
1870 input_set_capability(idev, EV_KEY, data->keycode[i]);
1871 error = input_register_device(idev);
1872 if (error) {
1873 dev_err(&hdev->dev, "error registering the input device");
1874 input_free_device(idev);
1875 return error;
1876 }
1877 data->input_keys = idev;
1878 return 0;
1879}
1880
1881static void picolcd_exit_keys(struct picolcd_data *data)
1882{
1883 struct input_dev *idev = data->input_keys;
1884
1885 data->input_keys = NULL;
1886 if (idev)
1887 input_unregister_device(idev);
1888}
1889
1890/* initialize CIR input device */
1891static inline int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report)
1892{
1893 /* support not implemented yet */
1894 return 0;
1895}
1896
1897static inline void picolcd_exit_cir(struct picolcd_data *data)
1898{
1899}
1900
1901static int picolcd_probe_lcd(struct hid_device *hdev, struct picolcd_data *data)
1902{
1903 struct hid_report *report;
1904 int error;
1905
1906 error = picolcd_check_version(hdev);
1907 if (error)
1908 return error;
1909
1910 if (data->version[0] != 0 && data->version[1] != 3)
1911 dev_info(&hdev->dev, "Device with untested firmware revision, "
1912 "please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n",
1913 dev_name(&hdev->dev));
1914
1915 /* Setup keypad input device */
1916 error = picolcd_init_keys(data, picolcd_in_report(REPORT_KEY_STATE, hdev));
1917 if (error)
1918 goto err;
1919
1920 /* Setup CIR input device */
1921 error = picolcd_init_cir(data, picolcd_in_report(REPORT_IR_DATA, hdev));
1922 if (error)
1923 goto err;
1924
Bruno Prémontb8c21cf2010-03-30 22:34:30 +02001925 /* Set up the framebuffer device */
1926 error = picolcd_init_framebuffer(data);
1927 if (error)
1928 goto err;
1929
Bruno Prémonte8d931b2010-03-30 22:36:07 +02001930 /* Setup lcd class device */
1931 error = picolcd_init_lcd(data, picolcd_out_report(REPORT_CONTRAST, hdev));
1932 if (error)
1933 goto err;
1934
Bruno Prémontf1c21762010-03-30 22:35:27 +02001935 /* Setup backlight class device */
1936 error = picolcd_init_backlight(data, picolcd_out_report(REPORT_BRIGHTNESS, hdev));
1937 if (error)
1938 goto err;
1939
Bruno Prémont467d6522010-03-30 22:36:49 +02001940 /* Setup the LED class devices */
1941 error = picolcd_init_leds(data, picolcd_out_report(REPORT_LED_STATE, hdev));
1942 if (error)
1943 goto err;
1944
Bruno Prémont236db472010-03-30 22:33:50 +02001945#ifdef CONFIG_DEBUG_FS
1946 report = picolcd_out_report(REPORT_READ_MEMORY, hdev);
1947 if (report && report->maxfield == 1 && report->field[0]->report_size == 8)
1948 data->addr_sz = report->field[0]->report_count - 1;
1949 else
1950 data->addr_sz = -1;
1951#endif
1952 return 0;
1953err:
Bruno Prémont467d6522010-03-30 22:36:49 +02001954 picolcd_exit_leds(data);
Bruno Prémontf1c21762010-03-30 22:35:27 +02001955 picolcd_exit_backlight(data);
Bruno Prémonte8d931b2010-03-30 22:36:07 +02001956 picolcd_exit_lcd(data);
Bruno Prémontb8c21cf2010-03-30 22:34:30 +02001957 picolcd_exit_framebuffer(data);
Bruno Prémont236db472010-03-30 22:33:50 +02001958 picolcd_exit_cir(data);
1959 picolcd_exit_keys(data);
1960 return error;
1961}
1962
1963static int picolcd_probe_bootloader(struct hid_device *hdev, struct picolcd_data *data)
1964{
1965 struct hid_report *report;
1966 int error;
1967
1968 error = picolcd_check_version(hdev);
1969 if (error)
1970 return error;
1971
1972 if (data->version[0] != 1 && data->version[1] != 0)
1973 dev_info(&hdev->dev, "Device with untested bootloader revision, "
1974 "please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n",
1975 dev_name(&hdev->dev));
1976
1977#ifdef CONFIG_DEBUG_FS
1978 report = picolcd_out_report(REPORT_BL_READ_MEMORY, hdev);
1979 if (report && report->maxfield == 1 && report->field[0]->report_size == 8)
1980 data->addr_sz = report->field[0]->report_count - 1;
1981 else
1982 data->addr_sz = -1;
1983#endif
1984 return 0;
1985}
1986
1987static int picolcd_probe(struct hid_device *hdev,
1988 const struct hid_device_id *id)
1989{
1990 struct picolcd_data *data;
1991 int error = -ENOMEM;
1992
1993 dbg_hid(PICOLCD_NAME " hardware probe...\n");
1994
1995 /*
1996 * Let's allocate the picolcd data structure, set some reasonable
1997 * defaults, and associate it with the device
1998 */
1999 data = kzalloc(sizeof(struct picolcd_data), GFP_KERNEL);
2000 if (data == NULL) {
2001 dev_err(&hdev->dev, "can't allocate space for Minibox PicoLCD device data\n");
2002 error = -ENOMEM;
2003 goto err_no_cleanup;
2004 }
2005
2006 spin_lock_init(&data->lock);
2007 mutex_init(&data->mutex);
2008 data->hdev = hdev;
2009 if (hdev->product == USB_DEVICE_ID_PICOLCD_BOOTLOADER)
2010 data->status |= PICOLCD_BOOTLOADER;
2011 hid_set_drvdata(hdev, data);
2012
2013 /* Parse the device reports and start it up */
2014 error = hid_parse(hdev);
2015 if (error) {
2016 dev_err(&hdev->dev, "device report parse failed\n");
2017 goto err_cleanup_data;
2018 }
2019
2020 /* We don't use hidinput but hid_hw_start() fails if nothing is
2021 * claimed. So spoof claimed input. */
2022 hdev->claimed = HID_CLAIMED_INPUT;
2023 error = hid_hw_start(hdev, 0);
2024 hdev->claimed = 0;
2025 if (error) {
2026 dev_err(&hdev->dev, "hardware start failed\n");
2027 goto err_cleanup_data;
2028 }
2029
2030 error = hdev->ll_driver->open(hdev);
2031 if (error) {
2032 dev_err(&hdev->dev, "failed to open input interrupt pipe for key and IR events\n");
2033 goto err_cleanup_hid_hw;
2034 }
2035
2036 error = device_create_file(&hdev->dev, &dev_attr_operation_mode);
2037 if (error) {
2038 dev_err(&hdev->dev, "failed to create sysfs attributes\n");
2039 goto err_cleanup_hid_ll;
2040 }
2041
2042 if (data->status & PICOLCD_BOOTLOADER)
2043 error = picolcd_probe_bootloader(hdev, data);
2044 else
2045 error = picolcd_probe_lcd(hdev, data);
2046 if (error)
2047 goto err_cleanup_sysfs;
2048
2049 dbg_hid(PICOLCD_NAME " activated and initialized\n");
2050 return 0;
2051
2052err_cleanup_sysfs:
2053 device_remove_file(&hdev->dev, &dev_attr_operation_mode);
2054err_cleanup_hid_ll:
2055 hdev->ll_driver->close(hdev);
2056err_cleanup_hid_hw:
2057 hid_hw_stop(hdev);
2058err_cleanup_data:
2059 kfree(data);
2060err_no_cleanup:
2061 hid_set_drvdata(hdev, NULL);
2062
2063 return error;
2064}
2065
2066static void picolcd_remove(struct hid_device *hdev)
2067{
2068 struct picolcd_data *data = hid_get_drvdata(hdev);
2069 unsigned long flags;
2070
2071 dbg_hid(PICOLCD_NAME " hardware remove...\n");
2072 spin_lock_irqsave(&data->lock, flags);
2073 data->status |= PICOLCD_FAILED;
2074 spin_unlock_irqrestore(&data->lock, flags);
2075
2076 device_remove_file(&hdev->dev, &dev_attr_operation_mode);
2077 hdev->ll_driver->close(hdev);
2078 hid_hw_stop(hdev);
2079 hid_set_drvdata(hdev, NULL);
2080
2081 /* Shortcut potential pending reply that will never arrive */
2082 spin_lock_irqsave(&data->lock, flags);
2083 if (data->pending)
2084 complete(&data->pending->ready);
2085 spin_unlock_irqrestore(&data->lock, flags);
2086
Bruno Prémont467d6522010-03-30 22:36:49 +02002087 /* Cleanup LED */
2088 picolcd_exit_leds(data);
Bruno Prémontb8c21cf2010-03-30 22:34:30 +02002089 /* Clean up the framebuffer */
Bruno Prémontf1c21762010-03-30 22:35:27 +02002090 picolcd_exit_backlight(data);
Bruno Prémonte8d931b2010-03-30 22:36:07 +02002091 picolcd_exit_lcd(data);
Bruno Prémontb8c21cf2010-03-30 22:34:30 +02002092 picolcd_exit_framebuffer(data);
Bruno Prémont236db472010-03-30 22:33:50 +02002093 /* Cleanup input */
2094 picolcd_exit_cir(data);
2095 picolcd_exit_keys(data);
2096
2097 mutex_destroy(&data->mutex);
2098 /* Finally, clean up the picolcd data itself */
2099 kfree(data);
2100}
2101
2102static const struct hid_device_id picolcd_devices[] = {
2103 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) },
2104 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) },
2105 { }
2106};
2107MODULE_DEVICE_TABLE(hid, picolcd_devices);
2108
2109static struct hid_driver picolcd_driver = {
2110 .name = "hid-picolcd",
2111 .id_table = picolcd_devices,
2112 .probe = picolcd_probe,
2113 .remove = picolcd_remove,
2114 .raw_event = picolcd_raw_event,
2115};
2116
2117static int __init picolcd_init(void)
2118{
2119 return hid_register_driver(&picolcd_driver);
2120}
2121
2122static void __exit picolcd_exit(void)
2123{
2124 hid_unregister_driver(&picolcd_driver);
2125}
2126
2127module_init(picolcd_init);
2128module_exit(picolcd_exit);
2129MODULE_DESCRIPTION("Minibox graphics PicoLCD Driver");
2130MODULE_LICENSE("GPL v2");