[PATCH/RFC 2.6.20 2/2] fbdev: Hecuba fb driver
This patch implements support for the E-Ink/hecuba display device. It uses deferred IO support. Thanks, jaya Signed-off-by: Jaya Kumar <[EMAIL PROTECTED]> --- hecubafb.c | 480 + 1 file changed, 480 insertions(+) --- diff --git a/drivers/video/hecubafb.c b/drivers/video/hecubafb.c new file mode 100644 index 000..9944bee --- /dev/null +++ b/drivers/video/hecubafb.c @@ -0,0 +1,480 @@ +/* + * linux/drivers/video/hecubafb.c -- FB driver for Hecuba controller + * + * Copyright (C) 2006, Jaya Kumar + * This work was sponsored by CIS(M) Sdn Bhd + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + * + * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven. + * This work was possible because of apollo display code from E-Ink's website + * http://support.eink.com/community + * All information used to write this code is from public material made + * available by E-Ink on its support site. Some commands such as 0xA4 + * were found by looping through cmd=0x00 thru 0xFF and supplying random + * values. There are other commands that the display is capable of, + * beyond the 5 used here but they are more complex. + * + * This driver is written to be used with the Hecuba display controller + * board, and tested with the EInk 800x600 display in 1 bit mode. + * The interface between Hecuba and the host is TTL based GPIO. The + * GPIO requirements are 8 writable data lines and 6 lines for control. + * Only 4 of the controls are actually used here but 6 for future use. + * The driver requires the IO addresses for data and control GPIO at + * load time. It is also possible to use this display with a standard + * PC parallel port. + * + * General notes: + * - User must set hecubafb_enable=1 to enable it + * - User must set dio_addr=0xIOADDR cio_addr=0xIOADDR c2io_addr=0xIOADDR + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Apollo controller specific defines */ +#define APOLLO_START_NEW_IMG 0xA0 +#define APOLLO_STOP_IMG_DATA 0xA1 +#define APOLLO_DISPLAY_IMG 0xA2 +#define APOLLO_ERASE_DISPLAY 0xA3 +#define APOLLO_INIT_DISPLAY0xA4 + +/* Hecuba interface specific defines */ +/* WUP is inverted, CD is inverted, DS is inverted */ +#define HCB_NWUP_BIT 0x01 +#define HCB_NDS_BIT0x02 +#define HCB_RW_BIT 0x04 +#define HCB_NCD_BIT0x08 +#define HCB_ACK_BIT0x80 + +/* Display specific information */ +#define DPY_W 600 +#define DPY_H 800 + +struct hecubafb_par { + unsigned long dio_addr; + unsigned long cio_addr; + unsigned long c2io_addr; + unsigned char ctl; + struct fb_info *info; + unsigned int irq; +}; + +static struct fb_fix_screeninfo hecubafb_fix __initdata = { + .id = "hecubafb", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_MONO01, + .xpanstep = 0, + .ypanstep = 0, + .ywrapstep =0, + .accel =FB_ACCEL_NONE, +}; + +static struct fb_var_screeninfo hecubafb_var __initdata = { + .xres = DPY_W, + .yres = DPY_H, + .xres_virtual = DPY_W, + .yres_virtual = DPY_H, + .bits_per_pixel = 1, + .nonstd = 1, +}; + +static unsigned long dio_addr; +static unsigned long cio_addr; +static unsigned long c2io_addr; +static unsigned long splashval; +static unsigned int nosplash; +static unsigned int hecubafb_enable; +static unsigned int irq; + +static DECLARE_WAIT_QUEUE_HEAD(hecubafb_waitq); + +static void hcb_set_ctl(struct hecubafb_par *par) +{ + outb(par->ctl, par->cio_addr); +} + +static unsigned char hcb_get_ctl(struct hecubafb_par *par) +{ + return inb(par->c2io_addr); +} + +static void hcb_set_data(struct hecubafb_par *par, unsigned char value) +{ + outb(value, par->dio_addr); +} + +static int __devinit apollo_init_control(struct hecubafb_par *par) +{ + unsigned char ctl; + /* for init, we want the following setup to be set: + WUP = lo + ACK = hi + DS = hi + RW = hi + CD = lo + */ + + /* write WUP to lo, DS to hi, RW to hi, CD to lo */ + par->ctl = HCB_NWUP_BIT | HCB_RW_BIT | HCB_NCD_BIT ; + par->ctl &= ~HCB_NDS_BIT; + hcb_set_ctl(par); + + /* check ACK is not lo */ + ctl = hcb_get_ctl(par); + if ((ctl & HCB_ACK_BIT)) { + printk(KERN_ERR "Fail because ACK is already low\n"); + return -ENXIO; + } + + return 0; +} + +void hcb_wait_for_ack(struct hecubafb_par *par) +{ + + int timeout; + unsigned char ctl; + + timeout=500; + do { + ctl = hcb_get_ctl(par); + if ((ctl & HCB_ACK_BIT)) +
[PATCH/RFC 2.6.20 2/2] fbdev: Hecuba fb driver
This patch implements support for the E-Ink/hecuba display device. It uses deferred IO support. Thanks, jaya Signed-off-by: Jaya Kumar [EMAIL PROTECTED] --- hecubafb.c | 480 + 1 file changed, 480 insertions(+) --- diff --git a/drivers/video/hecubafb.c b/drivers/video/hecubafb.c new file mode 100644 index 000..9944bee --- /dev/null +++ b/drivers/video/hecubafb.c @@ -0,0 +1,480 @@ +/* + * linux/drivers/video/hecubafb.c -- FB driver for Hecuba controller + * + * Copyright (C) 2006, Jaya Kumar + * This work was sponsored by CIS(M) Sdn Bhd + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + * + * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven. + * This work was possible because of apollo display code from E-Ink's website + * http://support.eink.com/community + * All information used to write this code is from public material made + * available by E-Ink on its support site. Some commands such as 0xA4 + * were found by looping through cmd=0x00 thru 0xFF and supplying random + * values. There are other commands that the display is capable of, + * beyond the 5 used here but they are more complex. + * + * This driver is written to be used with the Hecuba display controller + * board, and tested with the EInk 800x600 display in 1 bit mode. + * The interface between Hecuba and the host is TTL based GPIO. The + * GPIO requirements are 8 writable data lines and 6 lines for control. + * Only 4 of the controls are actually used here but 6 for future use. + * The driver requires the IO addresses for data and control GPIO at + * load time. It is also possible to use this display with a standard + * PC parallel port. + * + * General notes: + * - User must set hecubafb_enable=1 to enable it + * - User must set dio_addr=0xIOADDR cio_addr=0xIOADDR c2io_addr=0xIOADDR + * + */ + +#include linux/module.h +#include linux/kernel.h +#include linux/errno.h +#include linux/string.h +#include linux/mm.h +#include linux/slab.h +#include linux/vmalloc.h +#include linux/delay.h +#include linux/interrupt.h +#include linux/fb.h +#include linux/init.h +#include linux/platform_device.h +#include linux/list.h +#include asm/uaccess.h + +/* Apollo controller specific defines */ +#define APOLLO_START_NEW_IMG 0xA0 +#define APOLLO_STOP_IMG_DATA 0xA1 +#define APOLLO_DISPLAY_IMG 0xA2 +#define APOLLO_ERASE_DISPLAY 0xA3 +#define APOLLO_INIT_DISPLAY0xA4 + +/* Hecuba interface specific defines */ +/* WUP is inverted, CD is inverted, DS is inverted */ +#define HCB_NWUP_BIT 0x01 +#define HCB_NDS_BIT0x02 +#define HCB_RW_BIT 0x04 +#define HCB_NCD_BIT0x08 +#define HCB_ACK_BIT0x80 + +/* Display specific information */ +#define DPY_W 600 +#define DPY_H 800 + +struct hecubafb_par { + unsigned long dio_addr; + unsigned long cio_addr; + unsigned long c2io_addr; + unsigned char ctl; + struct fb_info *info; + unsigned int irq; +}; + +static struct fb_fix_screeninfo hecubafb_fix __initdata = { + .id = hecubafb, + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_MONO01, + .xpanstep = 0, + .ypanstep = 0, + .ywrapstep =0, + .accel =FB_ACCEL_NONE, +}; + +static struct fb_var_screeninfo hecubafb_var __initdata = { + .xres = DPY_W, + .yres = DPY_H, + .xres_virtual = DPY_W, + .yres_virtual = DPY_H, + .bits_per_pixel = 1, + .nonstd = 1, +}; + +static unsigned long dio_addr; +static unsigned long cio_addr; +static unsigned long c2io_addr; +static unsigned long splashval; +static unsigned int nosplash; +static unsigned int hecubafb_enable; +static unsigned int irq; + +static DECLARE_WAIT_QUEUE_HEAD(hecubafb_waitq); + +static void hcb_set_ctl(struct hecubafb_par *par) +{ + outb(par-ctl, par-cio_addr); +} + +static unsigned char hcb_get_ctl(struct hecubafb_par *par) +{ + return inb(par-c2io_addr); +} + +static void hcb_set_data(struct hecubafb_par *par, unsigned char value) +{ + outb(value, par-dio_addr); +} + +static int __devinit apollo_init_control(struct hecubafb_par *par) +{ + unsigned char ctl; + /* for init, we want the following setup to be set: + WUP = lo + ACK = hi + DS = hi + RW = hi + CD = lo + */ + + /* write WUP to lo, DS to hi, RW to hi, CD to lo */ + par-ctl = HCB_NWUP_BIT | HCB_RW_BIT | HCB_NCD_BIT ; + par-ctl = ~HCB_NDS_BIT; + hcb_set_ctl(par); + + /* check ACK is not lo */ + ctl = hcb_get_ctl(par); + if ((ctl HCB_ACK_BIT)) { + printk(KERN_ERR Fail because ACK is already low\n); + return -ENXIO; + } + + return 0; +} + +void hcb_wait_for_ack(struct hecubafb_par