Root/target/linux/xburst/patches-2.6.36/100-lcm.patch

1From cb0cdd5f614d723139331ecf56d28e529ff9b74c Mon Sep 17 00:00:00 2001
2From: Lars-Peter Clausen <lars@metafoo.de>
3Date: Sun, 1 Aug 2010 21:19:40 +0200
4Subject: [PATCH] Add ili8960 lcd driver
5
6---
7 drivers/video/backlight/Kconfig | 7 +
8 drivers/video/backlight/Makefile | 1 +
9 drivers/video/backlight/ili8960.c | 253 +++++++++++++++++++++++++++++++++++++
10 3 files changed, 261 insertions(+), 0 deletions(-)
11 create mode 100644 drivers/video/backlight/ili8960.c
12
13--- a/drivers/video/backlight/Kconfig
14+++ b/drivers/video/backlight/Kconfig
15@@ -59,6 +59,13 @@ config LCD_LTV350QV
16 
17       The LTV350QV panel is present on all ATSTK1000 boards.
18 
19+config LCD_ILI8960
20+ tristate "Ilitek ili8960 LCD driver"
21+ depends on LCD_CLASS_DEVICE && SPI
22+ default n
23+ help
24+ Driver for the Ilitek ili8960 LCD controller chip.
25+
26 config LCD_ILI9320
27     tristate
28     help
29--- a/drivers/video/backlight/Makefile
30+++ b/drivers/video/backlight/Makefile
31@@ -6,6 +6,7 @@ obj-$(CONFIG_LCD_HP700) += jornada72
32 obj-$(CONFIG_LCD_L4F00242T03) += l4f00242t03.o
33 obj-$(CONFIG_LCD_LMS283GF05) += lms283gf05.o
34 obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o
35+obj-$(CONFIG_LCD_ILI8960) += ili8960.o
36 obj-$(CONFIG_LCD_ILI9320) += ili9320.o
37 obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o
38 obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o
39--- /dev/null
40+++ b/drivers/video/backlight/ili8960.c
41@@ -0,0 +1,253 @@
42+/*
43+ * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
44+ * Driver for Ilitek ili8960 LCD
45+ *
46+ * This program is free software; you can redistribute it and/or modify it
47+ * under the terms of the GNU General Public License as published by the
48+ * Free Software Foundation; either version 2 of the License, or (at your
49+ * option) any later version.
50+ *
51+ * You should have received a copy of the GNU General Public License along
52+ * with this program; if not, write to the Free Software Foundation, Inc.,
53+ * 675 Mass Ave, Cambridge, MA 02139, USA.
54+ *
55+ */
56+
57+#include <linux/module.h>
58+#include <linux/spi/spi.h>
59+#include <linux/lcd.h>
60+#include <linux/backlight.h>
61+#include <linux/delay.h>
62+
63+struct ili8960 {
64+ struct spi_device *spi;
65+ struct lcd_device *lcd;
66+ struct backlight_device *bl;
67+ bool enabled;
68+ int brightness;
69+};
70+
71+static int ili8960_write_reg(struct spi_device *spi, uint8_t reg,
72+ uint8_t data)
73+{
74+ uint8_t buf[2];
75+ buf[0] = ((reg & 0x40) << 1) | (reg & 0x3f);
76+ buf[1] = data;
77+
78+ return spi_write(spi, buf, sizeof(buf));
79+}
80+
81+static int ili8960_programm_power(struct spi_device *spi, bool enabled)
82+{
83+ int ret;
84+
85+ if (enabled)
86+ mdelay(20);
87+
88+ ret = ili8960_write_reg(spi, 0x5, enabled ? 0xc7 : 0xc6);
89+
90+ if (!enabled)
91+ mdelay(20);
92+
93+ return ret;
94+}
95+
96+static int ili8960_set_power(struct lcd_device *lcd, int power)
97+{
98+ struct ili8960 *ili8960 = lcd_get_data(lcd);
99+
100+ switch (power) {
101+ case FB_BLANK_UNBLANK:
102+ ili8960->enabled = true;
103+ break;
104+ default:
105+ ili8960->enabled = false;
106+ break;
107+ }
108+
109+ return ili8960_programm_power(ili8960->spi, ili8960->enabled);
110+}
111+
112+static int ili8960_get_power(struct lcd_device *lcd)
113+{
114+ struct ili8960 *ili8960 = lcd_get_data(lcd);
115+ return ili8960->enabled ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
116+}
117+
118+static int ili8960_set_contrast(struct lcd_device *lcd, int contrast)
119+{
120+ struct ili8960 *ili8960 = lcd_get_data(lcd);
121+ ili8960_write_reg(ili8960->spi, 0x0d, contrast);
122+
123+ return 0;
124+}
125+
126+static int ili8960_set_mode(struct lcd_device *lcd, struct fb_videomode *mode)
127+{
128+ if (mode->xres != 320 && mode->yres != 240)
129+ return -EINVAL;
130+
131+ return 0;
132+}
133+
134+static int ili8960_set_brightness(struct ili8960 *ili8960, int brightness)
135+{
136+ int ret;
137+ ret = ili8960_write_reg(ili8960->spi, 0x3, brightness);
138+
139+ if (ret == 0)
140+ ili8960->brightness = brightness;
141+
142+ return ret;
143+}
144+
145+static ssize_t ili8960_show_brightness(struct device *dev,
146+ struct device_attribute *attr, char *buf)
147+{
148+ struct lcd_device *ld = to_lcd_device(dev);
149+ struct ili8960 *ili8960 = lcd_get_data(ld);
150+
151+ return sprintf(buf, "%d\n", ili8960->brightness);
152+}
153+
154+static ssize_t ili8960_store_brightness(struct device *dev,
155+ struct device_attribute *attr, const char *buf, size_t count)
156+{
157+ char *endp;
158+ struct lcd_device *ld = to_lcd_device(dev);
159+ struct ili8960 *ili8960 = lcd_get_data(ld);
160+ int brightness = simple_strtoul(buf, &endp, 0);
161+
162+ if (brightness > 255 || brightness < 0)
163+ return -EINVAL;
164+
165+ ili8960_set_brightness(ili8960, brightness);
166+
167+ return count;
168+}
169+
170+
171+static DEVICE_ATTR(brightness, 0644, ili8960_show_brightness,
172+ ili8960_store_brightness);
173+
174+static struct lcd_ops ili8960_lcd_ops = {
175+ .set_power = ili8960_set_power,
176+ .get_power = ili8960_get_power,
177+ .set_contrast = ili8960_set_contrast,
178+ .set_mode = ili8960_set_mode,
179+};
180+
181+static int __devinit ili8960_probe(struct spi_device *spi)
182+{
183+ int ret;
184+ struct ili8960 *ili8960;
185+
186+ ili8960 = kmalloc(sizeof(*ili8960), GFP_KERNEL);
187+
188+ spi->bits_per_word = 8;
189+ spi->mode = SPI_MODE_3;
190+
191+ ret = spi_setup(spi);
192+ if (ret) {
193+ dev_err(&spi->dev, "Failed to setup spi\n");
194+ goto err_free_ili8960;
195+ }
196+
197+ ili8960->spi = spi;
198+
199+ ili8960->lcd = lcd_device_register("ili8960-lcd", &spi->dev, ili8960,
200+ &ili8960_lcd_ops);
201+
202+ if (IS_ERR(ili8960->lcd)) {
203+ ret = PTR_ERR(ili8960->lcd);
204+ dev_err(&spi->dev, "Failed to register lcd device: %d\n", ret);
205+ goto err_free_ili8960;
206+ }
207+
208+ ili8960->lcd->props.max_contrast = 255;
209+
210+ ret = device_create_file(&ili8960->lcd->dev, &dev_attr_brightness);
211+ if (ret)
212+ goto err_unregister_lcd;
213+
214+ ili8960_programm_power(ili8960->spi, true);
215+ ili8960->enabled = true;
216+ dev_set_drvdata(&spi->dev, ili8960);
217+
218+ ili8960_write_reg(spi, 0x13, 0x01);
219+ ili8960_write_reg(spi, 0x5, 0xc7);
220+
221+ return 0;
222+err_unregister_lcd:
223+ lcd_device_unregister(ili8960->lcd);
224+err_free_ili8960:
225+ kfree(ili8960);
226+ return ret;
227+}
228+
229+static int __devexit ili8960_remove(struct spi_device *spi)
230+{
231+ struct ili8960 *ili8960 = spi_get_drvdata(spi);
232+
233+ device_remove_file(&ili8960->lcd->dev, &dev_attr_brightness);
234+ lcd_device_unregister(ili8960->lcd);
235+
236+ spi_set_drvdata(spi, NULL);
237+ kfree(ili8960);
238+ return 0;
239+}
240+
241+#ifdef CONFIG_PM
242+
243+static int ili8960_suspend(struct spi_device *spi, pm_message_t state)
244+{
245+ struct ili8960 *ili8960 = spi_get_drvdata(spi);
246+
247+ if (ili8960->enabled)
248+ ili8960_programm_power(ili8960->spi, false);
249+
250+ return 0;
251+}
252+
253+static int ili8960_resume(struct spi_device *spi)
254+{
255+ struct ili8960 *ili8960 = spi_get_drvdata(spi);
256+
257+ if (ili8960->enabled)
258+ ili8960_programm_power(ili8960->spi, true);
259+
260+ return 0;
261+}
262+
263+#else
264+#define ili8960_suspend NULL
265+#define ili8960_resume NULL
266+#endif
267+
268+static struct spi_driver ili8960_driver = {
269+ .driver = {
270+ .name = "ili8960",
271+ .owner = THIS_MODULE,
272+ },
273+ .probe = ili8960_probe,
274+ .remove = __devexit_p(ili8960_remove),
275+ .suspend = ili8960_suspend,
276+ .resume = ili8960_resume,
277+};
278+
279+static int __init ili8960_init(void)
280+{
281+ return spi_register_driver(&ili8960_driver);
282+}
283+module_init(ili8960_init);
284+
285+static void __exit ili8960_exit(void)
286+{
287+ spi_unregister_driver(&ili8960_driver);
288+}
289+module_exit(ili8960_exit)
290+
291+MODULE_AUTHOR("Lars-Peter Clausen");
292+MODULE_LICENSE("GPL");
293+MODULE_DESCRIPTION("LCD driver for Ilitek ili8960");
294+MODULE_ALIAS("spi:ili8960");
295

Archive Download this file



interactive