Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  *  Backlight Driver for HP Jornada 680
  3  *
  4  *  Copyright (c) 2005 Andriy Skulysh
  5  *
  6  *  Based on Sharp's Corgi Backlight Driver
  7  *
  8  * This file is subject to the terms and conditions of the GNU General Public
  9  * License.  See the file "COPYING" in the main directory of this archive
 10  * for more details.
 11  */
 12 
 13 #include <linux/module.h>
 14 #include <linux/kernel.h>
 15 #include <linux/init.h>
 16 #include <linux/platform_device.h>
 17 #include <linux/spinlock.h>
 18 #include <linux/fb.h>
 19 #include <linux/backlight.h>
 20 
 21 #include <cpu/dac.h>
 22 #include <mach/hp6xx.h>
 23 #include <asm/hd64461.h>
 24 
 25 #define HP680_MAX_INTENSITY 255
 26 #define HP680_DEFAULT_INTENSITY 10
 27 
 28 static int hp680bl_suspended;
 29 static int current_intensity = 0;
 30 static DEFINE_SPINLOCK(bl_lock);
 31 
 32 static void hp680bl_send_intensity(struct backlight_device *bd)
 33 {
 34         unsigned long flags;
 35         u16 v;
 36         int intensity = bd->props.brightness;
 37 
 38         if (bd->props.power != FB_BLANK_UNBLANK)
 39                 intensity = 0;
 40         if (bd->props.fb_blank != FB_BLANK_UNBLANK)
 41                 intensity = 0;
 42         if (hp680bl_suspended)
 43                 intensity = 0;
 44 
 45         spin_lock_irqsave(&bl_lock, flags);
 46         if (intensity && current_intensity == 0) {
 47                 sh_dac_enable(DAC_LCD_BRIGHTNESS);
 48                 v = inw(HD64461_GPBDR);
 49                 v &= ~HD64461_GPBDR_LCDOFF;
 50                 outw(v, HD64461_GPBDR);
 51                 sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS);
 52         } else if (intensity == 0 && current_intensity != 0) {
 53                 sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS);
 54                 sh_dac_disable(DAC_LCD_BRIGHTNESS);
 55                 v = inw(HD64461_GPBDR);
 56                 v |= HD64461_GPBDR_LCDOFF;
 57                 outw(v, HD64461_GPBDR);
 58         } else if (intensity) {
 59                 sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS);
 60         }
 61         spin_unlock_irqrestore(&bl_lock, flags);
 62 
 63         current_intensity = intensity;
 64 }
 65 
 66 
 67 #ifdef CONFIG_PM
 68 static int hp680bl_suspend(struct platform_device *pdev, pm_message_t state)
 69 {
 70         struct backlight_device *bd = platform_get_drvdata(pdev);
 71 
 72         hp680bl_suspended = 1;
 73         hp680bl_send_intensity(bd);
 74         return 0;
 75 }
 76 
 77 static int hp680bl_resume(struct platform_device *pdev)
 78 {
 79         struct backlight_device *bd = platform_get_drvdata(pdev);
 80 
 81         hp680bl_suspended = 0;
 82         hp680bl_send_intensity(bd);
 83         return 0;
 84 }
 85 #else
 86 #define hp680bl_suspend NULL
 87 #define hp680bl_resume  NULL
 88 #endif
 89 
 90 static int hp680bl_set_intensity(struct backlight_device *bd)
 91 {
 92         hp680bl_send_intensity(bd);
 93         return 0;
 94 }
 95 
 96 static int hp680bl_get_intensity(struct backlight_device *bd)
 97 {
 98         return current_intensity;
 99 }
100 
101 static struct backlight_ops hp680bl_ops = {
102         .get_brightness = hp680bl_get_intensity,
103         .update_status  = hp680bl_set_intensity,
104 };
105 
106 static int __init hp680bl_probe(struct platform_device *pdev)
107 {
108         struct backlight_device *bd;
109 
110         bd = backlight_device_register ("hp680-bl", &pdev->dev, NULL,
111                     &hp680bl_ops);
112         if (IS_ERR(bd))
113                 return PTR_ERR(bd);
114 
115         platform_set_drvdata(pdev, bd);
116 
117         bd->props.max_brightness = HP680_MAX_INTENSITY;
118         bd->props.brightness = HP680_DEFAULT_INTENSITY;
119         hp680bl_send_intensity(bd);
120 
121         return 0;
122 }
123 
124 static int hp680bl_remove(struct platform_device *pdev)
125 {
126         struct backlight_device *bd = platform_get_drvdata(pdev);
127 
128         bd->props.brightness = 0;
129         bd->props.power = 0;
130         hp680bl_send_intensity(bd);
131 
132         backlight_device_unregister(bd);
133 
134         return 0;
135 }
136 
137 static struct platform_driver hp680bl_driver = {
138         .probe          = hp680bl_probe,
139         .remove         = hp680bl_remove,
140         .suspend        = hp680bl_suspend,
141         .resume         = hp680bl_resume,
142         .driver         = {
143                 .name   = "hp680-bl",
144         },
145 };
146 
147 static struct platform_device *hp680bl_device;
148 
149 static int __init hp680bl_init(void)
150 {
151         int ret;
152 
153         ret = platform_driver_register(&hp680bl_driver);
154         if (ret)
155                 return ret;
156         hp680bl_device = platform_device_register_simple("hp680-bl", -1,
157                                                         NULL, 0);
158         if (IS_ERR(hp680bl_device)) {
159                 platform_driver_unregister(&hp680bl_driver);
160                 return PTR_ERR(hp680bl_device);
161         }
162         return 0;
163 }
164 
165 static void __exit hp680bl_exit(void)
166 {
167         platform_device_unregister(hp680bl_device);
168         platform_driver_unregister(&hp680bl_driver);
169 }
170 
171 module_init(hp680bl_init);
172 module_exit(hp680bl_exit);
173 
174 MODULE_AUTHOR("Andriy Skulysh <askulysh@gmail.com>");
175 MODULE_DESCRIPTION("HP Jornada 680 Backlight Driver");
176 MODULE_LICENSE("GPL");
177 
  This page was automatically generated by the LXR engine.