V4L/DVB: media/IR/imon: precendence issue: ! vs ==
[safe/jmp/linux-2.6] / drivers / video / backlight / jornada720_bl.c
1 /*
2  *
3  * Backlight driver for HP Jornada 700 series (710/720/728)
4  * Copyright (C) 2006-2009 Kristoffer Ericson <kristoffer.ericson@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License version
8  * 2 or any later version as published by the Free Software Foundation.
9  *
10  */
11
12 #include <linux/backlight.h>
13 #include <linux/device.h>
14 #include <linux/fb.h>
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/platform_device.h>
18
19 #include <mach/jornada720.h>
20 #include <mach/hardware.h>
21
22 #include <video/s1d13xxxfb.h>
23
24 #define BL_MAX_BRIGHT   255
25 #define BL_DEF_BRIGHT   25
26
27 static int jornada_bl_get_brightness(struct backlight_device *bd)
28 {
29         int ret;
30
31         /* check if backlight is on */
32         if (!(PPSR & PPC_LDD1))
33                 return 0;
34
35         jornada_ssp_start();
36
37         /* cmd should return txdummy */
38         ret = jornada_ssp_byte(GETBRIGHTNESS);
39
40         if (jornada_ssp_byte(GETBRIGHTNESS) != TXDUMMY) {
41                 printk(KERN_ERR "bl : get brightness timeout\n");
42                 jornada_ssp_end();
43                 return -ETIMEDOUT;
44         } else /* exchange txdummy for value */
45                 ret = jornada_ssp_byte(TXDUMMY);
46
47         jornada_ssp_end();
48
49         return (BL_MAX_BRIGHT - ret);
50 }
51
52 static int jornada_bl_update_status(struct backlight_device *bd)
53 {
54         int ret = 0;
55
56         jornada_ssp_start();
57
58         /* If backlight is off then really turn it off */
59         if ((bd->props.power != FB_BLANK_UNBLANK) || (bd->props.fb_blank != FB_BLANK_UNBLANK)) {
60                 ret = jornada_ssp_byte(BRIGHTNESSOFF);
61                 if (ret != TXDUMMY) {
62                         printk(KERN_INFO "bl : brightness off timeout\n");
63                         /* turn off backlight */
64                         PPSR &= ~PPC_LDD1;
65                         PPDR |= PPC_LDD1;
66                         ret = -ETIMEDOUT;
67                 }
68         } else  /* turn on backlight */
69                 PPSR |= PPC_LDD1;
70
71                 /* send command to our mcu */
72                 if (jornada_ssp_byte(SETBRIGHTNESS) != TXDUMMY) {
73                         printk(KERN_INFO "bl : failed to set brightness\n");
74                         ret = -ETIMEDOUT;
75                         goto out;
76                 }
77
78                 /* at this point we expect that the mcu has accepted
79                    our command and is waiting for our new value
80                    please note that maximum brightness is 255,
81                    but due to physical layout it is equal to 0, so we simply
82                    invert the value (MAX VALUE - NEW VALUE). */
83                 if (jornada_ssp_byte(BL_MAX_BRIGHT - bd->props.brightness) != TXDUMMY) {
84                         printk(KERN_ERR "bl : set brightness failed\n");
85                         ret = -ETIMEDOUT;
86                 }
87
88                 /* If infact we get an TXDUMMY as output we are happy and dont
89                    make any further comments about it */
90 out:
91         jornada_ssp_end();
92
93         return ret;
94 }
95
96 static const struct backlight_ops jornada_bl_ops = {
97         .get_brightness = jornada_bl_get_brightness,
98         .update_status = jornada_bl_update_status,
99         .options = BL_CORE_SUSPENDRESUME,
100 };
101
102 static int jornada_bl_probe(struct platform_device *pdev)
103 {
104         struct backlight_properties props;
105         int ret;
106         struct backlight_device *bd;
107
108         memset(&props, 0, sizeof(struct backlight_properties));
109         props.max_brightness = BL_MAX_BRIGHT;
110         bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL,
111                                        &jornada_bl_ops, &props);
112
113         if (IS_ERR(bd)) {
114                 ret = PTR_ERR(bd);
115                 printk(KERN_ERR "bl : failed to register device, err=%x\n", ret);
116                 return ret;
117         }
118
119         bd->props.power = FB_BLANK_UNBLANK;
120         bd->props.brightness = BL_DEF_BRIGHT;
121         /* note. make sure max brightness is set otherwise
122            you will get seemingly non-related errors when
123            trying to change brightness */
124         jornada_bl_update_status(bd);
125
126         platform_set_drvdata(pdev, bd);
127         printk(KERN_INFO "HP Jornada 700 series backlight driver\n");
128
129         return 0;
130 }
131
132 static int jornada_bl_remove(struct platform_device *pdev)
133 {
134         struct backlight_device *bd = platform_get_drvdata(pdev);
135
136         backlight_device_unregister(bd);
137
138         return 0;
139 }
140
141 static struct platform_driver jornada_bl_driver = {
142         .probe          = jornada_bl_probe,
143         .remove         = jornada_bl_remove,
144         .driver = {
145                 .name   = "jornada_bl",
146         },
147 };
148
149 int __init jornada_bl_init(void)
150 {
151         return platform_driver_register(&jornada_bl_driver);
152 }
153
154 void __exit jornada_bl_exit(void)
155 {
156         platform_driver_unregister(&jornada_bl_driver);
157 }
158
159 MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson>");
160 MODULE_DESCRIPTION("HP Jornada 710/720/728 Backlight driver");
161 MODULE_LICENSE("GPL");
162
163 module_init(jornada_bl_init);
164 module_exit(jornada_bl_exit);