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
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 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
24 #include <linux/module.h>
25 #include <linux/kernel.h>
26 #include <linux/errno.h>
27 #include <linux/string.h>
29 #include <linux/slab.h>
30 #include <linux/vmalloc.h>
31 #include <linux/delay.h>
32 #include <linux/interrupt.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>
43 #include <video/metronomefb.h>
45 #include <asm/unaligned.h>
47 /* Display specific information */
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 */
58 /* frame differs from image. frame includes non-visible pixels */
60 int fw
; /* frame width */
61 int fh
; /* frame height */
66 static struct epd_frame epd_frame_table
[] = {
75 | 0 << 15, /* sdcer */
79 | 0 << 15, /* gdspp */
81 | 0 << 15, /* dispc */
117 | 0 << 12 /* sdces */
118 | 0 << 15, /* sdcer */
122 | 0 << 15, /* gdspp */
124 | 0 << 15, /* dispc */
127 | 0 << 12, /* dsic */
133 static const struct fb_fix_screeninfo metronomefb_fix __devinitdata
= {
135 .type
= FB_TYPE_PACKED_PIXELS
,
136 .visual
= FB_VISUAL_STATIC_PSEUDOCOLOR
,
140 .line_length
= DPY_W
,
141 .accel
= FB_ACCEL_NONE
,
144 static const struct fb_var_screeninfo metronomefb_var __devinitdata
= {
147 .xres_virtual
= DPY_W
,
148 .yres_virtual
= DPY_H
,
153 .green
= { 0, 0, 0 },
155 .transp
= { 0, 0, 0 },
158 /* the waveform structure that is coming from userspace firmware */
159 struct waveform_hdr
{
176 } __attribute__ ((packed
));
178 /* main metronomefb functions */
179 static u8
calc_cksum(int start
, int end
, u8
*mem
)
184 for (i
= start
; i
< end
; i
++)
190 static u16
calc_img_cksum(u16
*start
, int length
)
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
)
211 int wfm_idx
, owfm_idx
;
213 struct waveform_hdr
*wfm_hdr
;
214 u8
*metromem
= par
->metromem_wfm
;
215 struct device
*dev
= &par
->pdev
->dev
;
220 dev_dbg(dev
, "Loading waveforms, mode %d, temperature %d\n", m
, t
);
222 wfm_hdr
= (struct waveform_hdr
*) mem
;
224 if (wfm_hdr
->fvsn
!= 1) {
225 dev_err(dev
, "Error: bad fvsn %x\n", wfm_hdr
->fvsn
);
228 if (wfm_hdr
->luts
!= 0) {
229 dev_err(dev
, "Error: bad luts %x\n", wfm_hdr
->luts
);
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
,
238 mc
= wfm_hdr
->mc
+ 1;
239 trc
= wfm_hdr
->trc
+ 1;
241 for (i
= 0; i
< 5; i
++) {
242 if (*(wfm_hdr
->stuff2a
+ i
) != 0) {
243 dev_err(dev
, "Error: unexpected value in padding\n");
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
)
255 for (i
= sizeof(*wfm_hdr
); i
<= sizeof(*wfm_hdr
) + trc
; i
++) {
257 trn
= i
- sizeof(*wfm_hdr
) - 1;
262 /* check temperature range table checksum */
263 cksum_idx
= sizeof(*wfm_hdr
) + trc
+ 1;
264 if (cksum_idx
> size
)
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
]);
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
)
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
]);
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
)
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
]);
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;
303 while (wfm_idx
< size
) {
306 if (v
== wfm_hdr
->swtb
) {
307 while (((v
= mem
[wfm_idx
++]) != wfm_hdr
->swtb
) &&
309 metromem
[mem_idx
++] = v
;
314 if (v
== wfm_hdr
->endb
)
318 for (i
= 0; i
<= rl
; i
++)
319 metromem
[mem_idx
++] = v
;
323 if (cksum_idx
> size
)
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
]);
332 par
->frame_count
= (mem_idx
/64);
334 p
= (u16
*)par
->metromem_wfm
;
335 img_cksum
= calc_img_cksum(p
, 16384 / 2);
336 p
[16384 / 2] = __cpu_to_le16(img_cksum
);
338 par
->current_wf_mode
= m
;
339 par
->current_wf_temp
= t
;
344 static int check_err(struct metronomefb_par
*par
)
348 res
= par
->board
->get_err(par
);
349 dev_dbg(&par
->pdev
->dev
, "ERR = %d\n", res
);
353 static inline int wait_for_rdy(struct metronomefb_par
*par
)
357 if (!par
->board
->get_rdy(par
))
358 res
= par
->board
->met_wait_event_intr(par
);
363 static int metronome_display_cmd(struct metronomefb_par
*par
)
371 res
= wait_for_rdy(par
);
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 */
381 if (par
->metromem_cmd
->opcode
== 0xCC40)
382 opcode
= cs
= 0xCC41;
384 opcode
= cs
= 0xCC40;
386 /* set the args ( 2 bytes ) for display */
388 par
->metromem_cmd
->args
[i
] = 0 << 3 /* border update */
390 // | ((borderval++ % 4) & 0x0F) << 4
391 | (par
->frame_count
- 1) << 8;
392 cs
+= par
->metromem_cmd
->args
[i
++];
395 memset((u8
*) (par
->metromem_cmd
->args
+ i
), 0, (32-i
)*2);
397 par
->metromem_cmd
->csum
= cs
;
398 par
->metromem_cmd
->opcode
= opcode
; /* display cmd */
404 static int __devinit
metronome_powerup_cmd(struct metronomefb_par
*par
)
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
;
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
];
423 memset((u8
*) (par
->metromem_cmd
->args
+ i
), 0, (32-i
)*2);
425 par
->metromem_cmd
->csum
= cs
;
428 par
->board
->set_rst(par
, 1);
431 par
->board
->set_stdby(par
, 1);
433 res
= par
->board
->met_wait_event(par
);
434 dev_dbg(&par
->pdev
->dev
, "%s: EXIT: %d\n", __func__
, res
);
438 static int __devinit
metronome_config_cmd(struct metronomefb_par
*par
)
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 */
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
));
448 memset((u8
*) (par
->metromem_cmd
->args
+ 4), 0, (32-4)*2);
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 */
454 return par
->board
->met_wait_event(par
);
457 static int __devinit
metronome_init_cmd(struct metronomefb_par
*par
)
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 */
467 dev_dbg(&par
->pdev
->dev
, "%s: ENTER\n", __func__
);
470 /* set the args ( 2 bytes ) for init */
472 par
->metromem_cmd
->args
[i
] = 0x0007;
473 cs
+= par
->metromem_cmd
->args
[i
++];
476 memset((u8
*) (par
->metromem_cmd
->args
+ i
), 0, (32-i
)*2);
478 par
->metromem_cmd
->csum
= cs
;
479 par
->metromem_cmd
->opcode
= 0xCC20; /* init cmd */
481 return par
->board
->met_wait_event(par
);
484 static int metronome_bootup(struct metronomefb_par
*par
)
488 res
= metronome_powerup_cmd(par
);
490 dev_err(&par
->pdev
->dev
, "metronomefb: POWERUP cmd failed\n");
495 res
= metronome_config_cmd(par
);
497 dev_err(&par
->pdev
->dev
, "metronomefb: CONFIG cmd failed\n");
502 res
= metronome_init_cmd(par
);
504 dev_err(&par
->pdev
->dev
, "metronomefb: INIT cmd failed\n");
511 static int __devinit
metronome_init_regs(struct metronomefb_par
*par
)
515 if (par
->board
->power_ctl
)
516 par
->board
->power_ctl(par
, METRONOME_POWER_ON
);
518 res
= metronome_bootup(par
);
523 static void metronomefb_dpy_update(struct metronomefb_par
*par
, int clear_all
)
528 u32
*buf
= (u32 __force
*)par
->info
->screen_base
;
529 u32
*img
= (u32
*)(par
->metromem_img
);
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
);
537 static int is_first_update
= 1;
538 static int partial_updates_count
= 0;
539 u32
*fxbuckets
= par
->fxbuckets
;
540 u32
*fybuckets
= par
->fybuckets
;
544 memset(fxbuckets
, 0, fx_buf
* sizeof(*fxbuckets
));
545 memset(fybuckets
, 0, fy
* sizeof(*fybuckets
));
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;
554 fxbuckets
[x
] |= diff
;
555 fybuckets
[y
] |= diff
;
557 img
[i
] = (img
[i
] >> 4) | tmp
;
558 cksum
+= img
[i
] & 0x0000ffff;
559 cksum
+= (img
[i
] >> 16);
563 *((u16
*)(par
->metromem_img
) + fbsize
/2) = cksum
;
565 if (clear_all
|| is_first_update
||
566 (partial_updates_count
== par
->partial_autorefresh_interval
)) {
568 partial_updates_count
= 0;
576 for (x
= 0; x
< fx_buf
; x
++)
582 for (x
= fx_buf
- 1; x
>= 0; x
--)
588 for (y
= 0; y
< fy
; y
++)
594 for (y
= fy
- 1; y
>= 0; y
--)
600 if ((min_x
> max_x
) || (min_y
> max_y
))
603 change_count
= (max_x
- min_x
+ 1) * (max_y
- min_y
+ 1) * sizeof(*buf
);
605 if (change_count
< fbsize
/ 100 * par
->manual_refresh_threshold
)
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
);
616 partial_updates_count
++;
619 if (m
!= par
->current_wf_mode
) {
620 load_waveform((u8
*) par
->firmware
->data
, par
->firmware
->size
,
621 m
, par
->current_wf_temp
, par
);
625 if (likely(!check_err(par
))) {
626 metronome_display_cmd(par
);
630 par
->board
->set_stdby(par
, 0);
631 printk("Resetting Metronome\n");
632 par
->board
->set_rst(par
, 0);
634 if (par
->board
->power_ctl
)
635 par
->board
->power_ctl(par
, METRONOME_POWER_OFF
);
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
);
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
)
652 struct metronomefb_par
*par
= info
->par
;
654 /* We will update entire display because we need to change
655 * 'previous image' field in pixels which was changed at
658 mutex_lock(&par
->lock
);
659 metronomefb_dpy_update(par
, 0);
660 mutex_unlock(&par
->lock
);
663 static void metronomefb_fillrect(struct fb_info
*info
,
664 const struct fb_fillrect
*rect
)
666 struct metronomefb_par
*par
= info
->par
;
668 mutex_lock(&par
->lock
);
669 sys_fillrect(info
, rect
);
670 metronomefb_dpy_update(par
, 0);
671 mutex_unlock(&par
->lock
);
674 static void metronomefb_copyarea(struct fb_info
*info
,
675 const struct fb_copyarea
*area
)
677 struct metronomefb_par
*par
= info
->par
;
679 mutex_lock(&par
->lock
);
680 sys_copyarea(info
, area
);
681 metronomefb_dpy_update(par
, 0);
682 mutex_unlock(&par
->lock
);
685 static void metronomefb_imageblit(struct fb_info
*info
,
686 const struct fb_image
*image
)
688 struct metronomefb_par
*par
= info
->par
;
690 mutex_lock(&par
->lock
);
691 sys_imageblit(info
, image
);
692 metronomefb_dpy_update(par
, 0);
693 mutex_unlock(&par
->lock
);
697 * this is the slow path from userspace. they can seek and write to
698 * the fb. it is based on fb_sys_write
700 static ssize_t
metronomefb_write(struct fb_info
*info
, const char __user
*buf
,
701 size_t count
, loff_t
*ppos
)
703 struct metronomefb_par
*par
= info
->par
;
704 unsigned long p
= *ppos
;
707 unsigned long total_size
;
709 if (info
->state
!= FBINFO_STATE_RUNNING
)
712 total_size
= info
->fix
.smem_len
;
717 if (count
> total_size
) {
722 if (count
+ p
> total_size
) {
726 count
= total_size
- p
;
729 dst
= (void __force
*)(info
->screen_base
+ p
);
731 mutex_lock(&par
->lock
);
733 if (copy_from_user(dst
, buf
, count
))
739 metronomefb_dpy_update(par
, 0);
740 mutex_unlock(&par
->lock
);
742 return (err
) ? err
: count
;
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
,
753 static struct fb_deferred_io metronomefb_defio
= {
755 .deferred_io
= metronomefb_dpy_deferred_io
,
758 static ssize_t
metronomefb_defio_delay_show(struct device
*dev
,
759 struct device_attribute
*attr
, char *buf
)
761 struct fb_info
*info
= dev_get_drvdata(dev
);
763 sprintf(buf
, "%lu\n", info
->fbdefio
->delay
* 1000 / HZ
);
764 return strlen(buf
) + 1;
767 static ssize_t
metronomefb_defio_delay_store(struct device
*dev
,
768 struct device_attribute
*attr
, const char *buf
, size_t size
)
770 struct fb_info
*info
= dev_get_drvdata(dev
);
772 unsigned long state
= simple_strtoul(buf
, &after
, 10);
773 size_t count
= after
- buf
;
774 ssize_t ret
= -EINVAL
;
776 if (*after
&& isspace(*after
))
779 state
= state
* HZ
/ 1000;
786 info
->fbdefio
->delay
= state
;
792 static ssize_t
metronomefb_manual_refresh_thr_show(struct device
*dev
,
793 struct device_attribute
*attr
, char *buf
)
795 struct fb_info
*info
= dev_get_drvdata(dev
);
796 struct metronomefb_par
*par
= info
->par
;
798 return sprintf(buf
, "%u\n", par
->manual_refresh_threshold
);
801 static ssize_t
metronomefb_manual_refresh_thr_store(struct device
*dev
,
802 struct device_attribute
*attr
, const char *buf
, size_t size
)
804 struct fb_info
*info
= dev_get_drvdata(dev
);
805 struct metronomefb_par
*par
= info
->par
;
807 unsigned long val
= simple_strtoul(buf
, &after
, 10);
808 size_t count
= after
- buf
;
809 ssize_t ret
= -EINVAL
;
811 if (*after
&& isspace(*after
))
820 par
->manual_refresh_threshold
= val
;
826 static ssize_t
metronomefb_autorefresh_interval_show(struct device
*dev
,
827 struct device_attribute
*attr
, char *buf
)
829 struct fb_info
*info
= dev_get_drvdata(dev
);
830 struct metronomefb_par
*par
= info
->par
;
832 return sprintf(buf
, "%u\n", par
->partial_autorefresh_interval
);
835 static ssize_t
metronomefb_autorefresh_interval_store(struct device
*dev
,
836 struct device_attribute
*attr
, const char *buf
, size_t size
)
838 struct fb_info
*info
= dev_get_drvdata(dev
);
839 struct metronomefb_par
*par
= info
->par
;
841 unsigned long val
= simple_strtoul(buf
, &after
, 10);
842 size_t count
= after
- buf
;
843 ssize_t ret
= -EINVAL
;
845 if (*after
&& isspace(*after
))
854 par
->partial_autorefresh_interval
= val
;
860 static ssize_t
metronomefb_temp_show(struct device
*dev
,
861 struct device_attribute
*attr
, char *buf
)
863 struct fb_info
*info
= dev_get_drvdata(dev
);
864 struct metronomefb_par
*par
= info
->par
;
866 return sprintf(buf
, "%u\n", par
->current_wf_temp
);
869 static ssize_t
metronomefb_temp_store(struct device
*dev
,
870 struct device_attribute
*attr
, const char *buf
, size_t size
)
872 struct fb_info
*info
= dev_get_drvdata(dev
);
873 struct metronomefb_par
*par
= info
->par
;
875 unsigned long val
= simple_strtoul(buf
, &after
, 10);
876 size_t count
= after
- buf
;
877 ssize_t ret
= -EINVAL
;
879 if (*after
&& isspace(*after
))
888 if (val
!= par
->current_wf_temp
)
889 load_waveform((u8
*) par
->firmware
->data
, par
->firmware
->size
,
890 par
->current_wf_mode
, val
, par
);
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
);
906 static int __devinit
metronomefb_probe(struct platform_device
*dev
)
908 struct fb_info
*info
;
909 struct metronome_board
*board
;
910 int retval
= -ENOMEM
;
912 unsigned char *videomemory
;
913 struct metronomefb_par
*par
;
914 const struct firmware
*fw_entry
;
920 /* pick up board specific routines */
921 board
= dev
->dev
.platform_data
;
925 /* try to count device specific driver, if can't, platform recalls */
926 if (!try_module_get(board
->owner
))
929 info
= framebuffer_alloc(sizeof(struct metronomefb_par
), &dev
->dev
);
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
942 panel_type
= board
->get_panel_type();
943 switch (panel_type
) {
957 dev_err(&dev
->dev
, "Unexpected panel type. Defaulting to 6\n");
962 fw
= epd_frame_table
[epd_dt_index
].fw
;
963 fh
= epd_frame_table
[epd_dt_index
].fh
;
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
);
972 memset(videomemory
, 0xff, videomemorysize
);
974 info
->screen_base
= (char __force __iomem
*)videomemory
;
975 info
->fbops
= &metronomefb_ops
;
977 info
->var
= metronomefb_var
;
980 info
->var
.xres_virtual
= fw
;
981 info
->var
.yres_virtual
= fh
;
983 info
->fix
= metronomefb_fix
;
984 info
->fix
.smem_len
= fw
* fh
; /* Real size of image area */
985 info
->fix
.line_length
= fw
;
990 par
->dt
= epd_dt_index
;
993 par
->fxbuckets
= kmalloc((fw
/ 4 + 1) * sizeof(*par
->fxbuckets
), GFP_KERNEL
);
997 par
->fybuckets
= kmalloc(fh
* sizeof(*par
->fybuckets
), GFP_KERNEL
);
1001 init_waitqueue_head(&par
->waitq
);
1002 par
->manual_refresh_threshold
= 60;
1003 par
->partial_autorefresh_interval
= 256;
1004 mutex_init(&par
->lock
);
1006 /* this table caches per page csum values. */
1007 par
->csum_table
= vmalloc(videomemorysize
/PAGE_SIZE
);
1008 if (!par
->csum_table
)
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
);
1016 dev_err(&dev
->dev
, "Failed to setup fb\n");
1017 goto err_csum_table
;
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");
1025 goto err_csum_table
;
1028 info
->fix
.smem_start
= 0;
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
);
1035 dev_err(&dev
->dev
, "Failed to get waveform\n");
1036 goto err_csum_table
;
1039 retval
= load_waveform((u8
*) fw_entry
->data
, fw_entry
->size
, WF_MODE_GC
, temp
,
1042 dev_err(&dev
->dev
, "Failed processing waveform\n");
1043 goto err_csum_table
;
1045 par
->firmware
= fw_entry
;
1047 retval
= board
->setup_io(par
);
1049 dev_err(&dev
->dev
, "metronomefb: setup_io() failed\n");
1050 goto err_csum_table
;
1053 if (board
->setup_irq(info
))
1054 goto err_csum_table
;
1056 retval
= metronome_init_regs(par
);
1060 info
->flags
= FBINFO_FLAG_DEFAULT
;
1062 info
->fbdefio
= &metronomefb_defio
;
1063 fb_deferred_io_init(info
);
1065 retval
= fb_alloc_cmap(&info
->cmap
, 8, 0);
1067 dev_err(&dev
->dev
, "Failed to allocate colormap\n");
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);
1077 retval
= register_framebuffer(info
);
1081 platform_set_drvdata(dev
, info
);
1083 retval
= device_create_file(info
->dev
, &dev_attr_defio_delay
);
1085 goto err_devattr_defio_delay
;
1087 retval
= device_create_file(info
->dev
, &dev_attr_manual_refresh_threshold
);
1089 goto err_devattr_manual_refresh_thr
;
1091 retval
= device_create_file(info
->dev
, &dev_attr_temp
);
1093 goto err_devattr_temp
;
1095 retval
= device_create_file(info
->dev
, &dev_attr_autorefresh_interval
);
1097 goto err_devattr_autorefresh
;
1100 "fb%d: Metronome frame buffer device, using %dK of video"
1101 " memory\n", info
->node
, videomemorysize
>> 10);
1105 device_remove_file(info
->dev
, &dev_attr_autorefresh_interval
);
1106 err_devattr_autorefresh
:
1107 device_remove_file(info
->dev
, &dev_attr_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
);
1115 fb_dealloc_cmap(&info
->cmap
);
1117 board
->cleanup(par
);
1119 vfree(par
->csum_table
);
1121 kfree(par
->fybuckets
);
1123 kfree(par
->fxbuckets
);
1127 framebuffer_release(info
);
1129 module_put(board
->owner
);
1133 static int __devexit
metronomefb_remove(struct platform_device
*dev
)
1135 struct fb_info
*info
= platform_get_drvdata(dev
);
1138 struct metronomefb_par
*par
= info
->par
;
1140 par
->board
->set_stdby(par
, 0);
1142 if (par
->board
->power_ctl
)
1143 par
->board
->power_ctl(par
, METRONOME_POWER_OFF
);
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
);
1166 static int metronomefb_suspend(struct platform_device
*pdev
, pm_message_t message
)
1168 struct fb_info
*info
= platform_get_drvdata(pdev
);
1169 struct metronomefb_par
*par
= info
->par
;
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
);
1179 static int metronomefb_resume(struct platform_device
*pdev
)
1181 struct fb_info
*info
= platform_get_drvdata(pdev
);
1182 struct metronomefb_par
*par
= info
->par
;
1184 if (par
->board
->power_ctl
)
1185 par
->board
->power_ctl(par
, METRONOME_POWER_ON
);
1187 mutex_lock(&par
->lock
);
1188 metronome_bootup(par
);
1189 mutex_unlock(&par
->lock
);
1195 #define metronomefb_suspend NULL
1196 #define metronomefb_resume NULL
1200 static struct platform_driver metronomefb_driver
= {
1202 .owner
= THIS_MODULE
,
1203 .name
= "metronomefb",
1205 .probe
= metronomefb_probe
,
1206 .remove
= __devexit_p(metronomefb_remove
),
1207 .suspend
= metronomefb_suspend
,
1208 .resume
= metronomefb_resume
,
1211 static int __init
metronomefb_init(void)
1213 return platform_driver_register(&metronomefb_driver
);
1216 static void __exit
metronomefb_exit(void)
1218 platform_driver_unregister(&metronomefb_driver
);
1221 module_param(temp
, int, 0);
1222 MODULE_PARM_DESC(temp
, "Set current temperature");
1224 module_init(metronomefb_init
);
1225 module_exit(metronomefb_exit
);
1227 MODULE_DESCRIPTION("fbdev driver for Metronome controller");
1228 MODULE_AUTHOR("Jaya Kumar");
1229 MODULE_LICENSE("GPL");