root/arch/arm/mach-pxa/am300epd.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. am300_wait_event
  2. am300_init_gpio_regs
  3. am300_init_board
  4. am300_cleanup
  5. am300_get_hdb
  6. am300_set_hdb
  7. am300_set_ctl
  8. am300_get_panel_type
  9. am300_handle_irq
  10. am300_setup_irq
  11. am300_init

   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");

/* [<][>][^][v][top][bottom][index][help] */