1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
39static unsigned int panel_type = 6;
40static struct platform_device *am300_device;
41static struct broadsheet_board am300_board;
42
43static 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
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
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
90#define DB0_GPIO_PIN 58
91#define DB15_GPIO_PIN 73
92
93static 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 };
96static char *gpio_names[] = { "PWR", "CFG", "RDY", "DC", "RST", "RD", "WR",
97 "CS", "IRQ", "LED" };
98
99static int am300_wait_event(struct broadsheetfb_par *par)
100{
101
102 wait_event(par->waitq, gpio_get_value(RDY_GPIO_PIN));
103 return 0;
104}
105
106static 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
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
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
142 gpio_direction_input(RDY_GPIO_PIN);
143 gpio_direction_input(IRQ_GPIO_PIN);
144
145
146 for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++)
147 gpio_direction_output(i, 0);
148
149
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
159err_req_gpio2:
160 while (--i >= DB0_GPIO_PIN)
161 gpio_free(i);
162 i = ARRAY_SIZE(gpios);
163err_req_gpio:
164 while (--i >= 0)
165 gpio_free(gpios[i]);
166
167 return err;
168}
169
170static int am300_init_board(struct broadsheetfb_par *par)
171{
172 return am300_init_gpio_regs(par);
173}
174
175static 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
189static 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
200static 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
209static 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
225static int am300_get_panel_type(void)
226{
227 return panel_type;
228}
229
230static 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
238static 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
252static 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
264int __init am300_init(void)
265{
266 int ret;
267
268 pxa2xx_mfp_config(ARRAY_AND_SIZE(am300_pin_config));
269
270
271 request_module("broadsheetfb");
272
273 am300_device = platform_device_alloc("broadsheetfb", -1);
274 if (!am300_device)
275 return -ENOMEM;
276
277
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
291module_param(panel_type, uint, 0);
292MODULE_PARM_DESC(panel_type, "Select the panel type: 37, 6, 97");
293
294MODULE_DESCRIPTION("board driver for am300 epd kit");
295MODULE_AUTHOR("Jaya Kumar");
296MODULE_LICENSE("GPL");
297