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