1 /* 2 * am300epd.c -- Platform device for AM300 EPD kit 3 * 4 * Copyright (C) 2008, Jaya Kumar 5 * 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. 9 * 10 * This work was made possible by help and equipment support from E-Ink 11 * Corporation. http://support.eink.com/community 12 * 13 * This driver is written to be used with the Broadsheet display controller. 14 * on the AM300 EPD prototype kit/development kit with an E-Ink 800x600 15 * Vizplex EPD on a Gumstix board using the Broadsheet interface board. 16 * 17 */ 18 19 #include <linux/module.h> 20 #include <linux/kernel.h> 21 #include <linux/errno.h> 22 #include <linux/string.h> 23 #include <linux/delay.h> 24 #include <linux/interrupt.h> 25 #include <linux/fb.h> 26 #include <linux/init.h> 27 #include <linux/platform_device.h> 28 #include <linux/irq.h> 29 #include <linux/gpio.h> 30 31 #include <mach/gumstix.h> 32 #include <mach/mfp-pxa25x.h> 33 #include <linux/platform_data/video-pxafb.h> 34 35 #include "generic.h" 36 37 #include <video/broadsheetfb.h> 38 39 static unsigned int panel_type = 6; 40 static struct platform_device *am300_device; 41 static struct broadsheet_board am300_board; 42 43 static unsigned long am300_pin_config[] __initdata = { 44 GPIO16_GPIO, 45 GPIO17_GPIO, 46 GPIO32_GPIO, 47 GPIO48_GPIO, 48 GPIO49_GPIO, 49 GPIO51_GPIO, 50 GPIO74_GPIO, 51 GPIO75_GPIO, 52 GPIO76_GPIO, 53 GPIO77_GPIO, 54 55 /* this is the 16-bit hdb bus 58-73 */ 56 GPIO58_GPIO, 57 GPIO59_GPIO, 58 GPIO60_GPIO, 59 GPIO61_GPIO, 60 61 GPIO62_GPIO, 62 GPIO63_GPIO, 63 GPIO64_GPIO, 64 GPIO65_GPIO, 65 66 GPIO66_GPIO, 67 GPIO67_GPIO, 68 GPIO68_GPIO, 69 GPIO69_GPIO, 70 71 GPIO70_GPIO, 72 GPIO71_GPIO, 73 GPIO72_GPIO, 74 GPIO73_GPIO, 75 }; 76 77 /* register offsets for gpio control */ 78 #define PWR_GPIO_PIN 16 79 #define CFG_GPIO_PIN 17 80 #define RDY_GPIO_PIN 32 81 #define DC_GPIO_PIN 48 82 #define RST_GPIO_PIN 49 83 #define LED_GPIO_PIN 51 84 #define RD_GPIO_PIN 74 85 #define WR_GPIO_PIN 75 86 #define CS_GPIO_PIN 76 87 #define IRQ_GPIO_PIN 77 88 89 /* hdb bus */ 90 #define DB0_GPIO_PIN 58 91 #define DB15_GPIO_PIN 73 92 93 static int gpios[] = { PWR_GPIO_PIN, CFG_GPIO_PIN, RDY_GPIO_PIN, DC_GPIO_PIN, 94 RST_GPIO_PIN, RD_GPIO_PIN, WR_GPIO_PIN, CS_GPIO_PIN, 95 IRQ_GPIO_PIN, LED_GPIO_PIN }; 96 static char *gpio_names[] = { "PWR", "CFG", "RDY", "DC", "RST", "RD", "WR", 97 "CS", "IRQ", "LED" }; 98 99 static int am300_wait_event(struct broadsheetfb_par *par) 100 { 101 /* todo: improve err recovery */ 102 wait_event(par->waitq, gpio_get_value(RDY_GPIO_PIN)); 103 return 0; 104 } 105 106 static int am300_init_gpio_regs(struct broadsheetfb_par *par) 107 { 108 int i; 109 int err; 110 char dbname[8]; 111 112 for (i = 0; i < ARRAY_SIZE(gpios); i++) { 113 err = gpio_request(gpios[i], gpio_names[i]); 114 if (err) { 115 dev_err(&am300_device->dev, "failed requesting " 116 "gpio %s, err=%d\n", gpio_names[i], err); 117 goto err_req_gpio; 118 } 119 } 120 121 /* we also need to take care of the hdb bus */ 122 for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++) { 123 sprintf(dbname, "DB%d", i); 124 err = gpio_request(i, dbname); 125 if (err) { 126 dev_err(&am300_device->dev, "failed requesting " 127 "gpio %d, err=%d\n", i, err); 128 goto err_req_gpio2; 129 } 130 } 131 132 /* setup the outputs and init values */ 133 gpio_direction_output(PWR_GPIO_PIN, 0); 134 gpio_direction_output(CFG_GPIO_PIN, 1); 135 gpio_direction_output(DC_GPIO_PIN, 0); 136 gpio_direction_output(RD_GPIO_PIN, 1); 137 gpio_direction_output(WR_GPIO_PIN, 1); 138 gpio_direction_output(CS_GPIO_PIN, 1); 139 gpio_direction_output(RST_GPIO_PIN, 0); 140 141 /* setup the inputs */ 142 gpio_direction_input(RDY_GPIO_PIN); 143 gpio_direction_input(IRQ_GPIO_PIN); 144 145 /* start the hdb bus as an input */ 146 for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++) 147 gpio_direction_output(i, 0); 148 149 /* go into command mode */ 150 gpio_set_value(CFG_GPIO_PIN, 1); 151 gpio_set_value(RST_GPIO_PIN, 0); 152 msleep(10); 153 gpio_set_value(RST_GPIO_PIN, 1); 154 msleep(10); 155 am300_wait_event(par); 156 157 return 0; 158 159 err_req_gpio2: 160 while (--i >= DB0_GPIO_PIN) 161 gpio_free(i); 162 i = ARRAY_SIZE(gpios); 163 err_req_gpio: 164 while (--i >= 0) 165 gpio_free(gpios[i]); 166 167 return err; 168 } 169 170 static int am300_init_board(struct broadsheetfb_par *par) 171 { 172 return am300_init_gpio_regs(par); 173 } 174 175 static void am300_cleanup(struct broadsheetfb_par *par) 176 { 177 int i; 178 179 free_irq(PXA_GPIO_TO_IRQ(RDY_GPIO_PIN), par); 180 181 for (i = 0; i < ARRAY_SIZE(gpios); i++) 182 gpio_free(gpios[i]); 183 184 for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++) 185 gpio_free(i); 186 187 } 188 189 static u16 am300_get_hdb(struct broadsheetfb_par *par) 190 { 191 u16 res = 0; 192 int i; 193 194 for (i = 0; i <= (DB15_GPIO_PIN - DB0_GPIO_PIN) ; i++) 195 res |= (gpio_get_value(DB0_GPIO_PIN + i)) ? (1 << i) : 0; 196 197 return res; 198 } 199 200 static void am300_set_hdb(struct broadsheetfb_par *par, u16 data) 201 { 202 int i; 203 204 for (i = 0; i <= (DB15_GPIO_PIN - DB0_GPIO_PIN) ; i++) 205 gpio_set_value(DB0_GPIO_PIN + i, (data >> i) & 0x01); 206 } 207 208 209 static void am300_set_ctl(struct broadsheetfb_par *par, unsigned char bit, 210 u8 state) 211 { 212 switch (bit) { 213 case BS_CS: 214 gpio_set_value(CS_GPIO_PIN, state); 215 break; 216 case BS_DC: 217 gpio_set_value(DC_GPIO_PIN, state); 218 break; 219 case BS_WR: 220 gpio_set_value(WR_GPIO_PIN, state); 221 break; 222 } 223 } 224 225 static int am300_get_panel_type(void) 226 { 227 return panel_type; 228 } 229 230 static irqreturn_t am300_handle_irq(int irq, void *dev_id) 231 { 232 struct broadsheetfb_par *par = dev_id; 233 234 wake_up(&par->waitq); 235 return IRQ_HANDLED; 236 } 237 238 static int am300_setup_irq(struct fb_info *info) 239 { 240 int ret; 241 struct broadsheetfb_par *par = info->par; 242 243 ret = request_irq(PXA_GPIO_TO_IRQ(RDY_GPIO_PIN), am300_handle_irq, 244 IRQF_DISABLED|IRQF_TRIGGER_RISING, 245 "AM300", par); 246 if (ret) 247 dev_err(&am300_device->dev, "request_irq failed: %d\n", ret); 248 249 return ret; 250 } 251 252 static struct broadsheet_board am300_board = { 253 .owner = THIS_MODULE, 254 .init = am300_init_board, 255 .cleanup = am300_cleanup, 256 .set_hdb = am300_set_hdb, 257 .get_hdb = am300_get_hdb, 258 .set_ctl = am300_set_ctl, 259 .wait_for_rdy = am300_wait_event, 260 .get_panel_type = am300_get_panel_type, 261 .setup_irq = am300_setup_irq, 262 }; 263 264 int __init am300_init(void) 265 { 266 int ret; 267 268 pxa2xx_mfp_config(ARRAY_AND_SIZE(am300_pin_config)); 269 270 /* request our platform independent driver */ 271 request_module("broadsheetfb"); 272 273 am300_device = platform_device_alloc("broadsheetfb", -1); 274 if (!am300_device) 275 return -ENOMEM; 276 277 /* the am300_board that will be seen by broadsheetfb is a copy */ 278 platform_device_add_data(am300_device, &am300_board, 279 sizeof(am300_board)); 280 281 ret = platform_device_add(am300_device); 282 283 if (ret) { 284 platform_device_put(am300_device); 285 return ret; 286 } 287 288 return 0; 289 } 290 291 module_param(panel_type, uint, 0); 292 MODULE_PARM_DESC(panel_type, "Select the panel type: 37, 6, 97"); 293 294 MODULE_DESCRIPTION("board driver for am300 epd kit"); 295 MODULE_AUTHOR("Jaya Kumar"); 296 MODULE_LICENSE("GPL"); 297