diff options
Diffstat (limited to 'drivers/video/backlight')
-rw-r--r-- | drivers/video/backlight/Kconfig | 32 | ||||
-rw-r--r-- | drivers/video/backlight/Makefile | 4 | ||||
-rw-r--r-- | drivers/video/backlight/da903x.c | 201 | ||||
-rw-r--r-- | drivers/video/backlight/kb3886_bl.c | 204 | ||||
-rw-r--r-- | drivers/video/backlight/tosa_bl.c | 198 | ||||
-rw-r--r-- | drivers/video/backlight/tosa_lcd.c | 280 |
6 files changed, 919 insertions, 0 deletions
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index a339e7f60672..4a4dd9adc328 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
@@ -75,6 +75,15 @@ config LCD_PLATFORM | |||
75 | This driver provides a platform-device registered LCD power | 75 | This driver provides a platform-device registered LCD power |
76 | control interface. | 76 | control interface. |
77 | 77 | ||
78 | config LCD_TOSA | ||
79 | tristate "Sharp SL-6000 LCD Driver" | ||
80 | depends on LCD_CLASS_DEVICE && SPI | ||
81 | depends on MACH_TOSA | ||
82 | default n | ||
83 | help | ||
84 | If you have an Sharp SL-6000 Zaurus say Y to enable a driver | ||
85 | for its LCD. | ||
86 | |||
78 | # | 87 | # |
79 | # Backlight | 88 | # Backlight |
80 | # | 89 | # |
@@ -174,6 +183,13 @@ config BACKLIGHT_PWM | |||
174 | If you have a LCD backlight adjustable by PWM, say Y to enable | 183 | If you have a LCD backlight adjustable by PWM, say Y to enable |
175 | this driver. | 184 | this driver. |
176 | 185 | ||
186 | config BACKLIGHT_DA903X | ||
187 | tristate "Backlight Driver for DA9030/DA9034 using WLED" | ||
188 | depends on BACKLIGHT_CLASS_DEVICE && PMIC_DA903X | ||
189 | help | ||
190 | If you have a LCD backlight connected to the WLED output of DA9030 | ||
191 | or DA9034 WLED output, say Y here to enable this driver. | ||
192 | |||
177 | config BACKLIGHT_MBP_NVIDIA | 193 | config BACKLIGHT_MBP_NVIDIA |
178 | tristate "MacBook Pro Nvidia Backlight Driver" | 194 | tristate "MacBook Pro Nvidia Backlight Driver" |
179 | depends on BACKLIGHT_CLASS_DEVICE && X86 | 195 | depends on BACKLIGHT_CLASS_DEVICE && X86 |
@@ -182,3 +198,19 @@ config BACKLIGHT_MBP_NVIDIA | |||
182 | If you have an Apple Macbook Pro with Nvidia graphics hardware say Y | 198 | If you have an Apple Macbook Pro with Nvidia graphics hardware say Y |
183 | to enable a driver for its backlight | 199 | to enable a driver for its backlight |
184 | 200 | ||
201 | config BACKLIGHT_TOSA | ||
202 | tristate "Sharp SL-6000 Backlight Driver" | ||
203 | depends on BACKLIGHT_CLASS_DEVICE && I2C | ||
204 | depends on MACH_TOSA && LCD_TOSA | ||
205 | default n | ||
206 | help | ||
207 | If you have an Sharp SL-6000 Zaurus say Y to enable a driver | ||
208 | for its backlight | ||
209 | |||
210 | config BACKLIGHT_SAHARA | ||
211 | tristate "Tabletkiosk Sahara Touch-iT Backlight Driver" | ||
212 | depends on BACKLIGHT_CLASS_DEVICE && X86 | ||
213 | default n | ||
214 | help | ||
215 | If you have a Tabletkiosk Sahara Touch-iT, say y to enable the | ||
216 | backlight driver. | ||
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 3ec551eb472c..103427de6703 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile | |||
@@ -7,6 +7,7 @@ obj-$(CONFIG_LCD_ILI9320) += ili9320.o | |||
7 | obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o | 7 | obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o |
8 | obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o | 8 | obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o |
9 | obj-$(CONFIG_LCD_TDO24M) += tdo24m.o | 9 | obj-$(CONFIG_LCD_TDO24M) += tdo24m.o |
10 | obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o | ||
10 | 11 | ||
11 | obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o | 12 | obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o |
12 | obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o | 13 | obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o |
@@ -17,5 +18,8 @@ obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o | |||
17 | obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o | 18 | obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o |
18 | obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o | 19 | obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o |
19 | obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o | 20 | obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o |
21 | obj-$(CONFIG_BACKLIGHT_DA903X) += da903x.o | ||
20 | obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o | 22 | obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o |
23 | obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o | ||
24 | obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o | ||
21 | 25 | ||
diff --git a/drivers/video/backlight/da903x.c b/drivers/video/backlight/da903x.c new file mode 100644 index 000000000000..242c38250166 --- /dev/null +++ b/drivers/video/backlight/da903x.c | |||
@@ -0,0 +1,201 @@ | |||
1 | /* | ||
2 | * Backlight driver for Dialog Semiconductor DA9030/DA9034 | ||
3 | * | ||
4 | * Copyright (C) 2008 Compulab, Ltd. | ||
5 | * Mike Rapoport <mike@compulab.co.il> | ||
6 | * | ||
7 | * Copyright (C) 2006-2008 Marvell International Ltd. | ||
8 | * Eric Miao <eric.miao@marvell.com> | ||
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 | #include <linux/kernel.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/fb.h> | ||
19 | #include <linux/backlight.h> | ||
20 | #include <linux/mfd/da903x.h> | ||
21 | |||
22 | #define DA9030_WLED_CONTROL 0x25 | ||
23 | #define DA9030_WLED_CP_EN (1 << 6) | ||
24 | #define DA9030_WLED_TRIM(x) ((x) & 0x7) | ||
25 | |||
26 | #define DA9034_WLED_CONTROL1 0x3C | ||
27 | #define DA9034_WLED_CONTROL2 0x3D | ||
28 | |||
29 | #define DA9034_WLED_BOOST_EN (1 << 5) | ||
30 | |||
31 | #define DA9030_MAX_BRIGHTNESS 7 | ||
32 | #define DA9034_MAX_BRIGHTNESS 0x7f | ||
33 | |||
34 | struct da903x_backlight_data { | ||
35 | struct device *da903x_dev; | ||
36 | int id; | ||
37 | int current_brightness; | ||
38 | }; | ||
39 | |||
40 | static int da903x_backlight_set(struct backlight_device *bl, int brightness) | ||
41 | { | ||
42 | struct da903x_backlight_data *data = bl_get_data(bl); | ||
43 | struct device *dev = data->da903x_dev; | ||
44 | uint8_t val; | ||
45 | int ret = 0; | ||
46 | |||
47 | switch (data->id) { | ||
48 | case DA9034_ID_WLED: | ||
49 | ret = da903x_update(dev, DA9034_WLED_CONTROL1, | ||
50 | brightness, 0x7f); | ||
51 | if (ret) | ||
52 | return ret; | ||
53 | |||
54 | if (data->current_brightness && brightness == 0) | ||
55 | ret = da903x_clr_bits(dev, | ||
56 | DA9034_WLED_CONTROL2, | ||
57 | DA9034_WLED_BOOST_EN); | ||
58 | |||
59 | if (data->current_brightness == 0 && brightness) | ||
60 | ret = da903x_set_bits(dev, | ||
61 | DA9034_WLED_CONTROL2, | ||
62 | DA9034_WLED_BOOST_EN); | ||
63 | break; | ||
64 | case DA9030_ID_WLED: | ||
65 | val = DA9030_WLED_TRIM(brightness); | ||
66 | val |= brightness ? DA9030_WLED_CP_EN : 0; | ||
67 | ret = da903x_write(dev, DA9030_WLED_CONTROL, val); | ||
68 | break; | ||
69 | } | ||
70 | |||
71 | if (ret) | ||
72 | return ret; | ||
73 | |||
74 | data->current_brightness = brightness; | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static int da903x_backlight_update_status(struct backlight_device *bl) | ||
79 | { | ||
80 | int brightness = bl->props.brightness; | ||
81 | |||
82 | if (bl->props.power != FB_BLANK_UNBLANK) | ||
83 | brightness = 0; | ||
84 | |||
85 | if (bl->props.fb_blank != FB_BLANK_UNBLANK) | ||
86 | brightness = 0; | ||
87 | |||
88 | return da903x_backlight_set(bl, brightness); | ||
89 | } | ||
90 | |||
91 | static int da903x_backlight_get_brightness(struct backlight_device *bl) | ||
92 | { | ||
93 | struct da903x_backlight_data *data = bl_get_data(bl); | ||
94 | return data->current_brightness; | ||
95 | } | ||
96 | |||
97 | static struct backlight_ops da903x_backlight_ops = { | ||
98 | .update_status = da903x_backlight_update_status, | ||
99 | .get_brightness = da903x_backlight_get_brightness, | ||
100 | }; | ||
101 | |||
102 | static int da903x_backlight_probe(struct platform_device *pdev) | ||
103 | { | ||
104 | struct da903x_backlight_data *data; | ||
105 | struct backlight_device *bl; | ||
106 | int max_brightness; | ||
107 | |||
108 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
109 | if (data == NULL) | ||
110 | return -ENOMEM; | ||
111 | |||
112 | switch (pdev->id) { | ||
113 | case DA9030_ID_WLED: | ||
114 | max_brightness = DA9030_MAX_BRIGHTNESS; | ||
115 | break; | ||
116 | case DA9034_ID_WLED: | ||
117 | max_brightness = DA9034_MAX_BRIGHTNESS; | ||
118 | break; | ||
119 | default: | ||
120 | dev_err(&pdev->dev, "invalid backlight device ID(%d)\n", | ||
121 | pdev->id); | ||
122 | return -EINVAL; | ||
123 | } | ||
124 | |||
125 | data->id = pdev->id; | ||
126 | data->da903x_dev = pdev->dev.parent; | ||
127 | data->current_brightness = 0; | ||
128 | |||
129 | bl = backlight_device_register(pdev->name, data->da903x_dev, | ||
130 | data, &da903x_backlight_ops); | ||
131 | if (IS_ERR(bl)) { | ||
132 | dev_err(&pdev->dev, "failed to register backlight\n"); | ||
133 | return PTR_ERR(bl); | ||
134 | } | ||
135 | |||
136 | bl->props.max_brightness = max_brightness; | ||
137 | bl->props.brightness = max_brightness; | ||
138 | |||
139 | platform_set_drvdata(pdev, bl); | ||
140 | backlight_update_status(bl); | ||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | static int da903x_backlight_remove(struct platform_device *pdev) | ||
145 | { | ||
146 | struct backlight_device *bl = platform_get_drvdata(pdev); | ||
147 | struct da903x_backlight_data *data = bl_get_data(bl); | ||
148 | |||
149 | backlight_device_unregister(bl); | ||
150 | kfree(data); | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | #ifdef CONFIG_PM | ||
155 | static int da903x_backlight_suspend(struct platform_device *pdev, | ||
156 | pm_message_t state) | ||
157 | { | ||
158 | struct backlight_device *bl = platform_get_drvdata(pdev); | ||
159 | return da903x_backlight_set(bl, 0); | ||
160 | } | ||
161 | |||
162 | static int da903x_backlight_resume(struct platform_device *pdev) | ||
163 | { | ||
164 | struct backlight_device *bl = platform_get_drvdata(pdev); | ||
165 | |||
166 | backlight_update_status(bl); | ||
167 | return 0; | ||
168 | } | ||
169 | #else | ||
170 | #define da903x_backlight_suspend NULL | ||
171 | #define da903x_backlight_resume NULL | ||
172 | #endif | ||
173 | |||
174 | static struct platform_driver da903x_backlight_driver = { | ||
175 | .driver = { | ||
176 | .name = "da903x-backlight", | ||
177 | .owner = THIS_MODULE, | ||
178 | }, | ||
179 | .probe = da903x_backlight_probe, | ||
180 | .remove = da903x_backlight_remove, | ||
181 | .suspend = da903x_backlight_suspend, | ||
182 | .resume = da903x_backlight_resume, | ||
183 | }; | ||
184 | |||
185 | static int __init da903x_backlight_init(void) | ||
186 | { | ||
187 | return platform_driver_register(&da903x_backlight_driver); | ||
188 | } | ||
189 | module_init(da903x_backlight_init); | ||
190 | |||
191 | static void __exit da903x_backlight_exit(void) | ||
192 | { | ||
193 | platform_driver_unregister(&da903x_backlight_driver); | ||
194 | } | ||
195 | module_exit(da903x_backlight_exit); | ||
196 | |||
197 | MODULE_DESCRIPTION("Backlight Driver for Dialog Semiconductor DA9030/DA9034"); | ||
198 | MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>" | ||
199 | "Mike Rapoport <mike@compulab.co.il>"); | ||
200 | MODULE_LICENSE("GPL"); | ||
201 | MODULE_ALIAS("platform:da903x-backlight"); | ||
diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c new file mode 100644 index 000000000000..a38fda1742dd --- /dev/null +++ b/drivers/video/backlight/kb3886_bl.c | |||
@@ -0,0 +1,204 @@ | |||
1 | /* | ||
2 | * Backlight Driver for the KB3886 Backlight | ||
3 | * | ||
4 | * Copyright (c) 2007-2008 Claudio Nieder | ||
5 | * | ||
6 | * Based on corgi_bl.c by Richard Purdie and kb3886 driver by Robert Woerle | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/mutex.h> | ||
19 | #include <linux/fb.h> | ||
20 | #include <linux/backlight.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/dmi.h> | ||
23 | |||
24 | #define KB3886_PARENT 0x64 | ||
25 | #define KB3886_IO 0x60 | ||
26 | #define KB3886_ADC_DAC_PWM 0xC4 | ||
27 | #define KB3886_PWM0_WRITE 0x81 | ||
28 | #define KB3886_PWM0_READ 0x41 | ||
29 | |||
30 | static DEFINE_MUTEX(bl_mutex); | ||
31 | |||
32 | static void kb3886_bl_set_intensity(int intensity) | ||
33 | { | ||
34 | mutex_lock(&bl_mutex); | ||
35 | intensity = intensity&0xff; | ||
36 | outb(KB3886_ADC_DAC_PWM, KB3886_PARENT); | ||
37 | msleep(10); | ||
38 | outb(KB3886_PWM0_WRITE, KB3886_IO); | ||
39 | msleep(10); | ||
40 | outb(intensity, KB3886_IO); | ||
41 | mutex_unlock(&bl_mutex); | ||
42 | } | ||
43 | |||
44 | struct kb3886bl_machinfo { | ||
45 | int max_intensity; | ||
46 | int default_intensity; | ||
47 | int limit_mask; | ||
48 | void (*set_bl_intensity)(int intensity); | ||
49 | }; | ||
50 | |||
51 | static struct kb3886bl_machinfo kb3886_bl_machinfo = { | ||
52 | .max_intensity = 0xff, | ||
53 | .default_intensity = 0xa0, | ||
54 | .limit_mask = 0x7f, | ||
55 | .set_bl_intensity = kb3886_bl_set_intensity, | ||
56 | }; | ||
57 | |||
58 | static struct platform_device kb3886bl_device = { | ||
59 | .name = "kb3886-bl", | ||
60 | .dev = { | ||
61 | .platform_data = &kb3886_bl_machinfo, | ||
62 | }, | ||
63 | .id = -1, | ||
64 | }; | ||
65 | |||
66 | static struct platform_device *devices[] __initdata = { | ||
67 | &kb3886bl_device, | ||
68 | }; | ||
69 | |||
70 | /* | ||
71 | * Back to driver | ||
72 | */ | ||
73 | |||
74 | static int kb3886bl_intensity; | ||
75 | static struct backlight_device *kb3886_backlight_device; | ||
76 | static struct kb3886bl_machinfo *bl_machinfo; | ||
77 | |||
78 | static unsigned long kb3886bl_flags; | ||
79 | #define KB3886BL_SUSPENDED 0x01 | ||
80 | |||
81 | static struct dmi_system_id __initdata kb3886bl_device_table[] = { | ||
82 | { | ||
83 | .ident = "Sahara Touch-iT", | ||
84 | .matches = { | ||
85 | DMI_MATCH(DMI_SYS_VENDOR, "SDV"), | ||
86 | DMI_MATCH(DMI_PRODUCT_NAME, "iTouch T201"), | ||
87 | }, | ||
88 | }, | ||
89 | { } | ||
90 | }; | ||
91 | |||
92 | static int kb3886bl_send_intensity(struct backlight_device *bd) | ||
93 | { | ||
94 | int intensity = bd->props.brightness; | ||
95 | |||
96 | if (bd->props.power != FB_BLANK_UNBLANK) | ||
97 | intensity = 0; | ||
98 | if (bd->props.fb_blank != FB_BLANK_UNBLANK) | ||
99 | intensity = 0; | ||
100 | if (kb3886bl_flags & KB3886BL_SUSPENDED) | ||
101 | intensity = 0; | ||
102 | |||
103 | bl_machinfo->set_bl_intensity(intensity); | ||
104 | |||
105 | kb3886bl_intensity = intensity; | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | #ifdef CONFIG_PM | ||
110 | static int kb3886bl_suspend(struct platform_device *pdev, pm_message_t state) | ||
111 | { | ||
112 | struct backlight_device *bd = platform_get_drvdata(pdev); | ||
113 | |||
114 | kb3886bl_flags |= KB3886BL_SUSPENDED; | ||
115 | backlight_update_status(bd); | ||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static int kb3886bl_resume(struct platform_device *pdev) | ||
120 | { | ||
121 | struct backlight_device *bd = platform_get_drvdata(pdev); | ||
122 | |||
123 | kb3886bl_flags &= ~KB3886BL_SUSPENDED; | ||
124 | backlight_update_status(bd); | ||
125 | return 0; | ||
126 | } | ||
127 | #else | ||
128 | #define kb3886bl_suspend NULL | ||
129 | #define kb3886bl_resume NULL | ||
130 | #endif | ||
131 | |||
132 | static int kb3886bl_get_intensity(struct backlight_device *bd) | ||
133 | { | ||
134 | return kb3886bl_intensity; | ||
135 | } | ||
136 | |||
137 | static struct backlight_ops kb3886bl_ops = { | ||
138 | .get_brightness = kb3886bl_get_intensity, | ||
139 | .update_status = kb3886bl_send_intensity, | ||
140 | }; | ||
141 | |||
142 | static int kb3886bl_probe(struct platform_device *pdev) | ||
143 | { | ||
144 | struct kb3886bl_machinfo *machinfo = pdev->dev.platform_data; | ||
145 | |||
146 | bl_machinfo = machinfo; | ||
147 | if (!machinfo->limit_mask) | ||
148 | machinfo->limit_mask = -1; | ||
149 | |||
150 | kb3886_backlight_device = backlight_device_register("kb3886-bl", | ||
151 | &pdev->dev, NULL, &kb3886bl_ops); | ||
152 | if (IS_ERR(kb3886_backlight_device)) | ||
153 | return PTR_ERR(kb3886_backlight_device); | ||
154 | |||
155 | platform_set_drvdata(pdev, kb3886_backlight_device); | ||
156 | |||
157 | kb3886_backlight_device->props.max_brightness = machinfo->max_intensity; | ||
158 | kb3886_backlight_device->props.power = FB_BLANK_UNBLANK; | ||
159 | kb3886_backlight_device->props.brightness = machinfo->default_intensity; | ||
160 | backlight_update_status(kb3886_backlight_device); | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static int kb3886bl_remove(struct platform_device *pdev) | ||
166 | { | ||
167 | struct backlight_device *bd = platform_get_drvdata(pdev); | ||
168 | |||
169 | backlight_device_unregister(bd); | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | static struct platform_driver kb3886bl_driver = { | ||
175 | .probe = kb3886bl_probe, | ||
176 | .remove = kb3886bl_remove, | ||
177 | .suspend = kb3886bl_suspend, | ||
178 | .resume = kb3886bl_resume, | ||
179 | .driver = { | ||
180 | .name = "kb3886-bl", | ||
181 | }, | ||
182 | }; | ||
183 | |||
184 | static int __init kb3886_init(void) | ||
185 | { | ||
186 | if (!dmi_check_system(kb3886bl_device_table)) | ||
187 | return -ENODEV; | ||
188 | |||
189 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
190 | return platform_driver_register(&kb3886bl_driver); | ||
191 | } | ||
192 | |||
193 | static void __exit kb3886_exit(void) | ||
194 | { | ||
195 | platform_driver_unregister(&kb3886bl_driver); | ||
196 | } | ||
197 | |||
198 | module_init(kb3886_init); | ||
199 | module_exit(kb3886_exit); | ||
200 | |||
201 | MODULE_AUTHOR("Claudio Nieder <private@claudio.ch>"); | ||
202 | MODULE_DESCRIPTION("Tabletkiosk Sahara Touch-iT Backlight Driver"); | ||
203 | MODULE_LICENSE("GPL"); | ||
204 | MODULE_ALIAS("dmi:*:svnSDV:pniTouchT201:*"); | ||
diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c new file mode 100644 index 000000000000..43edbada12d1 --- /dev/null +++ b/drivers/video/backlight/tosa_bl.c | |||
@@ -0,0 +1,198 @@ | |||
1 | /* | ||
2 | * LCD / Backlight control code for Sharp SL-6000x (tosa) | ||
3 | * | ||
4 | * Copyright (c) 2005 Dirk Opfer | ||
5 | * Copyright (c) 2007,2008 Dmitry Baryshkov | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/device.h> | ||
16 | #include <linux/spi/spi.h> | ||
17 | #include <linux/i2c.h> | ||
18 | #include <linux/gpio.h> | ||
19 | #include <linux/fb.h> | ||
20 | #include <linux/backlight.h> | ||
21 | |||
22 | #include <asm/mach/sharpsl_param.h> | ||
23 | |||
24 | #include <mach/tosa.h> | ||
25 | |||
26 | #define COMADJ_DEFAULT 97 | ||
27 | |||
28 | #define DAC_CH1 0 | ||
29 | #define DAC_CH2 1 | ||
30 | |||
31 | struct tosa_bl_data { | ||
32 | struct i2c_client *i2c; | ||
33 | struct backlight_device *bl; | ||
34 | |||
35 | int comadj; | ||
36 | }; | ||
37 | |||
38 | static void tosa_bl_set_backlight(struct tosa_bl_data *data, int brightness) | ||
39 | { | ||
40 | struct spi_device *spi = data->i2c->dev.platform_data; | ||
41 | |||
42 | i2c_smbus_write_byte_data(data->i2c, DAC_CH1, data->comadj); | ||
43 | |||
44 | /* SetBacklightDuty */ | ||
45 | i2c_smbus_write_byte_data(data->i2c, DAC_CH2, (u8)(brightness & 0xff)); | ||
46 | |||
47 | /* SetBacklightVR */ | ||
48 | gpio_set_value(TOSA_GPIO_BL_C20MA, brightness & 0x100); | ||
49 | |||
50 | tosa_bl_enable(spi, brightness); | ||
51 | } | ||
52 | |||
53 | static int tosa_bl_update_status(struct backlight_device *dev) | ||
54 | { | ||
55 | struct backlight_properties *props = &dev->props; | ||
56 | struct tosa_bl_data *data = dev_get_drvdata(&dev->dev); | ||
57 | int power = max(props->power, props->fb_blank); | ||
58 | int brightness = props->brightness; | ||
59 | |||
60 | if (power) | ||
61 | brightness = 0; | ||
62 | |||
63 | tosa_bl_set_backlight(data, brightness); | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static int tosa_bl_get_brightness(struct backlight_device *dev) | ||
69 | { | ||
70 | struct backlight_properties *props = &dev->props; | ||
71 | |||
72 | return props->brightness; | ||
73 | } | ||
74 | |||
75 | static struct backlight_ops bl_ops = { | ||
76 | .get_brightness = tosa_bl_get_brightness, | ||
77 | .update_status = tosa_bl_update_status, | ||
78 | }; | ||
79 | |||
80 | static int __devinit tosa_bl_probe(struct i2c_client *client, | ||
81 | const struct i2c_device_id *id) | ||
82 | { | ||
83 | struct tosa_bl_data *data = kzalloc(sizeof(struct tosa_bl_data), GFP_KERNEL); | ||
84 | int ret = 0; | ||
85 | if (!data) | ||
86 | return -ENOMEM; | ||
87 | |||
88 | data->comadj = sharpsl_param.comadj == -1 ? COMADJ_DEFAULT : sharpsl_param.comadj; | ||
89 | |||
90 | ret = gpio_request(TOSA_GPIO_BL_C20MA, "backlight"); | ||
91 | if (ret) { | ||
92 | dev_dbg(&data->bl->dev, "Unable to request gpio!\n"); | ||
93 | goto err_gpio_bl; | ||
94 | } | ||
95 | ret = gpio_direction_output(TOSA_GPIO_BL_C20MA, 0); | ||
96 | if (ret) | ||
97 | goto err_gpio_dir; | ||
98 | |||
99 | i2c_set_clientdata(client, data); | ||
100 | data->i2c = client; | ||
101 | |||
102 | data->bl = backlight_device_register("tosa-bl", &client->dev, | ||
103 | data, &bl_ops); | ||
104 | if (IS_ERR(data->bl)) { | ||
105 | ret = PTR_ERR(data->bl); | ||
106 | goto err_reg; | ||
107 | } | ||
108 | |||
109 | data->bl->props.brightness = 69; | ||
110 | data->bl->props.max_brightness = 512 - 1; | ||
111 | data->bl->props.power = FB_BLANK_UNBLANK; | ||
112 | |||
113 | backlight_update_status(data->bl); | ||
114 | |||
115 | return 0; | ||
116 | |||
117 | err_reg: | ||
118 | data->bl = NULL; | ||
119 | i2c_set_clientdata(client, NULL); | ||
120 | err_gpio_dir: | ||
121 | gpio_free(TOSA_GPIO_BL_C20MA); | ||
122 | err_gpio_bl: | ||
123 | kfree(data); | ||
124 | return ret; | ||
125 | } | ||
126 | |||
127 | static int __devexit tosa_bl_remove(struct i2c_client *client) | ||
128 | { | ||
129 | struct tosa_bl_data *data = i2c_get_clientdata(client); | ||
130 | |||
131 | backlight_device_unregister(data->bl); | ||
132 | data->bl = NULL; | ||
133 | i2c_set_clientdata(client, NULL); | ||
134 | |||
135 | gpio_free(TOSA_GPIO_BL_C20MA); | ||
136 | |||
137 | kfree(data); | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | #ifdef CONFIG_PM | ||
143 | static int tosa_bl_suspend(struct i2c_client *client, pm_message_t pm) | ||
144 | { | ||
145 | struct tosa_bl_data *data = i2c_get_clientdata(client); | ||
146 | |||
147 | tosa_bl_set_backlight(data, 0); | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static int tosa_bl_resume(struct i2c_client *client) | ||
153 | { | ||
154 | struct tosa_bl_data *data = i2c_get_clientdata(client); | ||
155 | |||
156 | backlight_update_status(data->bl); | ||
157 | return 0; | ||
158 | } | ||
159 | #else | ||
160 | #define tosa_bl_suspend NULL | ||
161 | #define tosa_bl_resume NULL | ||
162 | #endif | ||
163 | |||
164 | static const struct i2c_device_id tosa_bl_id[] = { | ||
165 | { "tosa-bl", 0 }, | ||
166 | { }, | ||
167 | }; | ||
168 | |||
169 | |||
170 | static struct i2c_driver tosa_bl_driver = { | ||
171 | .driver = { | ||
172 | .name = "tosa-bl", | ||
173 | .owner = THIS_MODULE, | ||
174 | }, | ||
175 | .probe = tosa_bl_probe, | ||
176 | .remove = __devexit_p(tosa_bl_remove), | ||
177 | .suspend = tosa_bl_suspend, | ||
178 | .resume = tosa_bl_resume, | ||
179 | .id_table = tosa_bl_id, | ||
180 | }; | ||
181 | |||
182 | static int __init tosa_bl_init(void) | ||
183 | { | ||
184 | return i2c_add_driver(&tosa_bl_driver); | ||
185 | } | ||
186 | |||
187 | static void __exit tosa_bl_exit(void) | ||
188 | { | ||
189 | i2c_del_driver(&tosa_bl_driver); | ||
190 | } | ||
191 | |||
192 | module_init(tosa_bl_init); | ||
193 | module_exit(tosa_bl_exit); | ||
194 | |||
195 | MODULE_AUTHOR("Dmitry Baryshkov"); | ||
196 | MODULE_LICENSE("GPL v2"); | ||
197 | MODULE_DESCRIPTION("LCD/Backlight control for Sharp SL-6000 PDA"); | ||
198 | |||
diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c new file mode 100644 index 000000000000..57a26649f1a5 --- /dev/null +++ b/drivers/video/backlight/tosa_lcd.c | |||
@@ -0,0 +1,280 @@ | |||
1 | /* | ||
2 | * LCD / Backlight control code for Sharp SL-6000x (tosa) | ||
3 | * | ||
4 | * Copyright (c) 2005 Dirk Opfer | ||
5 | * Copyright (c) 2007,2008 Dmitry Baryshkov | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/device.h> | ||
16 | #include <linux/spi/spi.h> | ||
17 | #include <linux/i2c.h> | ||
18 | #include <linux/gpio.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/lcd.h> | ||
21 | #include <linux/fb.h> | ||
22 | |||
23 | #include <asm/mach/sharpsl_param.h> | ||
24 | |||
25 | #include <mach/tosa.h> | ||
26 | |||
27 | #define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL) | ||
28 | |||
29 | #define TG_REG0_VQV 0x0001 | ||
30 | #define TG_REG0_COLOR 0x0002 | ||
31 | #define TG_REG0_UD 0x0004 | ||
32 | #define TG_REG0_LR 0x0008 | ||
33 | |||
34 | #define DAC_BASE 0x4e | ||
35 | |||
36 | struct tosa_lcd_data { | ||
37 | struct spi_device *spi; | ||
38 | struct lcd_device *lcd; | ||
39 | struct i2c_client *i2c; | ||
40 | |||
41 | int lcd_power; | ||
42 | }; | ||
43 | |||
44 | static int tosa_tg_send(struct spi_device *spi, int adrs, uint8_t data) | ||
45 | { | ||
46 | u8 buf[1]; | ||
47 | struct spi_message msg; | ||
48 | struct spi_transfer xfer = { | ||
49 | .len = 1, | ||
50 | .cs_change = 1, | ||
51 | .tx_buf = buf, | ||
52 | }; | ||
53 | |||
54 | buf[0] = ((adrs & 0x07) << 5) | (data & 0x1f); | ||
55 | spi_message_init(&msg); | ||
56 | spi_message_add_tail(&xfer, &msg); | ||
57 | |||
58 | return spi_sync(spi, &msg); | ||
59 | } | ||
60 | |||
61 | int tosa_bl_enable(struct spi_device *spi, int enable) | ||
62 | { | ||
63 | /* bl_enable GP04=1 otherwise GP04=0*/ | ||
64 | return tosa_tg_send(spi, TG_GPODR2, enable? 0x01 : 0x00); | ||
65 | } | ||
66 | EXPORT_SYMBOL(tosa_bl_enable); | ||
67 | |||
68 | static void tosa_lcd_tg_init(struct tosa_lcd_data *data) | ||
69 | { | ||
70 | /* TG on */ | ||
71 | gpio_set_value(TOSA_GPIO_TG_ON, 0); | ||
72 | |||
73 | mdelay(60); | ||
74 | |||
75 | /* delayed 0clk TCTL signal for VGA */ | ||
76 | tosa_tg_send(data->spi, TG_TPOSCTL, 0x00); | ||
77 | /* GPOS0=powercontrol, GPOS1=GPIO, GPOS2=TCTL */ | ||
78 | tosa_tg_send(data->spi, TG_GPOSR, 0x02); | ||
79 | } | ||
80 | |||
81 | static void tosa_lcd_tg_on(struct tosa_lcd_data *data) | ||
82 | { | ||
83 | struct spi_device *spi = data->spi; | ||
84 | const int value = TG_REG0_COLOR | TG_REG0_UD | TG_REG0_LR; | ||
85 | tosa_tg_send(spi, TG_PNLCTL, value | TG_REG0_VQV); /* this depends on mode */ | ||
86 | |||
87 | /* TG LCD pannel power up */ | ||
88 | tosa_tg_send(spi, TG_PINICTL,0x4); | ||
89 | mdelay(50); | ||
90 | |||
91 | /* TG LCD GVSS */ | ||
92 | tosa_tg_send(spi, TG_PINICTL,0x0); | ||
93 | |||
94 | if (!data->i2c) { | ||
95 | /* after the pannel is powered up the first time, we can access the i2c bus */ | ||
96 | /* so probe for the DAC */ | ||
97 | struct i2c_adapter *adap = i2c_get_adapter(0); | ||
98 | struct i2c_board_info info = { | ||
99 | .type = "tosa-bl", | ||
100 | .addr = DAC_BASE, | ||
101 | .platform_data = data->spi, | ||
102 | }; | ||
103 | data->i2c = i2c_new_device(adap, &info); | ||
104 | } | ||
105 | } | ||
106 | |||
107 | static void tosa_lcd_tg_off(struct tosa_lcd_data *data) | ||
108 | { | ||
109 | struct spi_device *spi = data->spi; | ||
110 | |||
111 | /* TG LCD VHSA off */ | ||
112 | tosa_tg_send(spi, TG_PINICTL,0x4); | ||
113 | mdelay(50); | ||
114 | |||
115 | /* TG LCD signal off */ | ||
116 | tosa_tg_send(spi, TG_PINICTL,0x6); | ||
117 | mdelay(50); | ||
118 | |||
119 | /* TG Off */ | ||
120 | gpio_set_value(TOSA_GPIO_TG_ON, 1); | ||
121 | mdelay(100); | ||
122 | } | ||
123 | |||
124 | int tosa_lcd_set_power(struct lcd_device *lcd, int power) | ||
125 | { | ||
126 | struct tosa_lcd_data *data = lcd_get_data(lcd); | ||
127 | |||
128 | if (POWER_IS_ON(power) && !POWER_IS_ON(data->lcd_power)) | ||
129 | tosa_lcd_tg_on(data); | ||
130 | |||
131 | if (!POWER_IS_ON(power) && POWER_IS_ON(data->lcd_power)) | ||
132 | tosa_lcd_tg_off(data); | ||
133 | |||
134 | data->lcd_power = power; | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static int tosa_lcd_get_power(struct lcd_device *lcd) | ||
139 | { | ||
140 | struct tosa_lcd_data *data = lcd_get_data(lcd); | ||
141 | |||
142 | return data->lcd_power; | ||
143 | } | ||
144 | |||
145 | static struct lcd_ops tosa_lcd_ops = { | ||
146 | .set_power = tosa_lcd_set_power, | ||
147 | .get_power = tosa_lcd_get_power, | ||
148 | }; | ||
149 | |||
150 | static int __devinit tosa_lcd_probe(struct spi_device *spi) | ||
151 | { | ||
152 | int ret; | ||
153 | struct tosa_lcd_data *data; | ||
154 | |||
155 | data = kzalloc(sizeof(struct tosa_lcd_data), GFP_KERNEL); | ||
156 | if (!data) | ||
157 | return -ENOMEM; | ||
158 | |||
159 | /* | ||
160 | * bits_per_word cannot be configured in platform data | ||
161 | */ | ||
162 | spi->bits_per_word = 8; | ||
163 | |||
164 | ret = spi_setup(spi); | ||
165 | if (ret < 0) | ||
166 | goto err_spi; | ||
167 | |||
168 | data->spi = spi; | ||
169 | dev_set_drvdata(&spi->dev, data); | ||
170 | |||
171 | ret = gpio_request(TOSA_GPIO_TG_ON, "tg #pwr"); | ||
172 | if (ret < 0) | ||
173 | goto err_gpio_tg; | ||
174 | |||
175 | mdelay(60); | ||
176 | |||
177 | ret = gpio_direction_output(TOSA_GPIO_TG_ON, 0); | ||
178 | if (ret < 0) | ||
179 | goto err_gpio_dir; | ||
180 | |||
181 | mdelay(60); | ||
182 | tosa_lcd_tg_init(data); | ||
183 | |||
184 | tosa_lcd_tg_on(data); | ||
185 | |||
186 | data->lcd = lcd_device_register("tosa-lcd", &spi->dev, data, | ||
187 | &tosa_lcd_ops); | ||
188 | |||
189 | if (IS_ERR(data->lcd)) { | ||
190 | ret = PTR_ERR(data->lcd); | ||
191 | data->lcd = NULL; | ||
192 | goto err_register; | ||
193 | } | ||
194 | |||
195 | return 0; | ||
196 | |||
197 | err_register: | ||
198 | tosa_lcd_tg_off(data); | ||
199 | err_gpio_dir: | ||
200 | gpio_free(TOSA_GPIO_TG_ON); | ||
201 | err_gpio_tg: | ||
202 | dev_set_drvdata(&spi->dev, NULL); | ||
203 | err_spi: | ||
204 | kfree(data); | ||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | static int __devexit tosa_lcd_remove(struct spi_device *spi) | ||
209 | { | ||
210 | struct tosa_lcd_data *data = dev_get_drvdata(&spi->dev); | ||
211 | |||
212 | lcd_device_unregister(data->lcd); | ||
213 | |||
214 | if (data->i2c) | ||
215 | i2c_unregister_device(data->i2c); | ||
216 | |||
217 | tosa_lcd_tg_off(data); | ||
218 | |||
219 | gpio_free(TOSA_GPIO_TG_ON); | ||
220 | dev_set_drvdata(&spi->dev, NULL); | ||
221 | kfree(data); | ||
222 | |||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | #ifdef CONFIG_PM | ||
227 | static int tosa_lcd_suspend(struct spi_device *spi, pm_message_t state) | ||
228 | { | ||
229 | struct tosa_lcd_data *data = dev_get_drvdata(&spi->dev); | ||
230 | |||
231 | tosa_lcd_tg_off(data); | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static int tosa_lcd_resume(struct spi_device *spi) | ||
237 | { | ||
238 | struct tosa_lcd_data *data = dev_get_drvdata(&spi->dev); | ||
239 | |||
240 | tosa_lcd_tg_init(data); | ||
241 | if (POWER_IS_ON(data->lcd_power)) | ||
242 | tosa_lcd_tg_on(data); | ||
243 | else | ||
244 | tosa_lcd_tg_off(data); | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | #else | ||
249 | #define tosa_lcd_suspend NULL | ||
250 | #define tosa_lcd_reume NULL | ||
251 | #endif | ||
252 | |||
253 | static struct spi_driver tosa_lcd_driver = { | ||
254 | .driver = { | ||
255 | .name = "tosa-lcd", | ||
256 | .owner = THIS_MODULE, | ||
257 | }, | ||
258 | .probe = tosa_lcd_probe, | ||
259 | .remove = __devexit_p(tosa_lcd_remove), | ||
260 | .suspend = tosa_lcd_suspend, | ||
261 | .resume = tosa_lcd_resume, | ||
262 | }; | ||
263 | |||
264 | static int __init tosa_lcd_init(void) | ||
265 | { | ||
266 | return spi_register_driver(&tosa_lcd_driver); | ||
267 | } | ||
268 | |||
269 | static void __exit tosa_lcd_exit(void) | ||
270 | { | ||
271 | spi_unregister_driver(&tosa_lcd_driver); | ||
272 | } | ||
273 | |||
274 | module_init(tosa_lcd_init); | ||
275 | module_exit(tosa_lcd_exit); | ||
276 | |||
277 | MODULE_AUTHOR("Dmitry Baryshkov"); | ||
278 | MODULE_LICENSE("GPL v2"); | ||
279 | MODULE_DESCRIPTION("LCD/Backlight control for Sharp SL-6000 PDA"); | ||
280 | |||