diff options
author | Christian Gmeiner <christian.gmeiner@gmail.com> | 2012-03-23 18:02:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 19:58:33 -0400 |
commit | c8df7428635c02ca3051e39179c83297d8b76fba (patch) | |
tree | 5163885a7b7e13024e332786826e6a81c5369893 /drivers/video | |
parent | 7be865ab8634d4ec2a6bdb9459b268cd60e832af (diff) |
backlight: add driver for Bachmann's ot200
Add backlight driver for Bachmann's ot200 visualisation device. The
driver uses MFGPT 7 of CS5535 silicon to regulate the backlight.
[akpm@linux-foundation.org: remove redundant test of `brightness']
Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Andres Salomon <dilinger@queued.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/backlight/Kconfig | 7 | ||||
-rw-r--r-- | drivers/video/backlight/Makefile | 2 | ||||
-rw-r--r-- | drivers/video/backlight/ot200_bl.c | 175 |
3 files changed, 183 insertions, 1 deletions
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 49e7d83f869f..248d6c0858dd 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
@@ -341,6 +341,13 @@ config BACKLIGHT_LP855X | |||
341 | This supports TI LP8550, LP8551, LP8552, LP8553 and LP8556 | 341 | This supports TI LP8550, LP8551, LP8552, LP8553 and LP8556 |
342 | backlight driver. | 342 | backlight driver. |
343 | 343 | ||
344 | config BACKLIGHT_OT200 | ||
345 | tristate "Backlight driver for ot200 visualisation device" | ||
346 | depends on BACKLIGHT_CLASS_DEVICE && CS5535_MFGPT | ||
347 | help | ||
348 | To compile this driver as a module, choose M here: the module will be | ||
349 | called ot200_bl. | ||
350 | |||
344 | endif # BACKLIGHT_CLASS_DEVICE | 351 | endif # BACKLIGHT_CLASS_DEVICE |
345 | 352 | ||
346 | endif # BACKLIGHT_LCD_SUPPORT | 353 | endif # BACKLIGHT_LCD_SUPPORT |
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 0ee06e0832bd..c71dd793363d 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile | |||
@@ -39,4 +39,4 @@ obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o | |||
39 | obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o | 39 | obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o |
40 | obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o | 40 | obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o |
41 | obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_bl.o | 41 | obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_bl.o |
42 | 42 | obj-$(CONFIG_BACKLIGHT_OT200) += ot200_bl.o | |
diff --git a/drivers/video/backlight/ot200_bl.c b/drivers/video/backlight/ot200_bl.c new file mode 100644 index 000000000000..f519d55a294c --- /dev/null +++ b/drivers/video/backlight/ot200_bl.c | |||
@@ -0,0 +1,175 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Bachmann electronic GmbH | ||
3 | * Christian Gmeiner <christian.gmeiner@gmail.com> | ||
4 | * | ||
5 | * Backlight driver for ot200 visualisation device from | ||
6 | * Bachmann electronic GmbH. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License version 2 as published by | ||
10 | * the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/fb.h> | ||
15 | #include <linux/backlight.h> | ||
16 | #include <linux/gpio.h> | ||
17 | #include <linux/cs5535.h> | ||
18 | |||
19 | static struct cs5535_mfgpt_timer *pwm_timer; | ||
20 | |||
21 | /* this array defines the mapping of brightness in % to pwm frequency */ | ||
22 | static const u8 dim_table[101] = {0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, | ||
23 | 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, | ||
24 | 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, | ||
25 | 10, 10, 11, 11, 12, 12, 13, 14, 15, 15, 16, | ||
26 | 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, | ||
27 | 30, 31, 33, 35, 37, 39, 41, 43, 45, 47, 50, | ||
28 | 53, 55, 58, 61, 65, 68, 72, 75, 79, 84, 88, | ||
29 | 93, 97, 103, 108, 114, 120, 126, 133, 140, | ||
30 | 147, 155, 163}; | ||
31 | |||
32 | struct ot200_backlight_data { | ||
33 | int current_brightness; | ||
34 | }; | ||
35 | |||
36 | #define GPIO_DIMM 27 | ||
37 | #define SCALE 1 | ||
38 | #define CMP1MODE 0x2 /* compare on GE; output high on compare | ||
39 | * greater than or equal */ | ||
40 | #define PWM_SETUP (SCALE | CMP1MODE << 6 | MFGPT_SETUP_CNTEN) | ||
41 | #define MAX_COMP2 163 | ||
42 | |||
43 | static int ot200_backlight_update_status(struct backlight_device *bl) | ||
44 | { | ||
45 | struct ot200_backlight_data *data = bl_get_data(bl); | ||
46 | int brightness = bl->props.brightness; | ||
47 | |||
48 | if (bl->props.state & BL_CORE_FBBLANK) | ||
49 | brightness = 0; | ||
50 | |||
51 | /* enable or disable PWM timer */ | ||
52 | if (brightness == 0) | ||
53 | cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, 0); | ||
54 | else if (data->current_brightness == 0) { | ||
55 | cs5535_mfgpt_write(pwm_timer, MFGPT_REG_COUNTER, 0); | ||
56 | cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, | ||
57 | MFGPT_SETUP_CNTEN); | ||
58 | } | ||
59 | |||
60 | /* apply new brightness value */ | ||
61 | cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP1, | ||
62 | MAX_COMP2 - dim_table[brightness]); | ||
63 | data->current_brightness = brightness; | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static int ot200_backlight_get_brightness(struct backlight_device *bl) | ||
69 | { | ||
70 | struct ot200_backlight_data *data = bl_get_data(bl); | ||
71 | return data->current_brightness; | ||
72 | } | ||
73 | |||
74 | static const struct backlight_ops ot200_backlight_ops = { | ||
75 | .update_status = ot200_backlight_update_status, | ||
76 | .get_brightness = ot200_backlight_get_brightness, | ||
77 | }; | ||
78 | |||
79 | static int ot200_backlight_probe(struct platform_device *pdev) | ||
80 | { | ||
81 | struct backlight_device *bl; | ||
82 | struct ot200_backlight_data *data; | ||
83 | struct backlight_properties props; | ||
84 | int retval = 0; | ||
85 | |||
86 | /* request gpio */ | ||
87 | if (gpio_request(GPIO_DIMM, "ot200 backlight dimmer") < 0) { | ||
88 | dev_err(&pdev->dev, "failed to request GPIO %d\n", GPIO_DIMM); | ||
89 | return -ENODEV; | ||
90 | } | ||
91 | |||
92 | /* request timer */ | ||
93 | pwm_timer = cs5535_mfgpt_alloc_timer(7, MFGPT_DOMAIN_ANY); | ||
94 | if (!pwm_timer) { | ||
95 | dev_err(&pdev->dev, "MFGPT 7 not available\n"); | ||
96 | retval = -ENODEV; | ||
97 | goto error_mfgpt_alloc; | ||
98 | } | ||
99 | |||
100 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
101 | if (!data) { | ||
102 | retval = -ENOMEM; | ||
103 | goto error_kzalloc; | ||
104 | } | ||
105 | |||
106 | /* setup gpio */ | ||
107 | cs5535_gpio_set(GPIO_DIMM, GPIO_OUTPUT_ENABLE); | ||
108 | cs5535_gpio_set(GPIO_DIMM, GPIO_OUTPUT_AUX1); | ||
109 | |||
110 | /* setup timer */ | ||
111 | cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP1, 0); | ||
112 | cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP2, MAX_COMP2); | ||
113 | cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, PWM_SETUP); | ||
114 | |||
115 | data->current_brightness = 100; | ||
116 | props.max_brightness = 100; | ||
117 | props.brightness = 100; | ||
118 | props.type = BACKLIGHT_RAW; | ||
119 | |||
120 | bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, data, | ||
121 | &ot200_backlight_ops, &props); | ||
122 | if (IS_ERR(bl)) { | ||
123 | dev_err(&pdev->dev, "failed to register backlight\n"); | ||
124 | retval = PTR_ERR(bl); | ||
125 | goto error_backlight_device_register; | ||
126 | } | ||
127 | |||
128 | platform_set_drvdata(pdev, bl); | ||
129 | |||
130 | return 0; | ||
131 | |||
132 | error_backlight_device_register: | ||
133 | kfree(data); | ||
134 | error_kzalloc: | ||
135 | cs5535_mfgpt_free_timer(pwm_timer); | ||
136 | error_mfgpt_alloc: | ||
137 | gpio_free(GPIO_DIMM); | ||
138 | return retval; | ||
139 | } | ||
140 | |||
141 | static int ot200_backlight_remove(struct platform_device *pdev) | ||
142 | { | ||
143 | struct backlight_device *bl = platform_get_drvdata(pdev); | ||
144 | struct ot200_backlight_data *data = bl_get_data(bl); | ||
145 | |||
146 | backlight_device_unregister(bl); | ||
147 | |||
148 | /* on module unload set brightness to 100% */ | ||
149 | cs5535_mfgpt_write(pwm_timer, MFGPT_REG_COUNTER, 0); | ||
150 | cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN); | ||
151 | cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP1, | ||
152 | MAX_COMP2 - dim_table[100]); | ||
153 | |||
154 | cs5535_mfgpt_free_timer(pwm_timer); | ||
155 | gpio_free(GPIO_DIMM); | ||
156 | |||
157 | kfree(data); | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | static struct platform_driver ot200_backlight_driver = { | ||
162 | .driver = { | ||
163 | .name = "ot200-backlight", | ||
164 | .owner = THIS_MODULE, | ||
165 | }, | ||
166 | .probe = ot200_backlight_probe, | ||
167 | .remove = ot200_backlight_remove, | ||
168 | }; | ||
169 | |||
170 | module_platform_driver(ot200_backlight_driver); | ||
171 | |||
172 | MODULE_DESCRIPTION("backlight driver for ot200 visualisation device"); | ||
173 | MODULE_AUTHOR("Christian Gmeiner <christian.gmeiner@gmail.com>"); | ||
174 | MODULE_LICENSE("GPL"); | ||
175 | MODULE_ALIAS("platform:ot200-backlight"); | ||