0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include <linux/module.h>
0027 #include <linux/kernel.h>
0028 #include <linux/errno.h>
0029 #include <linux/string.h>
0030 #include <linux/delay.h>
0031 #include <linux/interrupt.h>
0032 #include <linux/fb.h>
0033 #include <linux/init.h>
0034 #include <linux/platform_device.h>
0035 #include <linux/list.h>
0036 #include <linux/uaccess.h>
0037 #include <linux/irq.h>
0038
0039 #include <video/hecubafb.h>
0040
0041 static unsigned long dio_addr;
0042 static unsigned long cio_addr;
0043 static unsigned long c2io_addr;
0044 static unsigned long splashval;
0045 static unsigned int nosplash;
0046 static unsigned char ctl;
0047
0048 static void n411_set_ctl(struct hecubafb_par *par, unsigned char bit, unsigned
0049 char state)
0050 {
0051 switch (bit) {
0052 case HCB_CD_BIT:
0053 if (state)
0054 ctl &= ~(HCB_CD_BIT);
0055 else
0056 ctl |= HCB_CD_BIT;
0057 break;
0058 case HCB_DS_BIT:
0059 if (state)
0060 ctl &= ~(HCB_DS_BIT);
0061 else
0062 ctl |= HCB_DS_BIT;
0063 break;
0064 }
0065 outb(ctl, cio_addr);
0066 }
0067
0068 static unsigned char n411_get_ctl(struct hecubafb_par *par)
0069 {
0070 return inb(c2io_addr);
0071 }
0072
0073 static void n411_set_data(struct hecubafb_par *par, unsigned char value)
0074 {
0075 outb(value, dio_addr);
0076 }
0077
0078 static void n411_wait_for_ack(struct hecubafb_par *par, int clear)
0079 {
0080 int timeout;
0081 unsigned char tmp;
0082
0083 timeout = 500;
0084 do {
0085 tmp = n411_get_ctl(par);
0086 if ((tmp & HCB_ACK_BIT) && (!clear))
0087 return;
0088 else if (!(tmp & HCB_ACK_BIT) && (clear))
0089 return;
0090 udelay(1);
0091 } while (timeout--);
0092 printk(KERN_ERR "timed out waiting for ack\n");
0093 }
0094
0095 static int n411_init_control(struct hecubafb_par *par)
0096 {
0097 unsigned char tmp;
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107 ctl = HCB_WUP_BIT | HCB_RW_BIT | HCB_CD_BIT ;
0108 n411_set_ctl(par, HCB_DS_BIT, 1);
0109
0110
0111 tmp = n411_get_ctl(par);
0112 if (tmp & HCB_ACK_BIT) {
0113 printk(KERN_ERR "Fail because ACK is already low\n");
0114 return -ENXIO;
0115 }
0116
0117 return 0;
0118 }
0119
0120
0121 static int n411_init_board(struct hecubafb_par *par)
0122 {
0123 int retval;
0124
0125 retval = n411_init_control(par);
0126 if (retval)
0127 return retval;
0128
0129 par->send_command(par, APOLLO_INIT_DISPLAY);
0130 par->send_data(par, 0x81);
0131
0132
0133 udelay(1000);
0134
0135
0136 if (!nosplash) {
0137 par->send_command(par, APOLLO_ERASE_DISPLAY);
0138 par->send_data(par, splashval);
0139 }
0140
0141 return 0;
0142 }
0143
0144 static struct hecuba_board n411_board = {
0145 .owner = THIS_MODULE,
0146 .init = n411_init_board,
0147 .set_ctl = n411_set_ctl,
0148 .set_data = n411_set_data,
0149 .wait_for_ack = n411_wait_for_ack,
0150 };
0151
0152 static struct platform_device *n411_device;
0153 static int __init n411_init(void)
0154 {
0155 int ret;
0156 if (!dio_addr || !cio_addr || !c2io_addr) {
0157 printk(KERN_WARNING "no IO addresses supplied\n");
0158 return -EINVAL;
0159 }
0160
0161
0162 request_module("hecubafb");
0163
0164 n411_device = platform_device_alloc("hecubafb", -1);
0165 if (!n411_device)
0166 return -ENOMEM;
0167
0168 ret = platform_device_add_data(n411_device, &n411_board,
0169 sizeof(n411_board));
0170 if (ret)
0171 goto put_plat_device;
0172
0173
0174 ret = platform_device_add(n411_device);
0175
0176 if (ret)
0177 goto put_plat_device;
0178
0179 return 0;
0180
0181 put_plat_device:
0182 platform_device_put(n411_device);
0183 return ret;
0184 }
0185
0186 static void __exit n411_exit(void)
0187 {
0188 platform_device_unregister(n411_device);
0189 }
0190
0191 module_init(n411_init);
0192 module_exit(n411_exit);
0193
0194 module_param(nosplash, uint, 0);
0195 MODULE_PARM_DESC(nosplash, "Disable doing the splash screen");
0196 module_param_hw(dio_addr, ulong, ioport, 0);
0197 MODULE_PARM_DESC(dio_addr, "IO address for data, eg: 0x480");
0198 module_param_hw(cio_addr, ulong, ioport, 0);
0199 MODULE_PARM_DESC(cio_addr, "IO address for control, eg: 0x400");
0200 module_param_hw(c2io_addr, ulong, ioport, 0);
0201 MODULE_PARM_DESC(c2io_addr, "IO address for secondary control, eg: 0x408");
0202 module_param(splashval, ulong, 0);
0203 MODULE_PARM_DESC(splashval, "Splash pattern: 0x00 is black, 0x01 is white");
0204
0205 MODULE_DESCRIPTION("board driver for n411 hecuba/apollo epd kit");
0206 MODULE_AUTHOR("Jaya Kumar");
0207 MODULE_LICENSE("GPL");
0208