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