Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
bf537-lq035.c
Go to the documentation of this file.
1 /*
2  * Analog Devices Blackfin(BF537 STAMP) + SHARP TFT LCD.
3  * http://docs.blackfin.uclinux.org/doku.php?id=hw:cards:tft-lcd
4  *
5  * Copyright 2006-2010 Analog Devices Inc.
6  * Licensed under the GPL-2.
7  */
8 
9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10 
11 #include <linux/module.h>
12 #include <linux/kernel.h>
13 #include <linux/errno.h>
14 #include <linux/string.h>
15 #include <linux/mm.h>
16 #include <linux/delay.h>
17 #include <linux/fb.h>
18 #include <linux/ioport.h>
19 #include <linux/init.h>
20 #include <linux/types.h>
21 #include <linux/gpio.h>
22 #include <linux/interrupt.h>
23 #include <linux/sched.h>
24 #include <linux/timer.h>
25 #include <linux/device.h>
26 #include <linux/backlight.h>
27 #include <linux/lcd.h>
28 #include <linux/i2c.h>
29 #include <linux/spinlock.h>
30 #include <linux/dma-mapping.h>
31 #include <linux/slab.h>
32 #include <linux/platform_device.h>
33 
34 #include <asm/blackfin.h>
35 #include <asm/irq.h>
36 #include <asm/dpmc.h>
37 #include <asm/dma.h>
38 #include <asm/portmux.h>
39 
40 #define NO_BL 1
41 
42 #define MAX_BRIGHENESS 95
43 #define MIN_BRIGHENESS 5
44 #define NBR_PALETTE 256
45 
46 static const unsigned short ppi_pins[] = {
51 };
52 
53 static unsigned char *fb_buffer; /* RGB Buffer */
54 static unsigned long *dma_desc_table;
55 static int t_conf_done, lq035_open_cnt;
56 static DEFINE_SPINLOCK(bfin_lq035_lock);
57 
58 static int landscape;
59 module_param(landscape, int, 0);
60 MODULE_PARM_DESC(landscape,
61  "LANDSCAPE use 320x240 instead of Native 240x320 Resolution");
62 
63 static int bgr;
64 module_param(bgr, int, 0);
66  "BGR use 16-bit BGR-565 instead of RGB-565");
67 
68 static int nocursor = 1;
69 module_param(nocursor, int, 0644);
70 MODULE_PARM_DESC(nocursor, "cursor enable/disable");
71 
72 static unsigned long current_brightness; /* backlight */
73 
74 /* AD5280 vcomm */
75 static unsigned char vcomm_value = 150;
76 static struct i2c_client *ad5280_client;
77 
78 static void set_vcomm(void)
79 {
80  int nr;
81 
82  if (!ad5280_client)
83  return;
84 
85  nr = i2c_smbus_write_byte_data(ad5280_client, 0x00, vcomm_value);
86  if (nr)
87  pr_err("i2c_smbus_write_byte_data fail: %d\n", nr);
88 }
89 
90 static int __devinit ad5280_probe(struct i2c_client *client,
91  const struct i2c_device_id *id)
92 {
93  int ret;
94  if (!i2c_check_functionality(client->adapter,
96  dev_err(&client->dev, "SMBUS Byte Data not Supported\n");
97  return -EIO;
98  }
99 
100  ret = i2c_smbus_write_byte_data(client, 0x00, vcomm_value);
101  if (ret) {
102  dev_err(&client->dev, "write fail: %d\n", ret);
103  return ret;
104  }
105 
106  ad5280_client = client;
107 
108  return 0;
109 }
110 
111 static int __devexit ad5280_remove(struct i2c_client *client)
112 {
113  ad5280_client = NULL;
114  return 0;
115 }
116 
117 static const struct i2c_device_id ad5280_id[] = {
118  {"bf537-lq035-ad5280", 0},
119  {}
120 };
121 
122 MODULE_DEVICE_TABLE(i2c, ad5280_id);
123 
124 static struct i2c_driver ad5280_driver = {
125  .driver = {
126  .name = "bf537-lq035-ad5280",
127  },
128  .probe = ad5280_probe,
129  .remove = __devexit_p(ad5280_remove),
130  .id_table = ad5280_id,
131 };
132 
133 #ifdef CONFIG_PNAV10
134 #define MOD GPIO_PH13
135 
136 #define bfin_write_TIMER_LP_CONFIG bfin_write_TIMER0_CONFIG
137 #define bfin_write_TIMER_LP_WIDTH bfin_write_TIMER0_WIDTH
138 #define bfin_write_TIMER_LP_PERIOD bfin_write_TIMER0_PERIOD
139 #define bfin_read_TIMER_LP_COUNTER bfin_read_TIMER0_COUNTER
140 #define TIMDIS_LP TIMDIS0
141 #define TIMEN_LP TIMEN0
142 
143 #define bfin_write_TIMER_SPS_CONFIG bfin_write_TIMER1_CONFIG
144 #define bfin_write_TIMER_SPS_WIDTH bfin_write_TIMER1_WIDTH
145 #define bfin_write_TIMER_SPS_PERIOD bfin_write_TIMER1_PERIOD
146 #define TIMDIS_SPS TIMDIS1
147 #define TIMEN_SPS TIMEN1
148 
149 #define bfin_write_TIMER_SP_CONFIG bfin_write_TIMER5_CONFIG
150 #define bfin_write_TIMER_SP_WIDTH bfin_write_TIMER5_WIDTH
151 #define bfin_write_TIMER_SP_PERIOD bfin_write_TIMER5_PERIOD
152 #define TIMDIS_SP TIMDIS5
153 #define TIMEN_SP TIMEN5
154 
155 #define bfin_write_TIMER_PS_CLS_CONFIG bfin_write_TIMER2_CONFIG
156 #define bfin_write_TIMER_PS_CLS_WIDTH bfin_write_TIMER2_WIDTH
157 #define bfin_write_TIMER_PS_CLS_PERIOD bfin_write_TIMER2_PERIOD
158 #define TIMDIS_PS_CLS TIMDIS2
159 #define TIMEN_PS_CLS TIMEN2
160 
161 #define bfin_write_TIMER_REV_CONFIG bfin_write_TIMER3_CONFIG
162 #define bfin_write_TIMER_REV_WIDTH bfin_write_TIMER3_WIDTH
163 #define bfin_write_TIMER_REV_PERIOD bfin_write_TIMER3_PERIOD
164 #define TIMDIS_REV TIMDIS3
165 #define TIMEN_REV TIMEN3
166 #define bfin_read_TIMER_REV_COUNTER bfin_read_TIMER3_COUNTER
167 
168 #define FREQ_PPI_CLK (5*1024*1024) /* PPI_CLK 5MHz */
169 
170 #define TIMERS {P_TMR0, P_TMR1, P_TMR2, P_TMR3, P_TMR5, 0}
171 
172 #else
173 
174 #define UD GPIO_PF13 /* Up / Down */
175 #define MOD GPIO_PF10
176 #define LBR GPIO_PF14 /* Left Right */
177 
178 #define bfin_write_TIMER_LP_CONFIG bfin_write_TIMER6_CONFIG
179 #define bfin_write_TIMER_LP_WIDTH bfin_write_TIMER6_WIDTH
180 #define bfin_write_TIMER_LP_PERIOD bfin_write_TIMER6_PERIOD
181 #define bfin_read_TIMER_LP_COUNTER bfin_read_TIMER6_COUNTER
182 #define TIMDIS_LP TIMDIS6
183 #define TIMEN_LP TIMEN6
184 
185 #define bfin_write_TIMER_SPS_CONFIG bfin_write_TIMER1_CONFIG
186 #define bfin_write_TIMER_SPS_WIDTH bfin_write_TIMER1_WIDTH
187 #define bfin_write_TIMER_SPS_PERIOD bfin_write_TIMER1_PERIOD
188 #define TIMDIS_SPS TIMDIS1
189 #define TIMEN_SPS TIMEN1
190 
191 #define bfin_write_TIMER_SP_CONFIG bfin_write_TIMER0_CONFIG
192 #define bfin_write_TIMER_SP_WIDTH bfin_write_TIMER0_WIDTH
193 #define bfin_write_TIMER_SP_PERIOD bfin_write_TIMER0_PERIOD
194 #define TIMDIS_SP TIMDIS0
195 #define TIMEN_SP TIMEN0
196 
197 #define bfin_write_TIMER_PS_CLS_CONFIG bfin_write_TIMER7_CONFIG
198 #define bfin_write_TIMER_PS_CLS_WIDTH bfin_write_TIMER7_WIDTH
199 #define bfin_write_TIMER_PS_CLS_PERIOD bfin_write_TIMER7_PERIOD
200 #define TIMDIS_PS_CLS TIMDIS7
201 #define TIMEN_PS_CLS TIMEN7
202 
203 #define bfin_write_TIMER_REV_CONFIG bfin_write_TIMER5_CONFIG
204 #define bfin_write_TIMER_REV_WIDTH bfin_write_TIMER5_WIDTH
205 #define bfin_write_TIMER_REV_PERIOD bfin_write_TIMER5_PERIOD
206 #define TIMDIS_REV TIMDIS5
207 #define TIMEN_REV TIMEN5
208 #define bfin_read_TIMER_REV_COUNTER bfin_read_TIMER5_COUNTER
209 
210 #define FREQ_PPI_CLK (6*1000*1000) /* PPI_CLK 6MHz */
211 #define TIMERS {P_TMR0, P_TMR1, P_TMR5, P_TMR6, P_TMR7, 0}
212 
213 #endif
214 
215 #define LCD_X_RES 240 /* Horizontal Resolution */
216 #define LCD_Y_RES 320 /* Vertical Resolution */
217 
218 #define LCD_BBP 16 /* Bit Per Pixel */
219 
220 /* the LCD and the DMA start counting differently;
221  * since one starts at 0 and the other starts at 1,
222  * we have a difference of 1 between START_LINES
223  * and U_LINES.
224  */
225 #define START_LINES 8 /* lines for field flyback or field blanking signal */
226 #define U_LINES 9 /* number of undisplayed blanking lines */
227 
228 #define FRAMES_PER_SEC (60)
229 
230 #define DCLKS_PER_FRAME (FREQ_PPI_CLK/FRAMES_PER_SEC)
231 #define DCLKS_PER_LINE (DCLKS_PER_FRAME/(LCD_Y_RES+U_LINES))
232 
233 #define PPI_CONFIG_VALUE (PORT_DIR|XFR_TYPE|DLEN_16|POLS)
234 #define PPI_DELAY_VALUE (0)
235 #define TIMER_CONFIG (PWM_OUT|PERIOD_CNT|TIN_SEL|CLK_SEL)
236 
237 #define ACTIVE_VIDEO_MEM_OFFSET (LCD_X_RES*START_LINES*(LCD_BBP/8))
238 #define ACTIVE_VIDEO_MEM_SIZE (LCD_Y_RES*LCD_X_RES*(LCD_BBP/8))
239 #define TOTAL_VIDEO_MEM_SIZE ((LCD_Y_RES+U_LINES)*LCD_X_RES*(LCD_BBP/8))
240 #define TOTAL_DMA_DESC_SIZE (2 * sizeof(u32) * (LCD_Y_RES + U_LINES))
241 
242 static void start_timers(void) /* CHECK with HW */
243 {
244  unsigned long flags;
245 
246  local_irq_save(flags);
247 
249  SSYNC();
250 
251  while (bfin_read_TIMER_REV_COUNTER() <= 11)
252  continue;
254  SSYNC();
255 
256  while (bfin_read_TIMER_LP_COUNTER() < 3)
257  continue;
259  SSYNC();
260  t_conf_done = 1;
261  local_irq_restore(flags);
262 }
263 
264 static void config_timers(void)
265 {
266  /* Stop timers */
269  SSYNC();
270 
271  /* LP, timer 6 */
274 
276  SSYNC();
277 
278  /* SPS, timer 1 */
282  SSYNC();
283 
284  /* SP, timer 0 */
288  SSYNC();
289 
290  /* PS & CLS, timer 7 */
294 
295  SSYNC();
296 
297 #ifdef NO_BL
298  /* REV, timer 5 */
300 
303 
304  SSYNC();
305 #endif
306 }
307 
308 static void config_ppi(void)
309 {
312  /* 0x10 -> PORT_CFG -> 2 or 3 frame syncs */
314 }
315 
316 static int config_dma(void)
317 {
318  u32 i;
319 
320  if (landscape) {
321 
322  for (i = 0; i < U_LINES; ++i) {
323  /* blanking lines point to first line of fb_buffer */
324  dma_desc_table[2*i] = (unsigned long)&dma_desc_table[2*i+2];
325  dma_desc_table[2*i+1] = (unsigned long)fb_buffer;
326  }
327 
328  for (i = U_LINES; i < U_LINES + LCD_Y_RES; ++i) {
329  /* visible lines */
330  dma_desc_table[2*i] = (unsigned long)&dma_desc_table[2*i+2];
331  dma_desc_table[2*i+1] = (unsigned long)fb_buffer +
332  (LCD_Y_RES+U_LINES-1-i)*2;
333  }
334 
335  /* last descriptor points to first */
336  dma_desc_table[2*(LCD_Y_RES+U_LINES-1)] = (unsigned long)&dma_desc_table[0];
337 
338  set_dma_x_count(CH_PPI, LCD_X_RES);
339  set_dma_x_modify(CH_PPI, LCD_Y_RES * (LCD_BBP / 8));
340  set_dma_y_count(CH_PPI, 0);
341  set_dma_y_modify(CH_PPI, 0);
342  set_dma_next_desc_addr(CH_PPI, (void *)dma_desc_table[0]);
343  set_dma_config(CH_PPI, DMAFLOW_LARGE | NDSIZE_4 | WDSIZE_16);
344 
345  } else {
346 
347  set_dma_config(CH_PPI, set_bfin_dma_config(DIR_READ,
349  INTR_DISABLE,
350  DIMENSION_2D,
351  DATA_SIZE_16,
353  set_dma_x_count(CH_PPI, LCD_X_RES);
354  set_dma_x_modify(CH_PPI, LCD_BBP / 8);
355  set_dma_y_count(CH_PPI, LCD_Y_RES+U_LINES);
356  set_dma_y_modify(CH_PPI, LCD_BBP / 8);
357  set_dma_start_addr(CH_PPI, (unsigned long) fb_buffer);
358  }
359 
360  return 0;
361 }
362 
363 static int __devinit request_ports(void)
364 {
365  u16 tmr_req[] = TIMERS;
366 
367  /*
368  UD: PF13
369  MOD: PF10
370  LBR: PF14
371  PPI_CLK: PF15
372  */
373 
374  if (peripheral_request_list(ppi_pins, KBUILD_MODNAME)) {
375  pr_err("requesting PPI peripheral failed\n");
376  return -EBUSY;
377  }
378 
379  if (peripheral_request_list(tmr_req, KBUILD_MODNAME)) {
380  peripheral_free_list(ppi_pins);
381  pr_err("requesting timer peripheral failed\n");
382  return -EBUSY;
383  }
384 
385 #if (defined(UD) && defined(LBR))
386  if (gpio_request_one(UD, GPIOF_OUT_INIT_LOW, KBUILD_MODNAME)) {
387  pr_err("requesting GPIO %d failed\n", UD);
388  return -EBUSY;
389  }
390 
391  if (gpio_request_one(LBR, GPIOF_OUT_INIT_HIGH, KBUILD_MODNAME)) {
392  pr_err("requesting GPIO %d failed\n", LBR);
393  gpio_free(UD);
394  return -EBUSY;
395  }
396 #endif
397 
398  if (gpio_request_one(MOD, GPIOF_OUT_INIT_HIGH, KBUILD_MODNAME)) {
399  pr_err("requesting GPIO %d failed\n", MOD);
400 #if (defined(UD) && defined(LBR))
401  gpio_free(LBR);
402  gpio_free(UD);
403 #endif
404  return -EBUSY;
405  }
406 
407  SSYNC();
408  return 0;
409 }
410 
411 static void free_ports(void)
412 {
413  u16 tmr_req[] = TIMERS;
414 
415  peripheral_free_list(ppi_pins);
416  peripheral_free_list(tmr_req);
417 
418 #if defined(UD) && defined(LBR)
419  gpio_free(LBR);
420  gpio_free(UD);
421 #endif
422  gpio_free(MOD);
423 }
424 
425 static struct fb_info bfin_lq035_fb;
426 
427 static struct fb_var_screeninfo bfin_lq035_fb_defined = {
428  .bits_per_pixel = LCD_BBP,
429  .activate = FB_ACTIVATE_TEST,
430  .xres = LCD_X_RES, /*default portrait mode RGB*/
431  .yres = LCD_Y_RES,
432  .xres_virtual = LCD_X_RES,
433  .yres_virtual = LCD_Y_RES,
434  .height = -1,
435  .width = -1,
436  .left_margin = 0,
437  .right_margin = 0,
438  .upper_margin = 0,
439  .lower_margin = 0,
440  .red = {11, 5, 0},
441  .green = {5, 6, 0},
442  .blue = {0, 5, 0},
443  .transp = {0, 0, 0},
444 };
445 
446 static struct fb_fix_screeninfo bfin_lq035_fb_fix __devinitdata = {
447  .id = KBUILD_MODNAME,
448  .smem_len = ACTIVE_VIDEO_MEM_SIZE,
449  .type = FB_TYPE_PACKED_PIXELS,
450  .visual = FB_VISUAL_TRUECOLOR,
451  .xpanstep = 0,
452  .ypanstep = 0,
453  .line_length = LCD_X_RES*(LCD_BBP/8),
454  .accel = FB_ACCEL_NONE,
455 };
456 
457 
458 static int bfin_lq035_fb_open(struct fb_info *info, int user)
459 {
460  unsigned long flags;
461 
462  spin_lock_irqsave(&bfin_lq035_lock, flags);
463  lq035_open_cnt++;
464  spin_unlock_irqrestore(&bfin_lq035_lock, flags);
465 
466  if (lq035_open_cnt <= 1) {
468  SSYNC();
469 
470  set_vcomm();
471  config_dma();
472  config_ppi();
473 
474  /* start dma */
476  SSYNC();
478  SSYNC();
479 
480  if (!t_conf_done) {
481  config_timers();
482  start_timers();
483  }
484  /* gpio_set_value(MOD,1); */
485  }
486 
487  return 0;
488 }
489 
490 static int bfin_lq035_fb_release(struct fb_info *info, int user)
491 {
492  unsigned long flags;
493 
494  spin_lock_irqsave(&bfin_lq035_lock, flags);
495  lq035_open_cnt--;
496  spin_unlock_irqrestore(&bfin_lq035_lock, flags);
497 
498 
499  if (lq035_open_cnt <= 0) {
500 
502  SSYNC();
503 
505  }
506 
507  return 0;
508 }
509 
510 
511 static int bfin_lq035_fb_check_var(struct fb_var_screeninfo *var,
512  struct fb_info *info)
513 {
514  switch (var->bits_per_pixel) {
515  case 16:/* DIRECTCOLOUR, 64k */
516  var->red.offset = info->var.red.offset;
517  var->green.offset = info->var.green.offset;
518  var->blue.offset = info->var.blue.offset;
519  var->red.length = info->var.red.length;
520  var->green.length = info->var.green.length;
521  var->blue.length = info->var.blue.length;
522  var->transp.offset = 0;
523  var->transp.length = 0;
524  var->transp.msb_right = 0;
525  var->red.msb_right = 0;
526  var->green.msb_right = 0;
527  var->blue.msb_right = 0;
528  break;
529  default:
530  pr_debug("%s: depth not supported: %u BPP\n", __func__,
531  var->bits_per_pixel);
532  return -EINVAL;
533  }
534 
535  if (info->var.xres != var->xres ||
536  info->var.yres != var->yres ||
537  info->var.xres_virtual != var->xres_virtual ||
538  info->var.yres_virtual != var->yres_virtual) {
539  pr_debug("%s: Resolution not supported: X%u x Y%u\n",
540  __func__, var->xres, var->yres);
541  return -EINVAL;
542  }
543 
544  /*
545  * Memory limit
546  */
547 
548  if ((info->fix.line_length * var->yres_virtual) > info->fix.smem_len) {
549  pr_debug("%s: Memory Limit requested yres_virtual = %u\n",
550  __func__, var->yres_virtual);
551  return -ENOMEM;
552  }
553 
554  return 0;
555 }
556 
557 /* fb_rotate
558  * Rotate the display of this angle. This doesn't seems to be used by the core,
559  * but as our hardware supports it, so why not implementing it...
560  */
561 static void bfin_lq035_fb_rotate(struct fb_info *fbi, int angle)
562 {
563  pr_debug("%s: %p %d", __func__, fbi, angle);
564 #if (defined(UD) && defined(LBR))
565  switch (angle) {
566 
567  case 180:
568  gpio_set_value(LBR, 0);
569  gpio_set_value(UD, 1);
570  break;
571  default:
572  gpio_set_value(LBR, 1);
573  gpio_set_value(UD, 0);
574  break;
575  }
576 #endif
577 }
578 
579 static int bfin_lq035_fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
580 {
581  if (nocursor)
582  return 0;
583  else
584  return -EINVAL; /* just to force soft_cursor() call */
585 }
586 
587 static int bfin_lq035_fb_setcolreg(u_int regno, u_int red, u_int green,
589  struct fb_info *info)
590 {
591  if (regno >= NBR_PALETTE)
592  return -EINVAL;
593 
594  if (info->var.grayscale)
595  /* grayscale = 0.30*R + 0.59*G + 0.11*B */
596  red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
597 
598  if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
599 
600  u32 value;
601  /* Place color in the pseudopalette */
602  if (regno > 16)
603  return -EINVAL;
604 
605  red >>= (16 - info->var.red.length);
606  green >>= (16 - info->var.green.length);
607  blue >>= (16 - info->var.blue.length);
608 
609  value = (red << info->var.red.offset) |
610  (green << info->var.green.offset)|
611  (blue << info->var.blue.offset);
612  value &= 0xFFFF;
613 
614  ((u32 *) (info->pseudo_palette))[regno] = value;
615 
616  }
617 
618  return 0;
619 }
620 
621 static struct fb_ops bfin_lq035_fb_ops = {
622  .owner = THIS_MODULE,
623  .fb_open = bfin_lq035_fb_open,
624  .fb_release = bfin_lq035_fb_release,
625  .fb_check_var = bfin_lq035_fb_check_var,
626  .fb_rotate = bfin_lq035_fb_rotate,
627  .fb_fillrect = cfb_fillrect,
628  .fb_copyarea = cfb_copyarea,
629  .fb_imageblit = cfb_imageblit,
630  .fb_cursor = bfin_lq035_fb_cursor,
631  .fb_setcolreg = bfin_lq035_fb_setcolreg,
632 };
633 
634 static int bl_get_brightness(struct backlight_device *bd)
635 {
636  return current_brightness;
637 }
638 
639 static const struct backlight_ops bfin_lq035fb_bl_ops = {
640  .get_brightness = bl_get_brightness,
641 };
642 
643 static struct backlight_device *bl_dev;
644 
645 static int bfin_lcd_get_power(struct lcd_device *dev)
646 {
647  return 0;
648 }
649 
650 static int bfin_lcd_set_power(struct lcd_device *dev, int power)
651 {
652  return 0;
653 }
654 
655 static int bfin_lcd_get_contrast(struct lcd_device *dev)
656 {
657  return (int)vcomm_value;
658 }
659 
660 static int bfin_lcd_set_contrast(struct lcd_device *dev, int contrast)
661 {
662  if (contrast > 255)
663  contrast = 255;
664  if (contrast < 0)
665  contrast = 0;
666 
667  vcomm_value = (unsigned char)contrast;
668  set_vcomm();
669  return 0;
670 }
671 
672 static int bfin_lcd_check_fb(struct lcd_device *lcd, struct fb_info *fi)
673 {
674  if (!fi || (fi == &bfin_lq035_fb))
675  return 1;
676  return 0;
677 }
678 
679 static struct lcd_ops bfin_lcd_ops = {
680  .get_power = bfin_lcd_get_power,
681  .set_power = bfin_lcd_set_power,
682  .get_contrast = bfin_lcd_get_contrast,
683  .set_contrast = bfin_lcd_set_contrast,
684  .check_fb = bfin_lcd_check_fb,
685 };
686 
687 static struct lcd_device *lcd_dev;
688 
689 static int __devinit bfin_lq035_probe(struct platform_device *pdev)
690 {
691  struct backlight_properties props;
693  int ret;
694 
695  if (request_dma(CH_PPI, KBUILD_MODNAME)) {
696  pr_err("couldn't request PPI DMA\n");
697  return -EFAULT;
698  }
699 
700  if (request_ports()) {
701  pr_err("couldn't request gpio port\n");
702  ret = -EFAULT;
703  goto out_ports;
704  }
705 
707  &dma_handle, GFP_KERNEL);
708  if (fb_buffer == NULL) {
709  pr_err("couldn't allocate dma buffer\n");
710  ret = -ENOMEM;
711  goto out_dma_coherent;
712  }
713 
714  if (L1_DATA_A_LENGTH)
715  dma_desc_table = l1_data_sram_zalloc(TOTAL_DMA_DESC_SIZE);
716  else
717  dma_desc_table = dma_alloc_coherent(NULL, TOTAL_DMA_DESC_SIZE,
718  &dma_handle, 0);
719 
720  if (dma_desc_table == NULL) {
721  pr_err("couldn't allocate dma descriptor\n");
722  ret = -ENOMEM;
723  goto out_table;
724  }
725 
726  bfin_lq035_fb.screen_base = (void *)fb_buffer;
727  bfin_lq035_fb_fix.smem_start = (int)fb_buffer;
728  if (landscape) {
729  bfin_lq035_fb_defined.xres = LCD_Y_RES;
730  bfin_lq035_fb_defined.yres = LCD_X_RES;
731  bfin_lq035_fb_defined.xres_virtual = LCD_Y_RES;
732  bfin_lq035_fb_defined.yres_virtual = LCD_X_RES;
733 
734  bfin_lq035_fb_fix.line_length = LCD_Y_RES*(LCD_BBP/8);
735  } else {
736  bfin_lq035_fb.screen_base += ACTIVE_VIDEO_MEM_OFFSET;
737  bfin_lq035_fb_fix.smem_start += ACTIVE_VIDEO_MEM_OFFSET;
738  }
739 
740  bfin_lq035_fb_defined.green.msb_right = 0;
741  bfin_lq035_fb_defined.red.msb_right = 0;
742  bfin_lq035_fb_defined.blue.msb_right = 0;
743  bfin_lq035_fb_defined.green.offset = 5;
744  bfin_lq035_fb_defined.green.length = 6;
745  bfin_lq035_fb_defined.red.length = 5;
746  bfin_lq035_fb_defined.blue.length = 5;
747 
748  if (bgr) {
749  bfin_lq035_fb_defined.red.offset = 0;
750  bfin_lq035_fb_defined.blue.offset = 11;
751  } else {
752  bfin_lq035_fb_defined.red.offset = 11;
753  bfin_lq035_fb_defined.blue.offset = 0;
754  }
755 
756  bfin_lq035_fb.fbops = &bfin_lq035_fb_ops;
757  bfin_lq035_fb.var = bfin_lq035_fb_defined;
758 
759  bfin_lq035_fb.fix = bfin_lq035_fb_fix;
760  bfin_lq035_fb.flags = FBINFO_DEFAULT;
761 
762 
763  bfin_lq035_fb.pseudo_palette = devm_kzalloc(&pdev->dev,
764  sizeof(u32) * 16,
765  GFP_KERNEL);
766  if (bfin_lq035_fb.pseudo_palette == NULL) {
767  pr_err("failed to allocate pseudo_palette\n");
768  ret = -ENOMEM;
769  goto out_table;
770  }
771 
772  if (fb_alloc_cmap(&bfin_lq035_fb.cmap, NBR_PALETTE, 0) < 0) {
773  pr_err("failed to allocate colormap (%d entries)\n",
774  NBR_PALETTE);
775  ret = -EFAULT;
776  goto out_table;
777  }
778 
779  if (register_framebuffer(&bfin_lq035_fb) < 0) {
780  pr_err("unable to register framebuffer\n");
781  ret = -EINVAL;
782  goto out_reg;
783  }
784 
785  i2c_add_driver(&ad5280_driver);
786 
787  memset(&props, 0, sizeof(props));
788  props.type = BACKLIGHT_RAW;
789  props.max_brightness = MAX_BRIGHENESS;
790  bl_dev = backlight_device_register("bf537-bl", NULL, NULL,
791  &bfin_lq035fb_bl_ops, &props);
792 
793  lcd_dev = lcd_device_register(KBUILD_MODNAME, &pdev->dev, NULL,
794  &bfin_lcd_ops);
795  if (IS_ERR(lcd_dev)) {
796  pr_err("unable to register lcd\n");
797  ret = PTR_ERR(lcd_dev);
798  goto out_lcd;
799  }
800  lcd_dev->props.max_contrast = 255,
801 
802  pr_info("initialized");
803 
804  return 0;
805 out_lcd:
806  unregister_framebuffer(&bfin_lq035_fb);
807 out_reg:
808  fb_dealloc_cmap(&bfin_lq035_fb.cmap);
809 out_table:
811  fb_buffer = NULL;
812 out_dma_coherent:
813  free_ports();
814 out_ports:
815  free_dma(CH_PPI);
816  return ret;
817 }
818 
819 static int __devexit bfin_lq035_remove(struct platform_device *pdev)
820 {
821  if (fb_buffer != NULL)
823 
824  if (L1_DATA_A_LENGTH)
825  l1_data_sram_free(dma_desc_table);
826  else
828 
831  t_conf_done = 0;
832 
833  free_dma(CH_PPI);
834 
835 
836  fb_dealloc_cmap(&bfin_lq035_fb.cmap);
837 
838 
839  lcd_device_unregister(lcd_dev);
841 
842  unregister_framebuffer(&bfin_lq035_fb);
843  i2c_del_driver(&ad5280_driver);
844 
845  free_ports();
846 
847  pr_info("unregistered LCD driver\n");
848 
849  return 0;
850 }
851 
852 #ifdef CONFIG_PM
853 static int bfin_lq035_suspend(struct platform_device *pdev, pm_message_t state)
854 {
855  if (lq035_open_cnt > 0) {
857  SSYNC();
859  }
860 
861  return 0;
862 }
863 
864 static int bfin_lq035_resume(struct platform_device *pdev)
865 {
866  if (lq035_open_cnt > 0) {
868  SSYNC();
869 
870  config_dma();
871  config_ppi();
872 
875  SSYNC();
876 
877  config_timers();
878  start_timers();
879  } else {
880  t_conf_done = 0;
881  }
882 
883  return 0;
884 }
885 #else
886 # define bfin_lq035_suspend NULL
887 # define bfin_lq035_resume NULL
888 #endif
889 
890 static struct platform_driver bfin_lq035_driver = {
891  .probe = bfin_lq035_probe,
892  .remove = __devexit_p(bfin_lq035_remove),
893  .suspend = bfin_lq035_suspend,
894  .resume = bfin_lq035_resume,
895  .driver = {
896  .name = KBUILD_MODNAME,
897  .owner = THIS_MODULE,
898  },
899 };
900 
901 static int __init bfin_lq035_driver_init(void)
902 {
903  request_module("i2c-bfin-twi");
904  return platform_driver_register(&bfin_lq035_driver);
905 }
906 module_init(bfin_lq035_driver_init);
907 
908 static void __exit bfin_lq035_driver_cleanup(void)
909 {
910  platform_driver_unregister(&bfin_lq035_driver);
911 }
912 module_exit(bfin_lq035_driver_cleanup);
913 
914 MODULE_DESCRIPTION("SHARP LQ035Q7DB03 TFT LCD Driver");
915 MODULE_LICENSE("GPL");