]>
Commit | Line | Data |
---|---|---|
7a208463 MJ |
1 | /* |
2 | * Backlight Driver for Frontpath ProGear HX1050+ | |
3 | * | |
4 | * Copyright (c) 2006 Marcin Juszkiewicz | |
5 | * | |
6 | * Based on Progear LCD driver by M Schacht | |
7 | * <mschacht at alumni dot washington dot edu> | |
8 | * | |
9 | * Based on Sharp's Corgi Backlight Driver | |
10 | * Based on Backlight Driver for HP Jornada 680 | |
11 | * | |
12 | * This program is free software; you can redistribute it and/or modify | |
13 | * it under the terms of the GNU General Public License version 2 as | |
14 | * published by the Free Software Foundation. | |
15 | * | |
16 | */ | |
17 | ||
18 | #include <linux/module.h> | |
19 | #include <linux/kernel.h> | |
20 | #include <linux/init.h> | |
21 | #include <linux/platform_device.h> | |
22 | #include <linux/mutex.h> | |
23 | #include <linux/fb.h> | |
24 | #include <linux/backlight.h> | |
25 | #include <linux/pci.h> | |
7a208463 MJ |
26 | |
27 | #define PMU_LPCR 0xB0 | |
28 | #define SB_MPS1 0x61 | |
29 | #define HW_LEVEL_MAX 0x77 | |
30 | #define HW_LEVEL_MIN 0x4f | |
31 | ||
32 | static struct pci_dev *pmu_dev = NULL; | |
33 | static struct pci_dev *sb_dev = NULL; | |
34 | ||
35 | static int progearbl_set_intensity(struct backlight_device *bd) | |
36 | { | |
599a52d1 | 37 | int intensity = bd->props.brightness; |
7a208463 | 38 | |
599a52d1 | 39 | if (bd->props.power != FB_BLANK_UNBLANK) |
7a208463 | 40 | intensity = 0; |
599a52d1 | 41 | if (bd->props.fb_blank != FB_BLANK_UNBLANK) |
7a208463 MJ |
42 | intensity = 0; |
43 | ||
44 | pci_write_config_byte(pmu_dev, PMU_LPCR, intensity + HW_LEVEL_MIN); | |
45 | ||
46 | return 0; | |
47 | } | |
48 | ||
49 | static int progearbl_get_intensity(struct backlight_device *bd) | |
50 | { | |
51 | u8 intensity; | |
52 | pci_read_config_byte(pmu_dev, PMU_LPCR, &intensity); | |
53 | ||
54 | return intensity - HW_LEVEL_MIN; | |
55 | } | |
56 | ||
9905a43b | 57 | static const struct backlight_ops progearbl_ops = { |
7a208463 MJ |
58 | .get_brightness = progearbl_get_intensity, |
59 | .update_status = progearbl_set_intensity, | |
60 | }; | |
61 | ||
62 | static int progearbl_probe(struct platform_device *pdev) | |
63 | { | |
a19a6ee6 | 64 | struct backlight_properties props; |
7a208463 MJ |
65 | u8 temp; |
66 | struct backlight_device *progear_backlight_device; | |
a4ebb780 | 67 | int ret; |
7a208463 | 68 | |
89952d13 | 69 | pmu_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL); |
7a208463 MJ |
70 | if (!pmu_dev) { |
71 | printk("ALI M7101 PMU not found.\n"); | |
72 | return -ENODEV; | |
73 | } | |
74 | ||
89952d13 | 75 | sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); |
7a208463 MJ |
76 | if (!sb_dev) { |
77 | printk("ALI 1533 SB not found.\n"); | |
a4ebb780 JS |
78 | ret = -ENODEV; |
79 | goto put_pmu; | |
7a208463 MJ |
80 | } |
81 | ||
82 | /* Set SB_MPS1 to enable brightness control. */ | |
83 | pci_read_config_byte(sb_dev, SB_MPS1, &temp); | |
84 | pci_write_config_byte(sb_dev, SB_MPS1, temp | 0x20); | |
85 | ||
a19a6ee6 | 86 | memset(&props, 0, sizeof(struct backlight_properties)); |
bb7ca747 | 87 | props.type = BACKLIGHT_RAW; |
a19a6ee6 | 88 | props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN; |
7a208463 MJ |
89 | progear_backlight_device = backlight_device_register("progear-bl", |
90 | &pdev->dev, NULL, | |
a19a6ee6 MG |
91 | &progearbl_ops, |
92 | &props); | |
a4ebb780 JS |
93 | if (IS_ERR(progear_backlight_device)) { |
94 | ret = PTR_ERR(progear_backlight_device); | |
95 | goto put_sb; | |
96 | } | |
7a208463 MJ |
97 | |
98 | platform_set_drvdata(pdev, progear_backlight_device); | |
99 | ||
599a52d1 RP |
100 | progear_backlight_device->props.power = FB_BLANK_UNBLANK; |
101 | progear_backlight_device->props.brightness = HW_LEVEL_MAX - HW_LEVEL_MIN; | |
7a208463 MJ |
102 | progearbl_set_intensity(progear_backlight_device); |
103 | ||
104 | return 0; | |
a4ebb780 JS |
105 | put_sb: |
106 | pci_dev_put(sb_dev); | |
107 | put_pmu: | |
108 | pci_dev_put(pmu_dev); | |
109 | return ret; | |
7a208463 MJ |
110 | } |
111 | ||
112 | static int progearbl_remove(struct platform_device *pdev) | |
113 | { | |
114 | struct backlight_device *bd = platform_get_drvdata(pdev); | |
115 | backlight_device_unregister(bd); | |
116 | ||
117 | return 0; | |
118 | } | |
119 | ||
120 | static struct platform_driver progearbl_driver = { | |
121 | .probe = progearbl_probe, | |
122 | .remove = progearbl_remove, | |
123 | .driver = { | |
124 | .name = "progear-bl", | |
125 | }, | |
126 | }; | |
127 | ||
128 | static struct platform_device *progearbl_device; | |
129 | ||
130 | static int __init progearbl_init(void) | |
131 | { | |
132 | int ret = platform_driver_register(&progearbl_driver); | |
133 | ||
6cd6f35a AM |
134 | if (ret) |
135 | return ret; | |
136 | progearbl_device = platform_device_register_simple("progear-bl", -1, | |
137 | NULL, 0); | |
138 | if (IS_ERR(progearbl_device)) { | |
139 | platform_driver_unregister(&progearbl_driver); | |
140 | return PTR_ERR(progearbl_device); | |
7a208463 MJ |
141 | } |
142 | ||
6cd6f35a | 143 | return 0; |
7a208463 MJ |
144 | } |
145 | ||
146 | static void __exit progearbl_exit(void) | |
147 | { | |
148 | pci_dev_put(pmu_dev); | |
149 | pci_dev_put(sb_dev); | |
150 | ||
151 | platform_device_unregister(progearbl_device); | |
152 | platform_driver_unregister(&progearbl_driver); | |
153 | } | |
154 | ||
155 | module_init(progearbl_init); | |
156 | module_exit(progearbl_exit); | |
157 | ||
158 | MODULE_AUTHOR("Marcin Juszkiewicz <linux@hrw.one.pl>"); | |
159 | MODULE_DESCRIPTION("ProGear Backlight Driver"); | |
160 | MODULE_LICENSE("GPL"); |