0d6a1cf4d976b5e102d8bf0497ac2139cc524b05
[openwrt.git] / target / linux / xburst / files-2.6.32 / drivers / video / metronomefb.c
1 /*
2 * linux/drivers/video/metronomefb.c -- FB driver for Metronome controller
3 *
4 * Copyright (C) 2008, Jaya Kumar
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 *
10 * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven.
11 *
12 * This work was made possible by help and equipment support from E-Ink
13 * Corporation. http://support.eink.com/community
14 *
15 * This driver is written to be used with the Metronome display controller.
16 * It is intended to be architecture independent. A board specific driver
17 * must be used to perform all the physical IO interactions. An example
18 * is provided as am200epd.c
19 *
20 */
21
22 #define DEBUG
23
24 #include <linux/module.h>
25 #include <linux/kernel.h>
26 #include <linux/errno.h>
27 #include <linux/string.h>
28 #include <linux/mm.h>
29 #include <linux/slab.h>
30 #include <linux/vmalloc.h>
31 #include <linux/delay.h>
32 #include <linux/interrupt.h>
33 #include <linux/fb.h>
34 #include <linux/init.h>
35 #include <linux/platform_device.h>
36 #include <linux/list.h>
37 #include <linux/firmware.h>
38 #include <linux/dma-mapping.h>
39 #include <linux/uaccess.h>
40 #include <linux/irq.h>
41 #include <linux/ctype.h>
42
43 #include <video/metronomefb.h>
44
45 #include <asm/unaligned.h>
46
47 /* Display specific information */
48 #define DPY_W 832
49 #define DPY_H 622
50
51 #define WF_MODE_INIT 0 /* Initialization */
52 #define WF_MODE_MU 1 /* Monochrome update */
53 #define WF_MODE_GU 2 /* Grayscale update */
54 #define WF_MODE_GC 3 /* Grayscale clearing */
55
56 static int temp = 25;
57
58 /* frame differs from image. frame includes non-visible pixels */
59 struct epd_frame {
60 int fw; /* frame width */
61 int fh; /* frame height */
62 u16 config[4];
63 int wfm_size;
64 };
65
66 static struct epd_frame epd_frame_table[] = {
67 {
68 .fw = 832,
69 .fh = 622,
70 .config = {
71 15 /* sdlew */
72 | 2 << 8 /* sdosz */
73 | 0 << 11 /* sdor */
74 | 0 << 12 /* sdces */
75 | 0 << 15, /* sdcer */
76 42 /* gdspl */
77 | 1 << 8 /* gdr1 */
78 | 1 << 9 /* sdshr */
79 | 0 << 15, /* gdspp */
80 18 /* gdspw */
81 | 0 << 15, /* dispc */
82 599 /* vdlc */
83 | 0 << 11 /* dsi */
84 | 0 << 12, /* dsic */
85 },
86 .wfm_size = 47001,
87 },
88 {
89 .fw = 1088,
90 .fh = 791,
91 .config = {
92 0x0104,
93 0x031f,
94 0x0088,
95 0x02ff,
96 },
97 .wfm_size = 46770,
98 },
99 {
100 .fw = 1200,
101 .fh = 842,
102 .config = {
103 0x0101,
104 0x030e,
105 0x0012,
106 0x0280,
107 },
108 .wfm_size = 46770,
109 },
110 {
111 .fw = 800,
112 .fh = 600,
113 .config = {
114 15 /* sdlew */
115 | 2 << 8 /* sdosz */
116 | 0 << 11 /* sdor */
117 | 0 << 12 /* sdces */
118 | 0 << 15, /* sdcer */
119 42 /* gdspl */
120 | 1 << 8 /* gdr1 */
121 | 1 << 9 /* sdshr */
122 | 0 << 15, /* gdspp */
123 18 /* gdspw */
124 | 0 << 15, /* dispc */
125 599 /* vdlc */
126 | 0 << 11 /* dsi */
127 | 0 << 12, /* dsic */
128 },
129 .wfm_size = 46901,
130 },
131 };
132
133 static const struct fb_fix_screeninfo metronomefb_fix __devinitdata = {
134 .id = "metronomefb",
135 .type = FB_TYPE_PACKED_PIXELS,
136 .visual = FB_VISUAL_STATIC_PSEUDOCOLOR,
137 .xpanstep = 0,
138 .ypanstep = 0,
139 .ywrapstep = 0,
140 .line_length = DPY_W,
141 .accel = FB_ACCEL_NONE,
142 };
143
144 static const struct fb_var_screeninfo metronomefb_var __devinitdata = {
145 .xres = DPY_W,
146 .yres = DPY_H,
147 .xres_virtual = DPY_W,
148 .yres_virtual = DPY_H,
149 .bits_per_pixel = 8,
150 .grayscale = 1,
151 .nonstd = 1,
152 .red = { 4, 3, 0 },
153 .green = { 0, 0, 0 },
154 .blue = { 0, 0, 0 },
155 .transp = { 0, 0, 0 },
156 };
157
158 /* the waveform structure that is coming from userspace firmware */
159 struct waveform_hdr {
160 u8 stuff[32];
161
162 u8 wmta[3];
163 u8 fvsn;
164
165 u8 luts;
166 u8 mc;
167 u8 trc;
168 u8 stuff3;
169
170 u8 endb;
171 u8 swtb;
172 u8 stuff2a[2];
173
174 u8 stuff2b[3];
175 u8 wfm_cs;
176 } __attribute__ ((packed));
177
178 /* main metronomefb functions */
179 static u8 calc_cksum(int start, int end, u8 *mem)
180 {
181 u8 tmp = 0;
182 int i;
183
184 for (i = start; i < end; i++)
185 tmp += mem[i];
186
187 return tmp;
188 }
189
190 static u16 calc_img_cksum(u16 *start, int length)
191 {
192 u16 tmp = 0;
193
194 while (length--)
195 tmp += *start++;
196
197 return tmp;
198 }
199
200 /* here we decode the incoming waveform file and populate metromem */
201 static int load_waveform(u8 *mem, size_t size, int m, int t,
202 struct metronomefb_par *par)
203 {
204 int tta;
205 int wmta;
206 int trn = 0;
207 int i;
208 unsigned char v;
209 u8 cksum;
210 int cksum_idx;
211 int wfm_idx, owfm_idx;
212 int mem_idx = 0;
213 struct waveform_hdr *wfm_hdr;
214 u8 *metromem = par->metromem_wfm;
215 struct device *dev = &par->pdev->dev;
216 u8 mc, trc;
217 u16 *p;
218 u16 img_cksum;
219
220 dev_dbg(dev, "Loading waveforms, mode %d, temperature %d\n", m, t);
221
222 wfm_hdr = (struct waveform_hdr *) mem;
223
224 if (wfm_hdr->fvsn != 1) {
225 dev_err(dev, "Error: bad fvsn %x\n", wfm_hdr->fvsn);
226 return -EINVAL;
227 }
228 if (wfm_hdr->luts != 0) {
229 dev_err(dev, "Error: bad luts %x\n", wfm_hdr->luts);
230 return -EINVAL;
231 }
232 cksum = calc_cksum(32, 47, mem);
233 if (cksum != wfm_hdr->wfm_cs) {
234 dev_err(dev, "Error: bad cksum %x != %x\n", cksum,
235 wfm_hdr->wfm_cs);
236 return -EINVAL;
237 }
238 mc = wfm_hdr->mc + 1;
239 trc = wfm_hdr->trc + 1;
240
241 for (i = 0; i < 5; i++) {
242 if (*(wfm_hdr->stuff2a + i) != 0) {
243 dev_err(dev, "Error: unexpected value in padding\n");
244 return -EINVAL;
245 }
246 }
247
248 /* calculating trn. trn is something used to index into
249 the waveform. presumably selecting the right one for the
250 desired temperature. it works out the offset of the first
251 v that exceeds the specified temperature */
252 if ((sizeof(*wfm_hdr) + trc) > size)
253 return -EINVAL;
254
255 for (i = sizeof(*wfm_hdr); i <= sizeof(*wfm_hdr) + trc; i++) {
256 if (mem[i] > t) {
257 trn = i - sizeof(*wfm_hdr) - 1;
258 break;
259 }
260 }
261
262 /* check temperature range table checksum */
263 cksum_idx = sizeof(*wfm_hdr) + trc + 1;
264 if (cksum_idx > size)
265 return -EINVAL;
266 cksum = calc_cksum(sizeof(*wfm_hdr), cksum_idx, mem);
267 if (cksum != mem[cksum_idx]) {
268 dev_err(dev, "Error: bad temperature range table cksum"
269 " %x != %x\n", cksum, mem[cksum_idx]);
270 return -EINVAL;
271 }
272
273 /* check waveform mode table address checksum */
274 wmta = get_unaligned_le32(wfm_hdr->wmta) & 0x00FFFFFF;
275 cksum_idx = wmta + m*4 + 3;
276 if (cksum_idx > size)
277 return -EINVAL;
278 cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem);
279 if (cksum != mem[cksum_idx]) {
280 dev_err(dev, "Error: bad mode table address cksum"
281 " %x != %x\n", cksum, mem[cksum_idx]);
282 return -EINVAL;
283 }
284
285 /* check waveform temperature table address checksum */
286 tta = get_unaligned_le32(mem + wmta + m * 4) & 0x00FFFFFF;
287 cksum_idx = tta + trn*4 + 3;
288 if (cksum_idx > size)
289 return -EINVAL;
290 cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem);
291 if (cksum != mem[cksum_idx]) {
292 dev_err(dev, "Error: bad temperature table address cksum"
293 " %x != %x\n", cksum, mem[cksum_idx]);
294 return -EINVAL;
295 }
296
297 /* here we do the real work of putting the waveform into the
298 metromem buffer. this does runlength decoding of the waveform */
299 wfm_idx = get_unaligned_le32(mem + tta + trn * 4) & 0x00FFFFFF;
300 owfm_idx = wfm_idx;
301 if (wfm_idx > size)
302 return -EINVAL;
303 while (wfm_idx < size) {
304 unsigned char rl;
305 v = mem[wfm_idx++];
306 if (v == wfm_hdr->swtb) {
307 while (((v = mem[wfm_idx++]) != wfm_hdr->swtb) &&
308 wfm_idx < size)
309 metromem[mem_idx++] = v;
310
311 continue;
312 }
313
314 if (v == wfm_hdr->endb)
315 break;
316
317 rl = mem[wfm_idx++];
318 for (i = 0; i <= rl; i++)
319 metromem[mem_idx++] = v;
320 }
321
322 cksum_idx = wfm_idx;
323 if (cksum_idx > size)
324 return -EINVAL;
325 dev_dbg(dev, "mem_idx = %u\n", mem_idx);
326 cksum = calc_cksum(owfm_idx, cksum_idx, mem);
327 if (cksum != mem[cksum_idx]) {
328 dev_err(dev, "Error: bad waveform data cksum"
329 " %x != %x\n", cksum, mem[cksum_idx]);
330 return -EINVAL;
331 }
332 par->frame_count = (mem_idx/64);
333
334 p = (u16 *)par->metromem_wfm;
335 img_cksum = calc_img_cksum(p, 16384 / 2);
336 p[16384 / 2] = __cpu_to_le16(img_cksum);
337
338 par->current_wf_mode = m;
339 par->current_wf_temp = t;
340
341 return 0;
342 }
343
344 static int check_err(struct metronomefb_par *par)
345 {
346 int res;
347
348 res = par->board->get_err(par);
349 dev_dbg(&par->pdev->dev, "ERR = %d\n", res);
350 return res;
351 }
352
353 static inline int wait_for_rdy(struct metronomefb_par *par)
354 {
355 int res = 0;
356
357 if (!par->board->get_rdy(par))
358 res = par->board->met_wait_event_intr(par);
359
360 return res;
361 }
362
363 static int metronome_display_cmd(struct metronomefb_par *par)
364 {
365 int i;
366 u16 cs;
367 u16 opcode;
368 static u8 borderval;
369 int res;
370
371 res = wait_for_rdy(par);
372 if (res)
373 return res;
374
375 dev_dbg(&par->pdev->dev, "%s: ENTER\n", __func__);
376 /* setup display command
377 we can't immediately set the opcode since the controller
378 will try parse the command before we've set it all up
379 so we just set cs here and set the opcode at the end */
380
381 if (par->metromem_cmd->opcode == 0xCC40)
382 opcode = cs = 0xCC41;
383 else
384 opcode = cs = 0xCC40;
385
386 /* set the args ( 2 bytes ) for display */
387 i = 0;
388 par->metromem_cmd->args[i] = 0 << 3 /* border update */
389 | (3 << 4)
390 // | ((borderval++ % 4) & 0x0F) << 4
391 | (par->frame_count - 1) << 8;
392 cs += par->metromem_cmd->args[i++];
393
394 /* the rest are 0 */
395 memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2);
396
397 par->metromem_cmd->csum = cs;
398 par->metromem_cmd->opcode = opcode; /* display cmd */
399
400 return 0;
401
402 }
403
404 static int __devinit metronome_powerup_cmd(struct metronomefb_par *par)
405 {
406 int i;
407 u16 cs;
408 int res;
409
410 dev_dbg(&par->pdev->dev, "%s: ENTER\n", __func__);
411 /* setup power up command */
412 par->metromem_cmd->opcode = 0x1234; /* pwr up pseudo cmd */
413 cs = par->metromem_cmd->opcode;
414
415 /* set pwr1,2,3 to 1024 */
416 for (i = 0; i < 3; i++) {
417 // par->metromem_cmd->args[i] = 1024;
418 par->metromem_cmd->args[i] = 100;
419 cs += par->metromem_cmd->args[i];
420 }
421
422 /* the rest are 0 */
423 memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2);
424
425 par->metromem_cmd->csum = cs;
426
427 msleep(1);
428 par->board->set_rst(par, 1);
429
430 msleep(1);
431 par->board->set_stdby(par, 1);
432
433 res = par->board->met_wait_event(par);
434 dev_dbg(&par->pdev->dev, "%s: EXIT: %d\n", __func__, res);
435 return res;
436 }
437
438 static int __devinit metronome_config_cmd(struct metronomefb_par *par)
439 {
440 /* setup config command
441 we can't immediately set the opcode since the controller
442 will try parse the command before we've set it all up */
443
444 dev_dbg(&par->pdev->dev, "%s: ENTER\n", __func__);
445 memcpy(par->metromem_cmd->args, epd_frame_table[par->dt].config,
446 sizeof(epd_frame_table[par->dt].config));
447 /* the rest are 0 */
448 memset((u8 *) (par->metromem_cmd->args + 4), 0, (32-4)*2);
449
450 par->metromem_cmd->csum = 0xCC10;
451 par->metromem_cmd->csum += calc_img_cksum(par->metromem_cmd->args, 4);
452 par->metromem_cmd->opcode = 0xCC10; /* config cmd */
453
454 return par->board->met_wait_event(par);
455 }
456
457 static int __devinit metronome_init_cmd(struct metronomefb_par *par)
458 {
459 int i;
460 u16 cs;
461
462 /* setup init command
463 we can't immediately set the opcode since the controller
464 will try parse the command before we've set it all up
465 so we just set cs here and set the opcode at the end */
466
467 dev_dbg(&par->pdev->dev, "%s: ENTER\n", __func__);
468 cs = 0xCC20;
469
470 /* set the args ( 2 bytes ) for init */
471 i = 0;
472 par->metromem_cmd->args[i] = 0x0007;
473 cs += par->metromem_cmd->args[i++];
474
475 /* the rest are 0 */
476 memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2);
477
478 par->metromem_cmd->csum = cs;
479 par->metromem_cmd->opcode = 0xCC20; /* init cmd */
480
481 return par->board->met_wait_event(par);
482 }
483
484 static int metronome_bootup(struct metronomefb_par *par)
485 {
486 int res;
487
488 res = metronome_powerup_cmd(par);
489 if (res) {
490 dev_err(&par->pdev->dev, "metronomefb: POWERUP cmd failed\n");
491 goto finish;
492 }
493
494 check_err(par);
495 res = metronome_config_cmd(par);
496 if (res) {
497 dev_err(&par->pdev->dev, "metronomefb: CONFIG cmd failed\n");
498 goto finish;
499 }
500 check_err(par);
501
502 res = metronome_init_cmd(par);
503 if (res)
504 dev_err(&par->pdev->dev, "metronomefb: INIT cmd failed\n");
505 check_err(par);
506
507 finish:
508 return res;
509 }
510
511 static int __devinit metronome_init_regs(struct metronomefb_par *par)
512 {
513 int res;
514
515 if (par->board->power_ctl)
516 par->board->power_ctl(par, METRONOME_POWER_ON);
517
518 res = metronome_bootup(par);
519
520 return res;
521 }
522
523 static void metronomefb_dpy_update(struct metronomefb_par *par, int clear_all)
524 {
525 int x, y;
526 int i;
527 u16 cksum = 0;
528 u32 *buf = (u32 __force *)par->info->screen_base;
529 u32 *img = (u32 *)(par->metromem_img);
530 u32 diff;
531 u32 tmp;
532 unsigned int fbsize = par->info->fix.smem_len;
533 int fx = par->info->fix.line_length;
534 int fy = fbsize / fx;
535 int fx_buf = fx / sizeof(*buf);
536 int m;
537 static int is_first_update = 1;
538 static int partial_updates_count = 0;
539 u32 *fxbuckets = par->fxbuckets;
540 u32 *fybuckets = par->fybuckets;
541
542 wait_for_rdy(par);
543
544 memset(fxbuckets, 0, fx_buf * sizeof(*fxbuckets));
545 memset(fybuckets, 0, fy * sizeof(*fybuckets));
546
547 i = 0;
548 for (y = 0; y < fy; y++) {
549 for(x = 0; x < fx_buf; x++, i++) {
550 tmp = (buf[i] << 5) & 0xE0E0E0E0;
551 img[i] &= 0xF0F0F0F0;
552 diff = img[i] ^ tmp;
553
554 fxbuckets[x] |= diff;
555 fybuckets[y] |= diff;
556
557 img[i] = (img[i] >> 4) | tmp;
558 cksum += img[i] & 0x0000ffff;
559 cksum += (img[i] >> 16);
560 }
561 }
562
563 *((u16 *)(par->metromem_img) + fbsize/2) = cksum;
564
565 if (clear_all || is_first_update ||
566 (partial_updates_count == par->partial_autorefresh_interval)) {
567 m = WF_MODE_GC;
568 partial_updates_count = 0;
569 } else {
570 int min_x = fx_buf;
571 int max_x = 0;
572 int min_y = fy;
573 int max_y = 0;
574 int change_count;
575
576 for (x = 0; x < fx_buf; x++)
577 if(fxbuckets[x]) {
578 min_x = x;
579 break;
580 }
581
582 for (x = fx_buf - 1; x >= 0; x--)
583 if(fxbuckets[x]) {
584 max_x = x;
585 break;
586 }
587
588 for (y = 0; y < fy; y++)
589 if(fybuckets[y]) {
590 min_y = y;
591 break;
592 }
593
594 for (y = fy - 1; y >= 0; y--)
595 if(fybuckets[y]) {
596 max_y = y;
597 break;
598 }
599
600 if ((min_x > max_x) || (min_y > max_y))
601 change_count = 0;
602 else
603 change_count = (max_x - min_x + 1) * (max_y - min_y + 1) * sizeof(*buf);
604
605 if (change_count < fbsize / 100 * par->manual_refresh_threshold)
606 m = WF_MODE_GU;
607 else
608 m = WF_MODE_GC;
609
610 dev_dbg(&par->pdev->dev, "min_x = %d, max_x = %d, min_y = %d, max_y = %d\n",
611 min_x, max_x, min_y, max_y);
612 dev_dbg(&par->pdev->dev, "change_count = %u, treshold = %u%% (%u pixels)\n",
613 change_count, par->manual_refresh_threshold,
614 fbsize / 100 * par->manual_refresh_threshold);
615
616 partial_updates_count++;
617 }
618
619 if (m != par->current_wf_mode) {
620 load_waveform((u8 *) par->firmware->data, par->firmware->size,
621 m, par->current_wf_temp, par);
622 }
623
624 for(;;) {
625 if (likely(!check_err(par))) {
626 metronome_display_cmd(par);
627 break;
628 }
629
630 par->board->set_stdby(par, 0);
631 printk("Resetting Metronome\n");
632 par->board->set_rst(par, 0);
633 mdelay(1);
634 if (par->board->power_ctl)
635 par->board->power_ctl(par, METRONOME_POWER_OFF);
636
637 mdelay(1);
638 load_waveform((u8 *) par->firmware->data, par->firmware->size,
639 WF_MODE_GC, par->current_wf_temp, par);
640 if (par->board->power_ctl)
641 par->board->power_ctl(par, METRONOME_POWER_ON);
642 metronome_bootup(par);
643 }
644
645 is_first_update = 0;
646 }
647
648 /* this is called back from the deferred io workqueue */
649 static void metronomefb_dpy_deferred_io(struct fb_info *info,
650 struct list_head *pagelist)
651 {
652 struct metronomefb_par *par = info->par;
653
654 /* We will update entire display because we need to change
655 * 'previous image' field in pixels which was changed at
656 * previous refresh
657 */
658 mutex_lock(&par->lock);
659 metronomefb_dpy_update(par, 0);
660 mutex_unlock(&par->lock);
661 }
662
663 static void metronomefb_fillrect(struct fb_info *info,
664 const struct fb_fillrect *rect)
665 {
666 struct metronomefb_par *par = info->par;
667
668 mutex_lock(&par->lock);
669 sys_fillrect(info, rect);
670 metronomefb_dpy_update(par, 0);
671 mutex_unlock(&par->lock);
672 }
673
674 static void metronomefb_copyarea(struct fb_info *info,
675 const struct fb_copyarea *area)
676 {
677 struct metronomefb_par *par = info->par;
678
679 mutex_lock(&par->lock);
680 sys_copyarea(info, area);
681 metronomefb_dpy_update(par, 0);
682 mutex_unlock(&par->lock);
683 }
684
685 static void metronomefb_imageblit(struct fb_info *info,
686 const struct fb_image *image)
687 {
688 struct metronomefb_par *par = info->par;
689
690 mutex_lock(&par->lock);
691 sys_imageblit(info, image);
692 metronomefb_dpy_update(par, 0);
693 mutex_unlock(&par->lock);
694 }
695
696 /*
697 * this is the slow path from userspace. they can seek and write to
698 * the fb. it is based on fb_sys_write
699 */
700 static ssize_t metronomefb_write(struct fb_info *info, const char __user *buf,
701 size_t count, loff_t *ppos)
702 {
703 struct metronomefb_par *par = info->par;
704 unsigned long p = *ppos;
705 void *dst;
706 int err = 0;
707 unsigned long total_size;
708
709 if (info->state != FBINFO_STATE_RUNNING)
710 return -EPERM;
711
712 total_size = info->fix.smem_len;
713
714 if (p > total_size)
715 return -EFBIG;
716
717 if (count > total_size) {
718 err = -EFBIG;
719 count = total_size;
720 }
721
722 if (count + p > total_size) {
723 if (!err)
724 err = -ENOSPC;
725
726 count = total_size - p;
727 }
728
729 dst = (void __force *)(info->screen_base + p);
730
731 mutex_lock(&par->lock);
732
733 if (copy_from_user(dst, buf, count))
734 err = -EFAULT;
735
736 if (!err)
737 *ppos += count;
738
739 metronomefb_dpy_update(par, 0);
740 mutex_unlock(&par->lock);
741
742 return (err) ? err : count;
743 }
744
745 static struct fb_ops metronomefb_ops = {
746 .owner = THIS_MODULE,
747 .fb_write = metronomefb_write,
748 .fb_fillrect = metronomefb_fillrect,
749 .fb_copyarea = metronomefb_copyarea,
750 .fb_imageblit = metronomefb_imageblit,
751 };
752
753 static struct fb_deferred_io metronomefb_defio = {
754 .delay = HZ / 4,
755 .deferred_io = metronomefb_dpy_deferred_io,
756 };
757
758 static ssize_t metronomefb_defio_delay_show(struct device *dev,
759 struct device_attribute *attr, char *buf)
760 {
761 struct fb_info *info = dev_get_drvdata(dev);
762
763 sprintf(buf, "%lu\n", info->fbdefio->delay * 1000 / HZ);
764 return strlen(buf) + 1;
765 }
766
767 static ssize_t metronomefb_defio_delay_store(struct device *dev,
768 struct device_attribute *attr, const char *buf, size_t size)
769 {
770 struct fb_info *info = dev_get_drvdata(dev);
771 char *after;
772 unsigned long state = simple_strtoul(buf, &after, 10);
773 size_t count = after - buf;
774 ssize_t ret = -EINVAL;
775
776 if (*after && isspace(*after))
777 count++;
778
779 state = state * HZ / 1000;
780
781 if (!state)
782 state = 1;
783
784 if (count == size) {
785 ret = count;
786 info->fbdefio->delay = state;
787 }
788
789 return ret;
790 }
791
792 static ssize_t metronomefb_manual_refresh_thr_show(struct device *dev,
793 struct device_attribute *attr, char *buf)
794 {
795 struct fb_info *info = dev_get_drvdata(dev);
796 struct metronomefb_par *par = info->par;
797
798 return sprintf(buf, "%u\n", par->manual_refresh_threshold);
799 }
800
801 static ssize_t metronomefb_manual_refresh_thr_store(struct device *dev,
802 struct device_attribute *attr, const char *buf, size_t size)
803 {
804 struct fb_info *info = dev_get_drvdata(dev);
805 struct metronomefb_par *par = info->par;
806 char *after;
807 unsigned long val = simple_strtoul(buf, &after, 10);
808 size_t count = after - buf;
809 ssize_t ret = -EINVAL;
810
811 if (*after && isspace(*after))
812 count++;
813
814 if (val > 100)
815 return -EINVAL;
816
817
818 if (count == size) {
819 ret = count;
820 par->manual_refresh_threshold = val;
821 }
822
823 return ret;
824 }
825
826 static ssize_t metronomefb_autorefresh_interval_show(struct device *dev,
827 struct device_attribute *attr, char *buf)
828 {
829 struct fb_info *info = dev_get_drvdata(dev);
830 struct metronomefb_par *par = info->par;
831
832 return sprintf(buf, "%u\n", par->partial_autorefresh_interval);
833 }
834
835 static ssize_t metronomefb_autorefresh_interval_store(struct device *dev,
836 struct device_attribute *attr, const char *buf, size_t size)
837 {
838 struct fb_info *info = dev_get_drvdata(dev);
839 struct metronomefb_par *par = info->par;
840 char *after;
841 unsigned long val = simple_strtoul(buf, &after, 10);
842 size_t count = after - buf;
843 ssize_t ret = -EINVAL;
844
845 if (*after && isspace(*after))
846 count++;
847
848 if (val > 100)
849 return -EINVAL;
850
851
852 if (count == size) {
853 ret = count;
854 par->partial_autorefresh_interval = val;
855 }
856
857 return ret;
858 }
859
860 static ssize_t metronomefb_temp_show(struct device *dev,
861 struct device_attribute *attr, char *buf)
862 {
863 struct fb_info *info = dev_get_drvdata(dev);
864 struct metronomefb_par *par = info->par;
865
866 return sprintf(buf, "%u\n", par->current_wf_temp);
867 }
868
869 static ssize_t metronomefb_temp_store(struct device *dev,
870 struct device_attribute *attr, const char *buf, size_t size)
871 {
872 struct fb_info *info = dev_get_drvdata(dev);
873 struct metronomefb_par *par = info->par;
874 char *after;
875 unsigned long val = simple_strtoul(buf, &after, 10);
876 size_t count = after - buf;
877 ssize_t ret = -EINVAL;
878
879 if (*after && isspace(*after))
880 count++;
881
882 if (val > 100)
883 return -EINVAL;
884
885
886 if (count == size) {
887 ret = count;
888 if (val != par->current_wf_temp)
889 load_waveform((u8 *) par->firmware->data, par->firmware->size,
890 par->current_wf_mode, val, par);
891 }
892
893 return ret;
894 }
895
896 DEVICE_ATTR(defio_delay, 0644,
897 metronomefb_defio_delay_show, metronomefb_defio_delay_store);
898 DEVICE_ATTR(manual_refresh_threshold, 0644,
899 metronomefb_manual_refresh_thr_show, metronomefb_manual_refresh_thr_store);
900 DEVICE_ATTR(temp, 0644,
901 metronomefb_temp_show, metronomefb_temp_store);
902 DEVICE_ATTR(autorefresh_interval, 0644,
903 metronomefb_autorefresh_interval_show, metronomefb_autorefresh_interval_store);
904
905
906 static int __devinit metronomefb_probe(struct platform_device *dev)
907 {
908 struct fb_info *info;
909 struct metronome_board *board;
910 int retval = -ENOMEM;
911 int videomemorysize;
912 unsigned char *videomemory;
913 struct metronomefb_par *par;
914 const struct firmware *fw_entry;
915 int i;
916 int panel_type;
917 int fw, fh;
918 int epd_dt_index;
919
920 /* pick up board specific routines */
921 board = dev->dev.platform_data;
922 if (!board)
923 return -EINVAL;
924
925 /* try to count device specific driver, if can't, platform recalls */
926 if (!try_module_get(board->owner))
927 return -ENODEV;
928
929 info = framebuffer_alloc(sizeof(struct metronomefb_par), &dev->dev);
930 if (!info)
931 goto err;
932
933 /* we have two blocks of memory.
934 info->screen_base which is vm, and is the fb used by apps.
935 par->metromem which is physically contiguous memory and
936 contains the display controller commands, waveform,
937 processed image data and padding. this is the data pulled
938 by the device's LCD controller and pushed to Metronome.
939 the metromem memory is allocated by the board driver and
940 is provided to us */
941
942 panel_type = board->get_panel_type();
943 switch (panel_type) {
944 case 5:
945 epd_dt_index = 3;
946 break;
947 case 6:
948 epd_dt_index = 0;
949 break;
950 case 8:
951 epd_dt_index = 1;
952 break;
953 case 97:
954 epd_dt_index = 2;
955 break;
956 default:
957 dev_err(&dev->dev, "Unexpected panel type. Defaulting to 6\n");
958 epd_dt_index = 0;
959 break;
960 }
961
962 fw = epd_frame_table[epd_dt_index].fw;
963 fh = epd_frame_table[epd_dt_index].fh;
964
965 /* we need to add a spare page because our csum caching scheme walks
966 * to the end of the page */
967 videomemorysize = PAGE_SIZE + (fw * fh);
968 videomemory = vmalloc(videomemorysize);
969 if (!videomemory)
970 goto err_fb_rel;
971
972 memset(videomemory, 0xff, videomemorysize);
973
974 info->screen_base = (char __force __iomem *)videomemory;
975 info->fbops = &metronomefb_ops;
976
977 info->var = metronomefb_var;
978 info->var.xres = fw;
979 info->var.yres = fh;
980 info->var.xres_virtual = fw;
981 info->var.yres_virtual = fh;
982
983 info->fix = metronomefb_fix;
984 info->fix.smem_len = fw * fh; /* Real size of image area */
985 info->fix.line_length = fw;
986
987 par = info->par;
988 par->info = info;
989 par->board = board;
990 par->dt = epd_dt_index;
991 par->pdev = dev;
992
993 par->fxbuckets = kmalloc((fw / 4 + 1) * sizeof(*par->fxbuckets), GFP_KERNEL);
994 if (!par->fxbuckets)
995 goto err_vfree;
996
997 par->fybuckets = kmalloc(fh * sizeof(*par->fybuckets), GFP_KERNEL);
998 if (!par->fybuckets)
999 goto err_fxbuckets;
1000
1001 init_waitqueue_head(&par->waitq);
1002 par->manual_refresh_threshold = 60;
1003 par->partial_autorefresh_interval = 256;
1004 mutex_init(&par->lock);
1005
1006 /* this table caches per page csum values. */
1007 par->csum_table = vmalloc(videomemorysize/PAGE_SIZE);
1008 if (!par->csum_table)
1009 goto err_fybuckets;
1010
1011 /* the physical framebuffer that we use is setup by
1012 * the platform device driver. It will provide us
1013 * with cmd, wfm and image memory in a contiguous area. */
1014 retval = board->setup_fb(par);
1015 if (retval) {
1016 dev_err(&dev->dev, "Failed to setup fb\n");
1017 goto err_csum_table;
1018 }
1019
1020 /* after this point we should have a framebuffer */
1021 if ((!par->metromem_wfm) || (!par->metromem_img) ||
1022 (!par->metromem_dma)) {
1023 dev_err(&dev->dev, "fb access failure\n");
1024 retval = -EINVAL;
1025 goto err_csum_table;
1026 }
1027
1028 info->fix.smem_start = 0;
1029
1030 /* load the waveform in. assume mode 3, temp 31 for now
1031 a) request the waveform file from userspace
1032 b) process waveform and decode into metromem */
1033 retval = request_firmware(&fw_entry, "metronome.wbf", &dev->dev);
1034 if (retval < 0) {
1035 dev_err(&dev->dev, "Failed to get waveform\n");
1036 goto err_csum_table;
1037 }
1038
1039 retval = load_waveform((u8 *) fw_entry->data, fw_entry->size, WF_MODE_GC, temp,
1040 par);
1041 if (retval < 0) {
1042 dev_err(&dev->dev, "Failed processing waveform\n");
1043 goto err_csum_table;
1044 }
1045 par->firmware = fw_entry;
1046
1047 retval = board->setup_io(par);
1048 if (retval) {
1049 dev_err(&dev->dev, "metronomefb: setup_io() failed\n");
1050 goto err_csum_table;
1051 }
1052
1053 if (board->setup_irq(info))
1054 goto err_csum_table;
1055
1056 retval = metronome_init_regs(par);
1057 if (retval < 0)
1058 goto err_free_irq;
1059
1060 info->flags = FBINFO_FLAG_DEFAULT;
1061
1062 info->fbdefio = &metronomefb_defio;
1063 fb_deferred_io_init(info);
1064
1065 retval = fb_alloc_cmap(&info->cmap, 8, 0);
1066 if (retval < 0) {
1067 dev_err(&dev->dev, "Failed to allocate colormap\n");
1068 goto err_free_irq;
1069 }
1070
1071 /* set cmap */
1072 for (i = 0; i < 8; i++)
1073 info->cmap.red[i] = ((2 * i + 1)*(0xFFFF))/16;
1074 memcpy(info->cmap.green, info->cmap.red, sizeof(u16)*8);
1075 memcpy(info->cmap.blue, info->cmap.red, sizeof(u16)*8);
1076
1077 retval = register_framebuffer(info);
1078 if (retval < 0)
1079 goto err_cmap;
1080
1081 platform_set_drvdata(dev, info);
1082
1083 retval = device_create_file(info->dev, &dev_attr_defio_delay);
1084 if (retval)
1085 goto err_devattr_defio_delay;
1086
1087 retval = device_create_file(info->dev, &dev_attr_manual_refresh_threshold);
1088 if (retval)
1089 goto err_devattr_manual_refresh_thr;
1090
1091 retval = device_create_file(info->dev, &dev_attr_temp);
1092 if (retval)
1093 goto err_devattr_temp;
1094
1095 retval = device_create_file(info->dev, &dev_attr_autorefresh_interval);
1096 if (retval)
1097 goto err_devattr_autorefresh;
1098
1099 dev_info(&dev->dev,
1100 "fb%d: Metronome frame buffer device, using %dK of video"
1101 " memory\n", info->node, videomemorysize >> 10);
1102
1103 return 0;
1104
1105 device_remove_file(info->dev, &dev_attr_autorefresh_interval);
1106 err_devattr_autorefresh:
1107 device_remove_file(info->dev, &dev_attr_temp);
1108 err_devattr_temp:
1109 device_remove_file(info->dev, &dev_attr_manual_refresh_threshold);
1110 err_devattr_manual_refresh_thr:
1111 device_remove_file(info->dev, &dev_attr_defio_delay);
1112 err_devattr_defio_delay:
1113 unregister_framebuffer(info);
1114 err_cmap:
1115 fb_dealloc_cmap(&info->cmap);
1116 err_free_irq:
1117 board->cleanup(par);
1118 err_csum_table:
1119 vfree(par->csum_table);
1120 err_fybuckets:
1121 kfree(par->fybuckets);
1122 err_fxbuckets:
1123 kfree(par->fxbuckets);
1124 err_vfree:
1125 vfree(videomemory);
1126 err_fb_rel:
1127 framebuffer_release(info);
1128 err:
1129 module_put(board->owner);
1130 return retval;
1131 }
1132
1133 static int __devexit metronomefb_remove(struct platform_device *dev)
1134 {
1135 struct fb_info *info = platform_get_drvdata(dev);
1136
1137 if (info) {
1138 struct metronomefb_par *par = info->par;
1139
1140 par->board->set_stdby(par, 0);
1141 mdelay(1);
1142 if (par->board->power_ctl)
1143 par->board->power_ctl(par, METRONOME_POWER_OFF);
1144
1145 device_remove_file(info->dev, &dev_attr_autorefresh_interval);
1146 device_remove_file(info->dev, &dev_attr_temp);
1147 device_remove_file(info->dev, &dev_attr_manual_refresh_threshold);
1148 device_remove_file(info->dev, &dev_attr_defio_delay);
1149 unregister_framebuffer(info);
1150 fb_deferred_io_cleanup(info);
1151 fb_dealloc_cmap(&info->cmap);
1152 par->board->cleanup(par);
1153 vfree(par->csum_table);
1154 kfree(par->fybuckets);
1155 kfree(par->fxbuckets);
1156 vfree((void __force *)info->screen_base);
1157 module_put(par->board->owner);
1158 release_firmware(par->firmware);
1159 dev_dbg(&dev->dev, "calling release\n");
1160 framebuffer_release(info);
1161 }
1162 return 0;
1163 }
1164
1165 #ifdef CONFIG_PM
1166 static int metronomefb_suspend(struct platform_device *pdev, pm_message_t message)
1167 {
1168 struct fb_info *info = platform_get_drvdata(pdev);
1169 struct metronomefb_par *par = info->par;
1170
1171 par->board->set_stdby(par, 0);
1172 par->board->set_rst(par, 0);
1173 if (par->board->power_ctl)
1174 par->board->power_ctl(par, METRONOME_POWER_OFF);
1175
1176 return 0;
1177 }
1178
1179 static int metronomefb_resume(struct platform_device *pdev)
1180 {
1181 struct fb_info *info = platform_get_drvdata(pdev);
1182 struct metronomefb_par *par = info->par;
1183
1184 if (par->board->power_ctl)
1185 par->board->power_ctl(par, METRONOME_POWER_ON);
1186
1187 mutex_lock(&par->lock);
1188 metronome_bootup(par);
1189 mutex_unlock(&par->lock);
1190
1191 return 0;
1192 }
1193
1194 #else
1195 #define metronomefb_suspend NULL
1196 #define metronomefb_resume NULL
1197 #endif
1198
1199
1200 static struct platform_driver metronomefb_driver = {
1201 .driver = {
1202 .owner = THIS_MODULE,
1203 .name = "metronomefb",
1204 },
1205 .probe = metronomefb_probe,
1206 .remove = __devexit_p(metronomefb_remove),
1207 .suspend = metronomefb_suspend,
1208 .resume = metronomefb_resume,
1209 };
1210
1211 static int __init metronomefb_init(void)
1212 {
1213 return platform_driver_register(&metronomefb_driver);
1214 }
1215
1216 static void __exit metronomefb_exit(void)
1217 {
1218 platform_driver_unregister(&metronomefb_driver);
1219 }
1220
1221 module_param(temp, int, 0);
1222 MODULE_PARM_DESC(temp, "Set current temperature");
1223
1224 module_init(metronomefb_init);
1225 module_exit(metronomefb_exit);
1226
1227 MODULE_DESCRIPTION("fbdev driver for Metronome controller");
1228 MODULE_AUTHOR("Jaya Kumar");
1229 MODULE_LICENSE("GPL");
This page took 0.115742 seconds and 3 git commands to generate.