~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm/mach-pxa/am300epd.c

Version: ~ [ linux-5.5-rc7 ] ~ [ linux-5.4.13 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.97 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.166 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.210 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.210 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.81 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 "gumstix.h"
 32 #include "mfp-pxa25x.h"
 33 #include <mach/irqs.h>
 34 #include <linux/platform_data/video-pxafb.h>
 35 
 36 #include "generic.h"
 37 
 38 #include <video/broadsheetfb.h>
 39 
 40 static unsigned int panel_type = 6;
 41 static struct platform_device *am300_device;
 42 static struct broadsheet_board am300_board;
 43 
 44 static unsigned long am300_pin_config[] __initdata = {
 45         GPIO16_GPIO,
 46         GPIO17_GPIO,
 47         GPIO32_GPIO,
 48         GPIO48_GPIO,
 49         GPIO49_GPIO,
 50         GPIO51_GPIO,
 51         GPIO74_GPIO,
 52         GPIO75_GPIO,
 53         GPIO76_GPIO,
 54         GPIO77_GPIO,
 55 
 56         /* this is the 16-bit hdb bus 58-73 */
 57         GPIO58_GPIO,
 58         GPIO59_GPIO,
 59         GPIO60_GPIO,
 60         GPIO61_GPIO,
 61 
 62         GPIO62_GPIO,
 63         GPIO63_GPIO,
 64         GPIO64_GPIO,
 65         GPIO65_GPIO,
 66 
 67         GPIO66_GPIO,
 68         GPIO67_GPIO,
 69         GPIO68_GPIO,
 70         GPIO69_GPIO,
 71 
 72         GPIO70_GPIO,
 73         GPIO71_GPIO,
 74         GPIO72_GPIO,
 75         GPIO73_GPIO,
 76 };
 77 
 78 /* register offsets for gpio control */
 79 #define PWR_GPIO_PIN    16
 80 #define CFG_GPIO_PIN    17
 81 #define RDY_GPIO_PIN    32
 82 #define DC_GPIO_PIN     48
 83 #define RST_GPIO_PIN    49
 84 #define LED_GPIO_PIN    51
 85 #define RD_GPIO_PIN     74
 86 #define WR_GPIO_PIN     75
 87 #define CS_GPIO_PIN     76
 88 #define IRQ_GPIO_PIN    77
 89 
 90 /* hdb bus */
 91 #define DB0_GPIO_PIN    58
 92 #define DB15_GPIO_PIN   73
 93 
 94 static int gpios[] = { PWR_GPIO_PIN, CFG_GPIO_PIN, RDY_GPIO_PIN, DC_GPIO_PIN,
 95                         RST_GPIO_PIN, RD_GPIO_PIN, WR_GPIO_PIN, CS_GPIO_PIN,
 96                         IRQ_GPIO_PIN, LED_GPIO_PIN };
 97 static char *gpio_names[] = { "PWR", "CFG", "RDY", "DC", "RST", "RD", "WR",
 98                                 "CS", "IRQ", "LED" };
 99 
100 static int am300_wait_event(struct broadsheetfb_par *par)
101 {
102         /* todo: improve err recovery */
103         wait_event(par->waitq, gpio_get_value(RDY_GPIO_PIN));
104         return 0;
105 }
106 
107 static int am300_init_gpio_regs(struct broadsheetfb_par *par)
108 {
109         int i;
110         int err;
111         char dbname[8];
112 
113         for (i = 0; i < ARRAY_SIZE(gpios); i++) {
114                 err = gpio_request(gpios[i], gpio_names[i]);
115                 if (err) {
116                         dev_err(&am300_device->dev, "failed requesting "
117                                 "gpio %s, err=%d\n", gpio_names[i], err);
118                         goto err_req_gpio;
119                 }
120         }
121 
122         /* we also need to take care of the hdb bus */
123         for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++) {
124                 sprintf(dbname, "DB%d", i);
125                 err = gpio_request(i, dbname);
126                 if (err) {
127                         dev_err(&am300_device->dev, "failed requesting "
128                                 "gpio %d, err=%d\n", i, err);
129                         goto err_req_gpio2;
130                 }
131         }
132 
133         /* setup the outputs and init values */
134         gpio_direction_output(PWR_GPIO_PIN, 0);
135         gpio_direction_output(CFG_GPIO_PIN, 1);
136         gpio_direction_output(DC_GPIO_PIN, 0);
137         gpio_direction_output(RD_GPIO_PIN, 1);
138         gpio_direction_output(WR_GPIO_PIN, 1);
139         gpio_direction_output(CS_GPIO_PIN, 1);
140         gpio_direction_output(RST_GPIO_PIN, 0);
141 
142         /* setup the inputs */
143         gpio_direction_input(RDY_GPIO_PIN);
144         gpio_direction_input(IRQ_GPIO_PIN);
145 
146         /* start the hdb bus as an input */
147         for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++)
148                 gpio_direction_output(i, 0);
149 
150         /* go into command mode */
151         gpio_set_value(CFG_GPIO_PIN, 1);
152         gpio_set_value(RST_GPIO_PIN, 0);
153         msleep(10);
154         gpio_set_value(RST_GPIO_PIN, 1);
155         msleep(10);
156         am300_wait_event(par);
157 
158         return 0;
159 
160 err_req_gpio2:
161         while (--i >= DB0_GPIO_PIN)
162                 gpio_free(i);
163         i = ARRAY_SIZE(gpios);
164 err_req_gpio:
165         while (--i >= 0)
166                 gpio_free(gpios[i]);
167 
168         return err;
169 }
170 
171 static int am300_init_board(struct broadsheetfb_par *par)
172 {
173         return am300_init_gpio_regs(par);
174 }
175 
176 static void am300_cleanup(struct broadsheetfb_par *par)
177 {
178         int i;
179 
180         free_irq(PXA_GPIO_TO_IRQ(RDY_GPIO_PIN), par);
181 
182         for (i = 0; i < ARRAY_SIZE(gpios); i++)
183                 gpio_free(gpios[i]);
184 
185         for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++)
186                 gpio_free(i);
187 
188 }
189 
190 static u16 am300_get_hdb(struct broadsheetfb_par *par)
191 {
192         u16 res = 0;
193         int i;
194 
195         for (i = 0; i <= (DB15_GPIO_PIN - DB0_GPIO_PIN) ; i++)
196                 res |= (gpio_get_value(DB0_GPIO_PIN + i)) ? (1 << i) : 0;
197 
198         return res;
199 }
200 
201 static void am300_set_hdb(struct broadsheetfb_par *par, u16 data)
202 {
203         int i;
204 
205         for (i = 0; i <= (DB15_GPIO_PIN - DB0_GPIO_PIN) ; i++)
206                 gpio_set_value(DB0_GPIO_PIN + i, (data >> i) & 0x01);
207 }
208 
209 
210 static void am300_set_ctl(struct broadsheetfb_par *par, unsigned char bit,
211                                 u8 state)
212 {
213         switch (bit) {
214         case BS_CS:
215                 gpio_set_value(CS_GPIO_PIN, state);
216                 break;
217         case BS_DC:
218                 gpio_set_value(DC_GPIO_PIN, state);
219                 break;
220         case BS_WR:
221                 gpio_set_value(WR_GPIO_PIN, state);
222                 break;
223         }
224 }
225 
226 static int am300_get_panel_type(void)
227 {
228         return panel_type;
229 }
230 
231 static irqreturn_t am300_handle_irq(int irq, void *dev_id)
232 {
233         struct broadsheetfb_par *par = dev_id;
234 
235         wake_up(&par->waitq);
236         return IRQ_HANDLED;
237 }
238 
239 static int am300_setup_irq(struct fb_info *info)
240 {
241         int ret;
242         struct broadsheetfb_par *par = info->par;
243 
244         ret = request_irq(PXA_GPIO_TO_IRQ(RDY_GPIO_PIN), am300_handle_irq,
245                                 IRQF_TRIGGER_RISING, "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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp