aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/backlight/Kconfig17
-rw-r--r--drivers/video/backlight/Makefile4
-rw-r--r--drivers/video/backlight/ili9320.c330
-rw-r--r--drivers/video/backlight/ili9320.h80
-rw-r--r--drivers/video/backlight/vgg2432a4.c284
-rw-r--r--include/video/ili9320.h201
6 files changed, 915 insertions, 1 deletions
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 30bf7f2f1635..a5b3a92ffdc1 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -36,6 +36,23 @@ config LCD_LTV350QV
36 36
37 The LTV350QV panel is present on all ATSTK1000 boards. 37 The LTV350QV panel is present on all ATSTK1000 boards.
38 38
39config LCD_ILI9320
40 tristate
41 depends on LCD_CLASS_DEVICE && BACKLIGHT_LCD_SUPPORT
42 default n
43 help
44 If you have a panel based on the ILI9320 controller chip
45 then say y to include a power driver for it.
46
47config LCD_VGG2432A4
48 tristate "VGG2432A4 LCM device support"
49 depends on BACKLIGHT_LCD_SUPPORT && LCD_CLASS_DEVICE && SPI_MASTER
50 select LCD_ILI9320
51 default n
52 help
53 If you have a VGG2432A4 panel based on the ILI9320 controller chip
54 then say y to include a power driver for it.
55
39# 56#
40# Backlight 57# Backlight
41# 58#
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index b51a7cd12500..366d84e380cf 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -1,7 +1,9 @@
1# Backlight & LCD drivers 1# Backlight & LCD drivers
2 2
3obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o 3obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
4obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o 4obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o
5obj-$(CONFIG_LCD_ILI9320) += ili9320.o
6obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o
5 7
6obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o 8obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
7obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o 9obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o
diff --git a/drivers/video/backlight/ili9320.c b/drivers/video/backlight/ili9320.c
new file mode 100644
index 000000000000..ba89b41b639c
--- /dev/null
+++ b/drivers/video/backlight/ili9320.c
@@ -0,0 +1,330 @@
1/* drivers/video/backlight/ili9320.c
2 *
3 * ILI9320 LCD controller driver core.
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
28static inline int ili9320_write_spi(struct ili9320 *ili,
29 unsigned int reg,
30 unsigned int value)
31{
32 struct ili9320_spi *spi = &ili->access.spi;
33 unsigned char *addr = spi->buffer_addr;
34 unsigned char *data = spi->buffer_data;
35
36 /* spi message consits of:
37 * first byte: ID and operation
38 */
39
40 addr[0] = spi->id | ILI9320_SPI_INDEX | ILI9320_SPI_WRITE;
41 addr[1] = reg >> 8;
42 addr[2] = reg;
43
44 /* second message is the data to transfer */
45
46 data[0] = spi->id | ILI9320_SPI_DATA | ILI9320_SPI_WRITE;
47 data[1] = value >> 8;
48 data[2] = value;
49
50 return spi_sync(spi->dev, &spi->message);
51}
52
53int ili9320_write(struct ili9320 *ili, unsigned int reg, unsigned int value)
54{
55 dev_dbg(ili->dev, "write: reg=%02x, val=%04x\n", reg, value);
56 return ili->write(ili, reg, value);
57}
58
59EXPORT_SYMBOL_GPL(ili9320_write);
60
61int ili9320_write_regs(struct ili9320 *ili,
62 struct ili9320_reg *values,
63 int nr_values)
64{
65 int index;
66 int ret;
67
68 for (index = 0; index < nr_values; index++, values++) {
69 ret = ili9320_write(ili, values->address, values->value);
70 if (ret != 0)
71 return ret;
72 }
73
74 return 0;
75}
76
77EXPORT_SYMBOL_GPL(ili9320_write_regs);
78
79static void ili9320_reset(struct ili9320 *lcd)
80{
81 struct ili9320_platdata *cfg = lcd->platdata;
82
83 cfg->reset(1);
84 mdelay(50);
85
86 cfg->reset(0);
87 mdelay(50);
88
89 cfg->reset(1);
90 mdelay(100);
91}
92
93static inline int ili9320_init_chip(struct ili9320 *lcd)
94{
95 int ret;
96
97 ili9320_reset(lcd);
98
99 ret = lcd->client->init(lcd, lcd->platdata);
100 if (ret != 0) {
101 dev_err(lcd->dev, "failed to initialise display\n");
102 return ret;
103 }
104
105 lcd->initialised = 1;
106 return 0;
107}
108
109static inline int ili9320_power_on(struct ili9320 *lcd)
110{
111 if (!lcd->initialised)
112 ili9320_init_chip(lcd);
113
114 lcd->display1 |= (ILI9320_DISPLAY1_D(3) | ILI9320_DISPLAY1_BASEE);
115 ili9320_write(lcd, ILI9320_DISPLAY1, lcd->display1);
116
117 return 0;
118}
119
120static inline int ili9320_power_off(struct ili9320 *lcd)
121{
122 lcd->display1 &= ~(ILI9320_DISPLAY1_D(3) | ILI9320_DISPLAY1_BASEE);
123 ili9320_write(lcd, ILI9320_DISPLAY1, lcd->display1);
124
125 return 0;
126}
127
128#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
129
130static int ili9320_power(struct ili9320 *lcd, int power)
131{
132 int ret = 0;
133
134 dev_dbg(lcd->dev, "power %d => %d\n", lcd->power, power);
135
136 if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
137 ret = ili9320_power_on(lcd);
138 else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
139 ret = ili9320_power_off(lcd);
140
141 if (ret == 0)
142 lcd->power = power;
143 else
144 dev_warn(lcd->dev, "failed to set power mode %d\n", power);
145
146 return ret;
147}
148
149static inline struct ili9320 *to_our_lcd(struct lcd_device *lcd)
150{
151 return lcd_get_data(lcd);
152}
153
154static int ili9320_set_power(struct lcd_device *ld, int power)
155{
156 struct ili9320 *lcd = to_our_lcd(ld);
157
158 return ili9320_power(lcd, power);
159}
160
161static int ili9320_get_power(struct lcd_device *ld)
162{
163 struct ili9320 *lcd = to_our_lcd(ld);
164
165 return lcd->power;
166}
167
168static struct lcd_ops ili9320_ops = {
169 .get_power = ili9320_get_power,
170 .set_power = ili9320_set_power,
171};
172
173static void __devinit ili9320_setup_spi(struct ili9320 *ili,
174 struct spi_device *dev)
175{
176 struct ili9320_spi *spi = &ili->access.spi;
177
178 ili->write = ili9320_write_spi;
179 spi->dev = dev;
180
181 /* fill the two messages we are going to use to send the data
182 * with, the first the address followed by the data. The datasheet
183 * says they should be done as two distinct cycles of the SPI CS line.
184 */
185
186 spi->xfer[0].tx_buf = spi->buffer_addr;
187 spi->xfer[1].tx_buf = spi->buffer_data;
188 spi->xfer[0].len = 3;
189 spi->xfer[1].len = 3;
190 spi->xfer[0].bits_per_word = 8;
191 spi->xfer[1].bits_per_word = 8;
192 spi->xfer[0].cs_change = 1;
193
194 spi_message_init(&spi->message);
195 spi_message_add_tail(&spi->xfer[0], &spi->message);
196 spi_message_add_tail(&spi->xfer[1], &spi->message);
197}
198
199int __devinit ili9320_probe_spi(struct spi_device *spi,
200 struct ili9320_client *client)
201{
202 struct ili9320_platdata *cfg = spi->dev.platform_data;
203 struct device *dev = &spi->dev;
204 struct ili9320 *ili;
205 struct lcd_device *lcd;
206 int ret = 0;
207
208 /* verify we where given some information */
209
210 if (cfg == NULL) {
211 dev_err(dev, "no platform data supplied\n");
212 return -EINVAL;
213 }
214
215 if (cfg->hsize <= 0 || cfg->vsize <= 0 || cfg->reset == NULL) {
216 dev_err(dev, "invalid platform data supplied\n");
217 return -EINVAL;
218 }
219
220 /* allocate and initialse our state */
221
222 ili = kzalloc(sizeof(struct ili9320), GFP_KERNEL);
223 if (ili == NULL) {
224 dev_err(dev, "no memory for device\n");
225 return -ENOMEM;
226 }
227
228 ili->access.spi.id = ILI9320_SPI_IDCODE | ILI9320_SPI_ID(1);
229
230 ili->dev = dev;
231 ili->client = client;
232 ili->power = FB_BLANK_POWERDOWN;
233 ili->platdata = cfg;
234
235 dev_set_drvdata(&spi->dev, ili);
236
237 ili9320_setup_spi(ili, spi);
238
239 lcd = lcd_device_register("ili9320", dev, ili, &ili9320_ops);
240 if (IS_ERR(lcd)) {
241 dev_err(dev, "failed to register lcd device\n");
242 ret = PTR_ERR(lcd);
243 goto err_free;
244 }
245
246 ili->lcd = lcd;
247
248 dev_info(dev, "initialising %s\n", client->name);
249
250 ret = ili9320_power(ili, FB_BLANK_UNBLANK);
251 if (ret != 0) {
252 dev_err(dev, "failed to set lcd power state\n");
253 goto err_unregister;
254 }
255
256 return 0;
257
258 err_unregister:
259 lcd_device_unregister(lcd);
260
261 err_free:
262 kfree(ili);
263
264 return ret;
265}
266
267EXPORT_SYMBOL_GPL(ili9320_probe_spi);
268
269int __devexit ili9320_remove(struct ili9320 *ili)
270{
271 ili9320_power(ili, FB_BLANK_POWERDOWN);
272
273 lcd_device_unregister(ili->lcd);
274 kfree(ili);
275
276 return 0;
277}
278
279EXPORT_SYMBOL_GPL(ili9320_remove);
280
281#ifdef CONFIG_PM
282int ili9320_suspend(struct ili9320 *lcd, pm_message_t state)
283{
284 int ret;
285
286 dev_dbg(lcd->dev, "%s: event %d\n", __func__, state.event);
287
288 if (state.event == PM_EVENT_SUSPEND) {
289 ret = ili9320_power(lcd, FB_BLANK_POWERDOWN);
290
291 if (lcd->platdata->suspend == ILI9320_SUSPEND_DEEP) {
292 ili9320_write(lcd, ILI9320_POWER1, lcd->power1 |
293 ILI9320_POWER1_SLP |
294 ILI9320_POWER1_DSTB);
295 lcd->initialised = 0;
296 }
297
298 return ret;
299 }
300
301 return 0;
302}
303
304EXPORT_SYMBOL_GPL(ili9320_suspend);
305
306int ili9320_resume(struct ili9320 *lcd)
307{
308 dev_info(lcd->dev, "resuming from power state %d\n", lcd->power);
309
310 if (lcd->platdata->suspend == ILI9320_SUSPEND_DEEP) {
311 ili9320_write(lcd, ILI9320_POWER1, 0x00);
312 }
313
314 return ili9320_power(lcd, FB_BLANK_UNBLANK);
315}
316
317EXPORT_SYMBOL_GPL(ili9320_resume);
318#endif
319
320/* Power down all displays on reboot, poweroff or halt */
321void ili9320_shutdown(struct ili9320 *lcd)
322{
323 ili9320_power(lcd, FB_BLANK_POWERDOWN);
324}
325
326EXPORT_SYMBOL_GPL(ili9320_shutdown);
327
328MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
329MODULE_DESCRIPTION("ILI9320 LCD Driver");
330MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/backlight/ili9320.h b/drivers/video/backlight/ili9320.h
new file mode 100644
index 000000000000..e388eca7cac5
--- /dev/null
+++ b/drivers/video/backlight/ili9320.h
@@ -0,0 +1,80 @@
1/* drivers/video/backlight/ili9320.h
2 *
3 * ILI9320 LCD controller driver core.
4 *
5 * Copyright 2007 Simtec Electronics
6 * Ben Dooks <ben@simtec.co.uk>
7 *
8 * http://armlinux.simtec.co.uk/
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15/* Holder for register and value pairs. */
16struct ili9320_reg {
17 unsigned short address;
18 unsigned short value;
19};
20
21struct ili9320;
22
23struct ili9320_client {
24 const char *name;
25 int (*init)(struct ili9320 *ili, struct ili9320_platdata *cfg);
26
27};
28/* Device attached via an SPI bus. */
29struct ili9320_spi {
30 struct spi_device *dev;
31 struct spi_message message;
32 struct spi_transfer xfer[2];
33
34 unsigned char id;
35 unsigned char buffer_addr[4];
36 unsigned char buffer_data[4];
37};
38
39/* ILI9320 device state. */
40struct ili9320 {
41 union {
42 struct ili9320_spi spi; /* SPI attachged device. */
43 } access; /* Register access method. */
44
45 struct device *dev;
46 struct lcd_device *lcd; /* LCD device we created. */
47 struct ili9320_client *client;
48 struct ili9320_platdata *platdata;
49
50 int power; /* current power state. */
51 int initialised;
52
53 unsigned short display1;
54 unsigned short power1;
55
56 int (*write)(struct ili9320 *ili, unsigned int reg, unsigned int val);
57};
58
59
60/* ILI9320 register access routines */
61
62extern int ili9320_write(struct ili9320 *ili,
63 unsigned int reg, unsigned int value);
64
65extern int ili9320_write_regs(struct ili9320 *ili,
66 struct ili9320_reg *values,
67 int nr_values);
68
69/* Device probe */
70
71extern int ili9320_probe_spi(struct spi_device *spi,
72 struct ili9320_client *cli);
73
74extern int ili9320_remove(struct ili9320 *lcd);
75extern void ili9320_shutdown(struct ili9320 *lcd);
76
77/* PM */
78
79extern int ili9320_suspend(struct ili9320 *lcd, pm_message_t state);
80extern int ili9320_resume(struct ili9320 *lcd);
diff --git a/drivers/video/backlight/vgg2432a4.c b/drivers/video/backlight/vgg2432a4.c
new file mode 100644
index 000000000000..593c7687d54a
--- /dev/null
+++ b/drivers/video/backlight/vgg2432a4.c
@@ -0,0 +1,284 @@
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, ILI9320_RGBIF2_DPL);
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");
283
284
diff --git a/include/video/ili9320.h b/include/video/ili9320.h
new file mode 100644
index 000000000000..e5d1622e3f33
--- /dev/null
+++ b/include/video/ili9320.h
@@ -0,0 +1,201 @@
1/* include/video/ili9320.c
2 *
3 * ILI9320 LCD controller configuration control.
4 *
5 * Copyright 2007 Simtec Electronics
6 * Ben Dooks <ben@simtec.co.uk>
7 *
8 * http://armlinux.simtec.co.uk/
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#define ILI9320_REG(x) (x)
16
17#define ILI9320_INDEX ILI9320_REG(0x00)
18
19#define ILI9320_OSCILATION ILI9320_REG(0x00)
20#define ILI9320_DRIVER ILI9320_REG(0x01)
21#define ILI9320_DRIVEWAVE ILI9320_REG(0x02)
22#define ILI9320_ENTRYMODE ILI9320_REG(0x03)
23#define ILI9320_RESIZING ILI9320_REG(0x04)
24#define ILI9320_DISPLAY1 ILI9320_REG(0x07)
25#define ILI9320_DISPLAY2 ILI9320_REG(0x08)
26#define ILI9320_DISPLAY3 ILI9320_REG(0x09)
27#define ILI9320_DISPLAY4 ILI9320_REG(0x0A)
28#define ILI9320_RGB_IF1 ILI9320_REG(0x0C)
29#define ILI9320_FRAMEMAKER ILI9320_REG(0x0D)
30#define ILI9320_RGB_IF2 ILI9320_REG(0x0F)
31
32#define ILI9320_POWER1 ILI9320_REG(0x10)
33#define ILI9320_POWER2 ILI9320_REG(0x11)
34#define ILI9320_POWER3 ILI9320_REG(0x12)
35#define ILI9320_POWER4 ILI9320_REG(0x13)
36#define ILI9320_GRAM_HORIZ_ADDR ILI9320_REG(0x20)
37#define ILI9320_GRAM_VERT_ADD ILI9320_REG(0x21)
38#define ILI9320_POWER7 ILI9320_REG(0x29)
39#define ILI9320_FRAME_RATE_COLOUR ILI9320_REG(0x2B)
40
41#define ILI9320_GAMMA1 ILI9320_REG(0x30)
42#define ILI9320_GAMMA2 ILI9320_REG(0x31)
43#define ILI9320_GAMMA3 ILI9320_REG(0x32)
44#define ILI9320_GAMMA4 ILI9320_REG(0x35)
45#define ILI9320_GAMMA5 ILI9320_REG(0x36)
46#define ILI9320_GAMMA6 ILI9320_REG(0x37)
47#define ILI9320_GAMMA7 ILI9320_REG(0x38)
48#define ILI9320_GAMMA8 ILI9320_REG(0x39)
49#define ILI9320_GAMMA9 ILI9320_REG(0x3C)
50#define ILI9320_GAMMA10 ILI9320_REG(0x3D)
51
52#define ILI9320_HORIZ_START ILI9320_REG(0x50)
53#define ILI9320_HORIZ_END ILI9320_REG(0x51)
54#define ILI9320_VERT_START ILI9320_REG(0x52)
55#define ILI9320_VERT_END ILI9320_REG(0x53)
56
57#define ILI9320_DRIVER2 ILI9320_REG(0x60)
58#define ILI9320_BASE_IMAGE ILI9320_REG(0x61)
59#define ILI9320_VERT_SCROLL ILI9320_REG(0x6a)
60
61#define ILI9320_PARTIAL1_POSITION ILI9320_REG(0x80)
62#define ILI9320_PARTIAL1_START ILI9320_REG(0x81)
63#define ILI9320_PARTIAL1_END ILI9320_REG(0x82)
64#define ILI9320_PARTIAL2_POSITION ILI9320_REG(0x83)
65#define ILI9320_PARTIAL2_START ILI9320_REG(0x84)
66#define ILI9320_PARTIAL2_END ILI9320_REG(0x85)
67
68#define ILI9320_INTERFACE1 ILI9320_REG(0x90)
69#define ILI9320_INTERFACE2 ILI9320_REG(0x92)
70#define ILI9320_INTERFACE3 ILI9320_REG(0x93)
71#define ILI9320_INTERFACE4 ILI9320_REG(0x95)
72#define ILI9320_INTERFACE5 ILI9320_REG(0x97)
73#define ILI9320_INTERFACE6 ILI9320_REG(0x98)
74
75/* Register contents definitions. */
76
77#define ILI9320_OSCILATION_OSC (1 << 0)
78
79#define ILI9320_DRIVER_SS (1 << 8)
80#define ILI9320_DRIVER_SM (1 << 10)
81
82#define ILI9320_DRIVEWAVE_EOR (1 << 8)
83#define ILI9320_DRIVEWAVE_BC (1 << 9)
84#define ILI9320_DRIVEWAVE_MUSTSET (1 << 10)
85
86#define ILI9320_ENTRYMODE_AM (1 << 3)
87#define ILI9320_ENTRYMODE_ID(x) ((x) << 4)
88#define ILI9320_ENTRYMODE_ORG (1 << 7)
89#define ILI9320_ENTRYMODE_HWM (1 << 8)
90#define ILI9320_ENTRYMODE_BGR (1 << 12)
91#define ILI9320_ENTRYMODE_DFM (1 << 14)
92#define ILI9320_ENTRYMODE_TRI (1 << 15)
93
94
95#define ILI9320_RESIZING_RSZ(x) ((x) << 0)
96#define ILI9320_RESIZING_RCH(x) ((x) << 4)
97#define ILI9320_RESIZING_RCV(x) ((x) << 8)
98
99
100#define ILI9320_DISPLAY1_D(x) ((x) << 0)
101#define ILI9320_DISPLAY1_CL (1 << 3)
102#define ILI9320_DISPLAY1_DTE (1 << 4)
103#define ILI9320_DISPLAY1_GON (1 << 5)
104#define ILI9320_DISPLAY1_BASEE (1 << 8)
105#define ILI9320_DISPLAY1_PTDE(x) ((x) << 12)
106
107
108#define ILI9320_DISPLAY2_BP(x) ((x) << 0)
109#define ILI9320_DISPLAY2_FP(x) ((x) << 8)
110
111
112#define ILI9320_RGBIF1_RIM_RGB18 (0 << 0)
113#define ILI9320_RGBIF1_RIM_RGB16 (1 << 0)
114#define ILI9320_RGBIF1_RIM_RGB6 (2 << 0)
115
116#define ILI9320_RGBIF1_CLK_INT (0 << 4)
117#define ILI9320_RGBIF1_CLK_RGBIF (1 << 4)
118#define ILI9320_RGBIF1_CLK_VSYNC (2 << 4)
119
120#define ILI9320_RGBIF1_RM (1 << 8)
121
122#define ILI9320_RGBIF1_ENC_FRAMES(x) (((x) - 1)<< 13)
123
124#define ILI9320_RGBIF2_DPL (1 << 0)
125#define ILI9320_RGBIF2_EPL (1 << 1)
126#define ILI9320_RGBIF2_HSPL (1 << 3)
127#define ILI9320_RGBIF2_VSPL (1 << 4)
128
129
130#define ILI9320_POWER1_SLP (1 << 1)
131#define ILI9320_POWER1_DSTB (1 << 2)
132#define ILI9320_POWER1_AP(x) ((x) << 4)
133#define ILI9320_POWER1_APE (1 << 7)
134#define ILI9320_POWER1_BT(x) ((x) << 8)
135#define ILI9320_POWER1_SAP (1 << 12)
136
137
138#define ILI9320_POWER2_VC(x) ((x) << 0)
139#define ILI9320_POWER2_DC0(x) ((x) << 4)
140#define ILI9320_POWER2_DC1(x) ((x) << 8)
141
142
143#define ILI9320_POWER3_VRH(x) ((x) << 0)
144#define ILI9320_POWER3_PON (1 << 4)
145#define ILI9320_POWER3_VCMR (1 << 8)
146
147
148#define ILI9320_POWER4_VREOUT(x) ((x) << 8)
149
150
151#define ILI9320_DRIVER2_SCNL(x) ((x) << 0)
152#define ILI9320_DRIVER2_NL(x) ((x) << 8)
153#define ILI9320_DRIVER2_GS (1 << 15)
154
155
156#define ILI9320_BASEIMAGE_REV (1 << 0)
157#define ILI9320_BASEIMAGE_VLE (1 << 1)
158#define ILI9320_BASEIMAGE_NDL (1 << 2)
159
160
161#define ILI9320_INTERFACE4_RTNE(x) (x)
162#define ILI9320_INTERFACE4_DIVE(x) ((x) << 8)
163
164/* SPI interface definitions */
165
166#define ILI9320_SPI_IDCODE (0x70)
167#define ILI9320_SPI_ID(x) ((x) << 2)
168#define ILI9320_SPI_READ (0x01)
169#define ILI9320_SPI_WRITE (0x00)
170#define ILI9320_SPI_DATA (0x02)
171#define ILI9320_SPI_INDEX (0x00)
172
173/* platform data to pass configuration from lcd */
174
175enum ili9320_suspend {
176 ILI9320_SUSPEND_OFF,
177 ILI9320_SUSPEND_DEEP,
178};
179
180struct ili9320_platdata {
181 unsigned short hsize;
182 unsigned short vsize;
183
184 enum ili9320_suspend suspend;
185
186 /* set the reset line, 0 = reset asserted, 1 = normal */
187 void (*reset)(unsigned int val);
188
189 unsigned short entry_mode;
190 unsigned short display2;
191 unsigned short display3;
192 unsigned short display4;
193 unsigned short rgb_if1;
194 unsigned short rgb_if2;
195 unsigned short interface2;
196 unsigned short interface3;
197 unsigned short interface4;
198 unsigned short interface5;
199 unsigned short interface6;
200};
201