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
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>
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>
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
= {
55 /* this is the 16-bit hdb bus 58-73 */
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
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",
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
));
106 static int am300_init_gpio_regs(struct broadsheetfb_par
*par
)
112 for (i
= 0; i
< ARRAY_SIZE(gpios
); i
++) {
113 err
= gpio_request(gpios
[i
], gpio_names
[i
]);
115 dev_err(&am300_device
->dev
, "failed requesting "
116 "gpio %s, err=%d\n", gpio_names
[i
], err
);
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
);
126 dev_err(&am300_device
->dev
, "failed requesting "
127 "gpio %d, err=%d\n", i
, err
);
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);
141 /* setup the inputs */
142 gpio_direction_input(RDY_GPIO_PIN
);
143 gpio_direction_input(IRQ_GPIO_PIN
);
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);
149 /* go into command mode */
150 gpio_set_value(CFG_GPIO_PIN
, 1);
151 gpio_set_value(RST_GPIO_PIN
, 0);
153 gpio_set_value(RST_GPIO_PIN
, 1);
155 am300_wait_event(par
);
160 while (--i
>= DB0_GPIO_PIN
)
162 i
= ARRAY_SIZE(gpios
);
170 static int am300_init_board(struct broadsheetfb_par
*par
)
172 return am300_init_gpio_regs(par
);
175 static void am300_cleanup(struct broadsheetfb_par
*par
)
179 free_irq(IRQ_GPIO(RDY_GPIO_PIN
), par
);
181 for (i
= 0; i
< ARRAY_SIZE(gpios
); i
++)
184 for (i
= DB0_GPIO_PIN
; i
<= DB15_GPIO_PIN
; i
++)
189 static u16
am300_get_hdb(struct broadsheetfb_par
*par
)
194 for (i
= 0; i
<= (DB15_GPIO_PIN
- DB0_GPIO_PIN
) ; i
++)
195 res
|= (gpio_get_value(DB0_GPIO_PIN
+ i
)) ? (1 << i
) : 0;
200 static void am300_set_hdb(struct broadsheetfb_par
*par
, u16 data
)
204 for (i
= 0; i
<= (DB15_GPIO_PIN
- DB0_GPIO_PIN
) ; i
++)
205 gpio_set_value(DB0_GPIO_PIN
+ i
, (data
>> i
) & 0x01);
209 static void am300_set_ctl(struct broadsheetfb_par
*par
, unsigned char bit
,
214 gpio_set_value(CS_GPIO_PIN
, state
);
217 gpio_set_value(DC_GPIO_PIN
, state
);
220 gpio_set_value(WR_GPIO_PIN
, state
);
225 static int am300_get_panel_type(void)
230 static irqreturn_t
am300_handle_irq(int irq
, void *dev_id
)
232 struct broadsheetfb_par
*par
= dev_id
;
234 wake_up(&par
->waitq
);
238 static int am300_setup_irq(struct fb_info
*info
)
241 struct broadsheetfb_par
*par
= info
->par
;
243 ret
= request_irq(IRQ_GPIO(RDY_GPIO_PIN
), am300_handle_irq
,
244 IRQF_DISABLED
|IRQF_TRIGGER_RISING
,
247 dev_err(&am300_device
->dev
, "request_irq failed: %d\n", ret
);
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
,
264 int __init
am300_init(void)
268 pxa2xx_mfp_config(ARRAY_AND_SIZE(am300_pin_config
));
270 /* request our platform independent driver */
271 request_module("broadsheetfb");
273 am300_device
= platform_device_alloc("broadsheetfb", -1);
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
));
281 ret
= platform_device_add(am300_device
);
284 platform_device_put(am300_device
);
291 module_param(panel_type
, uint
, 0);
292 MODULE_PARM_DESC(panel_type
, "Select the panel type: 37, 6, 97");
294 MODULE_DESCRIPTION("board driver for am300 epd kit");
295 MODULE_AUTHOR("Jaya Kumar");
296 MODULE_LICENSE("GPL");