21 #include <linux/module.h>
22 #include <linux/kernel.h>
23 #include <linux/errno.h>
24 #include <linux/string.h>
32 #include <linux/list.h>
40 #include <asm/unaligned.h>
46 static int user_wfm_size;
56 static struct epd_frame epd_frame_table[] = {
109 .line_length =
DPY_W,
116 .xres_virtual =
DPY_W,
117 .yres_virtual =
DPY_H,
122 .green = { 0, 0, 0 },
124 .transp = { 0, 0, 0 },
153 for (i = start; i <
end; i++)
180 int wfm_idx, owfm_idx;
187 epd_frame_table[par->
dt].
wfm_size = user_wfm_size;
189 if (size != epd_frame_table[par->
dt].
wfm_size) {
190 dev_err(dev,
"Error: unexpected size %Zd != %d\n", size,
197 if (wfm_hdr->
fvsn != 1) {
198 dev_err(dev,
"Error: bad fvsn %x\n", wfm_hdr->
fvsn);
201 if (wfm_hdr->
luts != 0) {
202 dev_err(dev,
"Error: bad luts %x\n", wfm_hdr->
luts);
205 cksum = calc_cksum(32, 47, mem);
206 if (cksum != wfm_hdr->
wfm_cs) {
207 dev_err(dev,
"Error: bad cksum %x != %x\n", cksum,
213 for (i = 0; i < 5; i++) {
214 if (*(wfm_hdr->
stuff2a + i) != 0) {
215 dev_err(dev,
"Error: unexpected value in padding\n");
224 if ((
sizeof(*wfm_hdr) + wfm_hdr->
trc) > size)
227 for (i =
sizeof(*wfm_hdr); i <=
sizeof(*wfm_hdr) + wfm_hdr->
trc; i++) {
229 trn = i -
sizeof(*wfm_hdr) - 1;
235 cksum_idx =
sizeof(*wfm_hdr) + wfm_hdr->
trc + 1;
236 if (cksum_idx > size)
238 cksum = calc_cksum(
sizeof(*wfm_hdr), cksum_idx, mem);
239 if (cksum != mem[cksum_idx]) {
240 dev_err(dev,
"Error: bad temperature range table cksum"
241 " %x != %x\n", cksum, mem[cksum_idx]);
247 cksum_idx = wmta + m*4 + 3;
248 if (cksum_idx > size)
250 cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem);
251 if (cksum != mem[cksum_idx]) {
252 dev_err(dev,
"Error: bad mode table address cksum"
253 " %x != %x\n", cksum, mem[cksum_idx]);
259 cksum_idx = tta + trn*4 + 3;
260 if (cksum_idx > size)
262 cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem);
263 if (cksum != mem[cksum_idx]) {
264 dev_err(dev,
"Error: bad temperature table address cksum"
265 " %x != %x\n", cksum, mem[cksum_idx]);
275 while (wfm_idx < size) {
278 if (v == wfm_hdr->
swtb) {
279 while (((v = mem[wfm_idx++]) != wfm_hdr->
swtb) &&
281 metromem[mem_idx++] =
v;
286 if (v == wfm_hdr->
endb)
290 for (i = 0; i <= rl; i++)
291 metromem[mem_idx++] = v;
295 if (cksum_idx > size)
297 cksum = calc_cksum(owfm_idx, cksum_idx, mem);
298 if (cksum != mem[cksum_idx]) {
299 dev_err(dev,
"Error: bad waveform data cksum"
300 " %x != %x\n", cksum, mem[cksum_idx]);
321 opcode = cs = 0xCC41;
323 opcode = cs = 0xCC40;
328 | ((borderval++ % 4) & 0x0F) << 4
338 return par->
board->met_wait_event_intr(par);
351 for (i = 0; i < 3; i++) {
362 par->
board->set_rst(par, 1);
365 par->
board->set_stdby(par, 1);
367 return par->
board->met_wait_event(par);
377 sizeof(epd_frame_table[par->
dt].
config));
385 return par->
board->met_wait_event(par);
411 return par->
board->met_wait_event(par);
418 res = par->
board->setup_io(par);
422 res = metronome_powerup_cmd(par);
426 res = metronome_config_cmd(par);
430 res = metronome_init_cmd(par);
439 unsigned char *
buf = (
unsigned char __force *)par->
info->screen_base;
441 fbsize = par->
info->fix.smem_len;
447 metronome_display_cmd(par);
459 *(img +
i) = (buf[i] << 5) & 0xE0E0;
466 static void metronomefb_dpy_deferred_io(
struct fb_info *
info,
471 struct fb_deferred_io *fbdefio = info->fbdefio;
476 cksum = metronomefb_dpy_update_page(par,
483 metronome_display_cmd(par);
486 static void metronomefb_fillrect(
struct fb_info *info,
492 metronomefb_dpy_update(par);
495 static void metronomefb_copyarea(
struct fb_info *info,
501 metronomefb_dpy_update(par);
504 static void metronomefb_imageblit(
struct fb_info *info,
510 metronomefb_dpy_update(par);
517 static ssize_t metronomefb_write(
struct fb_info *info,
const char __user *buf,
518 size_t count, loff_t *ppos)
521 unsigned long p = *ppos;
529 total_size = info->
fix.smem_len;
534 if (count > total_size) {
539 if (count + p > total_size) {
543 count = total_size -
p;
554 metronomefb_dpy_update(par);
556 return (err) ? err :
count;
559 static struct fb_ops metronomefb_ops = {
561 .fb_write = metronomefb_write,
562 .fb_fillrect = metronomefb_fillrect,
563 .fb_copyarea = metronomefb_copyarea,
564 .fb_imageblit = metronomefb_imageblit,
567 static struct fb_deferred_io metronomefb_defio = {
569 .deferred_io = metronomefb_dpy_deferred_io,
578 unsigned char *videomemory;
587 board = dev->
dev.platform_data;
592 if (!try_module_get(board->
owner))
609 switch (panel_type) {
620 dev_err(&dev->
dev,
"Unexpected panel type. Defaulting to 6\n");
625 fw = epd_frame_table[epd_dt_index].
fw;
626 fh = epd_frame_table[epd_dt_index].
fh;
631 videomemory =
vzalloc(videomemorysize);
636 info->
fbops = &metronomefb_ops;
638 metronomefb_fix.line_length =
fw;
639 metronomefb_var.xres =
fw;
640 metronomefb_var.yres = fh;
641 metronomefb_var.xres_virtual =
fw;
642 metronomefb_var.yres_virtual = fh;
643 info->
var = metronomefb_var;
644 info->
fix = metronomefb_fix;
645 info->
fix.smem_len = videomemorysize;
649 par->
dt = epd_dt_index;
681 dev_err(&dev->
dev,
"Failed to get waveform\n");
685 retval = load_waveform((
u8 *) fw_entry->
data, fw_entry->
size, 3, 31,
689 dev_err(&dev->
dev,
"Failed processing waveform\n");
696 retval = metronome_init_regs(par);
702 info->fbdefio = &metronomefb_defio;
707 dev_err(&dev->
dev,
"Failed to allocate colormap\n");
712 for (i = 0; i < 8; i++)
713 info->
cmap.red[i] = (((2*i)+1)*(0xFFFF))/16;
721 platform_set_drvdata(dev, info);
724 "fb%d: Metronome frame buffer device, using %dK of video"
725 " memory\n", info->
node, videomemorysize >> 10);
740 module_put(board->
owner);
746 struct fb_info *info = platform_get_drvdata(dev);
754 par->
board->cleanup(par);
757 module_put(par->
board->owner);
765 .probe = metronomefb_probe,
769 .name =
"metronomefb",
773 static int __init metronomefb_init(
void)
778 static void __exit metronomefb_exit(
void)