Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.3 283 lines 6.6 kB view raw
1/* drivers/video/backlight/vgg2432a4.c 2 * 3 * VGG2432A4 (ILI9320) LCD controller driver. 4 * 5 * Copyright 2007 Simtec Electronics 6 * http://armlinux.simtec.co.uk/ 7 * Ben Dooks <ben@simtec.co.uk> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12*/ 13 14#include <linux/delay.h> 15#include <linux/err.h> 16#include <linux/fb.h> 17#include <linux/init.h> 18#include <linux/lcd.h> 19#include <linux/module.h> 20 21#include <linux/spi/spi.h> 22 23#include <video/ili9320.h> 24 25#include "ili9320.h" 26 27/* Device initialisation sequences */ 28 29static struct ili9320_reg vgg_init1[] = { 30 { 31 .address = ILI9320_POWER1, 32 .value = ILI9320_POWER1_AP(0) | ILI9320_POWER1_BT(0), 33 }, { 34 .address = ILI9320_POWER2, 35 .value = (ILI9320_POWER2_VC(7) | 36 ILI9320_POWER2_DC0(0) | ILI9320_POWER2_DC1(0)), 37 }, { 38 .address = ILI9320_POWER3, 39 .value = ILI9320_POWER3_VRH(0), 40 }, { 41 .address = ILI9320_POWER4, 42 .value = ILI9320_POWER4_VREOUT(0), 43 }, 44}; 45 46static struct ili9320_reg vgg_init2[] = { 47 { 48 .address = ILI9320_POWER1, 49 .value = (ILI9320_POWER1_AP(3) | ILI9320_POWER1_APE | 50 ILI9320_POWER1_BT(7) | ILI9320_POWER1_SAP), 51 }, { 52 .address = ILI9320_POWER2, 53 .value = ILI9320_POWER2_VC(7) | ILI9320_POWER2_DC0(3), 54 } 55}; 56 57static struct ili9320_reg vgg_gamma[] = { 58 { 59 .address = ILI9320_GAMMA1, 60 .value = 0x0000, 61 }, { 62 .address = ILI9320_GAMMA2, 63 .value = 0x0505, 64 }, { 65 .address = ILI9320_GAMMA3, 66 .value = 0x0004, 67 }, { 68 .address = ILI9320_GAMMA4, 69 .value = 0x0006, 70 }, { 71 .address = ILI9320_GAMMA5, 72 .value = 0x0707, 73 }, { 74 .address = ILI9320_GAMMA6, 75 .value = 0x0105, 76 }, { 77 .address = ILI9320_GAMMA7, 78 .value = 0x0002, 79 }, { 80 .address = ILI9320_GAMMA8, 81 .value = 0x0707, 82 }, { 83 .address = ILI9320_GAMMA9, 84 .value = 0x0704, 85 }, { 86 .address = ILI9320_GAMMA10, 87 .value = 0x807, 88 } 89 90}; 91 92static struct ili9320_reg vgg_init0[] = { 93 [0] = { 94 /* set direction and scan mode gate */ 95 .address = ILI9320_DRIVER, 96 .value = ILI9320_DRIVER_SS, 97 }, { 98 .address = ILI9320_DRIVEWAVE, 99 .value = (ILI9320_DRIVEWAVE_MUSTSET | 100 ILI9320_DRIVEWAVE_EOR | ILI9320_DRIVEWAVE_BC), 101 }, { 102 .address = ILI9320_ENTRYMODE, 103 .value = ILI9320_ENTRYMODE_ID(3) | ILI9320_ENTRYMODE_BGR, 104 }, { 105 .address = ILI9320_RESIZING, 106 .value = 0x0, 107 }, 108}; 109 110 111static int vgg2432a4_lcd_init(struct ili9320 *lcd, 112 struct ili9320_platdata *cfg) 113{ 114 unsigned int addr; 115 int ret; 116 117 /* Set VCore before anything else (VGG243237-6UFLWA) */ 118 ret = ili9320_write(lcd, 0x00e5, 0x8000); 119 if (ret) 120 goto err_initial; 121 122 /* Start the oscillator up before we can do anything else. */ 123 ret = ili9320_write(lcd, ILI9320_OSCILATION, ILI9320_OSCILATION_OSC); 124 if (ret) 125 goto err_initial; 126 127 /* must wait at-lesat 10ms after starting */ 128 mdelay(15); 129 130 ret = ili9320_write_regs(lcd, vgg_init0, ARRAY_SIZE(vgg_init0)); 131 if (ret != 0) 132 goto err_initial; 133 134 ili9320_write(lcd, ILI9320_DISPLAY2, cfg->display2); 135 ili9320_write(lcd, ILI9320_DISPLAY3, cfg->display3); 136 ili9320_write(lcd, ILI9320_DISPLAY4, cfg->display4); 137 138 ili9320_write(lcd, ILI9320_RGB_IF1, cfg->rgb_if1); 139 ili9320_write(lcd, ILI9320_FRAMEMAKER, 0x0); 140 ili9320_write(lcd, ILI9320_RGB_IF2, cfg->rgb_if2); 141 142 ret = ili9320_write_regs(lcd, vgg_init1, ARRAY_SIZE(vgg_init1)); 143 if (ret != 0) 144 goto err_vgg; 145 146 mdelay(300); 147 148 ret = ili9320_write_regs(lcd, vgg_init2, ARRAY_SIZE(vgg_init2)); 149 if (ret != 0) 150 goto err_vgg2; 151 152 mdelay(100); 153 154 ili9320_write(lcd, ILI9320_POWER3, 0x13c); 155 156 mdelay(100); 157 158 ili9320_write(lcd, ILI9320_POWER4, 0x1c00); 159 ili9320_write(lcd, ILI9320_POWER7, 0x000e); 160 161 mdelay(100); 162 163 ili9320_write(lcd, ILI9320_GRAM_HORIZ_ADDR, 0x00); 164 ili9320_write(lcd, ILI9320_GRAM_VERT_ADD, 0x00); 165 166 ret = ili9320_write_regs(lcd, vgg_gamma, ARRAY_SIZE(vgg_gamma)); 167 if (ret != 0) 168 goto err_vgg3; 169 170 ili9320_write(lcd, ILI9320_HORIZ_START, 0x0); 171 ili9320_write(lcd, ILI9320_HORIZ_END, cfg->hsize - 1); 172 ili9320_write(lcd, ILI9320_VERT_START, 0x0); 173 ili9320_write(lcd, ILI9320_VERT_END, cfg->vsize - 1); 174 175 ili9320_write(lcd, ILI9320_DRIVER2, 176 ILI9320_DRIVER2_NL(((cfg->vsize - 240) / 8) + 0x1D)); 177 178 ili9320_write(lcd, ILI9320_BASE_IMAGE, 0x1); 179 ili9320_write(lcd, ILI9320_VERT_SCROLL, 0x00); 180 181 for (addr = ILI9320_PARTIAL1_POSITION; addr <= ILI9320_PARTIAL2_END; 182 addr++) { 183 ili9320_write(lcd, addr, 0x0); 184 } 185 186 ili9320_write(lcd, ILI9320_INTERFACE1, 0x10); 187 ili9320_write(lcd, ILI9320_INTERFACE2, cfg->interface2); 188 ili9320_write(lcd, ILI9320_INTERFACE3, cfg->interface3); 189 ili9320_write(lcd, ILI9320_INTERFACE4, cfg->interface4); 190 ili9320_write(lcd, ILI9320_INTERFACE5, cfg->interface5); 191 ili9320_write(lcd, ILI9320_INTERFACE6, cfg->interface6); 192 193 lcd->display1 = (ILI9320_DISPLAY1_D(3) | ILI9320_DISPLAY1_DTE | 194 ILI9320_DISPLAY1_GON | ILI9320_DISPLAY1_BASEE | 195 0x40); 196 197 ili9320_write(lcd, ILI9320_DISPLAY1, lcd->display1); 198 199 return 0; 200 201 err_vgg3: 202 err_vgg2: 203 err_vgg: 204 err_initial: 205 return ret; 206} 207 208#ifdef CONFIG_PM 209static int vgg2432a4_suspend(struct spi_device *spi, pm_message_t state) 210{ 211 return ili9320_suspend(dev_get_drvdata(&spi->dev), state); 212} 213 214static int vgg2432a4_resume(struct spi_device *spi) 215{ 216 return ili9320_resume(dev_get_drvdata(&spi->dev)); 217} 218#else 219#define vgg2432a4_suspend NULL 220#define vgg2432a4_resume NULL 221#endif 222 223static struct ili9320_client vgg2432a4_client = { 224 .name = "VGG2432A4", 225 .init = vgg2432a4_lcd_init, 226}; 227 228/* Device probe */ 229 230static int __devinit vgg2432a4_probe(struct spi_device *spi) 231{ 232 int ret; 233 234 ret = ili9320_probe_spi(spi, &vgg2432a4_client); 235 if (ret != 0) { 236 dev_err(&spi->dev, "failed to initialise ili9320\n"); 237 return ret; 238 } 239 240 return 0; 241} 242 243static int __devexit vgg2432a4_remove(struct spi_device *spi) 244{ 245 return ili9320_remove(dev_get_drvdata(&spi->dev)); 246} 247 248static void vgg2432a4_shutdown(struct spi_device *spi) 249{ 250 ili9320_shutdown(dev_get_drvdata(&spi->dev)); 251} 252 253static struct spi_driver vgg2432a4_driver = { 254 .driver = { 255 .name = "VGG2432A4", 256 .owner = THIS_MODULE, 257 }, 258 .probe = vgg2432a4_probe, 259 .remove = __devexit_p(vgg2432a4_remove), 260 .shutdown = vgg2432a4_shutdown, 261 .suspend = vgg2432a4_suspend, 262 .resume = vgg2432a4_resume, 263}; 264 265/* Device driver initialisation */ 266 267static int __init vgg2432a4_init(void) 268{ 269 return spi_register_driver(&vgg2432a4_driver); 270} 271 272static void __exit vgg2432a4_exit(void) 273{ 274 spi_unregister_driver(&vgg2432a4_driver); 275} 276 277module_init(vgg2432a4_init); 278module_exit(vgg2432a4_exit); 279 280MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>"); 281MODULE_DESCRIPTION("VGG2432A4 LCD Driver"); 282MODULE_LICENSE("GPL v2"); 283MODULE_ALIAS("spi:VGG2432A4");