iwlwifi: introduce host commands callbacks
[linux/fpc-iii.git] / drivers / video / metronomefb.c
blobe9a89fd82757c606ea93001f986ca06225b9384f
1 /*
2 * linux/drivers/video/metronomefb.c -- FB driver for Metronome controller
4 * Copyright (C) 2008, Jaya Kumar
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.
10 * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven.
12 * This work was made possible by help and equipment support from E-Ink
13 * Corporation. http://support.eink.com/community
15 * This driver is written to be used with the Metronome display controller.
16 * It was tested with an E-Ink 800x600 Vizplex EPD on a Gumstix Connex board
17 * using the Lyre interface board.
19 * General notes:
20 * - User must set metronomefb_enable=1 to enable it.
21 * - See Documentation/fb/metronomefb.txt for how metronome works.
23 #include <linux/module.h>
24 #include <linux/kernel.h>
25 #include <linux/errno.h>
26 #include <linux/string.h>
27 #include <linux/mm.h>
28 #include <linux/slab.h>
29 #include <linux/vmalloc.h>
30 #include <linux/delay.h>
31 #include <linux/interrupt.h>
32 #include <linux/fb.h>
33 #include <linux/init.h>
34 #include <linux/platform_device.h>
35 #include <linux/list.h>
36 #include <linux/firmware.h>
37 #include <linux/dma-mapping.h>
38 #include <linux/uaccess.h>
39 #include <linux/irq.h>
41 #include <asm/arch/pxa-regs.h>
42 #include <asm/unaligned.h>
44 #define DEBUG 1
45 #ifdef DEBUG
46 #define DPRINTK(f, a...) printk(KERN_DEBUG "%s: " f, __func__ , ## a)
47 #else
48 #define DPRINTK(f, a...)
49 #endif
52 /* Display specific information */
53 #define DPY_W 832
54 #define DPY_H 622
56 struct metromem_desc {
57 u32 mFDADR0;
58 u32 mFSADR0;
59 u32 mFIDR0;
60 u32 mLDCMD0;
63 struct metromem_cmd {
64 u16 opcode;
65 u16 args[((64-2)/2)];
66 u16 csum;
69 struct metronomefb_par {
70 unsigned char *metromem;
71 struct metromem_desc *metromem_desc;
72 struct metromem_cmd *metromem_cmd;
73 unsigned char *metromem_wfm;
74 unsigned char *metromem_img;
75 u16 *metromem_img_csum;
76 u16 *csum_table;
77 int metromemsize;
78 dma_addr_t metromem_dma;
79 dma_addr_t metromem_desc_dma;
80 struct fb_info *info;
81 wait_queue_head_t waitq;
82 u8 frame_count;
85 /* frame differs from image. frame includes non-visible pixels */
86 struct epd_frame {
87 int fw; /* frame width */
88 int fh; /* frame height */
91 static struct epd_frame epd_frame_table[] = {
93 .fw = 832,
94 .fh = 622
98 static struct fb_fix_screeninfo metronomefb_fix __devinitdata = {
99 .id = "metronomefb",
100 .type = FB_TYPE_PACKED_PIXELS,
101 .visual = FB_VISUAL_STATIC_PSEUDOCOLOR,
102 .xpanstep = 0,
103 .ypanstep = 0,
104 .ywrapstep = 0,
105 .line_length = DPY_W,
106 .accel = FB_ACCEL_NONE,
109 static struct fb_var_screeninfo metronomefb_var __devinitdata = {
110 .xres = DPY_W,
111 .yres = DPY_H,
112 .xres_virtual = DPY_W,
113 .yres_virtual = DPY_H,
114 .bits_per_pixel = 8,
115 .grayscale = 1,
116 .nonstd = 1,
117 .red = { 4, 3, 0 },
118 .green = { 0, 0, 0 },
119 .blue = { 0, 0, 0 },
120 .transp = { 0, 0, 0 },
123 static unsigned int metronomefb_enable;
125 struct waveform_hdr {
126 u8 stuff[32];
128 u8 wmta[3];
129 u8 fvsn;
131 u8 luts;
132 u8 mc;
133 u8 trc;
134 u8 stuff3;
136 u8 endb;
137 u8 swtb;
138 u8 stuff2a[2];
140 u8 stuff2b[3];
141 u8 wfm_cs;
142 } __attribute__ ((packed));
144 /* main metronomefb functions */
145 static u8 calc_cksum(int start, int end, u8 *mem)
147 u8 tmp = 0;
148 int i;
150 for (i = start; i < end; i++)
151 tmp += mem[i];
153 return tmp;
156 static u16 calc_img_cksum(u16 *start, int length)
158 u16 tmp = 0;
160 while (length--)
161 tmp += *start++;
163 return tmp;
166 /* here we decode the incoming waveform file and populate metromem */
167 #define EXP_WFORM_SIZE 47001
168 static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t,
169 u8 *frame_count)
171 int tta;
172 int wmta;
173 int trn = 0;
174 int i;
175 unsigned char v;
176 u8 cksum;
177 int cksum_idx;
178 int wfm_idx, owfm_idx;
179 int mem_idx = 0;
180 struct waveform_hdr *wfm_hdr;
182 if (size != EXP_WFORM_SIZE) {
183 printk(KERN_ERR "Error: unexpected size %d != %d\n", size,
184 EXP_WFORM_SIZE);
185 return -EINVAL;
188 wfm_hdr = (struct waveform_hdr *) mem;
190 if (wfm_hdr->fvsn != 1) {
191 printk(KERN_ERR "Error: bad fvsn %x\n", wfm_hdr->fvsn);
192 return -EINVAL;
194 if (wfm_hdr->luts != 0) {
195 printk(KERN_ERR "Error: bad luts %x\n", wfm_hdr->luts);
196 return -EINVAL;
198 cksum = calc_cksum(32, 47, mem);
199 if (cksum != wfm_hdr->wfm_cs) {
200 printk(KERN_ERR "Error: bad cksum %x != %x\n", cksum,
201 wfm_hdr->wfm_cs);
202 return -EINVAL;
204 wfm_hdr->mc += 1;
205 wfm_hdr->trc += 1;
206 for (i = 0; i < 5; i++) {
207 if (*(wfm_hdr->stuff2a + i) != 0) {
208 printk(KERN_ERR "Error: unexpected value in padding\n");
209 return -EINVAL;
213 /* calculating trn. trn is something used to index into
214 the waveform. presumably selecting the right one for the
215 desired temperature. it works out the offset of the first
216 v that exceeds the specified temperature */
217 if ((sizeof(*wfm_hdr) + wfm_hdr->trc) > size)
218 return -EINVAL;
220 for (i = sizeof(*wfm_hdr); i <= sizeof(*wfm_hdr) + wfm_hdr->trc; i++) {
221 if (mem[i] > t) {
222 trn = i - sizeof(*wfm_hdr) - 1;
223 break;
227 /* check temperature range table checksum */
228 cksum_idx = sizeof(*wfm_hdr) + wfm_hdr->trc + 1;
229 if (cksum_idx > size)
230 return -EINVAL;
231 cksum = calc_cksum(sizeof(*wfm_hdr), cksum_idx, mem);
232 if (cksum != mem[cksum_idx]) {
233 printk(KERN_ERR "Error: bad temperature range table cksum"
234 " %x != %x\n", cksum, mem[cksum_idx]);
235 return -EINVAL;
238 /* check waveform mode table address checksum */
239 wmta = le32_to_cpu(get_unaligned((__le32 *) wfm_hdr->wmta));
240 wmta &= 0x00FFFFFF;
241 cksum_idx = wmta + m*4 + 3;
242 if (cksum_idx > size)
243 return -EINVAL;
244 cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem);
245 if (cksum != mem[cksum_idx]) {
246 printk(KERN_ERR "Error: bad mode table address cksum"
247 " %x != %x\n", cksum, mem[cksum_idx]);
248 return -EINVAL;
251 /* check waveform temperature table address checksum */
252 tta = le32_to_cpu(get_unaligned((int *) (mem + wmta + m*4)));
253 tta &= 0x00FFFFFF;
254 cksum_idx = tta + trn*4 + 3;
255 if (cksum_idx > size)
256 return -EINVAL;
257 cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem);
258 if (cksum != mem[cksum_idx]) {
259 printk(KERN_ERR "Error: bad temperature table address cksum"
260 " %x != %x\n", cksum, mem[cksum_idx]);
261 return -EINVAL;
264 /* here we do the real work of putting the waveform into the
265 metromem buffer. this does runlength decoding of the waveform */
266 wfm_idx = le32_to_cpu(get_unaligned((__le32 *) (mem + tta + trn*4)));
267 wfm_idx &= 0x00FFFFFF;
268 owfm_idx = wfm_idx;
269 if (wfm_idx > size)
270 return -EINVAL;
271 while (wfm_idx < size) {
272 unsigned char rl;
273 v = mem[wfm_idx++];
274 if (v == wfm_hdr->swtb) {
275 while (((v = mem[wfm_idx++]) != wfm_hdr->swtb) &&
276 wfm_idx < size)
277 metromem[mem_idx++] = v;
279 continue;
282 if (v == wfm_hdr->endb)
283 break;
285 rl = mem[wfm_idx++];
286 for (i = 0; i <= rl; i++)
287 metromem[mem_idx++] = v;
290 cksum_idx = wfm_idx;
291 if (cksum_idx > size)
292 return -EINVAL;
293 cksum = calc_cksum(owfm_idx, cksum_idx, mem);
294 if (cksum != mem[cksum_idx]) {
295 printk(KERN_ERR "Error: bad waveform data cksum"
296 " %x != %x\n", cksum, mem[cksum_idx]);
297 return -EINVAL;
299 *frame_count = (mem_idx/64);
301 return 0;
304 /* register offsets for gpio control */
305 #define LED_GPIO_PIN 51
306 #define STDBY_GPIO_PIN 48
307 #define RST_GPIO_PIN 49
308 #define RDY_GPIO_PIN 32
309 #define ERR_GPIO_PIN 17
310 #define PCBPWR_GPIO_PIN 16
312 #define AF_SEL_GPIO_N 0x3
313 #define GAFR0_U_OFFSET(pin) ((pin - 16) * 2)
314 #define GAFR1_L_OFFSET(pin) ((pin - 32) * 2)
315 #define GAFR1_U_OFFSET(pin) ((pin - 48) * 2)
316 #define GPDR1_OFFSET(pin) (pin - 32)
317 #define GPCR1_OFFSET(pin) (pin - 32)
318 #define GPSR1_OFFSET(pin) (pin - 32)
319 #define GPCR0_OFFSET(pin) (pin)
320 #define GPSR0_OFFSET(pin) (pin)
322 static void metronome_set_gpio_output(int pin, int val)
324 u8 index;
326 index = pin >> 4;
328 switch (index) {
329 case 1:
330 if (val)
331 GPSR0 |= (1 << GPSR0_OFFSET(pin));
332 else
333 GPCR0 |= (1 << GPCR0_OFFSET(pin));
334 break;
335 case 2:
336 break;
337 case 3:
338 if (val)
339 GPSR1 |= (1 << GPSR1_OFFSET(pin));
340 else
341 GPCR1 |= (1 << GPCR1_OFFSET(pin));
342 break;
343 default:
344 printk(KERN_ERR "unimplemented\n");
348 static void __devinit metronome_init_gpio_pin(int pin, int dir)
350 u8 index;
351 /* dir 0 is output, 1 is input
352 - do 2 things here:
353 - set gpio alternate function to standard gpio
354 - set gpio direction to input or output */
356 index = pin >> 4;
357 switch (index) {
358 case 1:
359 GAFR0_U &= ~(AF_SEL_GPIO_N << GAFR0_U_OFFSET(pin));
361 if (dir)
362 GPDR0 &= ~(1 << pin);
363 else
364 GPDR0 |= (1 << pin);
365 break;
366 case 2:
367 GAFR1_L &= ~(AF_SEL_GPIO_N << GAFR1_L_OFFSET(pin));
369 if (dir)
370 GPDR1 &= ~(1 << GPDR1_OFFSET(pin));
371 else
372 GPDR1 |= (1 << GPDR1_OFFSET(pin));
373 break;
374 case 3:
375 GAFR1_U &= ~(AF_SEL_GPIO_N << GAFR1_U_OFFSET(pin));
377 if (dir)
378 GPDR1 &= ~(1 << GPDR1_OFFSET(pin));
379 else
380 GPDR1 |= (1 << GPDR1_OFFSET(pin));
381 break;
382 default:
383 printk(KERN_ERR "unimplemented\n");
387 static void __devinit metronome_init_gpio_regs(void)
389 metronome_init_gpio_pin(LED_GPIO_PIN, 0);
390 metronome_set_gpio_output(LED_GPIO_PIN, 0);
392 metronome_init_gpio_pin(STDBY_GPIO_PIN, 0);
393 metronome_set_gpio_output(STDBY_GPIO_PIN, 0);
395 metronome_init_gpio_pin(RST_GPIO_PIN, 0);
396 metronome_set_gpio_output(RST_GPIO_PIN, 0);
398 metronome_init_gpio_pin(RDY_GPIO_PIN, 1);
400 metronome_init_gpio_pin(ERR_GPIO_PIN, 1);
402 metronome_init_gpio_pin(PCBPWR_GPIO_PIN, 0);
403 metronome_set_gpio_output(PCBPWR_GPIO_PIN, 0);
406 static void metronome_disable_lcd_controller(struct metronomefb_par *par)
408 LCSR = 0xffffffff; /* Clear LCD Status Register */
409 LCCR0 |= LCCR0_DIS; /* Disable LCD Controller */
411 /* we reset and just wait for things to settle */
412 msleep(200);
415 static void metronome_enable_lcd_controller(struct metronomefb_par *par)
417 LCSR = 0xffffffff;
418 FDADR0 = par->metromem_desc_dma;
419 LCCR0 |= LCCR0_ENB;
422 static void __devinit metronome_init_lcdc_regs(struct metronomefb_par *par)
424 /* here we do:
425 - disable the lcd controller
426 - setup lcd control registers
427 - setup dma descriptor
428 - reenable lcd controller
431 /* disable the lcd controller */
432 metronome_disable_lcd_controller(par);
434 /* setup lcd control registers */
435 LCCR0 = LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM | LCCR0_PAS
436 | LCCR0_QDM | LCCR0_BM | LCCR0_OUM;
438 LCCR1 = (epd_frame_table[0].fw/2 - 1) /* pixels per line */
439 | (27 << 10) /* hsync pulse width - 1 */
440 | (33 << 16) /* eol pixel count */
441 | (33 << 24); /* bol pixel count */
443 LCCR2 = (epd_frame_table[0].fh - 1) /* lines per panel */
444 | (24 << 10) /* vsync pulse width - 1 */
445 | (2 << 16) /* eof pixel count */
446 | (0 << 24); /* bof pixel count */
448 LCCR3 = 2 /* pixel clock divisor */
449 | (24 << 8) /* AC Bias pin freq */
450 | LCCR3_16BPP /* BPP */
451 | LCCR3_PCP; /* PCP falling edge */
453 /* setup dma descriptor */
454 par->metromem_desc->mFDADR0 = par->metromem_desc_dma;
455 par->metromem_desc->mFSADR0 = par->metromem_dma;
456 par->metromem_desc->mFIDR0 = 0;
457 par->metromem_desc->mLDCMD0 = epd_frame_table[0].fw
458 * epd_frame_table[0].fh;
459 /* reenable lcd controller */
460 metronome_enable_lcd_controller(par);
463 static int metronome_display_cmd(struct metronomefb_par *par)
465 int i;
466 u16 cs;
467 u16 opcode;
468 static u8 borderval;
469 u8 *ptr;
471 /* setup display command
472 we can't immediately set the opcode since the controller
473 will try parse the command before we've set it all up
474 so we just set cs here and set the opcode at the end */
476 ptr = par->metromem;
478 if (par->metromem_cmd->opcode == 0xCC40)
479 opcode = cs = 0xCC41;
480 else
481 opcode = cs = 0xCC40;
483 /* set the args ( 2 bytes ) for display */
484 i = 0;
485 par->metromem_cmd->args[i] = 1 << 3 /* border update */
486 | ((borderval++ % 4) & 0x0F) << 4
487 | (par->frame_count - 1) << 8;
488 cs += par->metromem_cmd->args[i++];
490 /* the rest are 0 */
491 memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2);
493 par->metromem_cmd->csum = cs;
494 par->metromem_cmd->opcode = opcode; /* display cmd */
496 i = wait_event_interruptible_timeout(par->waitq, (GPLR1 & 0x01), HZ);
497 return i;
500 static int __devinit metronome_powerup_cmd(struct metronomefb_par *par)
502 int i;
503 u16 cs;
505 /* setup power up command */
506 par->metromem_cmd->opcode = 0x1234; /* pwr up pseudo cmd */
507 cs = par->metromem_cmd->opcode;
509 /* set pwr1,2,3 to 1024 */
510 for (i = 0; i < 3; i++) {
511 par->metromem_cmd->args[i] = 1024;
512 cs += par->metromem_cmd->args[i];
515 /* the rest are 0 */
516 memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2);
518 par->metromem_cmd->csum = cs;
520 msleep(1);
521 metronome_set_gpio_output(RST_GPIO_PIN, 1);
523 msleep(1);
524 metronome_set_gpio_output(STDBY_GPIO_PIN, 1);
526 i = wait_event_timeout(par->waitq, (GPLR1 & 0x01), HZ);
527 return i;
530 static int __devinit metronome_config_cmd(struct metronomefb_par *par)
532 int i;
533 u16 cs;
535 /* setup config command
536 we can't immediately set the opcode since the controller
537 will try parse the command before we've set it all up
538 so we just set cs here and set the opcode at the end */
540 cs = 0xCC10;
542 /* set the 12 args ( 8 bytes ) for config. see spec for meanings */
543 i = 0;
544 par->metromem_cmd->args[i] = 15 /* sdlew */
545 | 2 << 8 /* sdosz */
546 | 0 << 11 /* sdor */
547 | 0 << 12 /* sdces */
548 | 0 << 15; /* sdcer */
549 cs += par->metromem_cmd->args[i++];
551 par->metromem_cmd->args[i] = 42 /* gdspl */
552 | 1 << 8 /* gdr1 */
553 | 1 << 9 /* sdshr */
554 | 0 << 15; /* gdspp */
555 cs += par->metromem_cmd->args[i++];
557 par->metromem_cmd->args[i] = 18 /* gdspw */
558 | 0 << 15; /* dispc */
559 cs += par->metromem_cmd->args[i++];
561 par->metromem_cmd->args[i] = 599 /* vdlc */
562 | 0 << 11 /* dsi */
563 | 0 << 12; /* dsic */
564 cs += par->metromem_cmd->args[i++];
566 /* the rest are 0 */
567 memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2);
569 par->metromem_cmd->csum = cs;
570 par->metromem_cmd->opcode = 0xCC10; /* config cmd */
572 i = wait_event_timeout(par->waitq, (GPLR1 & 0x01), HZ);
573 return i;
576 static int __devinit metronome_init_cmd(struct metronomefb_par *par)
578 int i;
579 u16 cs;
581 /* setup init command
582 we can't immediately set the opcode since the controller
583 will try parse the command before we've set it all up
584 so we just set cs here and set the opcode at the end */
586 cs = 0xCC20;
588 /* set the args ( 2 bytes ) for init */
589 i = 0;
590 par->metromem_cmd->args[i] = 0;
591 cs += par->metromem_cmd->args[i++];
593 /* the rest are 0 */
594 memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2);
596 par->metromem_cmd->csum = cs;
597 par->metromem_cmd->opcode = 0xCC20; /* init cmd */
599 i = wait_event_timeout(par->waitq, (GPLR1 & 0x01), HZ);
600 return i;
603 static int __devinit metronome_init_regs(struct metronomefb_par *par)
605 int res;
607 metronome_init_gpio_regs();
608 metronome_init_lcdc_regs(par);
610 res = metronome_powerup_cmd(par);
611 if (res)
612 return res;
614 res = metronome_config_cmd(par);
615 if (res)
616 return res;
618 res = metronome_init_cmd(par);
619 if (res)
620 return res;
622 return res;
625 static void metronomefb_dpy_update(struct metronomefb_par *par)
627 u16 cksum;
628 unsigned char *buf = (unsigned char __force *)par->info->screen_base;
630 /* copy from vm to metromem */
631 memcpy(par->metromem_img, buf, DPY_W*DPY_H);
633 cksum = calc_img_cksum((u16 *) par->metromem_img,
634 (epd_frame_table[0].fw * DPY_H)/2);
635 *((u16 *) (par->metromem_img) +
636 (epd_frame_table[0].fw * DPY_H)/2) = cksum;
637 metronome_display_cmd(par);
640 static u16 metronomefb_dpy_update_page(struct metronomefb_par *par, int index)
642 int i;
643 u16 csum = 0;
644 u16 *buf = (u16 __force *) (par->info->screen_base + index);
645 u16 *img = (u16 *) (par->metromem_img + index);
647 /* swizzle from vm to metromem and recalc cksum at the same time*/
648 for (i = 0; i < PAGE_SIZE/2; i++) {
649 *(img + i) = (buf[i] << 5) & 0xE0E0;
650 csum += *(img + i);
652 return csum;
655 /* this is called back from the deferred io workqueue */
656 static void metronomefb_dpy_deferred_io(struct fb_info *info,
657 struct list_head *pagelist)
659 u16 cksum;
660 struct page *cur;
661 struct fb_deferred_io *fbdefio = info->fbdefio;
662 struct metronomefb_par *par = info->par;
664 /* walk the written page list and swizzle the data */
665 list_for_each_entry(cur, &fbdefio->pagelist, lru) {
666 cksum = metronomefb_dpy_update_page(par,
667 (cur->index << PAGE_SHIFT));
668 par->metromem_img_csum -= par->csum_table[cur->index];
669 par->csum_table[cur->index] = cksum;
670 par->metromem_img_csum += cksum;
673 metronome_display_cmd(par);
676 static void metronomefb_fillrect(struct fb_info *info,
677 const struct fb_fillrect *rect)
679 struct metronomefb_par *par = info->par;
681 cfb_fillrect(info, rect);
682 metronomefb_dpy_update(par);
685 static void metronomefb_copyarea(struct fb_info *info,
686 const struct fb_copyarea *area)
688 struct metronomefb_par *par = info->par;
690 cfb_copyarea(info, area);
691 metronomefb_dpy_update(par);
694 static void metronomefb_imageblit(struct fb_info *info,
695 const struct fb_image *image)
697 struct metronomefb_par *par = info->par;
699 cfb_imageblit(info, image);
700 metronomefb_dpy_update(par);
704 * this is the slow path from userspace. they can seek and write to
705 * the fb. it is based on fb_sys_write
707 static ssize_t metronomefb_write(struct fb_info *info, const char __user *buf,
708 size_t count, loff_t *ppos)
710 struct metronomefb_par *par = info->par;
711 unsigned long p = *ppos;
712 void *dst;
713 int err = 0;
714 unsigned long total_size;
716 if (info->state != FBINFO_STATE_RUNNING)
717 return -EPERM;
719 total_size = info->fix.smem_len;
721 if (p > total_size)
722 return -EFBIG;
724 if (count > total_size) {
725 err = -EFBIG;
726 count = total_size;
729 if (count + p > total_size) {
730 if (!err)
731 err = -ENOSPC;
733 count = total_size - p;
736 dst = (void __force *) (info->screen_base + p);
738 if (copy_from_user(dst, buf, count))
739 err = -EFAULT;
741 if (!err)
742 *ppos += count;
744 metronomefb_dpy_update(par);
746 return (err) ? err : count;
749 static struct fb_ops metronomefb_ops = {
750 .owner = THIS_MODULE,
751 .fb_write = metronomefb_write,
752 .fb_fillrect = metronomefb_fillrect,
753 .fb_copyarea = metronomefb_copyarea,
754 .fb_imageblit = metronomefb_imageblit,
757 static struct fb_deferred_io metronomefb_defio = {
758 .delay = HZ,
759 .deferred_io = metronomefb_dpy_deferred_io,
762 static irqreturn_t metronome_handle_irq(int irq, void *dev_id)
764 struct fb_info *info = dev_id;
765 struct metronomefb_par *par = info->par;
767 wake_up_interruptible(&par->waitq);
768 return IRQ_HANDLED;
771 static int __devinit metronomefb_probe(struct platform_device *dev)
773 struct fb_info *info;
774 int retval = -ENOMEM;
775 int videomemorysize;
776 unsigned char *videomemory;
777 struct metronomefb_par *par;
778 const struct firmware *fw_entry;
779 int cmd_size, wfm_size, img_size, padding_size, totalsize;
780 int i;
782 /* we have two blocks of memory.
783 info->screen_base which is vm, and is the fb used by apps.
784 par->metromem which is physically contiguous memory and
785 contains the display controller commands, waveform,
786 processed image data and padding. this is the data pulled
787 by the pxa255's LCD controller and pushed to Metronome */
789 videomemorysize = (DPY_W*DPY_H);
790 videomemory = vmalloc(videomemorysize);
791 if (!videomemory)
792 return retval;
794 memset(videomemory, 0, videomemorysize);
796 info = framebuffer_alloc(sizeof(struct metronomefb_par), &dev->dev);
797 if (!info)
798 goto err_vfree;
800 info->screen_base = (char __iomem *) videomemory;
801 info->fbops = &metronomefb_ops;
803 info->var = metronomefb_var;
804 info->fix = metronomefb_fix;
805 info->fix.smem_len = videomemorysize;
806 par = info->par;
807 par->info = info;
808 init_waitqueue_head(&par->waitq);
810 /* this table caches per page csum values. */
811 par->csum_table = vmalloc(videomemorysize/PAGE_SIZE);
812 if (!par->csum_table)
813 goto err_csum_table;
815 /* the metromem buffer is divided as follows:
816 command | CRC | padding
817 16kb waveform data | CRC | padding
818 image data | CRC
819 and an extra 256 bytes for dma descriptors
820 eg: IW=832 IH=622 WS=128
823 cmd_size = 1 * epd_frame_table[0].fw;
824 wfm_size = ((16*1024 + 2 + epd_frame_table[0].fw - 1)
825 / epd_frame_table[0].fw) * epd_frame_table[0].fw;
826 img_size = epd_frame_table[0].fh * epd_frame_table[0].fw;
827 padding_size = 4 * epd_frame_table[0].fw;
828 totalsize = cmd_size + wfm_size + img_size + padding_size;
829 par->metromemsize = PAGE_ALIGN(totalsize + 256);
830 DPRINTK("desired memory size = %d\n", par->metromemsize);
831 dev->dev.coherent_dma_mask = 0xffffffffull;
832 par->metromem = dma_alloc_writecombine(&dev->dev, par->metromemsize,
833 &par->metromem_dma, GFP_KERNEL);
834 if (!par->metromem) {
835 printk(KERN_ERR
836 "metronomefb: unable to allocate dma buffer\n");
837 goto err_vfree;
840 info->fix.smem_start = par->metromem_dma;
841 par->metromem_cmd = (struct metromem_cmd *) par->metromem;
842 par->metromem_wfm = par->metromem + cmd_size;
843 par->metromem_img = par->metromem + cmd_size + wfm_size;
844 par->metromem_img_csum = (u16 *) (par->metromem_img +
845 (epd_frame_table[0].fw * DPY_H));
846 DPRINTK("img offset=0x%x\n", cmd_size + wfm_size);
847 par->metromem_desc = (struct metromem_desc *) (par->metromem + cmd_size
848 + wfm_size + img_size + padding_size);
849 par->metromem_desc_dma = par->metromem_dma + cmd_size + wfm_size
850 + img_size + padding_size;
852 /* load the waveform in. assume mode 3, temp 31 for now */
853 /* a) request the waveform file from userspace
854 b) process waveform and decode into metromem */
856 retval = request_firmware(&fw_entry, "waveform.wbf", &dev->dev);
857 if (retval < 0) {
858 printk(KERN_ERR "metronomefb: couldn't get waveform\n");
859 goto err_dma_free;
862 retval = load_waveform((u8 *) fw_entry->data, fw_entry->size,
863 par->metromem_wfm, 3, 31, &par->frame_count);
864 if (retval < 0) {
865 printk(KERN_ERR "metronomefb: couldn't process waveform\n");
866 goto err_ld_wfm;
868 release_firmware(fw_entry);
870 retval = request_irq(IRQ_GPIO(RDY_GPIO_PIN), metronome_handle_irq,
871 IRQF_DISABLED, "Metronome", info);
872 if (retval) {
873 dev_err(&dev->dev, "request_irq failed: %d\n", retval);
874 goto err_ld_wfm;
876 set_irq_type(IRQ_GPIO(RDY_GPIO_PIN), IRQT_FALLING);
878 retval = metronome_init_regs(par);
879 if (retval < 0)
880 goto err_free_irq;
882 info->flags = FBINFO_FLAG_DEFAULT;
884 info->fbdefio = &metronomefb_defio;
885 fb_deferred_io_init(info);
887 retval = fb_alloc_cmap(&info->cmap, 8, 0);
888 if (retval < 0) {
889 printk(KERN_ERR "Failed to allocate colormap\n");
890 goto err_fb_rel;
893 /* set cmap */
894 for (i = 0; i < 8; i++)
895 info->cmap.red[i] = (((2*i)+1)*(0xFFFF))/16;
896 memcpy(info->cmap.green, info->cmap.red, sizeof(u16)*8);
897 memcpy(info->cmap.blue, info->cmap.red, sizeof(u16)*8);
899 retval = register_framebuffer(info);
900 if (retval < 0)
901 goto err_cmap;
903 platform_set_drvdata(dev, info);
905 printk(KERN_INFO
906 "fb%d: Metronome frame buffer device, using %dK of video"
907 " memory\n", info->node, videomemorysize >> 10);
909 return 0;
911 err_cmap:
912 fb_dealloc_cmap(&info->cmap);
913 err_fb_rel:
914 framebuffer_release(info);
915 err_free_irq:
916 free_irq(IRQ_GPIO(RDY_GPIO_PIN), info);
917 err_ld_wfm:
918 release_firmware(fw_entry);
919 err_dma_free:
920 dma_free_writecombine(&dev->dev, par->metromemsize, par->metromem,
921 par->metromem_dma);
922 err_csum_table:
923 vfree(par->csum_table);
924 err_vfree:
925 vfree(videomemory);
926 return retval;
929 static int __devexit metronomefb_remove(struct platform_device *dev)
931 struct fb_info *info = platform_get_drvdata(dev);
933 if (info) {
934 struct metronomefb_par *par = info->par;
935 fb_deferred_io_cleanup(info);
936 dma_free_writecombine(&dev->dev, par->metromemsize,
937 par->metromem, par->metromem_dma);
938 fb_dealloc_cmap(&info->cmap);
939 vfree(par->csum_table);
940 unregister_framebuffer(info);
941 vfree((void __force *)info->screen_base);
942 free_irq(IRQ_GPIO(RDY_GPIO_PIN), info);
943 framebuffer_release(info);
945 return 0;
948 static struct platform_driver metronomefb_driver = {
949 .probe = metronomefb_probe,
950 .remove = metronomefb_remove,
951 .driver = {
952 .name = "metronomefb",
956 static struct platform_device *metronomefb_device;
958 static int __init metronomefb_init(void)
960 int ret;
962 if (!metronomefb_enable) {
963 printk(KERN_ERR
964 "Use metronomefb_enable to enable the device\n");
965 return -ENXIO;
968 ret = platform_driver_register(&metronomefb_driver);
969 if (!ret) {
970 metronomefb_device = platform_device_alloc("metronomefb", 0);
971 if (metronomefb_device)
972 ret = platform_device_add(metronomefb_device);
973 else
974 ret = -ENOMEM;
976 if (ret) {
977 platform_device_put(metronomefb_device);
978 platform_driver_unregister(&metronomefb_driver);
981 return ret;
985 static void __exit metronomefb_exit(void)
987 platform_device_unregister(metronomefb_device);
988 platform_driver_unregister(&metronomefb_driver);
991 module_param(metronomefb_enable, uint, 0);
992 MODULE_PARM_DESC(metronomefb_enable, "Enable communication with Metronome");
994 module_init(metronomefb_init);
995 module_exit(metronomefb_exit);
997 MODULE_DESCRIPTION("fbdev driver for Metronome controller");
998 MODULE_AUTHOR("Jaya Kumar");
999 MODULE_LICENSE("GPL");