RT-AC56 3.0.0.4.374.37 core
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / arch / arm / mach-pxa / am300epd.c
blob993d75e66390e38b3538eb4e539569904c1ee9d4
1 /*
2 * am300epd.c -- Platform device for AM300 EPD kit
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
8 * more details.
10 * This work was made possible by help and equipment support from E-Ink
11 * Corporation. http://support.eink.com/community
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.
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>
31 #include <mach/gumstix.h>
32 #include <mach/mfp-pxa25x.h>
33 #include <mach/pxafb.h>
35 #include "generic.h"
37 #include <video/broadsheetfb.h>
39 static unsigned int panel_type = 6;
40 static struct platform_device *am300_device;
41 static struct broadsheet_board am300_board;
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,
55 /* this is the 16-bit hdb bus 58-73 */
56 GPIO58_GPIO,
57 GPIO59_GPIO,
58 GPIO60_GPIO,
59 GPIO61_GPIO,
61 GPIO62_GPIO,
62 GPIO63_GPIO,
63 GPIO64_GPIO,
64 GPIO65_GPIO,
66 GPIO66_GPIO,
67 GPIO67_GPIO,
68 GPIO68_GPIO,
69 GPIO69_GPIO,
71 GPIO70_GPIO,
72 GPIO71_GPIO,
73 GPIO72_GPIO,
74 GPIO73_GPIO,
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
89 /* hdb bus */
90 #define DB0_GPIO_PIN 58
91 #define DB15_GPIO_PIN 73
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" };
99 static int am300_wait_event(struct broadsheetfb_par *par)
101 /* todo: improve err recovery */
102 wait_event(par->waitq, gpio_get_value(RDY_GPIO_PIN));
103 return 0;
106 static int am300_init_gpio_regs(struct broadsheetfb_par *par)
108 int i;
109 int err;
110 char dbname[8];
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;
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 while (i >= DB0_GPIO_PIN)
129 gpio_free(i--);
130 i = ARRAY_SIZE(gpios) - 1;
131 goto err_req_gpio;
135 /* setup the outputs and init values */
136 gpio_direction_output(PWR_GPIO_PIN, 0);
137 gpio_direction_output(CFG_GPIO_PIN, 1);
138 gpio_direction_output(DC_GPIO_PIN, 0);
139 gpio_direction_output(RD_GPIO_PIN, 1);
140 gpio_direction_output(WR_GPIO_PIN, 1);
141 gpio_direction_output(CS_GPIO_PIN, 1);
142 gpio_direction_output(RST_GPIO_PIN, 0);
144 /* setup the inputs */
145 gpio_direction_input(RDY_GPIO_PIN);
146 gpio_direction_input(IRQ_GPIO_PIN);
148 /* start the hdb bus as an input */
149 for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++)
150 gpio_direction_output(i, 0);
152 /* go into command mode */
153 gpio_set_value(CFG_GPIO_PIN, 1);
154 gpio_set_value(RST_GPIO_PIN, 0);
155 msleep(10);
156 gpio_set_value(RST_GPIO_PIN, 1);
157 msleep(10);
158 am300_wait_event(par);
160 return 0;
162 err_req_gpio:
163 while (i > 0)
164 gpio_free(gpios[i--]);
166 return err;
169 static int am300_init_board(struct broadsheetfb_par *par)
171 return am300_init_gpio_regs(par);
174 static void am300_cleanup(struct broadsheetfb_par *par)
176 int i;
178 free_irq(IRQ_GPIO(RDY_GPIO_PIN), par);
180 for (i = 0; i < ARRAY_SIZE(gpios); i++)
181 gpio_free(gpios[i]);
183 for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++)
184 gpio_free(i);
188 static u16 am300_get_hdb(struct broadsheetfb_par *par)
190 u16 res = 0;
191 int i;
193 for (i = 0; i <= (DB15_GPIO_PIN - DB0_GPIO_PIN) ; i++)
194 res |= (gpio_get_value(DB0_GPIO_PIN + i)) ? (1 << i) : 0;
196 return res;
199 static void am300_set_hdb(struct broadsheetfb_par *par, u16 data)
201 int i;
203 for (i = 0; i <= (DB15_GPIO_PIN - DB0_GPIO_PIN) ; i++)
204 gpio_set_value(DB0_GPIO_PIN + i, (data >> i) & 0x01);
208 static void am300_set_ctl(struct broadsheetfb_par *par, unsigned char bit,
209 u8 state)
211 switch (bit) {
212 case BS_CS:
213 gpio_set_value(CS_GPIO_PIN, state);
214 break;
215 case BS_DC:
216 gpio_set_value(DC_GPIO_PIN, state);
217 break;
218 case BS_WR:
219 gpio_set_value(WR_GPIO_PIN, state);
220 break;
224 static int am300_get_panel_type(void)
226 return panel_type;
229 static irqreturn_t am300_handle_irq(int irq, void *dev_id)
231 struct broadsheetfb_par *par = dev_id;
233 wake_up(&par->waitq);
234 return IRQ_HANDLED;
237 static int am300_setup_irq(struct fb_info *info)
239 int ret;
240 struct broadsheetfb_par *par = info->par;
242 ret = request_irq(IRQ_GPIO(RDY_GPIO_PIN), am300_handle_irq,
243 IRQF_DISABLED|IRQF_TRIGGER_RISING,
244 "AM300", par);
245 if (ret)
246 dev_err(&am300_device->dev, "request_irq failed: %d\n", ret);
248 return ret;
251 static struct broadsheet_board am300_board = {
252 .owner = THIS_MODULE,
253 .init = am300_init_board,
254 .cleanup = am300_cleanup,
255 .set_hdb = am300_set_hdb,
256 .get_hdb = am300_get_hdb,
257 .set_ctl = am300_set_ctl,
258 .wait_for_rdy = am300_wait_event,
259 .get_panel_type = am300_get_panel_type,
260 .setup_irq = am300_setup_irq,
263 int __init am300_init(void)
265 int ret;
267 pxa2xx_mfp_config(ARRAY_AND_SIZE(am300_pin_config));
269 /* request our platform independent driver */
270 request_module("broadsheetfb");
272 am300_device = platform_device_alloc("broadsheetfb", -1);
273 if (!am300_device)
274 return -ENOMEM;
276 /* the am300_board that will be seen by broadsheetfb is a copy */
277 platform_device_add_data(am300_device, &am300_board,
278 sizeof(am300_board));
280 ret = platform_device_add(am300_device);
282 if (ret) {
283 platform_device_put(am300_device);
284 return ret;
287 return 0;
290 module_param(panel_type, uint, 0);
291 MODULE_PARM_DESC(panel_type, "Select the panel type: 37, 6, 97");
293 MODULE_DESCRIPTION("board driver for am300 epd kit");
294 MODULE_AUTHOR("Jaya Kumar");
295 MODULE_LICENSE("GPL");