Commit dd37739f47ea278a57d66b2afe20243f0a6294a0

Authored by Jesper Juhl
Committed by Paul Mundt
1 parent 20733d59d5

Remove unneeded version.h includes from drivers/video/

It was pointed out by 'make versioncheck' that some includes of
linux/version.h are not needed in drivers/video/.
This patch removes them.

Signed-off-by: Jesper Juhl <jj@chaosbits.net>
Acked-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>

Showing 4 changed files with 0 additions and 5 deletions Inline Diff

drivers/video/backlight/adp8860_bl.c
1 /* 1 /*
2 * Backlight driver for Analog Devices ADP8860 Backlight Devices 2 * Backlight driver for Analog Devices ADP8860 Backlight Devices
3 * 3 *
4 * Copyright 2009-2010 Analog Devices Inc. 4 * Copyright 2009-2010 Analog Devices Inc.
5 * 5 *
6 * Licensed under the GPL-2 or later. 6 * Licensed under the GPL-2 or later.
7 */ 7 */
8 8
9 #include <linux/module.h> 9 #include <linux/module.h>
10 #include <linux/version.h>
11 #include <linux/init.h> 10 #include <linux/init.h>
12 #include <linux/errno.h> 11 #include <linux/errno.h>
13 #include <linux/pm.h> 12 #include <linux/pm.h>
14 #include <linux/platform_device.h> 13 #include <linux/platform_device.h>
15 #include <linux/i2c.h> 14 #include <linux/i2c.h>
16 #include <linux/fb.h> 15 #include <linux/fb.h>
17 #include <linux/backlight.h> 16 #include <linux/backlight.h>
18 #include <linux/leds.h> 17 #include <linux/leds.h>
19 #include <linux/slab.h> 18 #include <linux/slab.h>
20 #include <linux/workqueue.h> 19 #include <linux/workqueue.h>
21 20
22 #include <linux/i2c/adp8860.h> 21 #include <linux/i2c/adp8860.h>
23 #define ADP8860_EXT_FEATURES 22 #define ADP8860_EXT_FEATURES
24 #define ADP8860_USE_LEDS 23 #define ADP8860_USE_LEDS
25 24
26 #define ADP8860_MFDVID 0x00 /* Manufacturer and device ID */ 25 #define ADP8860_MFDVID 0x00 /* Manufacturer and device ID */
27 #define ADP8860_MDCR 0x01 /* Device mode and status */ 26 #define ADP8860_MDCR 0x01 /* Device mode and status */
28 #define ADP8860_MDCR2 0x02 /* Device mode and Status Register 2 */ 27 #define ADP8860_MDCR2 0x02 /* Device mode and Status Register 2 */
29 #define ADP8860_INTR_EN 0x03 /* Interrupts enable */ 28 #define ADP8860_INTR_EN 0x03 /* Interrupts enable */
30 #define ADP8860_CFGR 0x04 /* Configuration register */ 29 #define ADP8860_CFGR 0x04 /* Configuration register */
31 #define ADP8860_BLSEN 0x05 /* Sink enable backlight or independent */ 30 #define ADP8860_BLSEN 0x05 /* Sink enable backlight or independent */
32 #define ADP8860_BLOFF 0x06 /* Backlight off timeout */ 31 #define ADP8860_BLOFF 0x06 /* Backlight off timeout */
33 #define ADP8860_BLDIM 0x07 /* Backlight dim timeout */ 32 #define ADP8860_BLDIM 0x07 /* Backlight dim timeout */
34 #define ADP8860_BLFR 0x08 /* Backlight fade in and out rates */ 33 #define ADP8860_BLFR 0x08 /* Backlight fade in and out rates */
35 #define ADP8860_BLMX1 0x09 /* Backlight (Brightness Level 1-daylight) maximum current */ 34 #define ADP8860_BLMX1 0x09 /* Backlight (Brightness Level 1-daylight) maximum current */
36 #define ADP8860_BLDM1 0x0A /* Backlight (Brightness Level 1-daylight) dim current */ 35 #define ADP8860_BLDM1 0x0A /* Backlight (Brightness Level 1-daylight) dim current */
37 #define ADP8860_BLMX2 0x0B /* Backlight (Brightness Level 2-office) maximum current */ 36 #define ADP8860_BLMX2 0x0B /* Backlight (Brightness Level 2-office) maximum current */
38 #define ADP8860_BLDM2 0x0C /* Backlight (Brightness Level 2-office) dim current */ 37 #define ADP8860_BLDM2 0x0C /* Backlight (Brightness Level 2-office) dim current */
39 #define ADP8860_BLMX3 0x0D /* Backlight (Brightness Level 3-dark) maximum current */ 38 #define ADP8860_BLMX3 0x0D /* Backlight (Brightness Level 3-dark) maximum current */
40 #define ADP8860_BLDM3 0x0E /* Backlight (Brightness Level 3-dark) dim current */ 39 #define ADP8860_BLDM3 0x0E /* Backlight (Brightness Level 3-dark) dim current */
41 #define ADP8860_ISCFR 0x0F /* Independent sink current fade control register */ 40 #define ADP8860_ISCFR 0x0F /* Independent sink current fade control register */
42 #define ADP8860_ISCC 0x10 /* Independent sink current control register */ 41 #define ADP8860_ISCC 0x10 /* Independent sink current control register */
43 #define ADP8860_ISCT1 0x11 /* Independent Sink Current Timer Register LED[7:5] */ 42 #define ADP8860_ISCT1 0x11 /* Independent Sink Current Timer Register LED[7:5] */
44 #define ADP8860_ISCT2 0x12 /* Independent Sink Current Timer Register LED[4:1] */ 43 #define ADP8860_ISCT2 0x12 /* Independent Sink Current Timer Register LED[4:1] */
45 #define ADP8860_ISCF 0x13 /* Independent sink current fade register */ 44 #define ADP8860_ISCF 0x13 /* Independent sink current fade register */
46 #define ADP8860_ISC7 0x14 /* Independent Sink Current LED7 */ 45 #define ADP8860_ISC7 0x14 /* Independent Sink Current LED7 */
47 #define ADP8860_ISC6 0x15 /* Independent Sink Current LED6 */ 46 #define ADP8860_ISC6 0x15 /* Independent Sink Current LED6 */
48 #define ADP8860_ISC5 0x16 /* Independent Sink Current LED5 */ 47 #define ADP8860_ISC5 0x16 /* Independent Sink Current LED5 */
49 #define ADP8860_ISC4 0x17 /* Independent Sink Current LED4 */ 48 #define ADP8860_ISC4 0x17 /* Independent Sink Current LED4 */
50 #define ADP8860_ISC3 0x18 /* Independent Sink Current LED3 */ 49 #define ADP8860_ISC3 0x18 /* Independent Sink Current LED3 */
51 #define ADP8860_ISC2 0x19 /* Independent Sink Current LED2 */ 50 #define ADP8860_ISC2 0x19 /* Independent Sink Current LED2 */
52 #define ADP8860_ISC1 0x1A /* Independent Sink Current LED1 */ 51 #define ADP8860_ISC1 0x1A /* Independent Sink Current LED1 */
53 #define ADP8860_CCFG 0x1B /* Comparator configuration */ 52 #define ADP8860_CCFG 0x1B /* Comparator configuration */
54 #define ADP8860_CCFG2 0x1C /* Second comparator configuration */ 53 #define ADP8860_CCFG2 0x1C /* Second comparator configuration */
55 #define ADP8860_L2_TRP 0x1D /* L2 comparator reference */ 54 #define ADP8860_L2_TRP 0x1D /* L2 comparator reference */
56 #define ADP8860_L2_HYS 0x1E /* L2 hysteresis */ 55 #define ADP8860_L2_HYS 0x1E /* L2 hysteresis */
57 #define ADP8860_L3_TRP 0x1F /* L3 comparator reference */ 56 #define ADP8860_L3_TRP 0x1F /* L3 comparator reference */
58 #define ADP8860_L3_HYS 0x20 /* L3 hysteresis */ 57 #define ADP8860_L3_HYS 0x20 /* L3 hysteresis */
59 #define ADP8860_PH1LEVL 0x21 /* First phototransistor ambient light level-low byte register */ 58 #define ADP8860_PH1LEVL 0x21 /* First phototransistor ambient light level-low byte register */
60 #define ADP8860_PH1LEVH 0x22 /* First phototransistor ambient light level-high byte register */ 59 #define ADP8860_PH1LEVH 0x22 /* First phototransistor ambient light level-high byte register */
61 #define ADP8860_PH2LEVL 0x23 /* Second phototransistor ambient light level-low byte register */ 60 #define ADP8860_PH2LEVL 0x23 /* Second phototransistor ambient light level-low byte register */
62 #define ADP8860_PH2LEVH 0x24 /* Second phototransistor ambient light level-high byte register */ 61 #define ADP8860_PH2LEVH 0x24 /* Second phototransistor ambient light level-high byte register */
63 62
64 #define ADP8860_MANUFID 0x0 /* Analog Devices ADP8860 Manufacturer ID */ 63 #define ADP8860_MANUFID 0x0 /* Analog Devices ADP8860 Manufacturer ID */
65 #define ADP8861_MANUFID 0x4 /* Analog Devices ADP8861 Manufacturer ID */ 64 #define ADP8861_MANUFID 0x4 /* Analog Devices ADP8861 Manufacturer ID */
66 #define ADP8863_MANUFID 0x2 /* Analog Devices ADP8863 Manufacturer ID */ 65 #define ADP8863_MANUFID 0x2 /* Analog Devices ADP8863 Manufacturer ID */
67 66
68 #define ADP8860_DEVID(x) ((x) & 0xF) 67 #define ADP8860_DEVID(x) ((x) & 0xF)
69 #define ADP8860_MANID(x) ((x) >> 4) 68 #define ADP8860_MANID(x) ((x) >> 4)
70 69
71 /* MDCR Device mode and status */ 70 /* MDCR Device mode and status */
72 #define INT_CFG (1 << 6) 71 #define INT_CFG (1 << 6)
73 #define NSTBY (1 << 5) 72 #define NSTBY (1 << 5)
74 #define DIM_EN (1 << 4) 73 #define DIM_EN (1 << 4)
75 #define GDWN_DIS (1 << 3) 74 #define GDWN_DIS (1 << 3)
76 #define SIS_EN (1 << 2) 75 #define SIS_EN (1 << 2)
77 #define CMP_AUTOEN (1 << 1) 76 #define CMP_AUTOEN (1 << 1)
78 #define BLEN (1 << 0) 77 #define BLEN (1 << 0)
79 78
80 /* ADP8860_CCFG Main ALS comparator level enable */ 79 /* ADP8860_CCFG Main ALS comparator level enable */
81 #define L3_EN (1 << 1) 80 #define L3_EN (1 << 1)
82 #define L2_EN (1 << 0) 81 #define L2_EN (1 << 0)
83 82
84 #define CFGR_BLV_SHIFT 3 83 #define CFGR_BLV_SHIFT 3
85 #define CFGR_BLV_MASK 0x3 84 #define CFGR_BLV_MASK 0x3
86 #define ADP8860_FLAG_LED_MASK 0xFF 85 #define ADP8860_FLAG_LED_MASK 0xFF
87 86
88 #define FADE_VAL(in, out) ((0xF & (in)) | ((0xF & (out)) << 4)) 87 #define FADE_VAL(in, out) ((0xF & (in)) | ((0xF & (out)) << 4))
89 #define BL_CFGR_VAL(law, blv) ((((blv) & CFGR_BLV_MASK) << CFGR_BLV_SHIFT) | ((0x3 & (law)) << 1)) 88 #define BL_CFGR_VAL(law, blv) ((((blv) & CFGR_BLV_MASK) << CFGR_BLV_SHIFT) | ((0x3 & (law)) << 1))
90 #define ALS_CCFG_VAL(filt) ((0x7 & filt) << 5) 89 #define ALS_CCFG_VAL(filt) ((0x7 & filt) << 5)
91 90
92 enum { 91 enum {
93 adp8860, 92 adp8860,
94 adp8861, 93 adp8861,
95 adp8863 94 adp8863
96 }; 95 };
97 96
98 struct adp8860_led { 97 struct adp8860_led {
99 struct led_classdev cdev; 98 struct led_classdev cdev;
100 struct work_struct work; 99 struct work_struct work;
101 struct i2c_client *client; 100 struct i2c_client *client;
102 enum led_brightness new_brightness; 101 enum led_brightness new_brightness;
103 int id; 102 int id;
104 int flags; 103 int flags;
105 }; 104 };
106 105
107 struct adp8860_bl { 106 struct adp8860_bl {
108 struct i2c_client *client; 107 struct i2c_client *client;
109 struct backlight_device *bl; 108 struct backlight_device *bl;
110 struct adp8860_led *led; 109 struct adp8860_led *led;
111 struct adp8860_backlight_platform_data *pdata; 110 struct adp8860_backlight_platform_data *pdata;
112 struct mutex lock; 111 struct mutex lock;
113 unsigned long cached_daylight_max; 112 unsigned long cached_daylight_max;
114 int id; 113 int id;
115 int revid; 114 int revid;
116 int current_brightness; 115 int current_brightness;
117 unsigned en_ambl_sens:1; 116 unsigned en_ambl_sens:1;
118 unsigned gdwn_dis:1; 117 unsigned gdwn_dis:1;
119 }; 118 };
120 119
121 static int adp8860_read(struct i2c_client *client, int reg, uint8_t *val) 120 static int adp8860_read(struct i2c_client *client, int reg, uint8_t *val)
122 { 121 {
123 int ret; 122 int ret;
124 123
125 ret = i2c_smbus_read_byte_data(client, reg); 124 ret = i2c_smbus_read_byte_data(client, reg);
126 if (ret < 0) { 125 if (ret < 0) {
127 dev_err(&client->dev, "failed reading at 0x%02x\n", reg); 126 dev_err(&client->dev, "failed reading at 0x%02x\n", reg);
128 return ret; 127 return ret;
129 } 128 }
130 129
131 *val = (uint8_t)ret; 130 *val = (uint8_t)ret;
132 return 0; 131 return 0;
133 } 132 }
134 133
135 static int adp8860_write(struct i2c_client *client, u8 reg, u8 val) 134 static int adp8860_write(struct i2c_client *client, u8 reg, u8 val)
136 { 135 {
137 return i2c_smbus_write_byte_data(client, reg, val); 136 return i2c_smbus_write_byte_data(client, reg, val);
138 } 137 }
139 138
140 static int adp8860_set_bits(struct i2c_client *client, int reg, uint8_t bit_mask) 139 static int adp8860_set_bits(struct i2c_client *client, int reg, uint8_t bit_mask)
141 { 140 {
142 struct adp8860_bl *data = i2c_get_clientdata(client); 141 struct adp8860_bl *data = i2c_get_clientdata(client);
143 uint8_t reg_val; 142 uint8_t reg_val;
144 int ret; 143 int ret;
145 144
146 mutex_lock(&data->lock); 145 mutex_lock(&data->lock);
147 146
148 ret = adp8860_read(client, reg, &reg_val); 147 ret = adp8860_read(client, reg, &reg_val);
149 148
150 if (!ret && ((reg_val & bit_mask) == 0)) { 149 if (!ret && ((reg_val & bit_mask) == 0)) {
151 reg_val |= bit_mask; 150 reg_val |= bit_mask;
152 ret = adp8860_write(client, reg, reg_val); 151 ret = adp8860_write(client, reg, reg_val);
153 } 152 }
154 153
155 mutex_unlock(&data->lock); 154 mutex_unlock(&data->lock);
156 return ret; 155 return ret;
157 } 156 }
158 157
159 static int adp8860_clr_bits(struct i2c_client *client, int reg, uint8_t bit_mask) 158 static int adp8860_clr_bits(struct i2c_client *client, int reg, uint8_t bit_mask)
160 { 159 {
161 struct adp8860_bl *data = i2c_get_clientdata(client); 160 struct adp8860_bl *data = i2c_get_clientdata(client);
162 uint8_t reg_val; 161 uint8_t reg_val;
163 int ret; 162 int ret;
164 163
165 mutex_lock(&data->lock); 164 mutex_lock(&data->lock);
166 165
167 ret = adp8860_read(client, reg, &reg_val); 166 ret = adp8860_read(client, reg, &reg_val);
168 167
169 if (!ret && (reg_val & bit_mask)) { 168 if (!ret && (reg_val & bit_mask)) {
170 reg_val &= ~bit_mask; 169 reg_val &= ~bit_mask;
171 ret = adp8860_write(client, reg, reg_val); 170 ret = adp8860_write(client, reg, reg_val);
172 } 171 }
173 172
174 mutex_unlock(&data->lock); 173 mutex_unlock(&data->lock);
175 return ret; 174 return ret;
176 } 175 }
177 176
178 /* 177 /*
179 * Independent sink / LED 178 * Independent sink / LED
180 */ 179 */
181 #if defined(ADP8860_USE_LEDS) 180 #if defined(ADP8860_USE_LEDS)
182 static void adp8860_led_work(struct work_struct *work) 181 static void adp8860_led_work(struct work_struct *work)
183 { 182 {
184 struct adp8860_led *led = container_of(work, struct adp8860_led, work); 183 struct adp8860_led *led = container_of(work, struct adp8860_led, work);
185 adp8860_write(led->client, ADP8860_ISC1 - led->id + 1, 184 adp8860_write(led->client, ADP8860_ISC1 - led->id + 1,
186 led->new_brightness >> 1); 185 led->new_brightness >> 1);
187 } 186 }
188 187
189 static void adp8860_led_set(struct led_classdev *led_cdev, 188 static void adp8860_led_set(struct led_classdev *led_cdev,
190 enum led_brightness value) 189 enum led_brightness value)
191 { 190 {
192 struct adp8860_led *led; 191 struct adp8860_led *led;
193 192
194 led = container_of(led_cdev, struct adp8860_led, cdev); 193 led = container_of(led_cdev, struct adp8860_led, cdev);
195 led->new_brightness = value; 194 led->new_brightness = value;
196 schedule_work(&led->work); 195 schedule_work(&led->work);
197 } 196 }
198 197
199 static int adp8860_led_setup(struct adp8860_led *led) 198 static int adp8860_led_setup(struct adp8860_led *led)
200 { 199 {
201 struct i2c_client *client = led->client; 200 struct i2c_client *client = led->client;
202 int ret = 0; 201 int ret = 0;
203 202
204 ret = adp8860_write(client, ADP8860_ISC1 - led->id + 1, 0); 203 ret = adp8860_write(client, ADP8860_ISC1 - led->id + 1, 0);
205 ret |= adp8860_set_bits(client, ADP8860_ISCC, 1 << (led->id - 1)); 204 ret |= adp8860_set_bits(client, ADP8860_ISCC, 1 << (led->id - 1));
206 205
207 if (led->id > 4) 206 if (led->id > 4)
208 ret |= adp8860_set_bits(client, ADP8860_ISCT1, 207 ret |= adp8860_set_bits(client, ADP8860_ISCT1,
209 (led->flags & 0x3) << ((led->id - 5) * 2)); 208 (led->flags & 0x3) << ((led->id - 5) * 2));
210 else 209 else
211 ret |= adp8860_set_bits(client, ADP8860_ISCT2, 210 ret |= adp8860_set_bits(client, ADP8860_ISCT2,
212 (led->flags & 0x3) << ((led->id - 1) * 2)); 211 (led->flags & 0x3) << ((led->id - 1) * 2));
213 212
214 return ret; 213 return ret;
215 } 214 }
216 215
217 static int __devinit adp8860_led_probe(struct i2c_client *client) 216 static int __devinit adp8860_led_probe(struct i2c_client *client)
218 { 217 {
219 struct adp8860_backlight_platform_data *pdata = 218 struct adp8860_backlight_platform_data *pdata =
220 client->dev.platform_data; 219 client->dev.platform_data;
221 struct adp8860_bl *data = i2c_get_clientdata(client); 220 struct adp8860_bl *data = i2c_get_clientdata(client);
222 struct adp8860_led *led, *led_dat; 221 struct adp8860_led *led, *led_dat;
223 struct led_info *cur_led; 222 struct led_info *cur_led;
224 int ret, i; 223 int ret, i;
225 224
226 led = kzalloc(sizeof(*led) * pdata->num_leds, GFP_KERNEL); 225 led = kzalloc(sizeof(*led) * pdata->num_leds, GFP_KERNEL);
227 if (led == NULL) { 226 if (led == NULL) {
228 dev_err(&client->dev, "failed to alloc memory\n"); 227 dev_err(&client->dev, "failed to alloc memory\n");
229 return -ENOMEM; 228 return -ENOMEM;
230 } 229 }
231 230
232 ret = adp8860_write(client, ADP8860_ISCFR, pdata->led_fade_law); 231 ret = adp8860_write(client, ADP8860_ISCFR, pdata->led_fade_law);
233 ret = adp8860_write(client, ADP8860_ISCT1, 232 ret = adp8860_write(client, ADP8860_ISCT1,
234 (pdata->led_on_time & 0x3) << 6); 233 (pdata->led_on_time & 0x3) << 6);
235 ret |= adp8860_write(client, ADP8860_ISCF, 234 ret |= adp8860_write(client, ADP8860_ISCF,
236 FADE_VAL(pdata->led_fade_in, pdata->led_fade_out)); 235 FADE_VAL(pdata->led_fade_in, pdata->led_fade_out));
237 236
238 if (ret) { 237 if (ret) {
239 dev_err(&client->dev, "failed to write\n"); 238 dev_err(&client->dev, "failed to write\n");
240 goto err_free; 239 goto err_free;
241 } 240 }
242 241
243 for (i = 0; i < pdata->num_leds; ++i) { 242 for (i = 0; i < pdata->num_leds; ++i) {
244 cur_led = &pdata->leds[i]; 243 cur_led = &pdata->leds[i];
245 led_dat = &led[i]; 244 led_dat = &led[i];
246 245
247 led_dat->id = cur_led->flags & ADP8860_FLAG_LED_MASK; 246 led_dat->id = cur_led->flags & ADP8860_FLAG_LED_MASK;
248 247
249 if (led_dat->id > 7 || led_dat->id < 1) { 248 if (led_dat->id > 7 || led_dat->id < 1) {
250 dev_err(&client->dev, "Invalid LED ID %d\n", 249 dev_err(&client->dev, "Invalid LED ID %d\n",
251 led_dat->id); 250 led_dat->id);
252 goto err; 251 goto err;
253 } 252 }
254 253
255 if (pdata->bl_led_assign & (1 << (led_dat->id - 1))) { 254 if (pdata->bl_led_assign & (1 << (led_dat->id - 1))) {
256 dev_err(&client->dev, "LED %d used by Backlight\n", 255 dev_err(&client->dev, "LED %d used by Backlight\n",
257 led_dat->id); 256 led_dat->id);
258 goto err; 257 goto err;
259 } 258 }
260 259
261 led_dat->cdev.name = cur_led->name; 260 led_dat->cdev.name = cur_led->name;
262 led_dat->cdev.default_trigger = cur_led->default_trigger; 261 led_dat->cdev.default_trigger = cur_led->default_trigger;
263 led_dat->cdev.brightness_set = adp8860_led_set; 262 led_dat->cdev.brightness_set = adp8860_led_set;
264 led_dat->cdev.brightness = LED_OFF; 263 led_dat->cdev.brightness = LED_OFF;
265 led_dat->flags = cur_led->flags >> FLAG_OFFT_SHIFT; 264 led_dat->flags = cur_led->flags >> FLAG_OFFT_SHIFT;
266 led_dat->client = client; 265 led_dat->client = client;
267 led_dat->new_brightness = LED_OFF; 266 led_dat->new_brightness = LED_OFF;
268 INIT_WORK(&led_dat->work, adp8860_led_work); 267 INIT_WORK(&led_dat->work, adp8860_led_work);
269 268
270 ret = led_classdev_register(&client->dev, &led_dat->cdev); 269 ret = led_classdev_register(&client->dev, &led_dat->cdev);
271 if (ret) { 270 if (ret) {
272 dev_err(&client->dev, "failed to register LED %d\n", 271 dev_err(&client->dev, "failed to register LED %d\n",
273 led_dat->id); 272 led_dat->id);
274 goto err; 273 goto err;
275 } 274 }
276 275
277 ret = adp8860_led_setup(led_dat); 276 ret = adp8860_led_setup(led_dat);
278 if (ret) { 277 if (ret) {
279 dev_err(&client->dev, "failed to write\n"); 278 dev_err(&client->dev, "failed to write\n");
280 i++; 279 i++;
281 goto err; 280 goto err;
282 } 281 }
283 } 282 }
284 283
285 data->led = led; 284 data->led = led;
286 285
287 return 0; 286 return 0;
288 287
289 err: 288 err:
290 for (i = i - 1; i >= 0; --i) { 289 for (i = i - 1; i >= 0; --i) {
291 led_classdev_unregister(&led[i].cdev); 290 led_classdev_unregister(&led[i].cdev);
292 cancel_work_sync(&led[i].work); 291 cancel_work_sync(&led[i].work);
293 } 292 }
294 293
295 err_free: 294 err_free:
296 kfree(led); 295 kfree(led);
297 296
298 return ret; 297 return ret;
299 } 298 }
300 299
301 static int __devexit adp8860_led_remove(struct i2c_client *client) 300 static int __devexit adp8860_led_remove(struct i2c_client *client)
302 { 301 {
303 struct adp8860_backlight_platform_data *pdata = 302 struct adp8860_backlight_platform_data *pdata =
304 client->dev.platform_data; 303 client->dev.platform_data;
305 struct adp8860_bl *data = i2c_get_clientdata(client); 304 struct adp8860_bl *data = i2c_get_clientdata(client);
306 int i; 305 int i;
307 306
308 for (i = 0; i < pdata->num_leds; i++) { 307 for (i = 0; i < pdata->num_leds; i++) {
309 led_classdev_unregister(&data->led[i].cdev); 308 led_classdev_unregister(&data->led[i].cdev);
310 cancel_work_sync(&data->led[i].work); 309 cancel_work_sync(&data->led[i].work);
311 } 310 }
312 311
313 kfree(data->led); 312 kfree(data->led);
314 return 0; 313 return 0;
315 } 314 }
316 #else 315 #else
317 static int __devinit adp8860_led_probe(struct i2c_client *client) 316 static int __devinit adp8860_led_probe(struct i2c_client *client)
318 { 317 {
319 return 0; 318 return 0;
320 } 319 }
321 320
322 static int __devexit adp8860_led_remove(struct i2c_client *client) 321 static int __devexit adp8860_led_remove(struct i2c_client *client)
323 { 322 {
324 return 0; 323 return 0;
325 } 324 }
326 #endif 325 #endif
327 326
328 static int adp8860_bl_set(struct backlight_device *bl, int brightness) 327 static int adp8860_bl_set(struct backlight_device *bl, int brightness)
329 { 328 {
330 struct adp8860_bl *data = bl_get_data(bl); 329 struct adp8860_bl *data = bl_get_data(bl);
331 struct i2c_client *client = data->client; 330 struct i2c_client *client = data->client;
332 int ret = 0; 331 int ret = 0;
333 332
334 if (data->en_ambl_sens) { 333 if (data->en_ambl_sens) {
335 if ((brightness > 0) && (brightness < ADP8860_MAX_BRIGHTNESS)) { 334 if ((brightness > 0) && (brightness < ADP8860_MAX_BRIGHTNESS)) {
336 /* Disable Ambient Light auto adjust */ 335 /* Disable Ambient Light auto adjust */
337 ret |= adp8860_clr_bits(client, ADP8860_MDCR, 336 ret |= adp8860_clr_bits(client, ADP8860_MDCR,
338 CMP_AUTOEN); 337 CMP_AUTOEN);
339 ret |= adp8860_write(client, ADP8860_BLMX1, brightness); 338 ret |= adp8860_write(client, ADP8860_BLMX1, brightness);
340 } else { 339 } else {
341 /* 340 /*
342 * MAX_BRIGHTNESS -> Enable Ambient Light auto adjust 341 * MAX_BRIGHTNESS -> Enable Ambient Light auto adjust
343 * restore daylight l1 sysfs brightness 342 * restore daylight l1 sysfs brightness
344 */ 343 */
345 ret |= adp8860_write(client, ADP8860_BLMX1, 344 ret |= adp8860_write(client, ADP8860_BLMX1,
346 data->cached_daylight_max); 345 data->cached_daylight_max);
347 ret |= adp8860_set_bits(client, ADP8860_MDCR, 346 ret |= adp8860_set_bits(client, ADP8860_MDCR,
348 CMP_AUTOEN); 347 CMP_AUTOEN);
349 } 348 }
350 } else 349 } else
351 ret |= adp8860_write(client, ADP8860_BLMX1, brightness); 350 ret |= adp8860_write(client, ADP8860_BLMX1, brightness);
352 351
353 if (data->current_brightness && brightness == 0) 352 if (data->current_brightness && brightness == 0)
354 ret |= adp8860_set_bits(client, 353 ret |= adp8860_set_bits(client,
355 ADP8860_MDCR, DIM_EN); 354 ADP8860_MDCR, DIM_EN);
356 else if (data->current_brightness == 0 && brightness) 355 else if (data->current_brightness == 0 && brightness)
357 ret |= adp8860_clr_bits(client, 356 ret |= adp8860_clr_bits(client,
358 ADP8860_MDCR, DIM_EN); 357 ADP8860_MDCR, DIM_EN);
359 358
360 if (!ret) 359 if (!ret)
361 data->current_brightness = brightness; 360 data->current_brightness = brightness;
362 361
363 return ret; 362 return ret;
364 } 363 }
365 364
366 static int adp8860_bl_update_status(struct backlight_device *bl) 365 static int adp8860_bl_update_status(struct backlight_device *bl)
367 { 366 {
368 int brightness = bl->props.brightness; 367 int brightness = bl->props.brightness;
369 if (bl->props.power != FB_BLANK_UNBLANK) 368 if (bl->props.power != FB_BLANK_UNBLANK)
370 brightness = 0; 369 brightness = 0;
371 370
372 if (bl->props.fb_blank != FB_BLANK_UNBLANK) 371 if (bl->props.fb_blank != FB_BLANK_UNBLANK)
373 brightness = 0; 372 brightness = 0;
374 373
375 return adp8860_bl_set(bl, brightness); 374 return adp8860_bl_set(bl, brightness);
376 } 375 }
377 376
378 static int adp8860_bl_get_brightness(struct backlight_device *bl) 377 static int adp8860_bl_get_brightness(struct backlight_device *bl)
379 { 378 {
380 struct adp8860_bl *data = bl_get_data(bl); 379 struct adp8860_bl *data = bl_get_data(bl);
381 380
382 return data->current_brightness; 381 return data->current_brightness;
383 } 382 }
384 383
385 static const struct backlight_ops adp8860_bl_ops = { 384 static const struct backlight_ops adp8860_bl_ops = {
386 .update_status = adp8860_bl_update_status, 385 .update_status = adp8860_bl_update_status,
387 .get_brightness = adp8860_bl_get_brightness, 386 .get_brightness = adp8860_bl_get_brightness,
388 }; 387 };
389 388
390 static int adp8860_bl_setup(struct backlight_device *bl) 389 static int adp8860_bl_setup(struct backlight_device *bl)
391 { 390 {
392 struct adp8860_bl *data = bl_get_data(bl); 391 struct adp8860_bl *data = bl_get_data(bl);
393 struct i2c_client *client = data->client; 392 struct i2c_client *client = data->client;
394 struct adp8860_backlight_platform_data *pdata = data->pdata; 393 struct adp8860_backlight_platform_data *pdata = data->pdata;
395 int ret = 0; 394 int ret = 0;
396 395
397 ret |= adp8860_write(client, ADP8860_BLSEN, ~pdata->bl_led_assign); 396 ret |= adp8860_write(client, ADP8860_BLSEN, ~pdata->bl_led_assign);
398 ret |= adp8860_write(client, ADP8860_BLMX1, pdata->l1_daylight_max); 397 ret |= adp8860_write(client, ADP8860_BLMX1, pdata->l1_daylight_max);
399 ret |= adp8860_write(client, ADP8860_BLDM1, pdata->l1_daylight_dim); 398 ret |= adp8860_write(client, ADP8860_BLDM1, pdata->l1_daylight_dim);
400 399
401 if (data->en_ambl_sens) { 400 if (data->en_ambl_sens) {
402 data->cached_daylight_max = pdata->l1_daylight_max; 401 data->cached_daylight_max = pdata->l1_daylight_max;
403 ret |= adp8860_write(client, ADP8860_BLMX2, 402 ret |= adp8860_write(client, ADP8860_BLMX2,
404 pdata->l2_office_max); 403 pdata->l2_office_max);
405 ret |= adp8860_write(client, ADP8860_BLDM2, 404 ret |= adp8860_write(client, ADP8860_BLDM2,
406 pdata->l2_office_dim); 405 pdata->l2_office_dim);
407 ret |= adp8860_write(client, ADP8860_BLMX3, 406 ret |= adp8860_write(client, ADP8860_BLMX3,
408 pdata->l3_dark_max); 407 pdata->l3_dark_max);
409 ret |= adp8860_write(client, ADP8860_BLDM3, 408 ret |= adp8860_write(client, ADP8860_BLDM3,
410 pdata->l3_dark_dim); 409 pdata->l3_dark_dim);
411 410
412 ret |= adp8860_write(client, ADP8860_L2_TRP, pdata->l2_trip); 411 ret |= adp8860_write(client, ADP8860_L2_TRP, pdata->l2_trip);
413 ret |= adp8860_write(client, ADP8860_L2_HYS, pdata->l2_hyst); 412 ret |= adp8860_write(client, ADP8860_L2_HYS, pdata->l2_hyst);
414 ret |= adp8860_write(client, ADP8860_L3_TRP, pdata->l3_trip); 413 ret |= adp8860_write(client, ADP8860_L3_TRP, pdata->l3_trip);
415 ret |= adp8860_write(client, ADP8860_L3_HYS, pdata->l3_hyst); 414 ret |= adp8860_write(client, ADP8860_L3_HYS, pdata->l3_hyst);
416 ret |= adp8860_write(client, ADP8860_CCFG, L2_EN | L3_EN | 415 ret |= adp8860_write(client, ADP8860_CCFG, L2_EN | L3_EN |
417 ALS_CCFG_VAL(pdata->abml_filt)); 416 ALS_CCFG_VAL(pdata->abml_filt));
418 } 417 }
419 418
420 ret |= adp8860_write(client, ADP8860_CFGR, 419 ret |= adp8860_write(client, ADP8860_CFGR,
421 BL_CFGR_VAL(pdata->bl_fade_law, 0)); 420 BL_CFGR_VAL(pdata->bl_fade_law, 0));
422 421
423 ret |= adp8860_write(client, ADP8860_BLFR, FADE_VAL(pdata->bl_fade_in, 422 ret |= adp8860_write(client, ADP8860_BLFR, FADE_VAL(pdata->bl_fade_in,
424 pdata->bl_fade_out)); 423 pdata->bl_fade_out));
425 424
426 ret |= adp8860_set_bits(client, ADP8860_MDCR, BLEN | DIM_EN | NSTBY | 425 ret |= adp8860_set_bits(client, ADP8860_MDCR, BLEN | DIM_EN | NSTBY |
427 (data->gdwn_dis ? GDWN_DIS : 0)); 426 (data->gdwn_dis ? GDWN_DIS : 0));
428 427
429 return ret; 428 return ret;
430 } 429 }
431 430
432 static ssize_t adp8860_show(struct device *dev, char *buf, int reg) 431 static ssize_t adp8860_show(struct device *dev, char *buf, int reg)
433 { 432 {
434 struct adp8860_bl *data = dev_get_drvdata(dev); 433 struct adp8860_bl *data = dev_get_drvdata(dev);
435 int error; 434 int error;
436 uint8_t reg_val; 435 uint8_t reg_val;
437 436
438 mutex_lock(&data->lock); 437 mutex_lock(&data->lock);
439 error = adp8860_read(data->client, reg, &reg_val); 438 error = adp8860_read(data->client, reg, &reg_val);
440 mutex_unlock(&data->lock); 439 mutex_unlock(&data->lock);
441 440
442 if (error < 0) 441 if (error < 0)
443 return error; 442 return error;
444 443
445 return sprintf(buf, "%u\n", reg_val); 444 return sprintf(buf, "%u\n", reg_val);
446 } 445 }
447 446
448 static ssize_t adp8860_store(struct device *dev, const char *buf, 447 static ssize_t adp8860_store(struct device *dev, const char *buf,
449 size_t count, int reg) 448 size_t count, int reg)
450 { 449 {
451 struct adp8860_bl *data = dev_get_drvdata(dev); 450 struct adp8860_bl *data = dev_get_drvdata(dev);
452 unsigned long val; 451 unsigned long val;
453 int ret; 452 int ret;
454 453
455 ret = strict_strtoul(buf, 10, &val); 454 ret = strict_strtoul(buf, 10, &val);
456 if (ret) 455 if (ret)
457 return ret; 456 return ret;
458 457
459 mutex_lock(&data->lock); 458 mutex_lock(&data->lock);
460 adp8860_write(data->client, reg, val); 459 adp8860_write(data->client, reg, val);
461 mutex_unlock(&data->lock); 460 mutex_unlock(&data->lock);
462 461
463 return count; 462 return count;
464 } 463 }
465 464
466 static ssize_t adp8860_bl_l3_dark_max_show(struct device *dev, 465 static ssize_t adp8860_bl_l3_dark_max_show(struct device *dev,
467 struct device_attribute *attr, char *buf) 466 struct device_attribute *attr, char *buf)
468 { 467 {
469 return adp8860_show(dev, buf, ADP8860_BLMX3); 468 return adp8860_show(dev, buf, ADP8860_BLMX3);
470 } 469 }
471 470
472 static ssize_t adp8860_bl_l3_dark_max_store(struct device *dev, 471 static ssize_t adp8860_bl_l3_dark_max_store(struct device *dev,
473 struct device_attribute *attr, const char *buf, size_t count) 472 struct device_attribute *attr, const char *buf, size_t count)
474 { 473 {
475 return adp8860_store(dev, buf, count, ADP8860_BLMX3); 474 return adp8860_store(dev, buf, count, ADP8860_BLMX3);
476 } 475 }
477 476
478 static DEVICE_ATTR(l3_dark_max, 0664, adp8860_bl_l3_dark_max_show, 477 static DEVICE_ATTR(l3_dark_max, 0664, adp8860_bl_l3_dark_max_show,
479 adp8860_bl_l3_dark_max_store); 478 adp8860_bl_l3_dark_max_store);
480 479
481 static ssize_t adp8860_bl_l2_office_max_show(struct device *dev, 480 static ssize_t adp8860_bl_l2_office_max_show(struct device *dev,
482 struct device_attribute *attr, char *buf) 481 struct device_attribute *attr, char *buf)
483 { 482 {
484 return adp8860_show(dev, buf, ADP8860_BLMX2); 483 return adp8860_show(dev, buf, ADP8860_BLMX2);
485 } 484 }
486 485
487 static ssize_t adp8860_bl_l2_office_max_store(struct device *dev, 486 static ssize_t adp8860_bl_l2_office_max_store(struct device *dev,
488 struct device_attribute *attr, const char *buf, size_t count) 487 struct device_attribute *attr, const char *buf, size_t count)
489 { 488 {
490 return adp8860_store(dev, buf, count, ADP8860_BLMX2); 489 return adp8860_store(dev, buf, count, ADP8860_BLMX2);
491 } 490 }
492 static DEVICE_ATTR(l2_office_max, 0664, adp8860_bl_l2_office_max_show, 491 static DEVICE_ATTR(l2_office_max, 0664, adp8860_bl_l2_office_max_show,
493 adp8860_bl_l2_office_max_store); 492 adp8860_bl_l2_office_max_store);
494 493
495 static ssize_t adp8860_bl_l1_daylight_max_show(struct device *dev, 494 static ssize_t adp8860_bl_l1_daylight_max_show(struct device *dev,
496 struct device_attribute *attr, char *buf) 495 struct device_attribute *attr, char *buf)
497 { 496 {
498 return adp8860_show(dev, buf, ADP8860_BLMX1); 497 return adp8860_show(dev, buf, ADP8860_BLMX1);
499 } 498 }
500 499
501 static ssize_t adp8860_bl_l1_daylight_max_store(struct device *dev, 500 static ssize_t adp8860_bl_l1_daylight_max_store(struct device *dev,
502 struct device_attribute *attr, const char *buf, size_t count) 501 struct device_attribute *attr, const char *buf, size_t count)
503 { 502 {
504 struct adp8860_bl *data = dev_get_drvdata(dev); 503 struct adp8860_bl *data = dev_get_drvdata(dev);
505 int ret = strict_strtoul(buf, 10, &data->cached_daylight_max); 504 int ret = strict_strtoul(buf, 10, &data->cached_daylight_max);
506 if (ret) 505 if (ret)
507 return ret; 506 return ret;
508 507
509 return adp8860_store(dev, buf, count, ADP8860_BLMX1); 508 return adp8860_store(dev, buf, count, ADP8860_BLMX1);
510 } 509 }
511 static DEVICE_ATTR(l1_daylight_max, 0664, adp8860_bl_l1_daylight_max_show, 510 static DEVICE_ATTR(l1_daylight_max, 0664, adp8860_bl_l1_daylight_max_show,
512 adp8860_bl_l1_daylight_max_store); 511 adp8860_bl_l1_daylight_max_store);
513 512
514 static ssize_t adp8860_bl_l3_dark_dim_show(struct device *dev, 513 static ssize_t adp8860_bl_l3_dark_dim_show(struct device *dev,
515 struct device_attribute *attr, char *buf) 514 struct device_attribute *attr, char *buf)
516 { 515 {
517 return adp8860_show(dev, buf, ADP8860_BLDM3); 516 return adp8860_show(dev, buf, ADP8860_BLDM3);
518 } 517 }
519 518
520 static ssize_t adp8860_bl_l3_dark_dim_store(struct device *dev, 519 static ssize_t adp8860_bl_l3_dark_dim_store(struct device *dev,
521 struct device_attribute *attr, 520 struct device_attribute *attr,
522 const char *buf, size_t count) 521 const char *buf, size_t count)
523 { 522 {
524 return adp8860_store(dev, buf, count, ADP8860_BLDM3); 523 return adp8860_store(dev, buf, count, ADP8860_BLDM3);
525 } 524 }
526 static DEVICE_ATTR(l3_dark_dim, 0664, adp8860_bl_l3_dark_dim_show, 525 static DEVICE_ATTR(l3_dark_dim, 0664, adp8860_bl_l3_dark_dim_show,
527 adp8860_bl_l3_dark_dim_store); 526 adp8860_bl_l3_dark_dim_store);
528 527
529 static ssize_t adp8860_bl_l2_office_dim_show(struct device *dev, 528 static ssize_t adp8860_bl_l2_office_dim_show(struct device *dev,
530 struct device_attribute *attr, char *buf) 529 struct device_attribute *attr, char *buf)
531 { 530 {
532 return adp8860_show(dev, buf, ADP8860_BLDM2); 531 return adp8860_show(dev, buf, ADP8860_BLDM2);
533 } 532 }
534 533
535 static ssize_t adp8860_bl_l2_office_dim_store(struct device *dev, 534 static ssize_t adp8860_bl_l2_office_dim_store(struct device *dev,
536 struct device_attribute *attr, 535 struct device_attribute *attr,
537 const char *buf, size_t count) 536 const char *buf, size_t count)
538 { 537 {
539 return adp8860_store(dev, buf, count, ADP8860_BLDM2); 538 return adp8860_store(dev, buf, count, ADP8860_BLDM2);
540 } 539 }
541 static DEVICE_ATTR(l2_office_dim, 0664, adp8860_bl_l2_office_dim_show, 540 static DEVICE_ATTR(l2_office_dim, 0664, adp8860_bl_l2_office_dim_show,
542 adp8860_bl_l2_office_dim_store); 541 adp8860_bl_l2_office_dim_store);
543 542
544 static ssize_t adp8860_bl_l1_daylight_dim_show(struct device *dev, 543 static ssize_t adp8860_bl_l1_daylight_dim_show(struct device *dev,
545 struct device_attribute *attr, char *buf) 544 struct device_attribute *attr, char *buf)
546 { 545 {
547 return adp8860_show(dev, buf, ADP8860_BLDM1); 546 return adp8860_show(dev, buf, ADP8860_BLDM1);
548 } 547 }
549 548
550 static ssize_t adp8860_bl_l1_daylight_dim_store(struct device *dev, 549 static ssize_t adp8860_bl_l1_daylight_dim_store(struct device *dev,
551 struct device_attribute *attr, 550 struct device_attribute *attr,
552 const char *buf, size_t count) 551 const char *buf, size_t count)
553 { 552 {
554 return adp8860_store(dev, buf, count, ADP8860_BLDM1); 553 return adp8860_store(dev, buf, count, ADP8860_BLDM1);
555 } 554 }
556 static DEVICE_ATTR(l1_daylight_dim, 0664, adp8860_bl_l1_daylight_dim_show, 555 static DEVICE_ATTR(l1_daylight_dim, 0664, adp8860_bl_l1_daylight_dim_show,
557 adp8860_bl_l1_daylight_dim_store); 556 adp8860_bl_l1_daylight_dim_store);
558 557
559 #ifdef ADP8860_EXT_FEATURES 558 #ifdef ADP8860_EXT_FEATURES
560 static ssize_t adp8860_bl_ambient_light_level_show(struct device *dev, 559 static ssize_t adp8860_bl_ambient_light_level_show(struct device *dev,
561 struct device_attribute *attr, char *buf) 560 struct device_attribute *attr, char *buf)
562 { 561 {
563 struct adp8860_bl *data = dev_get_drvdata(dev); 562 struct adp8860_bl *data = dev_get_drvdata(dev);
564 int error; 563 int error;
565 uint8_t reg_val; 564 uint8_t reg_val;
566 uint16_t ret_val; 565 uint16_t ret_val;
567 566
568 mutex_lock(&data->lock); 567 mutex_lock(&data->lock);
569 error = adp8860_read(data->client, ADP8860_PH1LEVL, &reg_val); 568 error = adp8860_read(data->client, ADP8860_PH1LEVL, &reg_val);
570 ret_val = reg_val; 569 ret_val = reg_val;
571 error |= adp8860_read(data->client, ADP8860_PH1LEVH, &reg_val); 570 error |= adp8860_read(data->client, ADP8860_PH1LEVH, &reg_val);
572 mutex_unlock(&data->lock); 571 mutex_unlock(&data->lock);
573 572
574 if (error < 0) 573 if (error < 0)
575 return error; 574 return error;
576 575
577 /* Return 13-bit conversion value for the first light sensor */ 576 /* Return 13-bit conversion value for the first light sensor */
578 ret_val += (reg_val & 0x1F) << 8; 577 ret_val += (reg_val & 0x1F) << 8;
579 578
580 return sprintf(buf, "%u\n", ret_val); 579 return sprintf(buf, "%u\n", ret_val);
581 } 580 }
582 static DEVICE_ATTR(ambient_light_level, 0444, 581 static DEVICE_ATTR(ambient_light_level, 0444,
583 adp8860_bl_ambient_light_level_show, NULL); 582 adp8860_bl_ambient_light_level_show, NULL);
584 583
585 static ssize_t adp8860_bl_ambient_light_zone_show(struct device *dev, 584 static ssize_t adp8860_bl_ambient_light_zone_show(struct device *dev,
586 struct device_attribute *attr, char *buf) 585 struct device_attribute *attr, char *buf)
587 { 586 {
588 struct adp8860_bl *data = dev_get_drvdata(dev); 587 struct adp8860_bl *data = dev_get_drvdata(dev);
589 int error; 588 int error;
590 uint8_t reg_val; 589 uint8_t reg_val;
591 590
592 mutex_lock(&data->lock); 591 mutex_lock(&data->lock);
593 error = adp8860_read(data->client, ADP8860_CFGR, &reg_val); 592 error = adp8860_read(data->client, ADP8860_CFGR, &reg_val);
594 mutex_unlock(&data->lock); 593 mutex_unlock(&data->lock);
595 594
596 if (error < 0) 595 if (error < 0)
597 return error; 596 return error;
598 597
599 return sprintf(buf, "%u\n", 598 return sprintf(buf, "%u\n",
600 ((reg_val >> CFGR_BLV_SHIFT) & CFGR_BLV_MASK) + 1); 599 ((reg_val >> CFGR_BLV_SHIFT) & CFGR_BLV_MASK) + 1);
601 } 600 }
602 601
603 static ssize_t adp8860_bl_ambient_light_zone_store(struct device *dev, 602 static ssize_t adp8860_bl_ambient_light_zone_store(struct device *dev,
604 struct device_attribute *attr, 603 struct device_attribute *attr,
605 const char *buf, size_t count) 604 const char *buf, size_t count)
606 { 605 {
607 struct adp8860_bl *data = dev_get_drvdata(dev); 606 struct adp8860_bl *data = dev_get_drvdata(dev);
608 unsigned long val; 607 unsigned long val;
609 uint8_t reg_val; 608 uint8_t reg_val;
610 int ret; 609 int ret;
611 610
612 ret = strict_strtoul(buf, 10, &val); 611 ret = strict_strtoul(buf, 10, &val);
613 if (ret) 612 if (ret)
614 return ret; 613 return ret;
615 614
616 if (val == 0) { 615 if (val == 0) {
617 /* Enable automatic ambient light sensing */ 616 /* Enable automatic ambient light sensing */
618 adp8860_set_bits(data->client, ADP8860_MDCR, CMP_AUTOEN); 617 adp8860_set_bits(data->client, ADP8860_MDCR, CMP_AUTOEN);
619 } else if ((val > 0) && (val <= 3)) { 618 } else if ((val > 0) && (val <= 3)) {
620 /* Disable automatic ambient light sensing */ 619 /* Disable automatic ambient light sensing */
621 adp8860_clr_bits(data->client, ADP8860_MDCR, CMP_AUTOEN); 620 adp8860_clr_bits(data->client, ADP8860_MDCR, CMP_AUTOEN);
622 621
623 /* Set user supplied ambient light zone */ 622 /* Set user supplied ambient light zone */
624 mutex_lock(&data->lock); 623 mutex_lock(&data->lock);
625 adp8860_read(data->client, ADP8860_CFGR, &reg_val); 624 adp8860_read(data->client, ADP8860_CFGR, &reg_val);
626 reg_val &= ~(CFGR_BLV_MASK << CFGR_BLV_SHIFT); 625 reg_val &= ~(CFGR_BLV_MASK << CFGR_BLV_SHIFT);
627 reg_val |= (val - 1) << CFGR_BLV_SHIFT; 626 reg_val |= (val - 1) << CFGR_BLV_SHIFT;
628 adp8860_write(data->client, ADP8860_CFGR, reg_val); 627 adp8860_write(data->client, ADP8860_CFGR, reg_val);
629 mutex_unlock(&data->lock); 628 mutex_unlock(&data->lock);
630 } 629 }
631 630
632 return count; 631 return count;
633 } 632 }
634 static DEVICE_ATTR(ambient_light_zone, 0664, 633 static DEVICE_ATTR(ambient_light_zone, 0664,
635 adp8860_bl_ambient_light_zone_show, 634 adp8860_bl_ambient_light_zone_show,
636 adp8860_bl_ambient_light_zone_store); 635 adp8860_bl_ambient_light_zone_store);
637 #endif 636 #endif
638 637
639 static struct attribute *adp8860_bl_attributes[] = { 638 static struct attribute *adp8860_bl_attributes[] = {
640 &dev_attr_l3_dark_max.attr, 639 &dev_attr_l3_dark_max.attr,
641 &dev_attr_l3_dark_dim.attr, 640 &dev_attr_l3_dark_dim.attr,
642 &dev_attr_l2_office_max.attr, 641 &dev_attr_l2_office_max.attr,
643 &dev_attr_l2_office_dim.attr, 642 &dev_attr_l2_office_dim.attr,
644 &dev_attr_l1_daylight_max.attr, 643 &dev_attr_l1_daylight_max.attr,
645 &dev_attr_l1_daylight_dim.attr, 644 &dev_attr_l1_daylight_dim.attr,
646 #ifdef ADP8860_EXT_FEATURES 645 #ifdef ADP8860_EXT_FEATURES
647 &dev_attr_ambient_light_level.attr, 646 &dev_attr_ambient_light_level.attr,
648 &dev_attr_ambient_light_zone.attr, 647 &dev_attr_ambient_light_zone.attr,
649 #endif 648 #endif
650 NULL 649 NULL
651 }; 650 };
652 651
653 static const struct attribute_group adp8860_bl_attr_group = { 652 static const struct attribute_group adp8860_bl_attr_group = {
654 .attrs = adp8860_bl_attributes, 653 .attrs = adp8860_bl_attributes,
655 }; 654 };
656 655
657 static int __devinit adp8860_probe(struct i2c_client *client, 656 static int __devinit adp8860_probe(struct i2c_client *client,
658 const struct i2c_device_id *id) 657 const struct i2c_device_id *id)
659 { 658 {
660 struct backlight_device *bl; 659 struct backlight_device *bl;
661 struct adp8860_bl *data; 660 struct adp8860_bl *data;
662 struct adp8860_backlight_platform_data *pdata = 661 struct adp8860_backlight_platform_data *pdata =
663 client->dev.platform_data; 662 client->dev.platform_data;
664 struct backlight_properties props; 663 struct backlight_properties props;
665 uint8_t reg_val; 664 uint8_t reg_val;
666 int ret; 665 int ret;
667 666
668 if (!i2c_check_functionality(client->adapter, 667 if (!i2c_check_functionality(client->adapter,
669 I2C_FUNC_SMBUS_BYTE_DATA)) { 668 I2C_FUNC_SMBUS_BYTE_DATA)) {
670 dev_err(&client->dev, "SMBUS Byte Data not Supported\n"); 669 dev_err(&client->dev, "SMBUS Byte Data not Supported\n");
671 return -EIO; 670 return -EIO;
672 } 671 }
673 672
674 if (!pdata) { 673 if (!pdata) {
675 dev_err(&client->dev, "no platform data?\n"); 674 dev_err(&client->dev, "no platform data?\n");
676 return -EINVAL; 675 return -EINVAL;
677 } 676 }
678 677
679 data = kzalloc(sizeof(*data), GFP_KERNEL); 678 data = kzalloc(sizeof(*data), GFP_KERNEL);
680 if (data == NULL) 679 if (data == NULL)
681 return -ENOMEM; 680 return -ENOMEM;
682 681
683 ret = adp8860_read(client, ADP8860_MFDVID, &reg_val); 682 ret = adp8860_read(client, ADP8860_MFDVID, &reg_val);
684 if (ret < 0) 683 if (ret < 0)
685 goto out2; 684 goto out2;
686 685
687 switch (ADP8860_MANID(reg_val)) { 686 switch (ADP8860_MANID(reg_val)) {
688 case ADP8863_MANUFID: 687 case ADP8863_MANUFID:
689 data->gdwn_dis = !!pdata->gdwn_dis; 688 data->gdwn_dis = !!pdata->gdwn_dis;
690 case ADP8860_MANUFID: 689 case ADP8860_MANUFID:
691 data->en_ambl_sens = !!pdata->en_ambl_sens; 690 data->en_ambl_sens = !!pdata->en_ambl_sens;
692 break; 691 break;
693 case ADP8861_MANUFID: 692 case ADP8861_MANUFID:
694 data->gdwn_dis = !!pdata->gdwn_dis; 693 data->gdwn_dis = !!pdata->gdwn_dis;
695 break; 694 break;
696 default: 695 default:
697 dev_err(&client->dev, "failed to probe\n"); 696 dev_err(&client->dev, "failed to probe\n");
698 ret = -ENODEV; 697 ret = -ENODEV;
699 goto out2; 698 goto out2;
700 } 699 }
701 700
702 /* It's confirmed that the DEVID field is actually a REVID */ 701 /* It's confirmed that the DEVID field is actually a REVID */
703 702
704 data->revid = ADP8860_DEVID(reg_val); 703 data->revid = ADP8860_DEVID(reg_val);
705 data->client = client; 704 data->client = client;
706 data->pdata = pdata; 705 data->pdata = pdata;
707 data->id = id->driver_data; 706 data->id = id->driver_data;
708 data->current_brightness = 0; 707 data->current_brightness = 0;
709 i2c_set_clientdata(client, data); 708 i2c_set_clientdata(client, data);
710 709
711 memset(&props, 0, sizeof(props)); 710 memset(&props, 0, sizeof(props));
712 props.type = BACKLIGHT_RAW; 711 props.type = BACKLIGHT_RAW;
713 props.max_brightness = ADP8860_MAX_BRIGHTNESS; 712 props.max_brightness = ADP8860_MAX_BRIGHTNESS;
714 713
715 mutex_init(&data->lock); 714 mutex_init(&data->lock);
716 715
717 bl = backlight_device_register(dev_driver_string(&client->dev), 716 bl = backlight_device_register(dev_driver_string(&client->dev),
718 &client->dev, data, &adp8860_bl_ops, &props); 717 &client->dev, data, &adp8860_bl_ops, &props);
719 if (IS_ERR(bl)) { 718 if (IS_ERR(bl)) {
720 dev_err(&client->dev, "failed to register backlight\n"); 719 dev_err(&client->dev, "failed to register backlight\n");
721 ret = PTR_ERR(bl); 720 ret = PTR_ERR(bl);
722 goto out2; 721 goto out2;
723 } 722 }
724 723
725 bl->props.max_brightness = 724 bl->props.max_brightness =
726 bl->props.brightness = ADP8860_MAX_BRIGHTNESS; 725 bl->props.brightness = ADP8860_MAX_BRIGHTNESS;
727 726
728 data->bl = bl; 727 data->bl = bl;
729 728
730 if (data->en_ambl_sens) 729 if (data->en_ambl_sens)
731 ret = sysfs_create_group(&bl->dev.kobj, 730 ret = sysfs_create_group(&bl->dev.kobj,
732 &adp8860_bl_attr_group); 731 &adp8860_bl_attr_group);
733 732
734 if (ret) { 733 if (ret) {
735 dev_err(&client->dev, "failed to register sysfs\n"); 734 dev_err(&client->dev, "failed to register sysfs\n");
736 goto out1; 735 goto out1;
737 } 736 }
738 737
739 ret = adp8860_bl_setup(bl); 738 ret = adp8860_bl_setup(bl);
740 if (ret) { 739 if (ret) {
741 ret = -EIO; 740 ret = -EIO;
742 goto out; 741 goto out;
743 } 742 }
744 743
745 backlight_update_status(bl); 744 backlight_update_status(bl);
746 745
747 dev_info(&client->dev, "%s Rev.%d Backlight\n", 746 dev_info(&client->dev, "%s Rev.%d Backlight\n",
748 client->name, data->revid); 747 client->name, data->revid);
749 748
750 if (pdata->num_leds) 749 if (pdata->num_leds)
751 adp8860_led_probe(client); 750 adp8860_led_probe(client);
752 751
753 return 0; 752 return 0;
754 753
755 out: 754 out:
756 if (data->en_ambl_sens) 755 if (data->en_ambl_sens)
757 sysfs_remove_group(&data->bl->dev.kobj, 756 sysfs_remove_group(&data->bl->dev.kobj,
758 &adp8860_bl_attr_group); 757 &adp8860_bl_attr_group);
759 out1: 758 out1:
760 backlight_device_unregister(bl); 759 backlight_device_unregister(bl);
761 out2: 760 out2:
762 kfree(data); 761 kfree(data);
763 762
764 return ret; 763 return ret;
765 } 764 }
766 765
767 static int __devexit adp8860_remove(struct i2c_client *client) 766 static int __devexit adp8860_remove(struct i2c_client *client)
768 { 767 {
769 struct adp8860_bl *data = i2c_get_clientdata(client); 768 struct adp8860_bl *data = i2c_get_clientdata(client);
770 769
771 adp8860_clr_bits(client, ADP8860_MDCR, NSTBY); 770 adp8860_clr_bits(client, ADP8860_MDCR, NSTBY);
772 771
773 if (data->led) 772 if (data->led)
774 adp8860_led_remove(client); 773 adp8860_led_remove(client);
775 774
776 if (data->en_ambl_sens) 775 if (data->en_ambl_sens)
777 sysfs_remove_group(&data->bl->dev.kobj, 776 sysfs_remove_group(&data->bl->dev.kobj,
778 &adp8860_bl_attr_group); 777 &adp8860_bl_attr_group);
779 778
780 backlight_device_unregister(data->bl); 779 backlight_device_unregister(data->bl);
781 kfree(data); 780 kfree(data);
782 781
783 return 0; 782 return 0;
784 } 783 }
785 784
786 #ifdef CONFIG_PM 785 #ifdef CONFIG_PM
787 static int adp8860_i2c_suspend(struct i2c_client *client, pm_message_t message) 786 static int adp8860_i2c_suspend(struct i2c_client *client, pm_message_t message)
788 { 787 {
789 adp8860_clr_bits(client, ADP8860_MDCR, NSTBY); 788 adp8860_clr_bits(client, ADP8860_MDCR, NSTBY);
790 789
791 return 0; 790 return 0;
792 } 791 }
793 792
794 static int adp8860_i2c_resume(struct i2c_client *client) 793 static int adp8860_i2c_resume(struct i2c_client *client)
795 { 794 {
796 adp8860_set_bits(client, ADP8860_MDCR, NSTBY); 795 adp8860_set_bits(client, ADP8860_MDCR, NSTBY);
797 796
798 return 0; 797 return 0;
799 } 798 }
800 #else 799 #else
801 #define adp8860_i2c_suspend NULL 800 #define adp8860_i2c_suspend NULL
802 #define adp8860_i2c_resume NULL 801 #define adp8860_i2c_resume NULL
803 #endif 802 #endif
804 803
805 static const struct i2c_device_id adp8860_id[] = { 804 static const struct i2c_device_id adp8860_id[] = {
806 { "adp8860", adp8860 }, 805 { "adp8860", adp8860 },
807 { "adp8861", adp8861 }, 806 { "adp8861", adp8861 },
808 { "adp8863", adp8863 }, 807 { "adp8863", adp8863 },
809 { } 808 { }
810 }; 809 };
811 MODULE_DEVICE_TABLE(i2c, adp8860_id); 810 MODULE_DEVICE_TABLE(i2c, adp8860_id);
812 811
813 static struct i2c_driver adp8860_driver = { 812 static struct i2c_driver adp8860_driver = {
814 .driver = { 813 .driver = {
815 .name = KBUILD_MODNAME, 814 .name = KBUILD_MODNAME,
816 }, 815 },
817 .probe = adp8860_probe, 816 .probe = adp8860_probe,
818 .remove = __devexit_p(adp8860_remove), 817 .remove = __devexit_p(adp8860_remove),
819 .suspend = adp8860_i2c_suspend, 818 .suspend = adp8860_i2c_suspend,
820 .resume = adp8860_i2c_resume, 819 .resume = adp8860_i2c_resume,
821 .id_table = adp8860_id, 820 .id_table = adp8860_id,
822 }; 821 };
823 822
824 static int __init adp8860_init(void) 823 static int __init adp8860_init(void)
825 { 824 {
826 return i2c_add_driver(&adp8860_driver); 825 return i2c_add_driver(&adp8860_driver);
827 } 826 }
828 module_init(adp8860_init); 827 module_init(adp8860_init);
829 828
830 static void __exit adp8860_exit(void) 829 static void __exit adp8860_exit(void)
831 { 830 {
832 i2c_del_driver(&adp8860_driver); 831 i2c_del_driver(&adp8860_driver);
833 } 832 }
834 module_exit(adp8860_exit); 833 module_exit(adp8860_exit);
835 834
836 MODULE_LICENSE("GPL v2"); 835 MODULE_LICENSE("GPL v2");
837 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); 836 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
838 MODULE_DESCRIPTION("ADP8860 Backlight driver"); 837 MODULE_DESCRIPTION("ADP8860 Backlight driver");
839 MODULE_ALIAS("i2c:adp8860-backlight"); 838 MODULE_ALIAS("i2c:adp8860-backlight");
840 839
drivers/video/backlight/adp8870_bl.c
1 /* 1 /*
2 * Backlight driver for Analog Devices ADP8870 Backlight Devices 2 * Backlight driver for Analog Devices ADP8870 Backlight Devices
3 * 3 *
4 * Copyright 2009-2011 Analog Devices Inc. 4 * Copyright 2009-2011 Analog Devices Inc.
5 * 5 *
6 * Licensed under the GPL-2 or later. 6 * Licensed under the GPL-2 or later.
7 */ 7 */
8 8
9 #include <linux/module.h> 9 #include <linux/module.h>
10 #include <linux/version.h>
11 #include <linux/init.h> 10 #include <linux/init.h>
12 #include <linux/errno.h> 11 #include <linux/errno.h>
13 #include <linux/pm.h> 12 #include <linux/pm.h>
14 #include <linux/platform_device.h> 13 #include <linux/platform_device.h>
15 #include <linux/i2c.h> 14 #include <linux/i2c.h>
16 #include <linux/fb.h> 15 #include <linux/fb.h>
17 #include <linux/backlight.h> 16 #include <linux/backlight.h>
18 #include <linux/leds.h> 17 #include <linux/leds.h>
19 #include <linux/workqueue.h> 18 #include <linux/workqueue.h>
20 #include <linux/slab.h> 19 #include <linux/slab.h>
21 20
22 #include <linux/i2c/adp8870.h> 21 #include <linux/i2c/adp8870.h>
23 #define ADP8870_EXT_FEATURES 22 #define ADP8870_EXT_FEATURES
24 #define ADP8870_USE_LEDS 23 #define ADP8870_USE_LEDS
25 24
26 25
27 #define ADP8870_MFDVID 0x00 /* Manufacturer and device ID */ 26 #define ADP8870_MFDVID 0x00 /* Manufacturer and device ID */
28 #define ADP8870_MDCR 0x01 /* Device mode and status */ 27 #define ADP8870_MDCR 0x01 /* Device mode and status */
29 #define ADP8870_INT_STAT 0x02 /* Interrupts status */ 28 #define ADP8870_INT_STAT 0x02 /* Interrupts status */
30 #define ADP8870_INT_EN 0x03 /* Interrupts enable */ 29 #define ADP8870_INT_EN 0x03 /* Interrupts enable */
31 #define ADP8870_CFGR 0x04 /* Configuration register */ 30 #define ADP8870_CFGR 0x04 /* Configuration register */
32 #define ADP8870_BLSEL 0x05 /* Sink enable backlight or independent */ 31 #define ADP8870_BLSEL 0x05 /* Sink enable backlight or independent */
33 #define ADP8870_PWMLED 0x06 /* PWM Enable Selection Register */ 32 #define ADP8870_PWMLED 0x06 /* PWM Enable Selection Register */
34 #define ADP8870_BLOFF 0x07 /* Backlight off timeout */ 33 #define ADP8870_BLOFF 0x07 /* Backlight off timeout */
35 #define ADP8870_BLDIM 0x08 /* Backlight dim timeout */ 34 #define ADP8870_BLDIM 0x08 /* Backlight dim timeout */
36 #define ADP8870_BLFR 0x09 /* Backlight fade in and out rates */ 35 #define ADP8870_BLFR 0x09 /* Backlight fade in and out rates */
37 #define ADP8870_BLMX1 0x0A /* Backlight (Brightness Level 1-daylight) maximum current */ 36 #define ADP8870_BLMX1 0x0A /* Backlight (Brightness Level 1-daylight) maximum current */
38 #define ADP8870_BLDM1 0x0B /* Backlight (Brightness Level 1-daylight) dim current */ 37 #define ADP8870_BLDM1 0x0B /* Backlight (Brightness Level 1-daylight) dim current */
39 #define ADP8870_BLMX2 0x0C /* Backlight (Brightness Level 2-bright) maximum current */ 38 #define ADP8870_BLMX2 0x0C /* Backlight (Brightness Level 2-bright) maximum current */
40 #define ADP8870_BLDM2 0x0D /* Backlight (Brightness Level 2-bright) dim current */ 39 #define ADP8870_BLDM2 0x0D /* Backlight (Brightness Level 2-bright) dim current */
41 #define ADP8870_BLMX3 0x0E /* Backlight (Brightness Level 3-office) maximum current */ 40 #define ADP8870_BLMX3 0x0E /* Backlight (Brightness Level 3-office) maximum current */
42 #define ADP8870_BLDM3 0x0F /* Backlight (Brightness Level 3-office) dim current */ 41 #define ADP8870_BLDM3 0x0F /* Backlight (Brightness Level 3-office) dim current */
43 #define ADP8870_BLMX4 0x10 /* Backlight (Brightness Level 4-indoor) maximum current */ 42 #define ADP8870_BLMX4 0x10 /* Backlight (Brightness Level 4-indoor) maximum current */
44 #define ADP8870_BLDM4 0x11 /* Backlight (Brightness Level 4-indoor) dim current */ 43 #define ADP8870_BLDM4 0x11 /* Backlight (Brightness Level 4-indoor) dim current */
45 #define ADP8870_BLMX5 0x12 /* Backlight (Brightness Level 5-dark) maximum current */ 44 #define ADP8870_BLMX5 0x12 /* Backlight (Brightness Level 5-dark) maximum current */
46 #define ADP8870_BLDM5 0x13 /* Backlight (Brightness Level 5-dark) dim current */ 45 #define ADP8870_BLDM5 0x13 /* Backlight (Brightness Level 5-dark) dim current */
47 #define ADP8870_ISCLAW 0x1A /* Independent sink current fade law register */ 46 #define ADP8870_ISCLAW 0x1A /* Independent sink current fade law register */
48 #define ADP8870_ISCC 0x1B /* Independent sink current control register */ 47 #define ADP8870_ISCC 0x1B /* Independent sink current control register */
49 #define ADP8870_ISCT1 0x1C /* Independent Sink Current Timer Register LED[7:5] */ 48 #define ADP8870_ISCT1 0x1C /* Independent Sink Current Timer Register LED[7:5] */
50 #define ADP8870_ISCT2 0x1D /* Independent Sink Current Timer Register LED[4:1] */ 49 #define ADP8870_ISCT2 0x1D /* Independent Sink Current Timer Register LED[4:1] */
51 #define ADP8870_ISCF 0x1E /* Independent sink current fade register */ 50 #define ADP8870_ISCF 0x1E /* Independent sink current fade register */
52 #define ADP8870_ISC1 0x1F /* Independent Sink Current LED1 */ 51 #define ADP8870_ISC1 0x1F /* Independent Sink Current LED1 */
53 #define ADP8870_ISC2 0x20 /* Independent Sink Current LED2 */ 52 #define ADP8870_ISC2 0x20 /* Independent Sink Current LED2 */
54 #define ADP8870_ISC3 0x21 /* Independent Sink Current LED3 */ 53 #define ADP8870_ISC3 0x21 /* Independent Sink Current LED3 */
55 #define ADP8870_ISC4 0x22 /* Independent Sink Current LED4 */ 54 #define ADP8870_ISC4 0x22 /* Independent Sink Current LED4 */
56 #define ADP8870_ISC5 0x23 /* Independent Sink Current LED5 */ 55 #define ADP8870_ISC5 0x23 /* Independent Sink Current LED5 */
57 #define ADP8870_ISC6 0x24 /* Independent Sink Current LED6 */ 56 #define ADP8870_ISC6 0x24 /* Independent Sink Current LED6 */
58 #define ADP8870_ISC7 0x25 /* Independent Sink Current LED7 (Brightness Level 1-daylight) */ 57 #define ADP8870_ISC7 0x25 /* Independent Sink Current LED7 (Brightness Level 1-daylight) */
59 #define ADP8870_ISC7_L2 0x26 /* Independent Sink Current LED7 (Brightness Level 2-bright) */ 58 #define ADP8870_ISC7_L2 0x26 /* Independent Sink Current LED7 (Brightness Level 2-bright) */
60 #define ADP8870_ISC7_L3 0x27 /* Independent Sink Current LED7 (Brightness Level 3-office) */ 59 #define ADP8870_ISC7_L3 0x27 /* Independent Sink Current LED7 (Brightness Level 3-office) */
61 #define ADP8870_ISC7_L4 0x28 /* Independent Sink Current LED7 (Brightness Level 4-indoor) */ 60 #define ADP8870_ISC7_L4 0x28 /* Independent Sink Current LED7 (Brightness Level 4-indoor) */
62 #define ADP8870_ISC7_L5 0x29 /* Independent Sink Current LED7 (Brightness Level 5-dark) */ 61 #define ADP8870_ISC7_L5 0x29 /* Independent Sink Current LED7 (Brightness Level 5-dark) */
63 #define ADP8870_CMP_CTL 0x2D /* ALS Comparator Control Register */ 62 #define ADP8870_CMP_CTL 0x2D /* ALS Comparator Control Register */
64 #define ADP8870_ALS1_EN 0x2E /* Main ALS comparator level enable */ 63 #define ADP8870_ALS1_EN 0x2E /* Main ALS comparator level enable */
65 #define ADP8870_ALS2_EN 0x2F /* Second ALS comparator level enable */ 64 #define ADP8870_ALS2_EN 0x2F /* Second ALS comparator level enable */
66 #define ADP8870_ALS1_STAT 0x30 /* Main ALS Comparator Status Register */ 65 #define ADP8870_ALS1_STAT 0x30 /* Main ALS Comparator Status Register */
67 #define ADP8870_ALS2_STAT 0x31 /* Second ALS Comparator Status Register */ 66 #define ADP8870_ALS2_STAT 0x31 /* Second ALS Comparator Status Register */
68 #define ADP8870_L2TRP 0x32 /* L2 comparator reference */ 67 #define ADP8870_L2TRP 0x32 /* L2 comparator reference */
69 #define ADP8870_L2HYS 0x33 /* L2 hysteresis */ 68 #define ADP8870_L2HYS 0x33 /* L2 hysteresis */
70 #define ADP8870_L3TRP 0x34 /* L3 comparator reference */ 69 #define ADP8870_L3TRP 0x34 /* L3 comparator reference */
71 #define ADP8870_L3HYS 0x35 /* L3 hysteresis */ 70 #define ADP8870_L3HYS 0x35 /* L3 hysteresis */
72 #define ADP8870_L4TRP 0x36 /* L4 comparator reference */ 71 #define ADP8870_L4TRP 0x36 /* L4 comparator reference */
73 #define ADP8870_L4HYS 0x37 /* L4 hysteresis */ 72 #define ADP8870_L4HYS 0x37 /* L4 hysteresis */
74 #define ADP8870_L5TRP 0x38 /* L5 comparator reference */ 73 #define ADP8870_L5TRP 0x38 /* L5 comparator reference */
75 #define ADP8870_L5HYS 0x39 /* L5 hysteresis */ 74 #define ADP8870_L5HYS 0x39 /* L5 hysteresis */
76 #define ADP8870_PH1LEVL 0x40 /* First phototransistor ambient light level-low byte register */ 75 #define ADP8870_PH1LEVL 0x40 /* First phototransistor ambient light level-low byte register */
77 #define ADP8870_PH1LEVH 0x41 /* First phototransistor ambient light level-high byte register */ 76 #define ADP8870_PH1LEVH 0x41 /* First phototransistor ambient light level-high byte register */
78 #define ADP8870_PH2LEVL 0x42 /* Second phototransistor ambient light level-low byte register */ 77 #define ADP8870_PH2LEVL 0x42 /* Second phototransistor ambient light level-low byte register */
79 #define ADP8870_PH2LEVH 0x43 /* Second phototransistor ambient light level-high byte register */ 78 #define ADP8870_PH2LEVH 0x43 /* Second phototransistor ambient light level-high byte register */
80 79
81 #define ADP8870_MANUFID 0x3 /* Analog Devices AD8870 Manufacturer and device ID */ 80 #define ADP8870_MANUFID 0x3 /* Analog Devices AD8870 Manufacturer and device ID */
82 #define ADP8870_DEVID(x) ((x) & 0xF) 81 #define ADP8870_DEVID(x) ((x) & 0xF)
83 #define ADP8870_MANID(x) ((x) >> 4) 82 #define ADP8870_MANID(x) ((x) >> 4)
84 83
85 /* MDCR Device mode and status */ 84 /* MDCR Device mode and status */
86 #define D7ALSEN (1 << 7) 85 #define D7ALSEN (1 << 7)
87 #define INT_CFG (1 << 6) 86 #define INT_CFG (1 << 6)
88 #define NSTBY (1 << 5) 87 #define NSTBY (1 << 5)
89 #define DIM_EN (1 << 4) 88 #define DIM_EN (1 << 4)
90 #define GDWN_DIS (1 << 3) 89 #define GDWN_DIS (1 << 3)
91 #define SIS_EN (1 << 2) 90 #define SIS_EN (1 << 2)
92 #define CMP_AUTOEN (1 << 1) 91 #define CMP_AUTOEN (1 << 1)
93 #define BLEN (1 << 0) 92 #define BLEN (1 << 0)
94 93
95 /* ADP8870_ALS1_EN Main ALS comparator level enable */ 94 /* ADP8870_ALS1_EN Main ALS comparator level enable */
96 #define L5_EN (1 << 3) 95 #define L5_EN (1 << 3)
97 #define L4_EN (1 << 2) 96 #define L4_EN (1 << 2)
98 #define L3_EN (1 << 1) 97 #define L3_EN (1 << 1)
99 #define L2_EN (1 << 0) 98 #define L2_EN (1 << 0)
100 99
101 #define CFGR_BLV_SHIFT 3 100 #define CFGR_BLV_SHIFT 3
102 #define CFGR_BLV_MASK 0x7 101 #define CFGR_BLV_MASK 0x7
103 #define ADP8870_FLAG_LED_MASK 0xFF 102 #define ADP8870_FLAG_LED_MASK 0xFF
104 103
105 #define FADE_VAL(in, out) ((0xF & (in)) | ((0xF & (out)) << 4)) 104 #define FADE_VAL(in, out) ((0xF & (in)) | ((0xF & (out)) << 4))
106 #define BL_CFGR_VAL(law, blv) ((((blv) & CFGR_BLV_MASK) << CFGR_BLV_SHIFT) | ((0x3 & (law)) << 1)) 105 #define BL_CFGR_VAL(law, blv) ((((blv) & CFGR_BLV_MASK) << CFGR_BLV_SHIFT) | ((0x3 & (law)) << 1))
107 #define ALS_CMPR_CFG_VAL(filt) ((0x7 & (filt)) << 1) 106 #define ALS_CMPR_CFG_VAL(filt) ((0x7 & (filt)) << 1)
108 107
109 struct adp8870_bl { 108 struct adp8870_bl {
110 struct i2c_client *client; 109 struct i2c_client *client;
111 struct backlight_device *bl; 110 struct backlight_device *bl;
112 struct adp8870_led *led; 111 struct adp8870_led *led;
113 struct adp8870_backlight_platform_data *pdata; 112 struct adp8870_backlight_platform_data *pdata;
114 struct mutex lock; 113 struct mutex lock;
115 unsigned long cached_daylight_max; 114 unsigned long cached_daylight_max;
116 int id; 115 int id;
117 int revid; 116 int revid;
118 int current_brightness; 117 int current_brightness;
119 }; 118 };
120 119
121 struct adp8870_led { 120 struct adp8870_led {
122 struct led_classdev cdev; 121 struct led_classdev cdev;
123 struct work_struct work; 122 struct work_struct work;
124 struct i2c_client *client; 123 struct i2c_client *client;
125 enum led_brightness new_brightness; 124 enum led_brightness new_brightness;
126 int id; 125 int id;
127 int flags; 126 int flags;
128 }; 127 };
129 128
130 static int adp8870_read(struct i2c_client *client, int reg, uint8_t *val) 129 static int adp8870_read(struct i2c_client *client, int reg, uint8_t *val)
131 { 130 {
132 int ret; 131 int ret;
133 132
134 ret = i2c_smbus_read_byte_data(client, reg); 133 ret = i2c_smbus_read_byte_data(client, reg);
135 if (ret < 0) { 134 if (ret < 0) {
136 dev_err(&client->dev, "failed reading at 0x%02x\n", reg); 135 dev_err(&client->dev, "failed reading at 0x%02x\n", reg);
137 return ret; 136 return ret;
138 } 137 }
139 138
140 *val = ret; 139 *val = ret;
141 return 0; 140 return 0;
142 } 141 }
143 142
144 143
145 static int adp8870_write(struct i2c_client *client, u8 reg, u8 val) 144 static int adp8870_write(struct i2c_client *client, u8 reg, u8 val)
146 { 145 {
147 int ret = i2c_smbus_write_byte_data(client, reg, val); 146 int ret = i2c_smbus_write_byte_data(client, reg, val);
148 if (ret) 147 if (ret)
149 dev_err(&client->dev, "failed to write\n"); 148 dev_err(&client->dev, "failed to write\n");
150 149
151 return ret; 150 return ret;
152 } 151 }
153 152
154 static int adp8870_set_bits(struct i2c_client *client, int reg, uint8_t bit_mask) 153 static int adp8870_set_bits(struct i2c_client *client, int reg, uint8_t bit_mask)
155 { 154 {
156 struct adp8870_bl *data = i2c_get_clientdata(client); 155 struct adp8870_bl *data = i2c_get_clientdata(client);
157 uint8_t reg_val; 156 uint8_t reg_val;
158 int ret; 157 int ret;
159 158
160 mutex_lock(&data->lock); 159 mutex_lock(&data->lock);
161 160
162 ret = adp8870_read(client, reg, &reg_val); 161 ret = adp8870_read(client, reg, &reg_val);
163 162
164 if (!ret && ((reg_val & bit_mask) == 0)) { 163 if (!ret && ((reg_val & bit_mask) == 0)) {
165 reg_val |= bit_mask; 164 reg_val |= bit_mask;
166 ret = adp8870_write(client, reg, reg_val); 165 ret = adp8870_write(client, reg, reg_val);
167 } 166 }
168 167
169 mutex_unlock(&data->lock); 168 mutex_unlock(&data->lock);
170 return ret; 169 return ret;
171 } 170 }
172 171
173 static int adp8870_clr_bits(struct i2c_client *client, int reg, uint8_t bit_mask) 172 static int adp8870_clr_bits(struct i2c_client *client, int reg, uint8_t bit_mask)
174 { 173 {
175 struct adp8870_bl *data = i2c_get_clientdata(client); 174 struct adp8870_bl *data = i2c_get_clientdata(client);
176 uint8_t reg_val; 175 uint8_t reg_val;
177 int ret; 176 int ret;
178 177
179 mutex_lock(&data->lock); 178 mutex_lock(&data->lock);
180 179
181 ret = adp8870_read(client, reg, &reg_val); 180 ret = adp8870_read(client, reg, &reg_val);
182 181
183 if (!ret && (reg_val & bit_mask)) { 182 if (!ret && (reg_val & bit_mask)) {
184 reg_val &= ~bit_mask; 183 reg_val &= ~bit_mask;
185 ret = adp8870_write(client, reg, reg_val); 184 ret = adp8870_write(client, reg, reg_val);
186 } 185 }
187 186
188 mutex_unlock(&data->lock); 187 mutex_unlock(&data->lock);
189 return ret; 188 return ret;
190 } 189 }
191 190
192 /* 191 /*
193 * Independent sink / LED 192 * Independent sink / LED
194 */ 193 */
195 #if defined(ADP8870_USE_LEDS) 194 #if defined(ADP8870_USE_LEDS)
196 static void adp8870_led_work(struct work_struct *work) 195 static void adp8870_led_work(struct work_struct *work)
197 { 196 {
198 struct adp8870_led *led = container_of(work, struct adp8870_led, work); 197 struct adp8870_led *led = container_of(work, struct adp8870_led, work);
199 adp8870_write(led->client, ADP8870_ISC1 + led->id - 1, 198 adp8870_write(led->client, ADP8870_ISC1 + led->id - 1,
200 led->new_brightness >> 1); 199 led->new_brightness >> 1);
201 } 200 }
202 201
203 static void adp8870_led_set(struct led_classdev *led_cdev, 202 static void adp8870_led_set(struct led_classdev *led_cdev,
204 enum led_brightness value) 203 enum led_brightness value)
205 { 204 {
206 struct adp8870_led *led; 205 struct adp8870_led *led;
207 206
208 led = container_of(led_cdev, struct adp8870_led, cdev); 207 led = container_of(led_cdev, struct adp8870_led, cdev);
209 led->new_brightness = value; 208 led->new_brightness = value;
210 /* 209 /*
211 * Use workqueue for IO since I2C operations can sleep. 210 * Use workqueue for IO since I2C operations can sleep.
212 */ 211 */
213 schedule_work(&led->work); 212 schedule_work(&led->work);
214 } 213 }
215 214
216 static int adp8870_led_setup(struct adp8870_led *led) 215 static int adp8870_led_setup(struct adp8870_led *led)
217 { 216 {
218 struct i2c_client *client = led->client; 217 struct i2c_client *client = led->client;
219 int ret = 0; 218 int ret = 0;
220 219
221 ret = adp8870_write(client, ADP8870_ISC1 + led->id - 1, 0); 220 ret = adp8870_write(client, ADP8870_ISC1 + led->id - 1, 0);
222 if (ret) 221 if (ret)
223 return ret; 222 return ret;
224 223
225 ret = adp8870_set_bits(client, ADP8870_ISCC, 1 << (led->id - 1)); 224 ret = adp8870_set_bits(client, ADP8870_ISCC, 1 << (led->id - 1));
226 if (ret) 225 if (ret)
227 return ret; 226 return ret;
228 227
229 if (led->id > 4) 228 if (led->id > 4)
230 ret = adp8870_set_bits(client, ADP8870_ISCT1, 229 ret = adp8870_set_bits(client, ADP8870_ISCT1,
231 (led->flags & 0x3) << ((led->id - 5) * 2)); 230 (led->flags & 0x3) << ((led->id - 5) * 2));
232 else 231 else
233 ret = adp8870_set_bits(client, ADP8870_ISCT2, 232 ret = adp8870_set_bits(client, ADP8870_ISCT2,
234 (led->flags & 0x3) << ((led->id - 1) * 2)); 233 (led->flags & 0x3) << ((led->id - 1) * 2));
235 234
236 return ret; 235 return ret;
237 } 236 }
238 237
239 static int __devinit adp8870_led_probe(struct i2c_client *client) 238 static int __devinit adp8870_led_probe(struct i2c_client *client)
240 { 239 {
241 struct adp8870_backlight_platform_data *pdata = 240 struct adp8870_backlight_platform_data *pdata =
242 client->dev.platform_data; 241 client->dev.platform_data;
243 struct adp8870_bl *data = i2c_get_clientdata(client); 242 struct adp8870_bl *data = i2c_get_clientdata(client);
244 struct adp8870_led *led, *led_dat; 243 struct adp8870_led *led, *led_dat;
245 struct led_info *cur_led; 244 struct led_info *cur_led;
246 int ret, i; 245 int ret, i;
247 246
248 247
249 led = kcalloc(pdata->num_leds, sizeof(*led), GFP_KERNEL); 248 led = kcalloc(pdata->num_leds, sizeof(*led), GFP_KERNEL);
250 if (led == NULL) { 249 if (led == NULL) {
251 dev_err(&client->dev, "failed to alloc memory\n"); 250 dev_err(&client->dev, "failed to alloc memory\n");
252 return -ENOMEM; 251 return -ENOMEM;
253 } 252 }
254 253
255 ret = adp8870_write(client, ADP8870_ISCLAW, pdata->led_fade_law); 254 ret = adp8870_write(client, ADP8870_ISCLAW, pdata->led_fade_law);
256 if (ret) 255 if (ret)
257 goto err_free; 256 goto err_free;
258 257
259 ret = adp8870_write(client, ADP8870_ISCT1, 258 ret = adp8870_write(client, ADP8870_ISCT1,
260 (pdata->led_on_time & 0x3) << 6); 259 (pdata->led_on_time & 0x3) << 6);
261 if (ret) 260 if (ret)
262 goto err_free; 261 goto err_free;
263 262
264 ret = adp8870_write(client, ADP8870_ISCF, 263 ret = adp8870_write(client, ADP8870_ISCF,
265 FADE_VAL(pdata->led_fade_in, pdata->led_fade_out)); 264 FADE_VAL(pdata->led_fade_in, pdata->led_fade_out));
266 if (ret) 265 if (ret)
267 goto err_free; 266 goto err_free;
268 267
269 for (i = 0; i < pdata->num_leds; ++i) { 268 for (i = 0; i < pdata->num_leds; ++i) {
270 cur_led = &pdata->leds[i]; 269 cur_led = &pdata->leds[i];
271 led_dat = &led[i]; 270 led_dat = &led[i];
272 271
273 led_dat->id = cur_led->flags & ADP8870_FLAG_LED_MASK; 272 led_dat->id = cur_led->flags & ADP8870_FLAG_LED_MASK;
274 273
275 if (led_dat->id > 7 || led_dat->id < 1) { 274 if (led_dat->id > 7 || led_dat->id < 1) {
276 dev_err(&client->dev, "Invalid LED ID %d\n", 275 dev_err(&client->dev, "Invalid LED ID %d\n",
277 led_dat->id); 276 led_dat->id);
278 goto err; 277 goto err;
279 } 278 }
280 279
281 if (pdata->bl_led_assign & (1 << (led_dat->id - 1))) { 280 if (pdata->bl_led_assign & (1 << (led_dat->id - 1))) {
282 dev_err(&client->dev, "LED %d used by Backlight\n", 281 dev_err(&client->dev, "LED %d used by Backlight\n",
283 led_dat->id); 282 led_dat->id);
284 goto err; 283 goto err;
285 } 284 }
286 285
287 led_dat->cdev.name = cur_led->name; 286 led_dat->cdev.name = cur_led->name;
288 led_dat->cdev.default_trigger = cur_led->default_trigger; 287 led_dat->cdev.default_trigger = cur_led->default_trigger;
289 led_dat->cdev.brightness_set = adp8870_led_set; 288 led_dat->cdev.brightness_set = adp8870_led_set;
290 led_dat->cdev.brightness = LED_OFF; 289 led_dat->cdev.brightness = LED_OFF;
291 led_dat->flags = cur_led->flags >> FLAG_OFFT_SHIFT; 290 led_dat->flags = cur_led->flags >> FLAG_OFFT_SHIFT;
292 led_dat->client = client; 291 led_dat->client = client;
293 led_dat->new_brightness = LED_OFF; 292 led_dat->new_brightness = LED_OFF;
294 INIT_WORK(&led_dat->work, adp8870_led_work); 293 INIT_WORK(&led_dat->work, adp8870_led_work);
295 294
296 ret = led_classdev_register(&client->dev, &led_dat->cdev); 295 ret = led_classdev_register(&client->dev, &led_dat->cdev);
297 if (ret) { 296 if (ret) {
298 dev_err(&client->dev, "failed to register LED %d\n", 297 dev_err(&client->dev, "failed to register LED %d\n",
299 led_dat->id); 298 led_dat->id);
300 goto err; 299 goto err;
301 } 300 }
302 301
303 ret = adp8870_led_setup(led_dat); 302 ret = adp8870_led_setup(led_dat);
304 if (ret) { 303 if (ret) {
305 dev_err(&client->dev, "failed to write\n"); 304 dev_err(&client->dev, "failed to write\n");
306 i++; 305 i++;
307 goto err; 306 goto err;
308 } 307 }
309 } 308 }
310 309
311 data->led = led; 310 data->led = led;
312 311
313 return 0; 312 return 0;
314 313
315 err: 314 err:
316 for (i = i - 1; i >= 0; --i) { 315 for (i = i - 1; i >= 0; --i) {
317 led_classdev_unregister(&led[i].cdev); 316 led_classdev_unregister(&led[i].cdev);
318 cancel_work_sync(&led[i].work); 317 cancel_work_sync(&led[i].work);
319 } 318 }
320 319
321 err_free: 320 err_free:
322 kfree(led); 321 kfree(led);
323 322
324 return ret; 323 return ret;
325 } 324 }
326 325
327 static int __devexit adp8870_led_remove(struct i2c_client *client) 326 static int __devexit adp8870_led_remove(struct i2c_client *client)
328 { 327 {
329 struct adp8870_backlight_platform_data *pdata = 328 struct adp8870_backlight_platform_data *pdata =
330 client->dev.platform_data; 329 client->dev.platform_data;
331 struct adp8870_bl *data = i2c_get_clientdata(client); 330 struct adp8870_bl *data = i2c_get_clientdata(client);
332 int i; 331 int i;
333 332
334 for (i = 0; i < pdata->num_leds; i++) { 333 for (i = 0; i < pdata->num_leds; i++) {
335 led_classdev_unregister(&data->led[i].cdev); 334 led_classdev_unregister(&data->led[i].cdev);
336 cancel_work_sync(&data->led[i].work); 335 cancel_work_sync(&data->led[i].work);
337 } 336 }
338 337
339 kfree(data->led); 338 kfree(data->led);
340 return 0; 339 return 0;
341 } 340 }
342 #else 341 #else
343 static int __devinit adp8870_led_probe(struct i2c_client *client) 342 static int __devinit adp8870_led_probe(struct i2c_client *client)
344 { 343 {
345 return 0; 344 return 0;
346 } 345 }
347 346
348 static int __devexit adp8870_led_remove(struct i2c_client *client) 347 static int __devexit adp8870_led_remove(struct i2c_client *client)
349 { 348 {
350 return 0; 349 return 0;
351 } 350 }
352 #endif 351 #endif
353 352
354 static int adp8870_bl_set(struct backlight_device *bl, int brightness) 353 static int adp8870_bl_set(struct backlight_device *bl, int brightness)
355 { 354 {
356 struct adp8870_bl *data = bl_get_data(bl); 355 struct adp8870_bl *data = bl_get_data(bl);
357 struct i2c_client *client = data->client; 356 struct i2c_client *client = data->client;
358 int ret = 0; 357 int ret = 0;
359 358
360 if (data->pdata->en_ambl_sens) { 359 if (data->pdata->en_ambl_sens) {
361 if ((brightness > 0) && (brightness < ADP8870_MAX_BRIGHTNESS)) { 360 if ((brightness > 0) && (brightness < ADP8870_MAX_BRIGHTNESS)) {
362 /* Disable Ambient Light auto adjust */ 361 /* Disable Ambient Light auto adjust */
363 ret = adp8870_clr_bits(client, ADP8870_MDCR, 362 ret = adp8870_clr_bits(client, ADP8870_MDCR,
364 CMP_AUTOEN); 363 CMP_AUTOEN);
365 if (ret) 364 if (ret)
366 return ret; 365 return ret;
367 ret = adp8870_write(client, ADP8870_BLMX1, brightness); 366 ret = adp8870_write(client, ADP8870_BLMX1, brightness);
368 if (ret) 367 if (ret)
369 return ret; 368 return ret;
370 } else { 369 } else {
371 /* 370 /*
372 * MAX_BRIGHTNESS -> Enable Ambient Light auto adjust 371 * MAX_BRIGHTNESS -> Enable Ambient Light auto adjust
373 * restore daylight l1 sysfs brightness 372 * restore daylight l1 sysfs brightness
374 */ 373 */
375 ret = adp8870_write(client, ADP8870_BLMX1, 374 ret = adp8870_write(client, ADP8870_BLMX1,
376 data->cached_daylight_max); 375 data->cached_daylight_max);
377 if (ret) 376 if (ret)
378 return ret; 377 return ret;
379 378
380 ret = adp8870_set_bits(client, ADP8870_MDCR, 379 ret = adp8870_set_bits(client, ADP8870_MDCR,
381 CMP_AUTOEN); 380 CMP_AUTOEN);
382 if (ret) 381 if (ret)
383 return ret; 382 return ret;
384 } 383 }
385 } else { 384 } else {
386 ret = adp8870_write(client, ADP8870_BLMX1, brightness); 385 ret = adp8870_write(client, ADP8870_BLMX1, brightness);
387 if (ret) 386 if (ret)
388 return ret; 387 return ret;
389 } 388 }
390 389
391 if (data->current_brightness && brightness == 0) 390 if (data->current_brightness && brightness == 0)
392 ret = adp8870_set_bits(client, 391 ret = adp8870_set_bits(client,
393 ADP8870_MDCR, DIM_EN); 392 ADP8870_MDCR, DIM_EN);
394 else if (data->current_brightness == 0 && brightness) 393 else if (data->current_brightness == 0 && brightness)
395 ret = adp8870_clr_bits(client, 394 ret = adp8870_clr_bits(client,
396 ADP8870_MDCR, DIM_EN); 395 ADP8870_MDCR, DIM_EN);
397 396
398 if (!ret) 397 if (!ret)
399 data->current_brightness = brightness; 398 data->current_brightness = brightness;
400 399
401 return ret; 400 return ret;
402 } 401 }
403 402
404 static int adp8870_bl_update_status(struct backlight_device *bl) 403 static int adp8870_bl_update_status(struct backlight_device *bl)
405 { 404 {
406 int brightness = bl->props.brightness; 405 int brightness = bl->props.brightness;
407 if (bl->props.power != FB_BLANK_UNBLANK) 406 if (bl->props.power != FB_BLANK_UNBLANK)
408 brightness = 0; 407 brightness = 0;
409 408
410 if (bl->props.fb_blank != FB_BLANK_UNBLANK) 409 if (bl->props.fb_blank != FB_BLANK_UNBLANK)
411 brightness = 0; 410 brightness = 0;
412 411
413 return adp8870_bl_set(bl, brightness); 412 return adp8870_bl_set(bl, brightness);
414 } 413 }
415 414
416 static int adp8870_bl_get_brightness(struct backlight_device *bl) 415 static int adp8870_bl_get_brightness(struct backlight_device *bl)
417 { 416 {
418 struct adp8870_bl *data = bl_get_data(bl); 417 struct adp8870_bl *data = bl_get_data(bl);
419 418
420 return data->current_brightness; 419 return data->current_brightness;
421 } 420 }
422 421
423 static const struct backlight_ops adp8870_bl_ops = { 422 static const struct backlight_ops adp8870_bl_ops = {
424 .update_status = adp8870_bl_update_status, 423 .update_status = adp8870_bl_update_status,
425 .get_brightness = adp8870_bl_get_brightness, 424 .get_brightness = adp8870_bl_get_brightness,
426 }; 425 };
427 426
428 static int adp8870_bl_setup(struct backlight_device *bl) 427 static int adp8870_bl_setup(struct backlight_device *bl)
429 { 428 {
430 struct adp8870_bl *data = bl_get_data(bl); 429 struct adp8870_bl *data = bl_get_data(bl);
431 struct i2c_client *client = data->client; 430 struct i2c_client *client = data->client;
432 struct adp8870_backlight_platform_data *pdata = data->pdata; 431 struct adp8870_backlight_platform_data *pdata = data->pdata;
433 int ret = 0; 432 int ret = 0;
434 433
435 ret = adp8870_write(client, ADP8870_BLSEL, ~pdata->bl_led_assign); 434 ret = adp8870_write(client, ADP8870_BLSEL, ~pdata->bl_led_assign);
436 if (ret) 435 if (ret)
437 return ret; 436 return ret;
438 437
439 ret = adp8870_write(client, ADP8870_PWMLED, pdata->pwm_assign); 438 ret = adp8870_write(client, ADP8870_PWMLED, pdata->pwm_assign);
440 if (ret) 439 if (ret)
441 return ret; 440 return ret;
442 441
443 ret = adp8870_write(client, ADP8870_BLMX1, pdata->l1_daylight_max); 442 ret = adp8870_write(client, ADP8870_BLMX1, pdata->l1_daylight_max);
444 if (ret) 443 if (ret)
445 return ret; 444 return ret;
446 445
447 ret = adp8870_write(client, ADP8870_BLDM1, pdata->l1_daylight_dim); 446 ret = adp8870_write(client, ADP8870_BLDM1, pdata->l1_daylight_dim);
448 if (ret) 447 if (ret)
449 return ret; 448 return ret;
450 449
451 if (pdata->en_ambl_sens) { 450 if (pdata->en_ambl_sens) {
452 data->cached_daylight_max = pdata->l1_daylight_max; 451 data->cached_daylight_max = pdata->l1_daylight_max;
453 ret = adp8870_write(client, ADP8870_BLMX2, 452 ret = adp8870_write(client, ADP8870_BLMX2,
454 pdata->l2_bright_max); 453 pdata->l2_bright_max);
455 if (ret) 454 if (ret)
456 return ret; 455 return ret;
457 ret = adp8870_write(client, ADP8870_BLDM2, 456 ret = adp8870_write(client, ADP8870_BLDM2,
458 pdata->l2_bright_dim); 457 pdata->l2_bright_dim);
459 if (ret) 458 if (ret)
460 return ret; 459 return ret;
461 460
462 ret = adp8870_write(client, ADP8870_BLMX3, 461 ret = adp8870_write(client, ADP8870_BLMX3,
463 pdata->l3_office_max); 462 pdata->l3_office_max);
464 if (ret) 463 if (ret)
465 return ret; 464 return ret;
466 ret = adp8870_write(client, ADP8870_BLDM3, 465 ret = adp8870_write(client, ADP8870_BLDM3,
467 pdata->l3_office_dim); 466 pdata->l3_office_dim);
468 if (ret) 467 if (ret)
469 return ret; 468 return ret;
470 469
471 ret = adp8870_write(client, ADP8870_BLMX4, 470 ret = adp8870_write(client, ADP8870_BLMX4,
472 pdata->l4_indoor_max); 471 pdata->l4_indoor_max);
473 if (ret) 472 if (ret)
474 return ret; 473 return ret;
475 474
476 ret = adp8870_write(client, ADP8870_BLDM4, 475 ret = adp8870_write(client, ADP8870_BLDM4,
477 pdata->l4_indor_dim); 476 pdata->l4_indor_dim);
478 if (ret) 477 if (ret)
479 return ret; 478 return ret;
480 479
481 ret = adp8870_write(client, ADP8870_BLMX5, 480 ret = adp8870_write(client, ADP8870_BLMX5,
482 pdata->l5_dark_max); 481 pdata->l5_dark_max);
483 if (ret) 482 if (ret)
484 return ret; 483 return ret;
485 484
486 ret = adp8870_write(client, ADP8870_BLDM5, 485 ret = adp8870_write(client, ADP8870_BLDM5,
487 pdata->l5_dark_dim); 486 pdata->l5_dark_dim);
488 if (ret) 487 if (ret)
489 return ret; 488 return ret;
490 489
491 ret = adp8870_write(client, ADP8870_L2TRP, pdata->l2_trip); 490 ret = adp8870_write(client, ADP8870_L2TRP, pdata->l2_trip);
492 if (ret) 491 if (ret)
493 return ret; 492 return ret;
494 493
495 ret = adp8870_write(client, ADP8870_L2HYS, pdata->l2_hyst); 494 ret = adp8870_write(client, ADP8870_L2HYS, pdata->l2_hyst);
496 if (ret) 495 if (ret)
497 return ret; 496 return ret;
498 497
499 ret = adp8870_write(client, ADP8870_L3TRP, pdata->l3_trip); 498 ret = adp8870_write(client, ADP8870_L3TRP, pdata->l3_trip);
500 if (ret) 499 if (ret)
501 return ret; 500 return ret;
502 501
503 ret = adp8870_write(client, ADP8870_L3HYS, pdata->l3_hyst); 502 ret = adp8870_write(client, ADP8870_L3HYS, pdata->l3_hyst);
504 if (ret) 503 if (ret)
505 return ret; 504 return ret;
506 505
507 ret = adp8870_write(client, ADP8870_L4TRP, pdata->l4_trip); 506 ret = adp8870_write(client, ADP8870_L4TRP, pdata->l4_trip);
508 if (ret) 507 if (ret)
509 return ret; 508 return ret;
510 509
511 ret = adp8870_write(client, ADP8870_L4HYS, pdata->l4_hyst); 510 ret = adp8870_write(client, ADP8870_L4HYS, pdata->l4_hyst);
512 if (ret) 511 if (ret)
513 return ret; 512 return ret;
514 513
515 ret = adp8870_write(client, ADP8870_L5TRP, pdata->l5_trip); 514 ret = adp8870_write(client, ADP8870_L5TRP, pdata->l5_trip);
516 if (ret) 515 if (ret)
517 return ret; 516 return ret;
518 517
519 ret = adp8870_write(client, ADP8870_L5HYS, pdata->l5_hyst); 518 ret = adp8870_write(client, ADP8870_L5HYS, pdata->l5_hyst);
520 if (ret) 519 if (ret)
521 return ret; 520 return ret;
522 521
523 ret = adp8870_write(client, ADP8870_ALS1_EN, L5_EN | L4_EN | 522 ret = adp8870_write(client, ADP8870_ALS1_EN, L5_EN | L4_EN |
524 L3_EN | L2_EN); 523 L3_EN | L2_EN);
525 if (ret) 524 if (ret)
526 return ret; 525 return ret;
527 526
528 ret = adp8870_write(client, ADP8870_CMP_CTL, 527 ret = adp8870_write(client, ADP8870_CMP_CTL,
529 ALS_CMPR_CFG_VAL(pdata->abml_filt)); 528 ALS_CMPR_CFG_VAL(pdata->abml_filt));
530 if (ret) 529 if (ret)
531 return ret; 530 return ret;
532 } 531 }
533 532
534 ret = adp8870_write(client, ADP8870_CFGR, 533 ret = adp8870_write(client, ADP8870_CFGR,
535 BL_CFGR_VAL(pdata->bl_fade_law, 0)); 534 BL_CFGR_VAL(pdata->bl_fade_law, 0));
536 if (ret) 535 if (ret)
537 return ret; 536 return ret;
538 537
539 ret = adp8870_write(client, ADP8870_BLFR, FADE_VAL(pdata->bl_fade_in, 538 ret = adp8870_write(client, ADP8870_BLFR, FADE_VAL(pdata->bl_fade_in,
540 pdata->bl_fade_out)); 539 pdata->bl_fade_out));
541 if (ret) 540 if (ret)
542 return ret; 541 return ret;
543 /* 542 /*
544 * ADP8870 Rev0 requires GDWN_DIS bit set 543 * ADP8870 Rev0 requires GDWN_DIS bit set
545 */ 544 */
546 545
547 ret = adp8870_set_bits(client, ADP8870_MDCR, BLEN | DIM_EN | NSTBY | 546 ret = adp8870_set_bits(client, ADP8870_MDCR, BLEN | DIM_EN | NSTBY |
548 (data->revid == 0 ? GDWN_DIS : 0)); 547 (data->revid == 0 ? GDWN_DIS : 0));
549 548
550 return ret; 549 return ret;
551 } 550 }
552 551
553 static ssize_t adp8870_show(struct device *dev, char *buf, int reg) 552 static ssize_t adp8870_show(struct device *dev, char *buf, int reg)
554 { 553 {
555 struct adp8870_bl *data = dev_get_drvdata(dev); 554 struct adp8870_bl *data = dev_get_drvdata(dev);
556 int error; 555 int error;
557 uint8_t reg_val; 556 uint8_t reg_val;
558 557
559 mutex_lock(&data->lock); 558 mutex_lock(&data->lock);
560 error = adp8870_read(data->client, reg, &reg_val); 559 error = adp8870_read(data->client, reg, &reg_val);
561 mutex_unlock(&data->lock); 560 mutex_unlock(&data->lock);
562 561
563 if (error < 0) 562 if (error < 0)
564 return error; 563 return error;
565 564
566 return sprintf(buf, "%u\n", reg_val); 565 return sprintf(buf, "%u\n", reg_val);
567 } 566 }
568 567
569 static ssize_t adp8870_store(struct device *dev, const char *buf, 568 static ssize_t adp8870_store(struct device *dev, const char *buf,
570 size_t count, int reg) 569 size_t count, int reg)
571 { 570 {
572 struct adp8870_bl *data = dev_get_drvdata(dev); 571 struct adp8870_bl *data = dev_get_drvdata(dev);
573 unsigned long val; 572 unsigned long val;
574 int ret; 573 int ret;
575 574
576 ret = strict_strtoul(buf, 10, &val); 575 ret = strict_strtoul(buf, 10, &val);
577 if (ret) 576 if (ret)
578 return ret; 577 return ret;
579 578
580 mutex_lock(&data->lock); 579 mutex_lock(&data->lock);
581 adp8870_write(data->client, reg, val); 580 adp8870_write(data->client, reg, val);
582 mutex_unlock(&data->lock); 581 mutex_unlock(&data->lock);
583 582
584 return count; 583 return count;
585 } 584 }
586 585
587 static ssize_t adp8870_bl_l5_dark_max_show(struct device *dev, 586 static ssize_t adp8870_bl_l5_dark_max_show(struct device *dev,
588 struct device_attribute *attr, char *buf) 587 struct device_attribute *attr, char *buf)
589 { 588 {
590 return adp8870_show(dev, buf, ADP8870_BLMX5); 589 return adp8870_show(dev, buf, ADP8870_BLMX5);
591 } 590 }
592 591
593 static ssize_t adp8870_bl_l5_dark_max_store(struct device *dev, 592 static ssize_t adp8870_bl_l5_dark_max_store(struct device *dev,
594 struct device_attribute *attr, const char *buf, size_t count) 593 struct device_attribute *attr, const char *buf, size_t count)
595 { 594 {
596 return adp8870_store(dev, buf, count, ADP8870_BLMX5); 595 return adp8870_store(dev, buf, count, ADP8870_BLMX5);
597 } 596 }
598 static DEVICE_ATTR(l5_dark_max, 0664, adp8870_bl_l5_dark_max_show, 597 static DEVICE_ATTR(l5_dark_max, 0664, adp8870_bl_l5_dark_max_show,
599 adp8870_bl_l5_dark_max_store); 598 adp8870_bl_l5_dark_max_store);
600 599
601 600
602 static ssize_t adp8870_bl_l4_indoor_max_show(struct device *dev, 601 static ssize_t adp8870_bl_l4_indoor_max_show(struct device *dev,
603 struct device_attribute *attr, char *buf) 602 struct device_attribute *attr, char *buf)
604 { 603 {
605 return adp8870_show(dev, buf, ADP8870_BLMX4); 604 return adp8870_show(dev, buf, ADP8870_BLMX4);
606 } 605 }
607 606
608 static ssize_t adp8870_bl_l4_indoor_max_store(struct device *dev, 607 static ssize_t adp8870_bl_l4_indoor_max_store(struct device *dev,
609 struct device_attribute *attr, const char *buf, size_t count) 608 struct device_attribute *attr, const char *buf, size_t count)
610 { 609 {
611 return adp8870_store(dev, buf, count, ADP8870_BLMX4); 610 return adp8870_store(dev, buf, count, ADP8870_BLMX4);
612 } 611 }
613 static DEVICE_ATTR(l4_indoor_max, 0664, adp8870_bl_l4_indoor_max_show, 612 static DEVICE_ATTR(l4_indoor_max, 0664, adp8870_bl_l4_indoor_max_show,
614 adp8870_bl_l4_indoor_max_store); 613 adp8870_bl_l4_indoor_max_store);
615 614
616 615
617 static ssize_t adp8870_bl_l3_office_max_show(struct device *dev, 616 static ssize_t adp8870_bl_l3_office_max_show(struct device *dev,
618 struct device_attribute *attr, char *buf) 617 struct device_attribute *attr, char *buf)
619 { 618 {
620 return adp8870_show(dev, buf, ADP8870_BLMX3); 619 return adp8870_show(dev, buf, ADP8870_BLMX3);
621 } 620 }
622 621
623 static ssize_t adp8870_bl_l3_office_max_store(struct device *dev, 622 static ssize_t adp8870_bl_l3_office_max_store(struct device *dev,
624 struct device_attribute *attr, const char *buf, size_t count) 623 struct device_attribute *attr, const char *buf, size_t count)
625 { 624 {
626 return adp8870_store(dev, buf, count, ADP8870_BLMX3); 625 return adp8870_store(dev, buf, count, ADP8870_BLMX3);
627 } 626 }
628 627
629 static DEVICE_ATTR(l3_office_max, 0664, adp8870_bl_l3_office_max_show, 628 static DEVICE_ATTR(l3_office_max, 0664, adp8870_bl_l3_office_max_show,
630 adp8870_bl_l3_office_max_store); 629 adp8870_bl_l3_office_max_store);
631 630
632 static ssize_t adp8870_bl_l2_bright_max_show(struct device *dev, 631 static ssize_t adp8870_bl_l2_bright_max_show(struct device *dev,
633 struct device_attribute *attr, char *buf) 632 struct device_attribute *attr, char *buf)
634 { 633 {
635 return adp8870_show(dev, buf, ADP8870_BLMX2); 634 return adp8870_show(dev, buf, ADP8870_BLMX2);
636 } 635 }
637 636
638 static ssize_t adp8870_bl_l2_bright_max_store(struct device *dev, 637 static ssize_t adp8870_bl_l2_bright_max_store(struct device *dev,
639 struct device_attribute *attr, const char *buf, size_t count) 638 struct device_attribute *attr, const char *buf, size_t count)
640 { 639 {
641 return adp8870_store(dev, buf, count, ADP8870_BLMX2); 640 return adp8870_store(dev, buf, count, ADP8870_BLMX2);
642 } 641 }
643 static DEVICE_ATTR(l2_bright_max, 0664, adp8870_bl_l2_bright_max_show, 642 static DEVICE_ATTR(l2_bright_max, 0664, adp8870_bl_l2_bright_max_show,
644 adp8870_bl_l2_bright_max_store); 643 adp8870_bl_l2_bright_max_store);
645 644
646 static ssize_t adp8870_bl_l1_daylight_max_show(struct device *dev, 645 static ssize_t adp8870_bl_l1_daylight_max_show(struct device *dev,
647 struct device_attribute *attr, char *buf) 646 struct device_attribute *attr, char *buf)
648 { 647 {
649 return adp8870_show(dev, buf, ADP8870_BLMX1); 648 return adp8870_show(dev, buf, ADP8870_BLMX1);
650 } 649 }
651 650
652 static ssize_t adp8870_bl_l1_daylight_max_store(struct device *dev, 651 static ssize_t adp8870_bl_l1_daylight_max_store(struct device *dev,
653 struct device_attribute *attr, const char *buf, size_t count) 652 struct device_attribute *attr, const char *buf, size_t count)
654 { 653 {
655 struct adp8870_bl *data = dev_get_drvdata(dev); 654 struct adp8870_bl *data = dev_get_drvdata(dev);
656 int ret = strict_strtoul(buf, 10, &data->cached_daylight_max); 655 int ret = strict_strtoul(buf, 10, &data->cached_daylight_max);
657 if (ret) 656 if (ret)
658 return ret; 657 return ret;
659 658
660 return adp8870_store(dev, buf, count, ADP8870_BLMX1); 659 return adp8870_store(dev, buf, count, ADP8870_BLMX1);
661 } 660 }
662 static DEVICE_ATTR(l1_daylight_max, 0664, adp8870_bl_l1_daylight_max_show, 661 static DEVICE_ATTR(l1_daylight_max, 0664, adp8870_bl_l1_daylight_max_show,
663 adp8870_bl_l1_daylight_max_store); 662 adp8870_bl_l1_daylight_max_store);
664 663
665 static ssize_t adp8870_bl_l5_dark_dim_show(struct device *dev, 664 static ssize_t adp8870_bl_l5_dark_dim_show(struct device *dev,
666 struct device_attribute *attr, char *buf) 665 struct device_attribute *attr, char *buf)
667 { 666 {
668 return adp8870_show(dev, buf, ADP8870_BLDM5); 667 return adp8870_show(dev, buf, ADP8870_BLDM5);
669 } 668 }
670 669
671 static ssize_t adp8870_bl_l5_dark_dim_store(struct device *dev, 670 static ssize_t adp8870_bl_l5_dark_dim_store(struct device *dev,
672 struct device_attribute *attr, 671 struct device_attribute *attr,
673 const char *buf, size_t count) 672 const char *buf, size_t count)
674 { 673 {
675 return adp8870_store(dev, buf, count, ADP8870_BLDM5); 674 return adp8870_store(dev, buf, count, ADP8870_BLDM5);
676 } 675 }
677 static DEVICE_ATTR(l5_dark_dim, 0664, adp8870_bl_l5_dark_dim_show, 676 static DEVICE_ATTR(l5_dark_dim, 0664, adp8870_bl_l5_dark_dim_show,
678 adp8870_bl_l5_dark_dim_store); 677 adp8870_bl_l5_dark_dim_store);
679 678
680 static ssize_t adp8870_bl_l4_indoor_dim_show(struct device *dev, 679 static ssize_t adp8870_bl_l4_indoor_dim_show(struct device *dev,
681 struct device_attribute *attr, char *buf) 680 struct device_attribute *attr, char *buf)
682 { 681 {
683 return adp8870_show(dev, buf, ADP8870_BLDM4); 682 return adp8870_show(dev, buf, ADP8870_BLDM4);
684 } 683 }
685 684
686 static ssize_t adp8870_bl_l4_indoor_dim_store(struct device *dev, 685 static ssize_t adp8870_bl_l4_indoor_dim_store(struct device *dev,
687 struct device_attribute *attr, 686 struct device_attribute *attr,
688 const char *buf, size_t count) 687 const char *buf, size_t count)
689 { 688 {
690 return adp8870_store(dev, buf, count, ADP8870_BLDM4); 689 return adp8870_store(dev, buf, count, ADP8870_BLDM4);
691 } 690 }
692 static DEVICE_ATTR(l4_indoor_dim, 0664, adp8870_bl_l4_indoor_dim_show, 691 static DEVICE_ATTR(l4_indoor_dim, 0664, adp8870_bl_l4_indoor_dim_show,
693 adp8870_bl_l4_indoor_dim_store); 692 adp8870_bl_l4_indoor_dim_store);
694 693
695 694
696 static ssize_t adp8870_bl_l3_office_dim_show(struct device *dev, 695 static ssize_t adp8870_bl_l3_office_dim_show(struct device *dev,
697 struct device_attribute *attr, char *buf) 696 struct device_attribute *attr, char *buf)
698 { 697 {
699 return adp8870_show(dev, buf, ADP8870_BLDM3); 698 return adp8870_show(dev, buf, ADP8870_BLDM3);
700 } 699 }
701 700
702 static ssize_t adp8870_bl_l3_office_dim_store(struct device *dev, 701 static ssize_t adp8870_bl_l3_office_dim_store(struct device *dev,
703 struct device_attribute *attr, 702 struct device_attribute *attr,
704 const char *buf, size_t count) 703 const char *buf, size_t count)
705 { 704 {
706 return adp8870_store(dev, buf, count, ADP8870_BLDM3); 705 return adp8870_store(dev, buf, count, ADP8870_BLDM3);
707 } 706 }
708 static DEVICE_ATTR(l3_office_dim, 0664, adp8870_bl_l3_office_dim_show, 707 static DEVICE_ATTR(l3_office_dim, 0664, adp8870_bl_l3_office_dim_show,
709 adp8870_bl_l3_office_dim_store); 708 adp8870_bl_l3_office_dim_store);
710 709
711 static ssize_t adp8870_bl_l2_bright_dim_show(struct device *dev, 710 static ssize_t adp8870_bl_l2_bright_dim_show(struct device *dev,
712 struct device_attribute *attr, char *buf) 711 struct device_attribute *attr, char *buf)
713 { 712 {
714 return adp8870_show(dev, buf, ADP8870_BLDM2); 713 return adp8870_show(dev, buf, ADP8870_BLDM2);
715 } 714 }
716 715
717 static ssize_t adp8870_bl_l2_bright_dim_store(struct device *dev, 716 static ssize_t adp8870_bl_l2_bright_dim_store(struct device *dev,
718 struct device_attribute *attr, 717 struct device_attribute *attr,
719 const char *buf, size_t count) 718 const char *buf, size_t count)
720 { 719 {
721 return adp8870_store(dev, buf, count, ADP8870_BLDM2); 720 return adp8870_store(dev, buf, count, ADP8870_BLDM2);
722 } 721 }
723 static DEVICE_ATTR(l2_bright_dim, 0664, adp8870_bl_l2_bright_dim_show, 722 static DEVICE_ATTR(l2_bright_dim, 0664, adp8870_bl_l2_bright_dim_show,
724 adp8870_bl_l2_bright_dim_store); 723 adp8870_bl_l2_bright_dim_store);
725 724
726 static ssize_t adp8870_bl_l1_daylight_dim_show(struct device *dev, 725 static ssize_t adp8870_bl_l1_daylight_dim_show(struct device *dev,
727 struct device_attribute *attr, char *buf) 726 struct device_attribute *attr, char *buf)
728 { 727 {
729 return adp8870_show(dev, buf, ADP8870_BLDM1); 728 return adp8870_show(dev, buf, ADP8870_BLDM1);
730 } 729 }
731 730
732 static ssize_t adp8870_bl_l1_daylight_dim_store(struct device *dev, 731 static ssize_t adp8870_bl_l1_daylight_dim_store(struct device *dev,
733 struct device_attribute *attr, 732 struct device_attribute *attr,
734 const char *buf, size_t count) 733 const char *buf, size_t count)
735 { 734 {
736 return adp8870_store(dev, buf, count, ADP8870_BLDM1); 735 return adp8870_store(dev, buf, count, ADP8870_BLDM1);
737 } 736 }
738 static DEVICE_ATTR(l1_daylight_dim, 0664, adp8870_bl_l1_daylight_dim_show, 737 static DEVICE_ATTR(l1_daylight_dim, 0664, adp8870_bl_l1_daylight_dim_show,
739 adp8870_bl_l1_daylight_dim_store); 738 adp8870_bl_l1_daylight_dim_store);
740 739
741 #ifdef ADP8870_EXT_FEATURES 740 #ifdef ADP8870_EXT_FEATURES
742 static ssize_t adp8870_bl_ambient_light_level_show(struct device *dev, 741 static ssize_t adp8870_bl_ambient_light_level_show(struct device *dev,
743 struct device_attribute *attr, char *buf) 742 struct device_attribute *attr, char *buf)
744 { 743 {
745 struct adp8870_bl *data = dev_get_drvdata(dev); 744 struct adp8870_bl *data = dev_get_drvdata(dev);
746 int error; 745 int error;
747 uint8_t reg_val; 746 uint8_t reg_val;
748 uint16_t ret_val; 747 uint16_t ret_val;
749 748
750 mutex_lock(&data->lock); 749 mutex_lock(&data->lock);
751 error = adp8870_read(data->client, ADP8870_PH1LEVL, &reg_val); 750 error = adp8870_read(data->client, ADP8870_PH1LEVL, &reg_val);
752 if (error < 0) { 751 if (error < 0) {
753 mutex_unlock(&data->lock); 752 mutex_unlock(&data->lock);
754 return error; 753 return error;
755 } 754 }
756 ret_val = reg_val; 755 ret_val = reg_val;
757 error = adp8870_read(data->client, ADP8870_PH1LEVH, &reg_val); 756 error = adp8870_read(data->client, ADP8870_PH1LEVH, &reg_val);
758 mutex_unlock(&data->lock); 757 mutex_unlock(&data->lock);
759 758
760 if (error < 0) 759 if (error < 0)
761 return error; 760 return error;
762 761
763 /* Return 13-bit conversion value for the first light sensor */ 762 /* Return 13-bit conversion value for the first light sensor */
764 ret_val += (reg_val & 0x1F) << 8; 763 ret_val += (reg_val & 0x1F) << 8;
765 764
766 return sprintf(buf, "%u\n", ret_val); 765 return sprintf(buf, "%u\n", ret_val);
767 } 766 }
768 static DEVICE_ATTR(ambient_light_level, 0444, 767 static DEVICE_ATTR(ambient_light_level, 0444,
769 adp8870_bl_ambient_light_level_show, NULL); 768 adp8870_bl_ambient_light_level_show, NULL);
770 769
771 static ssize_t adp8870_bl_ambient_light_zone_show(struct device *dev, 770 static ssize_t adp8870_bl_ambient_light_zone_show(struct device *dev,
772 struct device_attribute *attr, char *buf) 771 struct device_attribute *attr, char *buf)
773 { 772 {
774 struct adp8870_bl *data = dev_get_drvdata(dev); 773 struct adp8870_bl *data = dev_get_drvdata(dev);
775 int error; 774 int error;
776 uint8_t reg_val; 775 uint8_t reg_val;
777 776
778 mutex_lock(&data->lock); 777 mutex_lock(&data->lock);
779 error = adp8870_read(data->client, ADP8870_CFGR, &reg_val); 778 error = adp8870_read(data->client, ADP8870_CFGR, &reg_val);
780 mutex_unlock(&data->lock); 779 mutex_unlock(&data->lock);
781 780
782 if (error < 0) 781 if (error < 0)
783 return error; 782 return error;
784 783
785 return sprintf(buf, "%u\n", 784 return sprintf(buf, "%u\n",
786 ((reg_val >> CFGR_BLV_SHIFT) & CFGR_BLV_MASK) + 1); 785 ((reg_val >> CFGR_BLV_SHIFT) & CFGR_BLV_MASK) + 1);
787 } 786 }
788 787
789 static ssize_t adp8870_bl_ambient_light_zone_store(struct device *dev, 788 static ssize_t adp8870_bl_ambient_light_zone_store(struct device *dev,
790 struct device_attribute *attr, 789 struct device_attribute *attr,
791 const char *buf, size_t count) 790 const char *buf, size_t count)
792 { 791 {
793 struct adp8870_bl *data = dev_get_drvdata(dev); 792 struct adp8870_bl *data = dev_get_drvdata(dev);
794 unsigned long val; 793 unsigned long val;
795 uint8_t reg_val; 794 uint8_t reg_val;
796 int ret; 795 int ret;
797 796
798 ret = strict_strtoul(buf, 10, &val); 797 ret = strict_strtoul(buf, 10, &val);
799 if (ret) 798 if (ret)
800 return ret; 799 return ret;
801 800
802 if (val == 0) { 801 if (val == 0) {
803 /* Enable automatic ambient light sensing */ 802 /* Enable automatic ambient light sensing */
804 adp8870_set_bits(data->client, ADP8870_MDCR, CMP_AUTOEN); 803 adp8870_set_bits(data->client, ADP8870_MDCR, CMP_AUTOEN);
805 } else if ((val > 0) && (val < 6)) { 804 } else if ((val > 0) && (val < 6)) {
806 /* Disable automatic ambient light sensing */ 805 /* Disable automatic ambient light sensing */
807 adp8870_clr_bits(data->client, ADP8870_MDCR, CMP_AUTOEN); 806 adp8870_clr_bits(data->client, ADP8870_MDCR, CMP_AUTOEN);
808 807
809 /* Set user supplied ambient light zone */ 808 /* Set user supplied ambient light zone */
810 mutex_lock(&data->lock); 809 mutex_lock(&data->lock);
811 adp8870_read(data->client, ADP8870_CFGR, &reg_val); 810 adp8870_read(data->client, ADP8870_CFGR, &reg_val);
812 reg_val &= ~(CFGR_BLV_MASK << CFGR_BLV_SHIFT); 811 reg_val &= ~(CFGR_BLV_MASK << CFGR_BLV_SHIFT);
813 reg_val |= (val - 1) << CFGR_BLV_SHIFT; 812 reg_val |= (val - 1) << CFGR_BLV_SHIFT;
814 adp8870_write(data->client, ADP8870_CFGR, reg_val); 813 adp8870_write(data->client, ADP8870_CFGR, reg_val);
815 mutex_unlock(&data->lock); 814 mutex_unlock(&data->lock);
816 } 815 }
817 816
818 return count; 817 return count;
819 } 818 }
820 static DEVICE_ATTR(ambient_light_zone, 0664, 819 static DEVICE_ATTR(ambient_light_zone, 0664,
821 adp8870_bl_ambient_light_zone_show, 820 adp8870_bl_ambient_light_zone_show,
822 adp8870_bl_ambient_light_zone_store); 821 adp8870_bl_ambient_light_zone_store);
823 #endif 822 #endif
824 823
825 static struct attribute *adp8870_bl_attributes[] = { 824 static struct attribute *adp8870_bl_attributes[] = {
826 &dev_attr_l5_dark_max.attr, 825 &dev_attr_l5_dark_max.attr,
827 &dev_attr_l5_dark_dim.attr, 826 &dev_attr_l5_dark_dim.attr,
828 &dev_attr_l4_indoor_max.attr, 827 &dev_attr_l4_indoor_max.attr,
829 &dev_attr_l4_indoor_dim.attr, 828 &dev_attr_l4_indoor_dim.attr,
830 &dev_attr_l3_office_max.attr, 829 &dev_attr_l3_office_max.attr,
831 &dev_attr_l3_office_dim.attr, 830 &dev_attr_l3_office_dim.attr,
832 &dev_attr_l2_bright_max.attr, 831 &dev_attr_l2_bright_max.attr,
833 &dev_attr_l2_bright_dim.attr, 832 &dev_attr_l2_bright_dim.attr,
834 &dev_attr_l1_daylight_max.attr, 833 &dev_attr_l1_daylight_max.attr,
835 &dev_attr_l1_daylight_dim.attr, 834 &dev_attr_l1_daylight_dim.attr,
836 #ifdef ADP8870_EXT_FEATURES 835 #ifdef ADP8870_EXT_FEATURES
837 &dev_attr_ambient_light_level.attr, 836 &dev_attr_ambient_light_level.attr,
838 &dev_attr_ambient_light_zone.attr, 837 &dev_attr_ambient_light_zone.attr,
839 #endif 838 #endif
840 NULL 839 NULL
841 }; 840 };
842 841
843 static const struct attribute_group adp8870_bl_attr_group = { 842 static const struct attribute_group adp8870_bl_attr_group = {
844 .attrs = adp8870_bl_attributes, 843 .attrs = adp8870_bl_attributes,
845 }; 844 };
846 845
847 static int __devinit adp8870_probe(struct i2c_client *client, 846 static int __devinit adp8870_probe(struct i2c_client *client,
848 const struct i2c_device_id *id) 847 const struct i2c_device_id *id)
849 { 848 {
850 struct backlight_properties props; 849 struct backlight_properties props;
851 struct backlight_device *bl; 850 struct backlight_device *bl;
852 struct adp8870_bl *data; 851 struct adp8870_bl *data;
853 struct adp8870_backlight_platform_data *pdata = 852 struct adp8870_backlight_platform_data *pdata =
854 client->dev.platform_data; 853 client->dev.platform_data;
855 uint8_t reg_val; 854 uint8_t reg_val;
856 int ret; 855 int ret;
857 856
858 if (!i2c_check_functionality(client->adapter, 857 if (!i2c_check_functionality(client->adapter,
859 I2C_FUNC_SMBUS_BYTE_DATA)) { 858 I2C_FUNC_SMBUS_BYTE_DATA)) {
860 dev_err(&client->dev, "SMBUS Byte Data not Supported\n"); 859 dev_err(&client->dev, "SMBUS Byte Data not Supported\n");
861 return -EIO; 860 return -EIO;
862 } 861 }
863 862
864 if (!pdata) { 863 if (!pdata) {
865 dev_err(&client->dev, "no platform data?\n"); 864 dev_err(&client->dev, "no platform data?\n");
866 return -EINVAL; 865 return -EINVAL;
867 } 866 }
868 867
869 ret = adp8870_read(client, ADP8870_MFDVID, &reg_val); 868 ret = adp8870_read(client, ADP8870_MFDVID, &reg_val);
870 if (ret < 0) 869 if (ret < 0)
871 return -EIO; 870 return -EIO;
872 871
873 if (ADP8870_MANID(reg_val) != ADP8870_MANUFID) { 872 if (ADP8870_MANID(reg_val) != ADP8870_MANUFID) {
874 dev_err(&client->dev, "failed to probe\n"); 873 dev_err(&client->dev, "failed to probe\n");
875 return -ENODEV; 874 return -ENODEV;
876 } 875 }
877 876
878 data = kzalloc(sizeof(*data), GFP_KERNEL); 877 data = kzalloc(sizeof(*data), GFP_KERNEL);
879 if (data == NULL) 878 if (data == NULL)
880 return -ENOMEM; 879 return -ENOMEM;
881 880
882 data->revid = ADP8870_DEVID(reg_val); 881 data->revid = ADP8870_DEVID(reg_val);
883 data->client = client; 882 data->client = client;
884 data->pdata = pdata; 883 data->pdata = pdata;
885 data->id = id->driver_data; 884 data->id = id->driver_data;
886 data->current_brightness = 0; 885 data->current_brightness = 0;
887 i2c_set_clientdata(client, data); 886 i2c_set_clientdata(client, data);
888 887
889 mutex_init(&data->lock); 888 mutex_init(&data->lock);
890 889
891 memset(&props, 0, sizeof(props)); 890 memset(&props, 0, sizeof(props));
892 props.type = BACKLIGHT_RAW; 891 props.type = BACKLIGHT_RAW;
893 props.max_brightness = props.brightness = ADP8870_MAX_BRIGHTNESS; 892 props.max_brightness = props.brightness = ADP8870_MAX_BRIGHTNESS;
894 bl = backlight_device_register(dev_driver_string(&client->dev), 893 bl = backlight_device_register(dev_driver_string(&client->dev),
895 &client->dev, data, &adp8870_bl_ops, &props); 894 &client->dev, data, &adp8870_bl_ops, &props);
896 if (IS_ERR(bl)) { 895 if (IS_ERR(bl)) {
897 dev_err(&client->dev, "failed to register backlight\n"); 896 dev_err(&client->dev, "failed to register backlight\n");
898 ret = PTR_ERR(bl); 897 ret = PTR_ERR(bl);
899 goto out2; 898 goto out2;
900 } 899 }
901 900
902 data->bl = bl; 901 data->bl = bl;
903 902
904 if (pdata->en_ambl_sens) 903 if (pdata->en_ambl_sens)
905 ret = sysfs_create_group(&bl->dev.kobj, 904 ret = sysfs_create_group(&bl->dev.kobj,
906 &adp8870_bl_attr_group); 905 &adp8870_bl_attr_group);
907 906
908 if (ret) { 907 if (ret) {
909 dev_err(&client->dev, "failed to register sysfs\n"); 908 dev_err(&client->dev, "failed to register sysfs\n");
910 goto out1; 909 goto out1;
911 } 910 }
912 911
913 ret = adp8870_bl_setup(bl); 912 ret = adp8870_bl_setup(bl);
914 if (ret) { 913 if (ret) {
915 ret = -EIO; 914 ret = -EIO;
916 goto out; 915 goto out;
917 } 916 }
918 917
919 backlight_update_status(bl); 918 backlight_update_status(bl);
920 919
921 dev_info(&client->dev, "Rev.%d Backlight\n", data->revid); 920 dev_info(&client->dev, "Rev.%d Backlight\n", data->revid);
922 921
923 if (pdata->num_leds) 922 if (pdata->num_leds)
924 adp8870_led_probe(client); 923 adp8870_led_probe(client);
925 924
926 return 0; 925 return 0;
927 926
928 out: 927 out:
929 if (data->pdata->en_ambl_sens) 928 if (data->pdata->en_ambl_sens)
930 sysfs_remove_group(&data->bl->dev.kobj, 929 sysfs_remove_group(&data->bl->dev.kobj,
931 &adp8870_bl_attr_group); 930 &adp8870_bl_attr_group);
932 out1: 931 out1:
933 backlight_device_unregister(bl); 932 backlight_device_unregister(bl);
934 out2: 933 out2:
935 i2c_set_clientdata(client, NULL); 934 i2c_set_clientdata(client, NULL);
936 kfree(data); 935 kfree(data);
937 936
938 return ret; 937 return ret;
939 } 938 }
940 939
941 static int __devexit adp8870_remove(struct i2c_client *client) 940 static int __devexit adp8870_remove(struct i2c_client *client)
942 { 941 {
943 struct adp8870_bl *data = i2c_get_clientdata(client); 942 struct adp8870_bl *data = i2c_get_clientdata(client);
944 943
945 adp8870_clr_bits(client, ADP8870_MDCR, NSTBY); 944 adp8870_clr_bits(client, ADP8870_MDCR, NSTBY);
946 945
947 if (data->led) 946 if (data->led)
948 adp8870_led_remove(client); 947 adp8870_led_remove(client);
949 948
950 if (data->pdata->en_ambl_sens) 949 if (data->pdata->en_ambl_sens)
951 sysfs_remove_group(&data->bl->dev.kobj, 950 sysfs_remove_group(&data->bl->dev.kobj,
952 &adp8870_bl_attr_group); 951 &adp8870_bl_attr_group);
953 952
954 backlight_device_unregister(data->bl); 953 backlight_device_unregister(data->bl);
955 i2c_set_clientdata(client, NULL); 954 i2c_set_clientdata(client, NULL);
956 kfree(data); 955 kfree(data);
957 956
958 return 0; 957 return 0;
959 } 958 }
960 959
961 #ifdef CONFIG_PM 960 #ifdef CONFIG_PM
962 static int adp8870_i2c_suspend(struct i2c_client *client, pm_message_t message) 961 static int adp8870_i2c_suspend(struct i2c_client *client, pm_message_t message)
963 { 962 {
964 adp8870_clr_bits(client, ADP8870_MDCR, NSTBY); 963 adp8870_clr_bits(client, ADP8870_MDCR, NSTBY);
965 964
966 return 0; 965 return 0;
967 } 966 }
968 967
969 static int adp8870_i2c_resume(struct i2c_client *client) 968 static int adp8870_i2c_resume(struct i2c_client *client)
970 { 969 {
971 adp8870_set_bits(client, ADP8870_MDCR, NSTBY); 970 adp8870_set_bits(client, ADP8870_MDCR, NSTBY);
972 971
973 return 0; 972 return 0;
974 } 973 }
975 #else 974 #else
976 #define adp8870_i2c_suspend NULL 975 #define adp8870_i2c_suspend NULL
977 #define adp8870_i2c_resume NULL 976 #define adp8870_i2c_resume NULL
978 #endif 977 #endif
979 978
980 static const struct i2c_device_id adp8870_id[] = { 979 static const struct i2c_device_id adp8870_id[] = {
981 { "adp8870", 0 }, 980 { "adp8870", 0 },
982 { } 981 { }
983 }; 982 };
984 MODULE_DEVICE_TABLE(i2c, adp8870_id); 983 MODULE_DEVICE_TABLE(i2c, adp8870_id);
985 984
986 static struct i2c_driver adp8870_driver = { 985 static struct i2c_driver adp8870_driver = {
987 .driver = { 986 .driver = {
988 .name = KBUILD_MODNAME, 987 .name = KBUILD_MODNAME,
989 }, 988 },
990 .probe = adp8870_probe, 989 .probe = adp8870_probe,
991 .remove = __devexit_p(adp8870_remove), 990 .remove = __devexit_p(adp8870_remove),
992 .suspend = adp8870_i2c_suspend, 991 .suspend = adp8870_i2c_suspend,
993 .resume = adp8870_i2c_resume, 992 .resume = adp8870_i2c_resume,
994 .id_table = adp8870_id, 993 .id_table = adp8870_id,
995 }; 994 };
996 995
997 static int __init adp8870_init(void) 996 static int __init adp8870_init(void)
998 { 997 {
999 return i2c_add_driver(&adp8870_driver); 998 return i2c_add_driver(&adp8870_driver);
1000 } 999 }
1001 module_init(adp8870_init); 1000 module_init(adp8870_init);
1002 1001
1003 static void __exit adp8870_exit(void) 1002 static void __exit adp8870_exit(void)
1004 { 1003 {
1005 i2c_del_driver(&adp8870_driver); 1004 i2c_del_driver(&adp8870_driver);
1006 } 1005 }
1007 module_exit(adp8870_exit); 1006 module_exit(adp8870_exit);
1008 1007
1009 MODULE_LICENSE("GPL v2"); 1008 MODULE_LICENSE("GPL v2");
1010 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); 1009 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
1011 MODULE_DESCRIPTION("ADP8870 Backlight driver"); 1010 MODULE_DESCRIPTION("ADP8870 Backlight driver");
1012 MODULE_ALIAS("platform:adp8870-backlight"); 1011 MODULE_ALIAS("platform:adp8870-backlight");
1013 1012
drivers/video/pxa3xx-gcu.c
1 /* 1 /*
2 * pxa3xx-gcu.c - Linux kernel module for PXA3xx graphics controllers 2 * pxa3xx-gcu.c - Linux kernel module for PXA3xx graphics controllers
3 * 3 *
4 * This driver needs a DirectFB counterpart in user space, communication 4 * This driver needs a DirectFB counterpart in user space, communication
5 * is handled via mmap()ed memory areas and an ioctl. 5 * is handled via mmap()ed memory areas and an ioctl.
6 * 6 *
7 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> 7 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
8 * Copyright (c) 2009 Janine Kropp <nin@directfb.org> 8 * Copyright (c) 2009 Janine Kropp <nin@directfb.org>
9 * Copyright (c) 2009 Denis Oliver Kropp <dok@directfb.org> 9 * Copyright (c) 2009 Denis Oliver Kropp <dok@directfb.org>
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version. 14 * (at your option) any later version.
15 * 15 *
16 * This program is distributed in the hope that it will be useful, 16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details. 19 * GNU General Public License for more details.
20 * 20 *
21 * You should have received a copy of the GNU General Public License 21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software 22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */ 24 */
25 25
26 /* 26 /*
27 * WARNING: This controller is attached to System Bus 2 of the PXA which 27 * WARNING: This controller is attached to System Bus 2 of the PXA which
28 * needs its arbiter to be enabled explicitly (CKENB & 1<<9). 28 * needs its arbiter to be enabled explicitly (CKENB & 1<<9).
29 * There is currently no way to do this from Linux, so you need to teach 29 * There is currently no way to do this from Linux, so you need to teach
30 * your bootloader for now. 30 * your bootloader for now.
31 */ 31 */
32 32
33 #include <linux/module.h> 33 #include <linux/module.h>
34 #include <linux/version.h>
35
36 #include <linux/platform_device.h> 34 #include <linux/platform_device.h>
37 #include <linux/dma-mapping.h> 35 #include <linux/dma-mapping.h>
38 #include <linux/miscdevice.h> 36 #include <linux/miscdevice.h>
39 #include <linux/interrupt.h> 37 #include <linux/interrupt.h>
40 #include <linux/spinlock.h> 38 #include <linux/spinlock.h>
41 #include <linux/uaccess.h> 39 #include <linux/uaccess.h>
42 #include <linux/ioctl.h> 40 #include <linux/ioctl.h>
43 #include <linux/delay.h> 41 #include <linux/delay.h>
44 #include <linux/sched.h> 42 #include <linux/sched.h>
45 #include <linux/slab.h> 43 #include <linux/slab.h>
46 #include <linux/clk.h> 44 #include <linux/clk.h>
47 #include <linux/fs.h> 45 #include <linux/fs.h>
48 #include <linux/io.h> 46 #include <linux/io.h>
49 47
50 #include "pxa3xx-gcu.h" 48 #include "pxa3xx-gcu.h"
51 49
52 #define DRV_NAME "pxa3xx-gcu" 50 #define DRV_NAME "pxa3xx-gcu"
53 #define MISCDEV_MINOR 197 51 #define MISCDEV_MINOR 197
54 52
55 #define REG_GCCR 0x00 53 #define REG_GCCR 0x00
56 #define GCCR_SYNC_CLR (1 << 9) 54 #define GCCR_SYNC_CLR (1 << 9)
57 #define GCCR_BP_RST (1 << 8) 55 #define GCCR_BP_RST (1 << 8)
58 #define GCCR_ABORT (1 << 6) 56 #define GCCR_ABORT (1 << 6)
59 #define GCCR_STOP (1 << 4) 57 #define GCCR_STOP (1 << 4)
60 58
61 #define REG_GCISCR 0x04 59 #define REG_GCISCR 0x04
62 #define REG_GCIECR 0x08 60 #define REG_GCIECR 0x08
63 #define REG_GCRBBR 0x20 61 #define REG_GCRBBR 0x20
64 #define REG_GCRBLR 0x24 62 #define REG_GCRBLR 0x24
65 #define REG_GCRBHR 0x28 63 #define REG_GCRBHR 0x28
66 #define REG_GCRBTR 0x2C 64 #define REG_GCRBTR 0x2C
67 #define REG_GCRBEXHR 0x30 65 #define REG_GCRBEXHR 0x30
68 66
69 #define IE_EOB (1 << 0) 67 #define IE_EOB (1 << 0)
70 #define IE_EEOB (1 << 5) 68 #define IE_EEOB (1 << 5)
71 #define IE_ALL 0xff 69 #define IE_ALL 0xff
72 70
73 #define SHARED_SIZE PAGE_ALIGN(sizeof(struct pxa3xx_gcu_shared)) 71 #define SHARED_SIZE PAGE_ALIGN(sizeof(struct pxa3xx_gcu_shared))
74 72
75 /* #define PXA3XX_GCU_DEBUG */ 73 /* #define PXA3XX_GCU_DEBUG */
76 /* #define PXA3XX_GCU_DEBUG_TIMER */ 74 /* #define PXA3XX_GCU_DEBUG_TIMER */
77 75
78 #ifdef PXA3XX_GCU_DEBUG 76 #ifdef PXA3XX_GCU_DEBUG
79 #define QDUMP(msg) \ 77 #define QDUMP(msg) \
80 do { \ 78 do { \
81 QPRINT(priv, KERN_DEBUG, msg); \ 79 QPRINT(priv, KERN_DEBUG, msg); \
82 } while (0) 80 } while (0)
83 #else 81 #else
84 #define QDUMP(msg) do {} while (0) 82 #define QDUMP(msg) do {} while (0)
85 #endif 83 #endif
86 84
87 #define QERROR(msg) \ 85 #define QERROR(msg) \
88 do { \ 86 do { \
89 QPRINT(priv, KERN_ERR, msg); \ 87 QPRINT(priv, KERN_ERR, msg); \
90 } while (0) 88 } while (0)
91 89
92 struct pxa3xx_gcu_batch { 90 struct pxa3xx_gcu_batch {
93 struct pxa3xx_gcu_batch *next; 91 struct pxa3xx_gcu_batch *next;
94 u32 *ptr; 92 u32 *ptr;
95 dma_addr_t phys; 93 dma_addr_t phys;
96 unsigned long length; 94 unsigned long length;
97 }; 95 };
98 96
99 struct pxa3xx_gcu_priv { 97 struct pxa3xx_gcu_priv {
100 void __iomem *mmio_base; 98 void __iomem *mmio_base;
101 struct clk *clk; 99 struct clk *clk;
102 struct pxa3xx_gcu_shared *shared; 100 struct pxa3xx_gcu_shared *shared;
103 dma_addr_t shared_phys; 101 dma_addr_t shared_phys;
104 struct resource *resource_mem; 102 struct resource *resource_mem;
105 struct miscdevice misc_dev; 103 struct miscdevice misc_dev;
106 struct file_operations misc_fops; 104 struct file_operations misc_fops;
107 wait_queue_head_t wait_idle; 105 wait_queue_head_t wait_idle;
108 wait_queue_head_t wait_free; 106 wait_queue_head_t wait_free;
109 spinlock_t spinlock; 107 spinlock_t spinlock;
110 struct timeval base_time; 108 struct timeval base_time;
111 109
112 struct pxa3xx_gcu_batch *free; 110 struct pxa3xx_gcu_batch *free;
113 111
114 struct pxa3xx_gcu_batch *ready; 112 struct pxa3xx_gcu_batch *ready;
115 struct pxa3xx_gcu_batch *ready_last; 113 struct pxa3xx_gcu_batch *ready_last;
116 struct pxa3xx_gcu_batch *running; 114 struct pxa3xx_gcu_batch *running;
117 }; 115 };
118 116
119 static inline unsigned long 117 static inline unsigned long
120 gc_readl(struct pxa3xx_gcu_priv *priv, unsigned int off) 118 gc_readl(struct pxa3xx_gcu_priv *priv, unsigned int off)
121 { 119 {
122 return __raw_readl(priv->mmio_base + off); 120 return __raw_readl(priv->mmio_base + off);
123 } 121 }
124 122
125 static inline void 123 static inline void
126 gc_writel(struct pxa3xx_gcu_priv *priv, unsigned int off, unsigned long val) 124 gc_writel(struct pxa3xx_gcu_priv *priv, unsigned int off, unsigned long val)
127 { 125 {
128 __raw_writel(val, priv->mmio_base + off); 126 __raw_writel(val, priv->mmio_base + off);
129 } 127 }
130 128
131 #define QPRINT(priv, level, msg) \ 129 #define QPRINT(priv, level, msg) \
132 do { \ 130 do { \
133 struct timeval tv; \ 131 struct timeval tv; \
134 struct pxa3xx_gcu_shared *shared = priv->shared; \ 132 struct pxa3xx_gcu_shared *shared = priv->shared; \
135 u32 base = gc_readl(priv, REG_GCRBBR); \ 133 u32 base = gc_readl(priv, REG_GCRBBR); \
136 \ 134 \
137 do_gettimeofday(&tv); \ 135 do_gettimeofday(&tv); \
138 \ 136 \
139 printk(level "%ld.%03ld.%03ld - %-17s: %-21s (%s, " \ 137 printk(level "%ld.%03ld.%03ld - %-17s: %-21s (%s, " \
140 "STATUS " \ 138 "STATUS " \
141 "0x%02lx, B 0x%08lx [%ld], E %5ld, H %5ld, " \ 139 "0x%02lx, B 0x%08lx [%ld], E %5ld, H %5ld, " \
142 "T %5ld)\n", \ 140 "T %5ld)\n", \
143 tv.tv_sec - priv->base_time.tv_sec, \ 141 tv.tv_sec - priv->base_time.tv_sec, \
144 tv.tv_usec / 1000, tv.tv_usec % 1000, \ 142 tv.tv_usec / 1000, tv.tv_usec % 1000, \
145 __func__, msg, \ 143 __func__, msg, \
146 shared->hw_running ? "running" : " idle", \ 144 shared->hw_running ? "running" : " idle", \
147 gc_readl(priv, REG_GCISCR), \ 145 gc_readl(priv, REG_GCISCR), \
148 gc_readl(priv, REG_GCRBBR), \ 146 gc_readl(priv, REG_GCRBBR), \
149 gc_readl(priv, REG_GCRBLR), \ 147 gc_readl(priv, REG_GCRBLR), \
150 (gc_readl(priv, REG_GCRBEXHR) - base) / 4, \ 148 (gc_readl(priv, REG_GCRBEXHR) - base) / 4, \
151 (gc_readl(priv, REG_GCRBHR) - base) / 4, \ 149 (gc_readl(priv, REG_GCRBHR) - base) / 4, \
152 (gc_readl(priv, REG_GCRBTR) - base) / 4); \ 150 (gc_readl(priv, REG_GCRBTR) - base) / 4); \
153 } while (0) 151 } while (0)
154 152
155 static void 153 static void
156 pxa3xx_gcu_reset(struct pxa3xx_gcu_priv *priv) 154 pxa3xx_gcu_reset(struct pxa3xx_gcu_priv *priv)
157 { 155 {
158 QDUMP("RESET"); 156 QDUMP("RESET");
159 157
160 /* disable interrupts */ 158 /* disable interrupts */
161 gc_writel(priv, REG_GCIECR, 0); 159 gc_writel(priv, REG_GCIECR, 0);
162 160
163 /* reset hardware */ 161 /* reset hardware */
164 gc_writel(priv, REG_GCCR, GCCR_ABORT); 162 gc_writel(priv, REG_GCCR, GCCR_ABORT);
165 gc_writel(priv, REG_GCCR, 0); 163 gc_writel(priv, REG_GCCR, 0);
166 164
167 memset(priv->shared, 0, SHARED_SIZE); 165 memset(priv->shared, 0, SHARED_SIZE);
168 priv->shared->buffer_phys = priv->shared_phys; 166 priv->shared->buffer_phys = priv->shared_phys;
169 priv->shared->magic = PXA3XX_GCU_SHARED_MAGIC; 167 priv->shared->magic = PXA3XX_GCU_SHARED_MAGIC;
170 168
171 do_gettimeofday(&priv->base_time); 169 do_gettimeofday(&priv->base_time);
172 170
173 /* set up the ring buffer pointers */ 171 /* set up the ring buffer pointers */
174 gc_writel(priv, REG_GCRBLR, 0); 172 gc_writel(priv, REG_GCRBLR, 0);
175 gc_writel(priv, REG_GCRBBR, priv->shared_phys); 173 gc_writel(priv, REG_GCRBBR, priv->shared_phys);
176 gc_writel(priv, REG_GCRBTR, priv->shared_phys); 174 gc_writel(priv, REG_GCRBTR, priv->shared_phys);
177 175
178 /* enable all IRQs except EOB */ 176 /* enable all IRQs except EOB */
179 gc_writel(priv, REG_GCIECR, IE_ALL & ~IE_EOB); 177 gc_writel(priv, REG_GCIECR, IE_ALL & ~IE_EOB);
180 } 178 }
181 179
182 static void 180 static void
183 dump_whole_state(struct pxa3xx_gcu_priv *priv) 181 dump_whole_state(struct pxa3xx_gcu_priv *priv)
184 { 182 {
185 struct pxa3xx_gcu_shared *sh = priv->shared; 183 struct pxa3xx_gcu_shared *sh = priv->shared;
186 u32 base = gc_readl(priv, REG_GCRBBR); 184 u32 base = gc_readl(priv, REG_GCRBBR);
187 185
188 QDUMP("DUMP"); 186 QDUMP("DUMP");
189 187
190 printk(KERN_DEBUG "== PXA3XX-GCU DUMP ==\n" 188 printk(KERN_DEBUG "== PXA3XX-GCU DUMP ==\n"
191 "%s, STATUS 0x%02lx, B 0x%08lx [%ld], E %5ld, H %5ld, T %5ld\n", 189 "%s, STATUS 0x%02lx, B 0x%08lx [%ld], E %5ld, H %5ld, T %5ld\n",
192 sh->hw_running ? "running" : "idle ", 190 sh->hw_running ? "running" : "idle ",
193 gc_readl(priv, REG_GCISCR), 191 gc_readl(priv, REG_GCISCR),
194 gc_readl(priv, REG_GCRBBR), 192 gc_readl(priv, REG_GCRBBR),
195 gc_readl(priv, REG_GCRBLR), 193 gc_readl(priv, REG_GCRBLR),
196 (gc_readl(priv, REG_GCRBEXHR) - base) / 4, 194 (gc_readl(priv, REG_GCRBEXHR) - base) / 4,
197 (gc_readl(priv, REG_GCRBHR) - base) / 4, 195 (gc_readl(priv, REG_GCRBHR) - base) / 4,
198 (gc_readl(priv, REG_GCRBTR) - base) / 4); 196 (gc_readl(priv, REG_GCRBTR) - base) / 4);
199 } 197 }
200 198
201 static void 199 static void
202 flush_running(struct pxa3xx_gcu_priv *priv) 200 flush_running(struct pxa3xx_gcu_priv *priv)
203 { 201 {
204 struct pxa3xx_gcu_batch *running = priv->running; 202 struct pxa3xx_gcu_batch *running = priv->running;
205 struct pxa3xx_gcu_batch *next; 203 struct pxa3xx_gcu_batch *next;
206 204
207 while (running) { 205 while (running) {
208 next = running->next; 206 next = running->next;
209 running->next = priv->free; 207 running->next = priv->free;
210 priv->free = running; 208 priv->free = running;
211 running = next; 209 running = next;
212 } 210 }
213 211
214 priv->running = NULL; 212 priv->running = NULL;
215 } 213 }
216 214
217 static void 215 static void
218 run_ready(struct pxa3xx_gcu_priv *priv) 216 run_ready(struct pxa3xx_gcu_priv *priv)
219 { 217 {
220 unsigned int num = 0; 218 unsigned int num = 0;
221 struct pxa3xx_gcu_shared *shared = priv->shared; 219 struct pxa3xx_gcu_shared *shared = priv->shared;
222 struct pxa3xx_gcu_batch *ready = priv->ready; 220 struct pxa3xx_gcu_batch *ready = priv->ready;
223 221
224 QDUMP("Start"); 222 QDUMP("Start");
225 223
226 BUG_ON(!ready); 224 BUG_ON(!ready);
227 225
228 shared->buffer[num++] = 0x05000000; 226 shared->buffer[num++] = 0x05000000;
229 227
230 while (ready) { 228 while (ready) {
231 shared->buffer[num++] = 0x00000001; 229 shared->buffer[num++] = 0x00000001;
232 shared->buffer[num++] = ready->phys; 230 shared->buffer[num++] = ready->phys;
233 ready = ready->next; 231 ready = ready->next;
234 } 232 }
235 233
236 shared->buffer[num++] = 0x05000000; 234 shared->buffer[num++] = 0x05000000;
237 priv->running = priv->ready; 235 priv->running = priv->ready;
238 priv->ready = priv->ready_last = NULL; 236 priv->ready = priv->ready_last = NULL;
239 gc_writel(priv, REG_GCRBLR, 0); 237 gc_writel(priv, REG_GCRBLR, 0);
240 shared->hw_running = 1; 238 shared->hw_running = 1;
241 239
242 /* ring base address */ 240 /* ring base address */
243 gc_writel(priv, REG_GCRBBR, shared->buffer_phys); 241 gc_writel(priv, REG_GCRBBR, shared->buffer_phys);
244 242
245 /* ring tail address */ 243 /* ring tail address */
246 gc_writel(priv, REG_GCRBTR, shared->buffer_phys + num * 4); 244 gc_writel(priv, REG_GCRBTR, shared->buffer_phys + num * 4);
247 245
248 /* ring length */ 246 /* ring length */
249 gc_writel(priv, REG_GCRBLR, ((num + 63) & ~63) * 4); 247 gc_writel(priv, REG_GCRBLR, ((num + 63) & ~63) * 4);
250 } 248 }
251 249
252 static irqreturn_t 250 static irqreturn_t
253 pxa3xx_gcu_handle_irq(int irq, void *ctx) 251 pxa3xx_gcu_handle_irq(int irq, void *ctx)
254 { 252 {
255 struct pxa3xx_gcu_priv *priv = ctx; 253 struct pxa3xx_gcu_priv *priv = ctx;
256 struct pxa3xx_gcu_shared *shared = priv->shared; 254 struct pxa3xx_gcu_shared *shared = priv->shared;
257 u32 status = gc_readl(priv, REG_GCISCR) & IE_ALL; 255 u32 status = gc_readl(priv, REG_GCISCR) & IE_ALL;
258 256
259 QDUMP("-Interrupt"); 257 QDUMP("-Interrupt");
260 258
261 if (!status) 259 if (!status)
262 return IRQ_NONE; 260 return IRQ_NONE;
263 261
264 spin_lock(&priv->spinlock); 262 spin_lock(&priv->spinlock);
265 shared->num_interrupts++; 263 shared->num_interrupts++;
266 264
267 if (status & IE_EEOB) { 265 if (status & IE_EEOB) {
268 QDUMP(" [EEOB]"); 266 QDUMP(" [EEOB]");
269 267
270 flush_running(priv); 268 flush_running(priv);
271 wake_up_all(&priv->wait_free); 269 wake_up_all(&priv->wait_free);
272 270
273 if (priv->ready) { 271 if (priv->ready) {
274 run_ready(priv); 272 run_ready(priv);
275 } else { 273 } else {
276 /* There is no more data prepared by the userspace. 274 /* There is no more data prepared by the userspace.
277 * Set hw_running = 0 and wait for the next userspace 275 * Set hw_running = 0 and wait for the next userspace
278 * kick-off */ 276 * kick-off */
279 shared->num_idle++; 277 shared->num_idle++;
280 shared->hw_running = 0; 278 shared->hw_running = 0;
281 279
282 QDUMP(" '-> Idle."); 280 QDUMP(" '-> Idle.");
283 281
284 /* set ring buffer length to zero */ 282 /* set ring buffer length to zero */
285 gc_writel(priv, REG_GCRBLR, 0); 283 gc_writel(priv, REG_GCRBLR, 0);
286 284
287 wake_up_all(&priv->wait_idle); 285 wake_up_all(&priv->wait_idle);
288 } 286 }
289 287
290 shared->num_done++; 288 shared->num_done++;
291 } else { 289 } else {
292 QERROR(" [???]"); 290 QERROR(" [???]");
293 dump_whole_state(priv); 291 dump_whole_state(priv);
294 } 292 }
295 293
296 /* Clear the interrupt */ 294 /* Clear the interrupt */
297 gc_writel(priv, REG_GCISCR, status); 295 gc_writel(priv, REG_GCISCR, status);
298 spin_unlock(&priv->spinlock); 296 spin_unlock(&priv->spinlock);
299 297
300 return IRQ_HANDLED; 298 return IRQ_HANDLED;
301 } 299 }
302 300
303 static int 301 static int
304 pxa3xx_gcu_wait_idle(struct pxa3xx_gcu_priv *priv) 302 pxa3xx_gcu_wait_idle(struct pxa3xx_gcu_priv *priv)
305 { 303 {
306 int ret = 0; 304 int ret = 0;
307 305
308 QDUMP("Waiting for idle..."); 306 QDUMP("Waiting for idle...");
309 307
310 /* Does not need to be atomic. There's a lock in user space, 308 /* Does not need to be atomic. There's a lock in user space,
311 * but anyhow, this is just for statistics. */ 309 * but anyhow, this is just for statistics. */
312 priv->shared->num_wait_idle++; 310 priv->shared->num_wait_idle++;
313 311
314 while (priv->shared->hw_running) { 312 while (priv->shared->hw_running) {
315 int num = priv->shared->num_interrupts; 313 int num = priv->shared->num_interrupts;
316 u32 rbexhr = gc_readl(priv, REG_GCRBEXHR); 314 u32 rbexhr = gc_readl(priv, REG_GCRBEXHR);
317 315
318 ret = wait_event_interruptible_timeout(priv->wait_idle, 316 ret = wait_event_interruptible_timeout(priv->wait_idle,
319 !priv->shared->hw_running, HZ*4); 317 !priv->shared->hw_running, HZ*4);
320 318
321 if (ret < 0) 319 if (ret < 0)
322 break; 320 break;
323 321
324 if (ret > 0) 322 if (ret > 0)
325 continue; 323 continue;
326 324
327 if (gc_readl(priv, REG_GCRBEXHR) == rbexhr && 325 if (gc_readl(priv, REG_GCRBEXHR) == rbexhr &&
328 priv->shared->num_interrupts == num) { 326 priv->shared->num_interrupts == num) {
329 QERROR("TIMEOUT"); 327 QERROR("TIMEOUT");
330 ret = -ETIMEDOUT; 328 ret = -ETIMEDOUT;
331 break; 329 break;
332 } 330 }
333 } 331 }
334 332
335 QDUMP("done"); 333 QDUMP("done");
336 334
337 return ret; 335 return ret;
338 } 336 }
339 337
340 static int 338 static int
341 pxa3xx_gcu_wait_free(struct pxa3xx_gcu_priv *priv) 339 pxa3xx_gcu_wait_free(struct pxa3xx_gcu_priv *priv)
342 { 340 {
343 int ret = 0; 341 int ret = 0;
344 342
345 QDUMP("Waiting for free..."); 343 QDUMP("Waiting for free...");
346 344
347 /* Does not need to be atomic. There's a lock in user space, 345 /* Does not need to be atomic. There's a lock in user space,
348 * but anyhow, this is just for statistics. */ 346 * but anyhow, this is just for statistics. */
349 priv->shared->num_wait_free++; 347 priv->shared->num_wait_free++;
350 348
351 while (!priv->free) { 349 while (!priv->free) {
352 u32 rbexhr = gc_readl(priv, REG_GCRBEXHR); 350 u32 rbexhr = gc_readl(priv, REG_GCRBEXHR);
353 351
354 ret = wait_event_interruptible_timeout(priv->wait_free, 352 ret = wait_event_interruptible_timeout(priv->wait_free,
355 priv->free, HZ*4); 353 priv->free, HZ*4);
356 354
357 if (ret < 0) 355 if (ret < 0)
358 break; 356 break;
359 357
360 if (ret > 0) 358 if (ret > 0)
361 continue; 359 continue;
362 360
363 if (gc_readl(priv, REG_GCRBEXHR) == rbexhr) { 361 if (gc_readl(priv, REG_GCRBEXHR) == rbexhr) {
364 QERROR("TIMEOUT"); 362 QERROR("TIMEOUT");
365 ret = -ETIMEDOUT; 363 ret = -ETIMEDOUT;
366 break; 364 break;
367 } 365 }
368 } 366 }
369 367
370 QDUMP("done"); 368 QDUMP("done");
371 369
372 return ret; 370 return ret;
373 } 371 }
374 372
375 /* Misc device layer */ 373 /* Misc device layer */
376 374
377 static ssize_t 375 static ssize_t
378 pxa3xx_gcu_misc_write(struct file *filp, const char *buff, 376 pxa3xx_gcu_misc_write(struct file *filp, const char *buff,
379 size_t count, loff_t *offp) 377 size_t count, loff_t *offp)
380 { 378 {
381 int ret; 379 int ret;
382 unsigned long flags; 380 unsigned long flags;
383 struct pxa3xx_gcu_batch *buffer; 381 struct pxa3xx_gcu_batch *buffer;
384 struct pxa3xx_gcu_priv *priv = 382 struct pxa3xx_gcu_priv *priv =
385 container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops); 383 container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops);
386 384
387 int words = count / 4; 385 int words = count / 4;
388 386
389 /* Does not need to be atomic. There's a lock in user space, 387 /* Does not need to be atomic. There's a lock in user space,
390 * but anyhow, this is just for statistics. */ 388 * but anyhow, this is just for statistics. */
391 priv->shared->num_writes++; 389 priv->shared->num_writes++;
392 390
393 priv->shared->num_words += words; 391 priv->shared->num_words += words;
394 392
395 /* Last word reserved for batch buffer end command */ 393 /* Last word reserved for batch buffer end command */
396 if (words >= PXA3XX_GCU_BATCH_WORDS) 394 if (words >= PXA3XX_GCU_BATCH_WORDS)
397 return -E2BIG; 395 return -E2BIG;
398 396
399 /* Wait for a free buffer */ 397 /* Wait for a free buffer */
400 if (!priv->free) { 398 if (!priv->free) {
401 ret = pxa3xx_gcu_wait_free(priv); 399 ret = pxa3xx_gcu_wait_free(priv);
402 if (ret < 0) 400 if (ret < 0)
403 return ret; 401 return ret;
404 } 402 }
405 403
406 /* 404 /*
407 * Get buffer from free list 405 * Get buffer from free list
408 */ 406 */
409 spin_lock_irqsave(&priv->spinlock, flags); 407 spin_lock_irqsave(&priv->spinlock, flags);
410 408
411 buffer = priv->free; 409 buffer = priv->free;
412 priv->free = buffer->next; 410 priv->free = buffer->next;
413 411
414 spin_unlock_irqrestore(&priv->spinlock, flags); 412 spin_unlock_irqrestore(&priv->spinlock, flags);
415 413
416 414
417 /* Copy data from user into buffer */ 415 /* Copy data from user into buffer */
418 ret = copy_from_user(buffer->ptr, buff, words * 4); 416 ret = copy_from_user(buffer->ptr, buff, words * 4);
419 if (ret) { 417 if (ret) {
420 spin_lock_irqsave(&priv->spinlock, flags); 418 spin_lock_irqsave(&priv->spinlock, flags);
421 buffer->next = priv->free; 419 buffer->next = priv->free;
422 priv->free = buffer; 420 priv->free = buffer;
423 spin_unlock_irqrestore(&priv->spinlock, flags); 421 spin_unlock_irqrestore(&priv->spinlock, flags);
424 return -EFAULT; 422 return -EFAULT;
425 } 423 }
426 424
427 buffer->length = words; 425 buffer->length = words;
428 426
429 /* Append batch buffer end command */ 427 /* Append batch buffer end command */
430 buffer->ptr[words] = 0x01000000; 428 buffer->ptr[words] = 0x01000000;
431 429
432 /* 430 /*
433 * Add buffer to ready list 431 * Add buffer to ready list
434 */ 432 */
435 spin_lock_irqsave(&priv->spinlock, flags); 433 spin_lock_irqsave(&priv->spinlock, flags);
436 434
437 buffer->next = NULL; 435 buffer->next = NULL;
438 436
439 if (priv->ready) { 437 if (priv->ready) {
440 BUG_ON(priv->ready_last == NULL); 438 BUG_ON(priv->ready_last == NULL);
441 439
442 priv->ready_last->next = buffer; 440 priv->ready_last->next = buffer;
443 } else 441 } else
444 priv->ready = buffer; 442 priv->ready = buffer;
445 443
446 priv->ready_last = buffer; 444 priv->ready_last = buffer;
447 445
448 if (!priv->shared->hw_running) 446 if (!priv->shared->hw_running)
449 run_ready(priv); 447 run_ready(priv);
450 448
451 spin_unlock_irqrestore(&priv->spinlock, flags); 449 spin_unlock_irqrestore(&priv->spinlock, flags);
452 450
453 return words * 4; 451 return words * 4;
454 } 452 }
455 453
456 454
457 static long 455 static long
458 pxa3xx_gcu_misc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 456 pxa3xx_gcu_misc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
459 { 457 {
460 unsigned long flags; 458 unsigned long flags;
461 struct pxa3xx_gcu_priv *priv = 459 struct pxa3xx_gcu_priv *priv =
462 container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops); 460 container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops);
463 461
464 switch (cmd) { 462 switch (cmd) {
465 case PXA3XX_GCU_IOCTL_RESET: 463 case PXA3XX_GCU_IOCTL_RESET:
466 spin_lock_irqsave(&priv->spinlock, flags); 464 spin_lock_irqsave(&priv->spinlock, flags);
467 pxa3xx_gcu_reset(priv); 465 pxa3xx_gcu_reset(priv);
468 spin_unlock_irqrestore(&priv->spinlock, flags); 466 spin_unlock_irqrestore(&priv->spinlock, flags);
469 return 0; 467 return 0;
470 468
471 case PXA3XX_GCU_IOCTL_WAIT_IDLE: 469 case PXA3XX_GCU_IOCTL_WAIT_IDLE:
472 return pxa3xx_gcu_wait_idle(priv); 470 return pxa3xx_gcu_wait_idle(priv);
473 } 471 }
474 472
475 return -ENOSYS; 473 return -ENOSYS;
476 } 474 }
477 475
478 static int 476 static int
479 pxa3xx_gcu_misc_mmap(struct file *filp, struct vm_area_struct *vma) 477 pxa3xx_gcu_misc_mmap(struct file *filp, struct vm_area_struct *vma)
480 { 478 {
481 unsigned int size = vma->vm_end - vma->vm_start; 479 unsigned int size = vma->vm_end - vma->vm_start;
482 struct pxa3xx_gcu_priv *priv = 480 struct pxa3xx_gcu_priv *priv =
483 container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops); 481 container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops);
484 482
485 switch (vma->vm_pgoff) { 483 switch (vma->vm_pgoff) {
486 case 0: 484 case 0:
487 /* hand out the shared data area */ 485 /* hand out the shared data area */
488 if (size != SHARED_SIZE) 486 if (size != SHARED_SIZE)
489 return -EINVAL; 487 return -EINVAL;
490 488
491 return dma_mmap_coherent(NULL, vma, 489 return dma_mmap_coherent(NULL, vma,
492 priv->shared, priv->shared_phys, size); 490 priv->shared, priv->shared_phys, size);
493 491
494 case SHARED_SIZE >> PAGE_SHIFT: 492 case SHARED_SIZE >> PAGE_SHIFT:
495 /* hand out the MMIO base for direct register access 493 /* hand out the MMIO base for direct register access
496 * from userspace */ 494 * from userspace */
497 if (size != resource_size(priv->resource_mem)) 495 if (size != resource_size(priv->resource_mem))
498 return -EINVAL; 496 return -EINVAL;
499 497
500 vma->vm_flags |= VM_IO; 498 vma->vm_flags |= VM_IO;
501 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 499 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
502 500
503 return io_remap_pfn_range(vma, vma->vm_start, 501 return io_remap_pfn_range(vma, vma->vm_start,
504 priv->resource_mem->start >> PAGE_SHIFT, 502 priv->resource_mem->start >> PAGE_SHIFT,
505 size, vma->vm_page_prot); 503 size, vma->vm_page_prot);
506 } 504 }
507 505
508 return -EINVAL; 506 return -EINVAL;
509 } 507 }
510 508
511 509
512 #ifdef PXA3XX_GCU_DEBUG_TIMER 510 #ifdef PXA3XX_GCU_DEBUG_TIMER
513 static struct timer_list pxa3xx_gcu_debug_timer; 511 static struct timer_list pxa3xx_gcu_debug_timer;
514 512
515 static void pxa3xx_gcu_debug_timedout(unsigned long ptr) 513 static void pxa3xx_gcu_debug_timedout(unsigned long ptr)
516 { 514 {
517 struct pxa3xx_gcu_priv *priv = (struct pxa3xx_gcu_priv *) ptr; 515 struct pxa3xx_gcu_priv *priv = (struct pxa3xx_gcu_priv *) ptr;
518 516
519 QERROR("Timer DUMP"); 517 QERROR("Timer DUMP");
520 518
521 /* init the timer structure */ 519 /* init the timer structure */
522 init_timer(&pxa3xx_gcu_debug_timer); 520 init_timer(&pxa3xx_gcu_debug_timer);
523 pxa3xx_gcu_debug_timer.function = pxa3xx_gcu_debug_timedout; 521 pxa3xx_gcu_debug_timer.function = pxa3xx_gcu_debug_timedout;
524 pxa3xx_gcu_debug_timer.data = ptr; 522 pxa3xx_gcu_debug_timer.data = ptr;
525 pxa3xx_gcu_debug_timer.expires = jiffies + 5*HZ; /* one second */ 523 pxa3xx_gcu_debug_timer.expires = jiffies + 5*HZ; /* one second */
526 524
527 add_timer(&pxa3xx_gcu_debug_timer); 525 add_timer(&pxa3xx_gcu_debug_timer);
528 } 526 }
529 527
530 static void pxa3xx_gcu_init_debug_timer(void) 528 static void pxa3xx_gcu_init_debug_timer(void)
531 { 529 {
532 pxa3xx_gcu_debug_timedout((unsigned long) &pxa3xx_gcu_debug_timer); 530 pxa3xx_gcu_debug_timedout((unsigned long) &pxa3xx_gcu_debug_timer);
533 } 531 }
534 #else 532 #else
535 static inline void pxa3xx_gcu_init_debug_timer(void) {} 533 static inline void pxa3xx_gcu_init_debug_timer(void) {}
536 #endif 534 #endif
537 535
538 static int 536 static int
539 add_buffer(struct platform_device *dev, 537 add_buffer(struct platform_device *dev,
540 struct pxa3xx_gcu_priv *priv) 538 struct pxa3xx_gcu_priv *priv)
541 { 539 {
542 struct pxa3xx_gcu_batch *buffer; 540 struct pxa3xx_gcu_batch *buffer;
543 541
544 buffer = kzalloc(sizeof(struct pxa3xx_gcu_batch), GFP_KERNEL); 542 buffer = kzalloc(sizeof(struct pxa3xx_gcu_batch), GFP_KERNEL);
545 if (!buffer) 543 if (!buffer)
546 return -ENOMEM; 544 return -ENOMEM;
547 545
548 buffer->ptr = dma_alloc_coherent(&dev->dev, PXA3XX_GCU_BATCH_WORDS * 4, 546 buffer->ptr = dma_alloc_coherent(&dev->dev, PXA3XX_GCU_BATCH_WORDS * 4,
549 &buffer->phys, GFP_KERNEL); 547 &buffer->phys, GFP_KERNEL);
550 if (!buffer->ptr) { 548 if (!buffer->ptr) {
551 kfree(buffer); 549 kfree(buffer);
552 return -ENOMEM; 550 return -ENOMEM;
553 } 551 }
554 552
555 buffer->next = priv->free; 553 buffer->next = priv->free;
556 554
557 priv->free = buffer; 555 priv->free = buffer;
558 556
559 return 0; 557 return 0;
560 } 558 }
561 559
562 static void 560 static void
563 free_buffers(struct platform_device *dev, 561 free_buffers(struct platform_device *dev,
564 struct pxa3xx_gcu_priv *priv) 562 struct pxa3xx_gcu_priv *priv)
565 { 563 {
566 struct pxa3xx_gcu_batch *next, *buffer = priv->free; 564 struct pxa3xx_gcu_batch *next, *buffer = priv->free;
567 565
568 while (buffer) { 566 while (buffer) {
569 next = buffer->next; 567 next = buffer->next;
570 568
571 dma_free_coherent(&dev->dev, PXA3XX_GCU_BATCH_WORDS * 4, 569 dma_free_coherent(&dev->dev, PXA3XX_GCU_BATCH_WORDS * 4,
572 buffer->ptr, buffer->phys); 570 buffer->ptr, buffer->phys);
573 571
574 kfree(buffer); 572 kfree(buffer);
575 573
576 buffer = next; 574 buffer = next;
577 } 575 }
578 576
579 priv->free = NULL; 577 priv->free = NULL;
580 } 578 }
581 579
582 static int __devinit 580 static int __devinit
583 pxa3xx_gcu_probe(struct platform_device *dev) 581 pxa3xx_gcu_probe(struct platform_device *dev)
584 { 582 {
585 int i, ret, irq; 583 int i, ret, irq;
586 struct resource *r; 584 struct resource *r;
587 struct pxa3xx_gcu_priv *priv; 585 struct pxa3xx_gcu_priv *priv;
588 586
589 priv = kzalloc(sizeof(struct pxa3xx_gcu_priv), GFP_KERNEL); 587 priv = kzalloc(sizeof(struct pxa3xx_gcu_priv), GFP_KERNEL);
590 if (!priv) 588 if (!priv)
591 return -ENOMEM; 589 return -ENOMEM;
592 590
593 for (i = 0; i < 8; i++) { 591 for (i = 0; i < 8; i++) {
594 ret = add_buffer(dev, priv); 592 ret = add_buffer(dev, priv);
595 if (ret) { 593 if (ret) {
596 dev_err(&dev->dev, "failed to allocate DMA memory\n"); 594 dev_err(&dev->dev, "failed to allocate DMA memory\n");
597 goto err_free_priv; 595 goto err_free_priv;
598 } 596 }
599 } 597 }
600 598
601 init_waitqueue_head(&priv->wait_idle); 599 init_waitqueue_head(&priv->wait_idle);
602 init_waitqueue_head(&priv->wait_free); 600 init_waitqueue_head(&priv->wait_free);
603 spin_lock_init(&priv->spinlock); 601 spin_lock_init(&priv->spinlock);
604 602
605 /* we allocate the misc device structure as part of our own allocation, 603 /* we allocate the misc device structure as part of our own allocation,
606 * so we can get a pointer to our priv structure later on with 604 * so we can get a pointer to our priv structure later on with
607 * container_of(). This isn't really necessary as we have a fixed minor 605 * container_of(). This isn't really necessary as we have a fixed minor
608 * number anyway, but this is to avoid statics. */ 606 * number anyway, but this is to avoid statics. */
609 607
610 priv->misc_fops.owner = THIS_MODULE; 608 priv->misc_fops.owner = THIS_MODULE;
611 priv->misc_fops.write = pxa3xx_gcu_misc_write; 609 priv->misc_fops.write = pxa3xx_gcu_misc_write;
612 priv->misc_fops.unlocked_ioctl = pxa3xx_gcu_misc_ioctl; 610 priv->misc_fops.unlocked_ioctl = pxa3xx_gcu_misc_ioctl;
613 priv->misc_fops.mmap = pxa3xx_gcu_misc_mmap; 611 priv->misc_fops.mmap = pxa3xx_gcu_misc_mmap;
614 612
615 priv->misc_dev.minor = MISCDEV_MINOR, 613 priv->misc_dev.minor = MISCDEV_MINOR,
616 priv->misc_dev.name = DRV_NAME, 614 priv->misc_dev.name = DRV_NAME,
617 priv->misc_dev.fops = &priv->misc_fops, 615 priv->misc_dev.fops = &priv->misc_fops,
618 616
619 /* register misc device */ 617 /* register misc device */
620 ret = misc_register(&priv->misc_dev); 618 ret = misc_register(&priv->misc_dev);
621 if (ret < 0) { 619 if (ret < 0) {
622 dev_err(&dev->dev, "misc_register() for minor %d failed\n", 620 dev_err(&dev->dev, "misc_register() for minor %d failed\n",
623 MISCDEV_MINOR); 621 MISCDEV_MINOR);
624 goto err_free_priv; 622 goto err_free_priv;
625 } 623 }
626 624
627 /* handle IO resources */ 625 /* handle IO resources */
628 r = platform_get_resource(dev, IORESOURCE_MEM, 0); 626 r = platform_get_resource(dev, IORESOURCE_MEM, 0);
629 if (r == NULL) { 627 if (r == NULL) {
630 dev_err(&dev->dev, "no I/O memory resource defined\n"); 628 dev_err(&dev->dev, "no I/O memory resource defined\n");
631 ret = -ENODEV; 629 ret = -ENODEV;
632 goto err_misc_deregister; 630 goto err_misc_deregister;
633 } 631 }
634 632
635 if (!request_mem_region(r->start, resource_size(r), dev->name)) { 633 if (!request_mem_region(r->start, resource_size(r), dev->name)) {
636 dev_err(&dev->dev, "failed to request I/O memory\n"); 634 dev_err(&dev->dev, "failed to request I/O memory\n");
637 ret = -EBUSY; 635 ret = -EBUSY;
638 goto err_misc_deregister; 636 goto err_misc_deregister;
639 } 637 }
640 638
641 priv->mmio_base = ioremap_nocache(r->start, resource_size(r)); 639 priv->mmio_base = ioremap_nocache(r->start, resource_size(r));
642 if (!priv->mmio_base) { 640 if (!priv->mmio_base) {
643 dev_err(&dev->dev, "failed to map I/O memory\n"); 641 dev_err(&dev->dev, "failed to map I/O memory\n");
644 ret = -EBUSY; 642 ret = -EBUSY;
645 goto err_free_mem_region; 643 goto err_free_mem_region;
646 } 644 }
647 645
648 /* allocate dma memory */ 646 /* allocate dma memory */
649 priv->shared = dma_alloc_coherent(&dev->dev, SHARED_SIZE, 647 priv->shared = dma_alloc_coherent(&dev->dev, SHARED_SIZE,
650 &priv->shared_phys, GFP_KERNEL); 648 &priv->shared_phys, GFP_KERNEL);
651 649
652 if (!priv->shared) { 650 if (!priv->shared) {
653 dev_err(&dev->dev, "failed to allocate DMA memory\n"); 651 dev_err(&dev->dev, "failed to allocate DMA memory\n");
654 ret = -ENOMEM; 652 ret = -ENOMEM;
655 goto err_free_io; 653 goto err_free_io;
656 } 654 }
657 655
658 /* enable the clock */ 656 /* enable the clock */
659 priv->clk = clk_get(&dev->dev, NULL); 657 priv->clk = clk_get(&dev->dev, NULL);
660 if (IS_ERR(priv->clk)) { 658 if (IS_ERR(priv->clk)) {
661 dev_err(&dev->dev, "failed to get clock\n"); 659 dev_err(&dev->dev, "failed to get clock\n");
662 ret = -ENODEV; 660 ret = -ENODEV;
663 goto err_free_dma; 661 goto err_free_dma;
664 } 662 }
665 663
666 ret = clk_enable(priv->clk); 664 ret = clk_enable(priv->clk);
667 if (ret < 0) { 665 if (ret < 0) {
668 dev_err(&dev->dev, "failed to enable clock\n"); 666 dev_err(&dev->dev, "failed to enable clock\n");
669 goto err_put_clk; 667 goto err_put_clk;
670 } 668 }
671 669
672 /* request the IRQ */ 670 /* request the IRQ */
673 irq = platform_get_irq(dev, 0); 671 irq = platform_get_irq(dev, 0);
674 if (irq < 0) { 672 if (irq < 0) {
675 dev_err(&dev->dev, "no IRQ defined\n"); 673 dev_err(&dev->dev, "no IRQ defined\n");
676 ret = -ENODEV; 674 ret = -ENODEV;
677 goto err_put_clk; 675 goto err_put_clk;
678 } 676 }
679 677
680 ret = request_irq(irq, pxa3xx_gcu_handle_irq, 678 ret = request_irq(irq, pxa3xx_gcu_handle_irq,
681 IRQF_DISABLED, DRV_NAME, priv); 679 IRQF_DISABLED, DRV_NAME, priv);
682 if (ret) { 680 if (ret) {
683 dev_err(&dev->dev, "request_irq failed\n"); 681 dev_err(&dev->dev, "request_irq failed\n");
684 ret = -EBUSY; 682 ret = -EBUSY;
685 goto err_put_clk; 683 goto err_put_clk;
686 } 684 }
687 685
688 platform_set_drvdata(dev, priv); 686 platform_set_drvdata(dev, priv);
689 priv->resource_mem = r; 687 priv->resource_mem = r;
690 pxa3xx_gcu_reset(priv); 688 pxa3xx_gcu_reset(priv);
691 pxa3xx_gcu_init_debug_timer(); 689 pxa3xx_gcu_init_debug_timer();
692 690
693 dev_info(&dev->dev, "registered @0x%p, DMA 0x%p (%d bytes), IRQ %d\n", 691 dev_info(&dev->dev, "registered @0x%p, DMA 0x%p (%d bytes), IRQ %d\n",
694 (void *) r->start, (void *) priv->shared_phys, 692 (void *) r->start, (void *) priv->shared_phys,
695 SHARED_SIZE, irq); 693 SHARED_SIZE, irq);
696 return 0; 694 return 0;
697 695
698 err_put_clk: 696 err_put_clk:
699 clk_disable(priv->clk); 697 clk_disable(priv->clk);
700 clk_put(priv->clk); 698 clk_put(priv->clk);
701 699
702 err_free_dma: 700 err_free_dma:
703 dma_free_coherent(&dev->dev, SHARED_SIZE, 701 dma_free_coherent(&dev->dev, SHARED_SIZE,
704 priv->shared, priv->shared_phys); 702 priv->shared, priv->shared_phys);
705 703
706 err_free_io: 704 err_free_io:
707 iounmap(priv->mmio_base); 705 iounmap(priv->mmio_base);
708 706
709 err_free_mem_region: 707 err_free_mem_region:
710 release_mem_region(r->start, resource_size(r)); 708 release_mem_region(r->start, resource_size(r));
711 709
712 err_misc_deregister: 710 err_misc_deregister:
713 misc_deregister(&priv->misc_dev); 711 misc_deregister(&priv->misc_dev);
714 712
715 err_free_priv: 713 err_free_priv:
716 platform_set_drvdata(dev, NULL); 714 platform_set_drvdata(dev, NULL);
717 free_buffers(dev, priv); 715 free_buffers(dev, priv);
718 kfree(priv); 716 kfree(priv);
719 return ret; 717 return ret;
720 } 718 }
721 719
722 static int __devexit 720 static int __devexit
723 pxa3xx_gcu_remove(struct platform_device *dev) 721 pxa3xx_gcu_remove(struct platform_device *dev)
724 { 722 {
725 struct pxa3xx_gcu_priv *priv = platform_get_drvdata(dev); 723 struct pxa3xx_gcu_priv *priv = platform_get_drvdata(dev);
726 struct resource *r = priv->resource_mem; 724 struct resource *r = priv->resource_mem;
727 725
728 pxa3xx_gcu_wait_idle(priv); 726 pxa3xx_gcu_wait_idle(priv);
729 727
730 misc_deregister(&priv->misc_dev); 728 misc_deregister(&priv->misc_dev);
731 dma_free_coherent(&dev->dev, SHARED_SIZE, 729 dma_free_coherent(&dev->dev, SHARED_SIZE,
732 priv->shared, priv->shared_phys); 730 priv->shared, priv->shared_phys);
733 iounmap(priv->mmio_base); 731 iounmap(priv->mmio_base);
734 release_mem_region(r->start, resource_size(r)); 732 release_mem_region(r->start, resource_size(r));
735 platform_set_drvdata(dev, NULL); 733 platform_set_drvdata(dev, NULL);
736 clk_disable(priv->clk); 734 clk_disable(priv->clk);
737 free_buffers(dev, priv); 735 free_buffers(dev, priv);
738 kfree(priv); 736 kfree(priv);
739 737
740 return 0; 738 return 0;
741 } 739 }
742 740
743 static struct platform_driver pxa3xx_gcu_driver = { 741 static struct platform_driver pxa3xx_gcu_driver = {
744 .probe = pxa3xx_gcu_probe, 742 .probe = pxa3xx_gcu_probe,
745 .remove = __devexit_p(pxa3xx_gcu_remove), 743 .remove = __devexit_p(pxa3xx_gcu_remove),
746 .driver = { 744 .driver = {
747 .owner = THIS_MODULE, 745 .owner = THIS_MODULE,
748 .name = DRV_NAME, 746 .name = DRV_NAME,
749 }, 747 },
750 }; 748 };
751 749
752 static int __init 750 static int __init
753 pxa3xx_gcu_init(void) 751 pxa3xx_gcu_init(void)
754 { 752 {
755 return platform_driver_register(&pxa3xx_gcu_driver); 753 return platform_driver_register(&pxa3xx_gcu_driver);
756 } 754 }
757 755
758 static void __exit 756 static void __exit
759 pxa3xx_gcu_exit(void) 757 pxa3xx_gcu_exit(void)
760 { 758 {
761 platform_driver_unregister(&pxa3xx_gcu_driver); 759 platform_driver_unregister(&pxa3xx_gcu_driver);
762 } 760 }
763 761
764 module_init(pxa3xx_gcu_init); 762 module_init(pxa3xx_gcu_init);
765 module_exit(pxa3xx_gcu_exit); 763 module_exit(pxa3xx_gcu_exit);
766 764
767 MODULE_DESCRIPTION("PXA3xx graphics controller unit driver"); 765 MODULE_DESCRIPTION("PXA3xx graphics controller unit driver");
768 MODULE_LICENSE("GPL"); 766 MODULE_LICENSE("GPL");
769 MODULE_ALIAS_MISCDEV(MISCDEV_MINOR); 767 MODULE_ALIAS_MISCDEV(MISCDEV_MINOR);
770 MODULE_AUTHOR("Janine Kropp <nin@directfb.org>, " 768 MODULE_AUTHOR("Janine Kropp <nin@directfb.org>, "
771 "Denis Oliver Kropp <dok@directfb.org>, " 769 "Denis Oliver Kropp <dok@directfb.org>, "
772 "Daniel Mack <daniel@caiaq.de>"); 770 "Daniel Mack <daniel@caiaq.de>");
773 771
drivers/video/xilinxfb.c
1 /* 1 /*
2 * Xilinx TFT frame buffer driver 2 * Xilinx TFT frame buffer driver
3 * 3 *
4 * Author: MontaVista Software, Inc. 4 * Author: MontaVista Software, Inc.
5 * source@mvista.com 5 * source@mvista.com
6 * 6 *
7 * 2002-2007 (c) MontaVista Software, Inc. 7 * 2002-2007 (c) MontaVista Software, Inc.
8 * 2007 (c) Secret Lab Technologies, Ltd. 8 * 2007 (c) Secret Lab Technologies, Ltd.
9 * 2009 (c) Xilinx Inc. 9 * 2009 (c) Xilinx Inc.
10 * 10 *
11 * This file is licensed under the terms of the GNU General Public License 11 * This file is licensed under the terms of the GNU General Public License
12 * version 2. This program is licensed "as is" without any warranty of any 12 * version 2. This program is licensed "as is" without any warranty of any
13 * kind, whether express or implied. 13 * kind, whether express or implied.
14 */ 14 */
15 15
16 /* 16 /*
17 * This driver was based on au1100fb.c by MontaVista rewritten for 2.6 17 * This driver was based on au1100fb.c by MontaVista rewritten for 2.6
18 * by Embedded Alley Solutions <source@embeddedalley.com>, which in turn 18 * by Embedded Alley Solutions <source@embeddedalley.com>, which in turn
19 * was based on skeletonfb.c, Skeleton for a frame buffer device by 19 * was based on skeletonfb.c, Skeleton for a frame buffer device by
20 * Geert Uytterhoeven. 20 * Geert Uytterhoeven.
21 */ 21 */
22 22
23 #include <linux/device.h> 23 #include <linux/device.h>
24 #include <linux/module.h> 24 #include <linux/module.h>
25 #include <linux/kernel.h> 25 #include <linux/kernel.h>
26 #include <linux/version.h>
27 #include <linux/errno.h> 26 #include <linux/errno.h>
28 #include <linux/string.h> 27 #include <linux/string.h>
29 #include <linux/mm.h> 28 #include <linux/mm.h>
30 #include <linux/fb.h> 29 #include <linux/fb.h>
31 #include <linux/init.h> 30 #include <linux/init.h>
32 #include <linux/dma-mapping.h> 31 #include <linux/dma-mapping.h>
33 #include <linux/of_device.h> 32 #include <linux/of_device.h>
34 #include <linux/of_platform.h> 33 #include <linux/of_platform.h>
35 #include <linux/of_address.h> 34 #include <linux/of_address.h>
36 #include <linux/io.h> 35 #include <linux/io.h>
37 #include <linux/xilinxfb.h> 36 #include <linux/xilinxfb.h>
38 #include <linux/slab.h> 37 #include <linux/slab.h>
39 38
40 #ifdef CONFIG_PPC_DCR 39 #ifdef CONFIG_PPC_DCR
41 #include <asm/dcr.h> 40 #include <asm/dcr.h>
42 #endif 41 #endif
43 42
44 #define DRIVER_NAME "xilinxfb" 43 #define DRIVER_NAME "xilinxfb"
45 44
46 45
47 /* 46 /*
48 * Xilinx calls it "PLB TFT LCD Controller" though it can also be used for 47 * Xilinx calls it "PLB TFT LCD Controller" though it can also be used for
49 * the VGA port on the Xilinx ML40x board. This is a hardware display 48 * the VGA port on the Xilinx ML40x board. This is a hardware display
50 * controller for a 640x480 resolution TFT or VGA screen. 49 * controller for a 640x480 resolution TFT or VGA screen.
51 * 50 *
52 * The interface to the framebuffer is nice and simple. There are two 51 * The interface to the framebuffer is nice and simple. There are two
53 * control registers. The first tells the LCD interface where in memory 52 * control registers. The first tells the LCD interface where in memory
54 * the frame buffer is (only the 11 most significant bits are used, so 53 * the frame buffer is (only the 11 most significant bits are used, so
55 * don't start thinking about scrolling). The second allows the LCD to 54 * don't start thinking about scrolling). The second allows the LCD to
56 * be turned on or off as well as rotated 180 degrees. 55 * be turned on or off as well as rotated 180 degrees.
57 * 56 *
58 * In case of direct PLB access the second control register will be at 57 * In case of direct PLB access the second control register will be at
59 * an offset of 4 as compared to the DCR access where the offset is 1 58 * an offset of 4 as compared to the DCR access where the offset is 1
60 * i.e. REG_CTRL. So this is taken care in the function 59 * i.e. REG_CTRL. So this is taken care in the function
61 * xilinx_fb_out_be32 where it left shifts the offset 2 times in case of 60 * xilinx_fb_out_be32 where it left shifts the offset 2 times in case of
62 * direct PLB access. 61 * direct PLB access.
63 */ 62 */
64 #define NUM_REGS 2 63 #define NUM_REGS 2
65 #define REG_FB_ADDR 0 64 #define REG_FB_ADDR 0
66 #define REG_CTRL 1 65 #define REG_CTRL 1
67 #define REG_CTRL_ENABLE 0x0001 66 #define REG_CTRL_ENABLE 0x0001
68 #define REG_CTRL_ROTATE 0x0002 67 #define REG_CTRL_ROTATE 0x0002
69 68
70 /* 69 /*
71 * The hardware only handles a single mode: 640x480 24 bit true 70 * The hardware only handles a single mode: 640x480 24 bit true
72 * color. Each pixel gets a word (32 bits) of memory. Within each word, 71 * color. Each pixel gets a word (32 bits) of memory. Within each word,
73 * the 8 most significant bits are ignored, the next 8 bits are the red 72 * the 8 most significant bits are ignored, the next 8 bits are the red
74 * level, the next 8 bits are the green level and the 8 least 73 * level, the next 8 bits are the green level and the 8 least
75 * significant bits are the blue level. Each row of the LCD uses 1024 74 * significant bits are the blue level. Each row of the LCD uses 1024
76 * words, but only the first 640 pixels are displayed with the other 384 75 * words, but only the first 640 pixels are displayed with the other 384
77 * words being ignored. There are 480 rows. 76 * words being ignored. There are 480 rows.
78 */ 77 */
79 #define BYTES_PER_PIXEL 4 78 #define BYTES_PER_PIXEL 4
80 #define BITS_PER_PIXEL (BYTES_PER_PIXEL * 8) 79 #define BITS_PER_PIXEL (BYTES_PER_PIXEL * 8)
81 80
82 #define RED_SHIFT 16 81 #define RED_SHIFT 16
83 #define GREEN_SHIFT 8 82 #define GREEN_SHIFT 8
84 #define BLUE_SHIFT 0 83 #define BLUE_SHIFT 0
85 84
86 #define PALETTE_ENTRIES_NO 16 /* passed to fb_alloc_cmap() */ 85 #define PALETTE_ENTRIES_NO 16 /* passed to fb_alloc_cmap() */
87 86
88 /* 87 /*
89 * Default xilinxfb configuration 88 * Default xilinxfb configuration
90 */ 89 */
91 static struct xilinxfb_platform_data xilinx_fb_default_pdata = { 90 static struct xilinxfb_platform_data xilinx_fb_default_pdata = {
92 .xres = 640, 91 .xres = 640,
93 .yres = 480, 92 .yres = 480,
94 .xvirt = 1024, 93 .xvirt = 1024,
95 .yvirt = 480, 94 .yvirt = 480,
96 }; 95 };
97 96
98 /* 97 /*
99 * Here are the default fb_fix_screeninfo and fb_var_screeninfo structures 98 * Here are the default fb_fix_screeninfo and fb_var_screeninfo structures
100 */ 99 */
101 static struct fb_fix_screeninfo xilinx_fb_fix = { 100 static struct fb_fix_screeninfo xilinx_fb_fix = {
102 .id = "Xilinx", 101 .id = "Xilinx",
103 .type = FB_TYPE_PACKED_PIXELS, 102 .type = FB_TYPE_PACKED_PIXELS,
104 .visual = FB_VISUAL_TRUECOLOR, 103 .visual = FB_VISUAL_TRUECOLOR,
105 .accel = FB_ACCEL_NONE 104 .accel = FB_ACCEL_NONE
106 }; 105 };
107 106
108 static struct fb_var_screeninfo xilinx_fb_var = { 107 static struct fb_var_screeninfo xilinx_fb_var = {
109 .bits_per_pixel = BITS_PER_PIXEL, 108 .bits_per_pixel = BITS_PER_PIXEL,
110 109
111 .red = { RED_SHIFT, 8, 0 }, 110 .red = { RED_SHIFT, 8, 0 },
112 .green = { GREEN_SHIFT, 8, 0 }, 111 .green = { GREEN_SHIFT, 8, 0 },
113 .blue = { BLUE_SHIFT, 8, 0 }, 112 .blue = { BLUE_SHIFT, 8, 0 },
114 .transp = { 0, 0, 0 }, 113 .transp = { 0, 0, 0 },
115 114
116 .activate = FB_ACTIVATE_NOW 115 .activate = FB_ACTIVATE_NOW
117 }; 116 };
118 117
119 118
120 #define PLB_ACCESS_FLAG 0x1 /* 1 = PLB, 0 = DCR */ 119 #define PLB_ACCESS_FLAG 0x1 /* 1 = PLB, 0 = DCR */
121 120
122 struct xilinxfb_drvdata { 121 struct xilinxfb_drvdata {
123 122
124 struct fb_info info; /* FB driver info record */ 123 struct fb_info info; /* FB driver info record */
125 124
126 phys_addr_t regs_phys; /* phys. address of the control 125 phys_addr_t regs_phys; /* phys. address of the control
127 registers */ 126 registers */
128 void __iomem *regs; /* virt. address of the control 127 void __iomem *regs; /* virt. address of the control
129 registers */ 128 registers */
130 #ifdef CONFIG_PPC_DCR 129 #ifdef CONFIG_PPC_DCR
131 dcr_host_t dcr_host; 130 dcr_host_t dcr_host;
132 unsigned int dcr_len; 131 unsigned int dcr_len;
133 #endif 132 #endif
134 void *fb_virt; /* virt. address of the frame buffer */ 133 void *fb_virt; /* virt. address of the frame buffer */
135 dma_addr_t fb_phys; /* phys. address of the frame buffer */ 134 dma_addr_t fb_phys; /* phys. address of the frame buffer */
136 int fb_alloced; /* Flag, was the fb memory alloced? */ 135 int fb_alloced; /* Flag, was the fb memory alloced? */
137 136
138 u8 flags; /* features of the driver */ 137 u8 flags; /* features of the driver */
139 138
140 u32 reg_ctrl_default; 139 u32 reg_ctrl_default;
141 140
142 u32 pseudo_palette[PALETTE_ENTRIES_NO]; 141 u32 pseudo_palette[PALETTE_ENTRIES_NO];
143 /* Fake palette of 16 colors */ 142 /* Fake palette of 16 colors */
144 }; 143 };
145 144
146 #define to_xilinxfb_drvdata(_info) \ 145 #define to_xilinxfb_drvdata(_info) \
147 container_of(_info, struct xilinxfb_drvdata, info) 146 container_of(_info, struct xilinxfb_drvdata, info)
148 147
149 /* 148 /*
150 * The XPS TFT Controller can be accessed through PLB or DCR interface. 149 * The XPS TFT Controller can be accessed through PLB or DCR interface.
151 * To perform the read/write on the registers we need to check on 150 * To perform the read/write on the registers we need to check on
152 * which bus its connected and call the appropriate write API. 151 * which bus its connected and call the appropriate write API.
153 */ 152 */
154 static void xilinx_fb_out_be32(struct xilinxfb_drvdata *drvdata, u32 offset, 153 static void xilinx_fb_out_be32(struct xilinxfb_drvdata *drvdata, u32 offset,
155 u32 val) 154 u32 val)
156 { 155 {
157 if (drvdata->flags & PLB_ACCESS_FLAG) 156 if (drvdata->flags & PLB_ACCESS_FLAG)
158 out_be32(drvdata->regs + (offset << 2), val); 157 out_be32(drvdata->regs + (offset << 2), val);
159 #ifdef CONFIG_PPC_DCR 158 #ifdef CONFIG_PPC_DCR
160 else 159 else
161 dcr_write(drvdata->dcr_host, offset, val); 160 dcr_write(drvdata->dcr_host, offset, val);
162 #endif 161 #endif
163 } 162 }
164 163
165 static int 164 static int
166 xilinx_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, 165 xilinx_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
167 unsigned transp, struct fb_info *fbi) 166 unsigned transp, struct fb_info *fbi)
168 { 167 {
169 u32 *palette = fbi->pseudo_palette; 168 u32 *palette = fbi->pseudo_palette;
170 169
171 if (regno >= PALETTE_ENTRIES_NO) 170 if (regno >= PALETTE_ENTRIES_NO)
172 return -EINVAL; 171 return -EINVAL;
173 172
174 if (fbi->var.grayscale) { 173 if (fbi->var.grayscale) {
175 /* Convert color to grayscale. 174 /* Convert color to grayscale.
176 * grayscale = 0.30*R + 0.59*G + 0.11*B */ 175 * grayscale = 0.30*R + 0.59*G + 0.11*B */
177 red = green = blue = 176 red = green = blue =
178 (red * 77 + green * 151 + blue * 28 + 127) >> 8; 177 (red * 77 + green * 151 + blue * 28 + 127) >> 8;
179 } 178 }
180 179
181 /* fbi->fix.visual is always FB_VISUAL_TRUECOLOR */ 180 /* fbi->fix.visual is always FB_VISUAL_TRUECOLOR */
182 181
183 /* We only handle 8 bits of each color. */ 182 /* We only handle 8 bits of each color. */
184 red >>= 8; 183 red >>= 8;
185 green >>= 8; 184 green >>= 8;
186 blue >>= 8; 185 blue >>= 8;
187 palette[regno] = (red << RED_SHIFT) | (green << GREEN_SHIFT) | 186 palette[regno] = (red << RED_SHIFT) | (green << GREEN_SHIFT) |
188 (blue << BLUE_SHIFT); 187 (blue << BLUE_SHIFT);
189 188
190 return 0; 189 return 0;
191 } 190 }
192 191
193 static int 192 static int
194 xilinx_fb_blank(int blank_mode, struct fb_info *fbi) 193 xilinx_fb_blank(int blank_mode, struct fb_info *fbi)
195 { 194 {
196 struct xilinxfb_drvdata *drvdata = to_xilinxfb_drvdata(fbi); 195 struct xilinxfb_drvdata *drvdata = to_xilinxfb_drvdata(fbi);
197 196
198 switch (blank_mode) { 197 switch (blank_mode) {
199 case FB_BLANK_UNBLANK: 198 case FB_BLANK_UNBLANK:
200 /* turn on panel */ 199 /* turn on panel */
201 xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default); 200 xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default);
202 break; 201 break;
203 202
204 case FB_BLANK_NORMAL: 203 case FB_BLANK_NORMAL:
205 case FB_BLANK_VSYNC_SUSPEND: 204 case FB_BLANK_VSYNC_SUSPEND:
206 case FB_BLANK_HSYNC_SUSPEND: 205 case FB_BLANK_HSYNC_SUSPEND:
207 case FB_BLANK_POWERDOWN: 206 case FB_BLANK_POWERDOWN:
208 /* turn off panel */ 207 /* turn off panel */
209 xilinx_fb_out_be32(drvdata, REG_CTRL, 0); 208 xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
210 default: 209 default:
211 break; 210 break;
212 211
213 } 212 }
214 return 0; /* success */ 213 return 0; /* success */
215 } 214 }
216 215
217 static struct fb_ops xilinxfb_ops = 216 static struct fb_ops xilinxfb_ops =
218 { 217 {
219 .owner = THIS_MODULE, 218 .owner = THIS_MODULE,
220 .fb_setcolreg = xilinx_fb_setcolreg, 219 .fb_setcolreg = xilinx_fb_setcolreg,
221 .fb_blank = xilinx_fb_blank, 220 .fb_blank = xilinx_fb_blank,
222 .fb_fillrect = cfb_fillrect, 221 .fb_fillrect = cfb_fillrect,
223 .fb_copyarea = cfb_copyarea, 222 .fb_copyarea = cfb_copyarea,
224 .fb_imageblit = cfb_imageblit, 223 .fb_imageblit = cfb_imageblit,
225 }; 224 };
226 225
227 /* --------------------------------------------------------------------- 226 /* ---------------------------------------------------------------------
228 * Bus independent setup/teardown 227 * Bus independent setup/teardown
229 */ 228 */
230 229
231 static int xilinxfb_assign(struct device *dev, 230 static int xilinxfb_assign(struct device *dev,
232 struct xilinxfb_drvdata *drvdata, 231 struct xilinxfb_drvdata *drvdata,
233 unsigned long physaddr, 232 unsigned long physaddr,
234 struct xilinxfb_platform_data *pdata) 233 struct xilinxfb_platform_data *pdata)
235 { 234 {
236 int rc; 235 int rc;
237 int fbsize = pdata->xvirt * pdata->yvirt * BYTES_PER_PIXEL; 236 int fbsize = pdata->xvirt * pdata->yvirt * BYTES_PER_PIXEL;
238 237
239 if (drvdata->flags & PLB_ACCESS_FLAG) { 238 if (drvdata->flags & PLB_ACCESS_FLAG) {
240 /* 239 /*
241 * Map the control registers in if the controller 240 * Map the control registers in if the controller
242 * is on direct PLB interface. 241 * is on direct PLB interface.
243 */ 242 */
244 if (!request_mem_region(physaddr, 8, DRIVER_NAME)) { 243 if (!request_mem_region(physaddr, 8, DRIVER_NAME)) {
245 dev_err(dev, "Couldn't lock memory region at 0x%08lX\n", 244 dev_err(dev, "Couldn't lock memory region at 0x%08lX\n",
246 physaddr); 245 physaddr);
247 rc = -ENODEV; 246 rc = -ENODEV;
248 goto err_region; 247 goto err_region;
249 } 248 }
250 249
251 drvdata->regs_phys = physaddr; 250 drvdata->regs_phys = physaddr;
252 drvdata->regs = ioremap(physaddr, 8); 251 drvdata->regs = ioremap(physaddr, 8);
253 if (!drvdata->regs) { 252 if (!drvdata->regs) {
254 dev_err(dev, "Couldn't lock memory region at 0x%08lX\n", 253 dev_err(dev, "Couldn't lock memory region at 0x%08lX\n",
255 physaddr); 254 physaddr);
256 rc = -ENODEV; 255 rc = -ENODEV;
257 goto err_map; 256 goto err_map;
258 } 257 }
259 } 258 }
260 259
261 /* Allocate the framebuffer memory */ 260 /* Allocate the framebuffer memory */
262 if (pdata->fb_phys) { 261 if (pdata->fb_phys) {
263 drvdata->fb_phys = pdata->fb_phys; 262 drvdata->fb_phys = pdata->fb_phys;
264 drvdata->fb_virt = ioremap(pdata->fb_phys, fbsize); 263 drvdata->fb_virt = ioremap(pdata->fb_phys, fbsize);
265 } else { 264 } else {
266 drvdata->fb_alloced = 1; 265 drvdata->fb_alloced = 1;
267 drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(fbsize), 266 drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(fbsize),
268 &drvdata->fb_phys, GFP_KERNEL); 267 &drvdata->fb_phys, GFP_KERNEL);
269 } 268 }
270 269
271 if (!drvdata->fb_virt) { 270 if (!drvdata->fb_virt) {
272 dev_err(dev, "Could not allocate frame buffer memory\n"); 271 dev_err(dev, "Could not allocate frame buffer memory\n");
273 rc = -ENOMEM; 272 rc = -ENOMEM;
274 if (drvdata->flags & PLB_ACCESS_FLAG) 273 if (drvdata->flags & PLB_ACCESS_FLAG)
275 goto err_fbmem; 274 goto err_fbmem;
276 else 275 else
277 goto err_region; 276 goto err_region;
278 } 277 }
279 278
280 /* Clear (turn to black) the framebuffer */ 279 /* Clear (turn to black) the framebuffer */
281 memset_io((void __iomem *)drvdata->fb_virt, 0, fbsize); 280 memset_io((void __iomem *)drvdata->fb_virt, 0, fbsize);
282 281
283 /* Tell the hardware where the frame buffer is */ 282 /* Tell the hardware where the frame buffer is */
284 xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys); 283 xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys);
285 284
286 /* Turn on the display */ 285 /* Turn on the display */
287 drvdata->reg_ctrl_default = REG_CTRL_ENABLE; 286 drvdata->reg_ctrl_default = REG_CTRL_ENABLE;
288 if (pdata->rotate_screen) 287 if (pdata->rotate_screen)
289 drvdata->reg_ctrl_default |= REG_CTRL_ROTATE; 288 drvdata->reg_ctrl_default |= REG_CTRL_ROTATE;
290 xilinx_fb_out_be32(drvdata, REG_CTRL, 289 xilinx_fb_out_be32(drvdata, REG_CTRL,
291 drvdata->reg_ctrl_default); 290 drvdata->reg_ctrl_default);
292 291
293 /* Fill struct fb_info */ 292 /* Fill struct fb_info */
294 drvdata->info.device = dev; 293 drvdata->info.device = dev;
295 drvdata->info.screen_base = (void __iomem *)drvdata->fb_virt; 294 drvdata->info.screen_base = (void __iomem *)drvdata->fb_virt;
296 drvdata->info.fbops = &xilinxfb_ops; 295 drvdata->info.fbops = &xilinxfb_ops;
297 drvdata->info.fix = xilinx_fb_fix; 296 drvdata->info.fix = xilinx_fb_fix;
298 drvdata->info.fix.smem_start = drvdata->fb_phys; 297 drvdata->info.fix.smem_start = drvdata->fb_phys;
299 drvdata->info.fix.smem_len = fbsize; 298 drvdata->info.fix.smem_len = fbsize;
300 drvdata->info.fix.line_length = pdata->xvirt * BYTES_PER_PIXEL; 299 drvdata->info.fix.line_length = pdata->xvirt * BYTES_PER_PIXEL;
301 300
302 drvdata->info.pseudo_palette = drvdata->pseudo_palette; 301 drvdata->info.pseudo_palette = drvdata->pseudo_palette;
303 drvdata->info.flags = FBINFO_DEFAULT; 302 drvdata->info.flags = FBINFO_DEFAULT;
304 drvdata->info.var = xilinx_fb_var; 303 drvdata->info.var = xilinx_fb_var;
305 drvdata->info.var.height = pdata->screen_height_mm; 304 drvdata->info.var.height = pdata->screen_height_mm;
306 drvdata->info.var.width = pdata->screen_width_mm; 305 drvdata->info.var.width = pdata->screen_width_mm;
307 drvdata->info.var.xres = pdata->xres; 306 drvdata->info.var.xres = pdata->xres;
308 drvdata->info.var.yres = pdata->yres; 307 drvdata->info.var.yres = pdata->yres;
309 drvdata->info.var.xres_virtual = pdata->xvirt; 308 drvdata->info.var.xres_virtual = pdata->xvirt;
310 drvdata->info.var.yres_virtual = pdata->yvirt; 309 drvdata->info.var.yres_virtual = pdata->yvirt;
311 310
312 /* Allocate a colour map */ 311 /* Allocate a colour map */
313 rc = fb_alloc_cmap(&drvdata->info.cmap, PALETTE_ENTRIES_NO, 0); 312 rc = fb_alloc_cmap(&drvdata->info.cmap, PALETTE_ENTRIES_NO, 0);
314 if (rc) { 313 if (rc) {
315 dev_err(dev, "Fail to allocate colormap (%d entries)\n", 314 dev_err(dev, "Fail to allocate colormap (%d entries)\n",
316 PALETTE_ENTRIES_NO); 315 PALETTE_ENTRIES_NO);
317 goto err_cmap; 316 goto err_cmap;
318 } 317 }
319 318
320 /* Register new frame buffer */ 319 /* Register new frame buffer */
321 rc = register_framebuffer(&drvdata->info); 320 rc = register_framebuffer(&drvdata->info);
322 if (rc) { 321 if (rc) {
323 dev_err(dev, "Could not register frame buffer\n"); 322 dev_err(dev, "Could not register frame buffer\n");
324 goto err_regfb; 323 goto err_regfb;
325 } 324 }
326 325
327 if (drvdata->flags & PLB_ACCESS_FLAG) { 326 if (drvdata->flags & PLB_ACCESS_FLAG) {
328 /* Put a banner in the log (for DEBUG) */ 327 /* Put a banner in the log (for DEBUG) */
329 dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr, 328 dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr,
330 drvdata->regs); 329 drvdata->regs);
331 } 330 }
332 /* Put a banner in the log (for DEBUG) */ 331 /* Put a banner in the log (for DEBUG) */
333 dev_dbg(dev, "fb: phys=%llx, virt=%p, size=%x\n", 332 dev_dbg(dev, "fb: phys=%llx, virt=%p, size=%x\n",
334 (unsigned long long)drvdata->fb_phys, drvdata->fb_virt, fbsize); 333 (unsigned long long)drvdata->fb_phys, drvdata->fb_virt, fbsize);
335 334
336 return 0; /* success */ 335 return 0; /* success */
337 336
338 err_regfb: 337 err_regfb:
339 fb_dealloc_cmap(&drvdata->info.cmap); 338 fb_dealloc_cmap(&drvdata->info.cmap);
340 339
341 err_cmap: 340 err_cmap:
342 if (drvdata->fb_alloced) 341 if (drvdata->fb_alloced)
343 dma_free_coherent(dev, PAGE_ALIGN(fbsize), drvdata->fb_virt, 342 dma_free_coherent(dev, PAGE_ALIGN(fbsize), drvdata->fb_virt,
344 drvdata->fb_phys); 343 drvdata->fb_phys);
345 else 344 else
346 iounmap(drvdata->fb_virt); 345 iounmap(drvdata->fb_virt);
347 346
348 /* Turn off the display */ 347 /* Turn off the display */
349 xilinx_fb_out_be32(drvdata, REG_CTRL, 0); 348 xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
350 349
351 err_fbmem: 350 err_fbmem:
352 if (drvdata->flags & PLB_ACCESS_FLAG) 351 if (drvdata->flags & PLB_ACCESS_FLAG)
353 iounmap(drvdata->regs); 352 iounmap(drvdata->regs);
354 353
355 err_map: 354 err_map:
356 if (drvdata->flags & PLB_ACCESS_FLAG) 355 if (drvdata->flags & PLB_ACCESS_FLAG)
357 release_mem_region(physaddr, 8); 356 release_mem_region(physaddr, 8);
358 357
359 err_region: 358 err_region:
360 kfree(drvdata); 359 kfree(drvdata);
361 dev_set_drvdata(dev, NULL); 360 dev_set_drvdata(dev, NULL);
362 361
363 return rc; 362 return rc;
364 } 363 }
365 364
366 static int xilinxfb_release(struct device *dev) 365 static int xilinxfb_release(struct device *dev)
367 { 366 {
368 struct xilinxfb_drvdata *drvdata = dev_get_drvdata(dev); 367 struct xilinxfb_drvdata *drvdata = dev_get_drvdata(dev);
369 368
370 #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO) 369 #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
371 xilinx_fb_blank(VESA_POWERDOWN, &drvdata->info); 370 xilinx_fb_blank(VESA_POWERDOWN, &drvdata->info);
372 #endif 371 #endif
373 372
374 unregister_framebuffer(&drvdata->info); 373 unregister_framebuffer(&drvdata->info);
375 374
376 fb_dealloc_cmap(&drvdata->info.cmap); 375 fb_dealloc_cmap(&drvdata->info.cmap);
377 376
378 if (drvdata->fb_alloced) 377 if (drvdata->fb_alloced)
379 dma_free_coherent(dev, PAGE_ALIGN(drvdata->info.fix.smem_len), 378 dma_free_coherent(dev, PAGE_ALIGN(drvdata->info.fix.smem_len),
380 drvdata->fb_virt, drvdata->fb_phys); 379 drvdata->fb_virt, drvdata->fb_phys);
381 else 380 else
382 iounmap(drvdata->fb_virt); 381 iounmap(drvdata->fb_virt);
383 382
384 /* Turn off the display */ 383 /* Turn off the display */
385 xilinx_fb_out_be32(drvdata, REG_CTRL, 0); 384 xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
386 385
387 /* Release the resources, as allocated based on interface */ 386 /* Release the resources, as allocated based on interface */
388 if (drvdata->flags & PLB_ACCESS_FLAG) { 387 if (drvdata->flags & PLB_ACCESS_FLAG) {
389 iounmap(drvdata->regs); 388 iounmap(drvdata->regs);
390 release_mem_region(drvdata->regs_phys, 8); 389 release_mem_region(drvdata->regs_phys, 8);
391 } 390 }
392 #ifdef CONFIG_PPC_DCR 391 #ifdef CONFIG_PPC_DCR
393 else 392 else
394 dcr_unmap(drvdata->dcr_host, drvdata->dcr_len); 393 dcr_unmap(drvdata->dcr_host, drvdata->dcr_len);
395 #endif 394 #endif
396 395
397 kfree(drvdata); 396 kfree(drvdata);
398 dev_set_drvdata(dev, NULL); 397 dev_set_drvdata(dev, NULL);
399 398
400 return 0; 399 return 0;
401 } 400 }
402 401
403 /* --------------------------------------------------------------------- 402 /* ---------------------------------------------------------------------
404 * OF bus binding 403 * OF bus binding
405 */ 404 */
406 405
407 static int __devinit xilinxfb_of_probe(struct platform_device *op) 406 static int __devinit xilinxfb_of_probe(struct platform_device *op)
408 { 407 {
409 const u32 *prop; 408 const u32 *prop;
410 u32 *p; 409 u32 *p;
411 u32 tft_access; 410 u32 tft_access;
412 struct xilinxfb_platform_data pdata; 411 struct xilinxfb_platform_data pdata;
413 struct resource res; 412 struct resource res;
414 int size, rc; 413 int size, rc;
415 struct xilinxfb_drvdata *drvdata; 414 struct xilinxfb_drvdata *drvdata;
416 415
417 /* Copy with the default pdata (not a ptr reference!) */ 416 /* Copy with the default pdata (not a ptr reference!) */
418 pdata = xilinx_fb_default_pdata; 417 pdata = xilinx_fb_default_pdata;
419 418
420 /* Allocate the driver data region */ 419 /* Allocate the driver data region */
421 drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); 420 drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
422 if (!drvdata) { 421 if (!drvdata) {
423 dev_err(&op->dev, "Couldn't allocate device private record\n"); 422 dev_err(&op->dev, "Couldn't allocate device private record\n");
424 return -ENOMEM; 423 return -ENOMEM;
425 } 424 }
426 425
427 /* 426 /*
428 * To check whether the core is connected directly to DCR or PLB 427 * To check whether the core is connected directly to DCR or PLB
429 * interface and initialize the tft_access accordingly. 428 * interface and initialize the tft_access accordingly.
430 */ 429 */
431 p = (u32 *)of_get_property(op->dev.of_node, "xlnx,dcr-splb-slave-if", NULL); 430 p = (u32 *)of_get_property(op->dev.of_node, "xlnx,dcr-splb-slave-if", NULL);
432 tft_access = p ? *p : 0; 431 tft_access = p ? *p : 0;
433 432
434 /* 433 /*
435 * Fill the resource structure if its direct PLB interface 434 * Fill the resource structure if its direct PLB interface
436 * otherwise fill the dcr_host structure. 435 * otherwise fill the dcr_host structure.
437 */ 436 */
438 if (tft_access) { 437 if (tft_access) {
439 drvdata->flags |= PLB_ACCESS_FLAG; 438 drvdata->flags |= PLB_ACCESS_FLAG;
440 rc = of_address_to_resource(op->dev.of_node, 0, &res); 439 rc = of_address_to_resource(op->dev.of_node, 0, &res);
441 if (rc) { 440 if (rc) {
442 dev_err(&op->dev, "invalid address\n"); 441 dev_err(&op->dev, "invalid address\n");
443 goto err; 442 goto err;
444 } 443 }
445 } 444 }
446 #ifdef CONFIG_PPC_DCR 445 #ifdef CONFIG_PPC_DCR
447 else { 446 else {
448 int start; 447 int start;
449 res.start = 0; 448 res.start = 0;
450 start = dcr_resource_start(op->dev.of_node, 0); 449 start = dcr_resource_start(op->dev.of_node, 0);
451 drvdata->dcr_len = dcr_resource_len(op->dev.of_node, 0); 450 drvdata->dcr_len = dcr_resource_len(op->dev.of_node, 0);
452 drvdata->dcr_host = dcr_map(op->dev.of_node, start, drvdata->dcr_len); 451 drvdata->dcr_host = dcr_map(op->dev.of_node, start, drvdata->dcr_len);
453 if (!DCR_MAP_OK(drvdata->dcr_host)) { 452 if (!DCR_MAP_OK(drvdata->dcr_host)) {
454 dev_err(&op->dev, "invalid DCR address\n"); 453 dev_err(&op->dev, "invalid DCR address\n");
455 goto err; 454 goto err;
456 } 455 }
457 } 456 }
458 #endif 457 #endif
459 458
460 prop = of_get_property(op->dev.of_node, "phys-size", &size); 459 prop = of_get_property(op->dev.of_node, "phys-size", &size);
461 if ((prop) && (size >= sizeof(u32)*2)) { 460 if ((prop) && (size >= sizeof(u32)*2)) {
462 pdata.screen_width_mm = prop[0]; 461 pdata.screen_width_mm = prop[0];
463 pdata.screen_height_mm = prop[1]; 462 pdata.screen_height_mm = prop[1];
464 } 463 }
465 464
466 prop = of_get_property(op->dev.of_node, "resolution", &size); 465 prop = of_get_property(op->dev.of_node, "resolution", &size);
467 if ((prop) && (size >= sizeof(u32)*2)) { 466 if ((prop) && (size >= sizeof(u32)*2)) {
468 pdata.xres = prop[0]; 467 pdata.xres = prop[0];
469 pdata.yres = prop[1]; 468 pdata.yres = prop[1];
470 } 469 }
471 470
472 prop = of_get_property(op->dev.of_node, "virtual-resolution", &size); 471 prop = of_get_property(op->dev.of_node, "virtual-resolution", &size);
473 if ((prop) && (size >= sizeof(u32)*2)) { 472 if ((prop) && (size >= sizeof(u32)*2)) {
474 pdata.xvirt = prop[0]; 473 pdata.xvirt = prop[0];
475 pdata.yvirt = prop[1]; 474 pdata.yvirt = prop[1];
476 } 475 }
477 476
478 if (of_find_property(op->dev.of_node, "rotate-display", NULL)) 477 if (of_find_property(op->dev.of_node, "rotate-display", NULL))
479 pdata.rotate_screen = 1; 478 pdata.rotate_screen = 1;
480 479
481 dev_set_drvdata(&op->dev, drvdata); 480 dev_set_drvdata(&op->dev, drvdata);
482 return xilinxfb_assign(&op->dev, drvdata, res.start, &pdata); 481 return xilinxfb_assign(&op->dev, drvdata, res.start, &pdata);
483 482
484 err: 483 err:
485 kfree(drvdata); 484 kfree(drvdata);
486 return -ENODEV; 485 return -ENODEV;
487 } 486 }
488 487
489 static int __devexit xilinxfb_of_remove(struct platform_device *op) 488 static int __devexit xilinxfb_of_remove(struct platform_device *op)
490 { 489 {
491 return xilinxfb_release(&op->dev); 490 return xilinxfb_release(&op->dev);
492 } 491 }
493 492
494 /* Match table for of_platform binding */ 493 /* Match table for of_platform binding */
495 static struct of_device_id xilinxfb_of_match[] __devinitdata = { 494 static struct of_device_id xilinxfb_of_match[] __devinitdata = {
496 { .compatible = "xlnx,xps-tft-1.00.a", }, 495 { .compatible = "xlnx,xps-tft-1.00.a", },
497 { .compatible = "xlnx,xps-tft-2.00.a", }, 496 { .compatible = "xlnx,xps-tft-2.00.a", },
498 { .compatible = "xlnx,xps-tft-2.01.a", }, 497 { .compatible = "xlnx,xps-tft-2.01.a", },
499 { .compatible = "xlnx,plb-tft-cntlr-ref-1.00.a", }, 498 { .compatible = "xlnx,plb-tft-cntlr-ref-1.00.a", },
500 { .compatible = "xlnx,plb-dvi-cntlr-ref-1.00.c", }, 499 { .compatible = "xlnx,plb-dvi-cntlr-ref-1.00.c", },
501 {}, 500 {},
502 }; 501 };
503 MODULE_DEVICE_TABLE(of, xilinxfb_of_match); 502 MODULE_DEVICE_TABLE(of, xilinxfb_of_match);
504 503
505 static struct platform_driver xilinxfb_of_driver = { 504 static struct platform_driver xilinxfb_of_driver = {
506 .probe = xilinxfb_of_probe, 505 .probe = xilinxfb_of_probe,
507 .remove = __devexit_p(xilinxfb_of_remove), 506 .remove = __devexit_p(xilinxfb_of_remove),
508 .driver = { 507 .driver = {
509 .name = DRIVER_NAME, 508 .name = DRIVER_NAME,
510 .owner = THIS_MODULE, 509 .owner = THIS_MODULE,
511 .of_match_table = xilinxfb_of_match, 510 .of_match_table = xilinxfb_of_match,
512 }, 511 },
513 }; 512 };
514 513
515 514
516 /* --------------------------------------------------------------------- 515 /* ---------------------------------------------------------------------
517 * Module setup and teardown 516 * Module setup and teardown
518 */ 517 */
519 518
520 static int __init 519 static int __init
521 xilinxfb_init(void) 520 xilinxfb_init(void)
522 { 521 {
523 return platform_driver_register(&xilinxfb_of_driver); 522 return platform_driver_register(&xilinxfb_of_driver);
524 } 523 }
525 524
526 static void __exit 525 static void __exit
527 xilinxfb_cleanup(void) 526 xilinxfb_cleanup(void)
528 { 527 {
529 platform_driver_unregister(&xilinxfb_of_driver); 528 platform_driver_unregister(&xilinxfb_of_driver);
530 } 529 }
531 530
532 module_init(xilinxfb_init); 531 module_init(xilinxfb_init);
533 module_exit(xilinxfb_cleanup); 532 module_exit(xilinxfb_cleanup);
534 533
535 MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>"); 534 MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
536 MODULE_DESCRIPTION("Xilinx TFT frame buffer driver"); 535 MODULE_DESCRIPTION("Xilinx TFT frame buffer driver");
537 MODULE_LICENSE("GPL"); 536 MODULE_LICENSE("GPL");
538 537