Update DEP-5 uri
[debian/omnibook.git] / lcd.c
1 /*
2  * lcd.c -- LCD brightness and on/off
3  * 
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2, or (at your option) any
7  * later version.
8  * 
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * Written by Maciek Górniak <mago@acn.waw.pl>, 2002
15  * Modified by Soós Péter <sp@osb.hu>, 2002-2004
16  * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
17  */
18
19 #include "omnibook.h"
20 #include <linux/err.h>
21
22 #ifdef CONFIG_OMNIBOOK_BACKLIGHT
23 #include <linux/backlight.h>
24 #endif
25
26 #include "hardware.h"
27
28 unsigned int omnibook_max_brightness;
29
30 #ifdef CONFIG_OMNIBOOK_BACKLIGHT
31 static struct backlight_device *omnibook_backlight_device;
32
33 static int omnibook_get_backlight(struct backlight_device *bd);
34 static int omnibook_set_backlight(struct backlight_device *bd);
35
36 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)
37 static struct backlight_properties props;
38 #endif
39 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
40 static struct backlight_ops omnibookbl_ops = {
41 #else /* 2.6.21 */
42 static struct backlight_properties omnibookbl_data = {
43         .owner = THIS_MODULE,
44 #endif /* 2.6.21 */
45         .get_brightness = omnibook_get_backlight,
46         .update_status = omnibook_set_backlight,
47 };
48
49 static int omnibook_get_backlight(struct backlight_device *bd)
50 {
51         int retval = 0;
52         struct omnibook_operation *io_op;
53         u8 brgt;
54
55 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
56         io_op = bl_get_data(bd);
57 #else /* 2.6.23 */      
58         io_op = class_get_devdata(&bd->class_dev);
59 #endif /* 2.6.23 */
60         retval = backend_byte_read(io_op, &brgt);
61         if (!retval)
62                 retval = brgt;
63
64         return retval;
65 }
66
67 static int omnibook_set_backlight(struct backlight_device *bd)
68 {
69 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
70         u8 intensity = bd->props.brightness;
71 #else /* 2.6.21 */
72         u8 intensity = bd->props->brightness;
73 #endif /* 2.6.21 */     
74         struct omnibook_operation *io_op;
75
76 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
77         io_op = bl_get_data(bd);
78 #else /* 2.6.23 */      
79         io_op = class_get_devdata(&bd->class_dev);
80 #endif /* 2.6.23 */
81         return backend_byte_write(io_op, intensity);
82 }
83 #endif /* CONFIG_OMNIBOOK_BACKLIGHT */
84
85 static int omnibook_brightness_read(char *buffer, struct omnibook_operation *io_op)
86 {
87         int len = 0;
88         u8 brgt;
89
90         backend_byte_read(io_op, &brgt);
91
92         len +=
93             sprintf(buffer + len, "LCD brightness: %2d (max value: %d)\n", brgt,
94                     omnibook_max_brightness);
95
96         return len;
97 }
98
99 static int omnibook_brightness_write(char *buffer, struct omnibook_operation *io_op)
100 {
101         unsigned int brgt = 0;
102         char *endp;
103
104         if (strncmp(buffer, "off", 3) == 0)
105                 omnibook_lcd_blank(1);
106         else if (strncmp(buffer, "on", 2) == 0)
107                 omnibook_lcd_blank(0);
108         else {
109                 brgt = simple_strtoul(buffer, &endp, 10);
110                 if ((endp == buffer) || (brgt > omnibook_max_brightness))
111                         return -EINVAL;
112                 else {
113                         backend_byte_write(io_op, brgt);
114 #ifdef CONFIG_OMNIBOOK_BACKLIGHT
115 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
116                         omnibook_backlight_device->props.brightness = brgt;
117 #else /* 2.6.21 */
118                         omnibookbl_data.brightness = brgt;
119 #endif
120 #endif  
121                 }
122         }
123         return 0;
124 }
125
126 static int __init omnibook_brightness_init(struct omnibook_operation *io_op)
127 {
128         /*
129          * FIXME: What is exactly the max value for each model ?
130          * I know that it's 7 for the TSM30X, TSM70, TSM40 and TSA105
131          * and previous versions of this driver (wrongly) assumed it was 10 for
132          * all models.
133          * 
134          * XE3GF
135          * TSM30X
136          * TSM70
137          * TSM40
138          * TSA105
139          * TSX205
140          */
141         if (omnibook_ectype & (XE3GF | TSM70 | TSM30X | TSM40 | TSA105 | TSX205))
142                 omnibook_max_brightness = 7;
143         else {
144                 omnibook_max_brightness = 10;
145                 printk(O_WARN "Assuming that LCD brightness is between 0 and %i,\n",
146                        omnibook_max_brightness);
147                 printk(O_WARN
148                        "please contact http://sourceforge.net/projects/omnibook to confirm.\n");
149         }
150
151 #ifdef CONFIG_OMNIBOOK_BACKLIGHT
152 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)
153         memset (&props, 0, sizeof(struct backlight_properties));
154         props.max_brightness = omnibook_max_brightness;
155         omnibook_backlight_device =
156             backlight_device_register(OMNIBOOK_MODULE_NAME, NULL, (void *)io_op, 
157                                       &omnibookbl_ops, &props);
158 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
159         omnibook_backlight_device =
160             backlight_device_register(OMNIBOOK_MODULE_NAME, NULL, (void *)io_op, &omnibookbl_ops);
161 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
162         omnibook_backlight_device =
163             backlight_device_register(OMNIBOOK_MODULE_NAME, NULL, (void *)io_op, &omnibookbl_data);
164 #else /*  < 2.6.20 */
165         omnibook_backlight_device =
166             backlight_device_register(OMNIBOOK_MODULE_NAME, (void *)io_op, &omnibookbl_data);
167 #endif
168         if (IS_ERR(omnibook_backlight_device)) {
169                 printk(O_ERR "Unable to register as backlight device.\n");
170                 return -ENODEV;
171         }
172 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)
173         backend_byte_read(io_op, (u8*) &omnibook_backlight_device->props.brightness);
174 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
175         omnibook_backlight_device->props.max_brightness = omnibook_max_brightness;
176         backend_byte_read(io_op, (u8*) &omnibook_backlight_device->props.brightness);
177 #else /* < 2.6.21 */
178         omnibookbl_data.max_brightness = omnibook_max_brightness;
179         backend_byte_read(io_op, (u8*) &omnibookbl_data.brightness);
180 #endif
181  
182 #endif /* CONFIG_OMNIBOOK_BACKLIGHT */
183         return 0;
184 }
185 static void __exit omnibook_brightness_cleanup(struct omnibook_operation *io_op)
186 {
187 #ifdef CONFIG_OMNIBOOK_BACKLIGHT
188         backlight_device_unregister(omnibook_backlight_device);
189 #endif
190 }
191
192 static struct omnibook_tbl lcd_table[] __initdata = {
193         {TSM70 | TSX205, {CDI, TSM70_LCD_READ, TSM70_LCD_WRITE, 0, 0, 0}},
194         {TSM40, {SMI, SMI_GET_LCD_BRIGHTNESS, SMI_SET_LCD_BRIGHTNESS, 0, 0, 0}},
195         {XE3GF | TSP10 | TSM70 | TSM30X, SIMPLE_BYTE(EC, XE3GF_BRTS, XE3GF_BRTS_MASK)},
196         {XE3GC, SIMPLE_BYTE(EC, XE3GC_BTVL, XE3GC_BTVL_MASK)},
197         {AMILOD, SIMPLE_BYTE(EC, AMILOD_CBRG, XE3GC_BTVL_MASK)},
198         {TSA105, SIMPLE_BYTE(EC, A105_BNDT, A105_BNDT_MASK)},
199         {0,}
200 };
201
202 static struct omnibook_feature __declared_feature lcd_driver = {
203         .name = "lcd",
204         .enabled = 1,
205         .read = omnibook_brightness_read,
206         .write = omnibook_brightness_write,
207         .init = omnibook_brightness_init,
208         .exit = omnibook_brightness_cleanup,
209         .ectypes = XE3GF | XE3GC | AMILOD | TSP10 | TSM70 | TSM30X | TSM40 | TSA105 | TSX205,
210         .tbl = lcd_table,
211 };
212
213 module_param_named(lcd, lcd_driver.enabled, int, S_IRUGO);
214 MODULE_PARM_DESC(lcd, "Use 0 to disable, 1 to enable to LCD brightness support");
215
216 /* End of file */