[s3c24xx] jbt6k74: Change the state machine to have one state field for
[openwrt.git] / target / linux / s3c24xx / files-2.6.30 / drivers / video / display / jbt6k74.c
1 /* Linux kernel driver for the tpo JBT6K74-AS LCM ASIC
2 *
3 * Copyright (C) 2006-2007 by Openmoko, Inc.
4 * Author: Harald Welte <laforge@openmoko.org>,
5 * Stefan Schmidt <stefan@openmoko.org>
6 * Copyright (C) 2008 by Harald Welte <laforge@openmoko.org>
7 * All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 * MA 02111-1307 USA
23 *
24 */
25
26 #include <linux/kernel.h>
27 #include <linux/types.h>
28 #include <linux/module.h>
29 #include <linux/device.h>
30 #include <linux/platform_device.h>
31 #include <linux/delay.h>
32 #include <linux/jbt6k74.h>
33 #include <linux/fb.h>
34 #include <linux/time.h>
35
36 enum jbt_register {
37 JBT_REG_SLEEP_IN = 0x10,
38 JBT_REG_SLEEP_OUT = 0x11,
39
40 JBT_REG_DISPLAY_OFF = 0x28,
41 JBT_REG_DISPLAY_ON = 0x29,
42
43 JBT_REG_RGB_FORMAT = 0x3a,
44 JBT_REG_QUAD_RATE = 0x3b,
45
46 JBT_REG_POWER_ON_OFF = 0xb0,
47 JBT_REG_BOOSTER_OP = 0xb1,
48 JBT_REG_BOOSTER_MODE = 0xb2,
49 JBT_REG_BOOSTER_FREQ = 0xb3,
50 JBT_REG_OPAMP_SYSCLK = 0xb4,
51 JBT_REG_VSC_VOLTAGE = 0xb5,
52 JBT_REG_VCOM_VOLTAGE = 0xb6,
53 JBT_REG_EXT_DISPL = 0xb7,
54 JBT_REG_OUTPUT_CONTROL = 0xb8,
55 JBT_REG_DCCLK_DCEV = 0xb9,
56 JBT_REG_DISPLAY_MODE1 = 0xba,
57 JBT_REG_DISPLAY_MODE2 = 0xbb,
58 JBT_REG_DISPLAY_MODE = 0xbc,
59 JBT_REG_ASW_SLEW = 0xbd,
60 JBT_REG_DUMMY_DISPLAY = 0xbe,
61 JBT_REG_DRIVE_SYSTEM = 0xbf,
62
63 JBT_REG_SLEEP_OUT_FR_A = 0xc0,
64 JBT_REG_SLEEP_OUT_FR_B = 0xc1,
65 JBT_REG_SLEEP_OUT_FR_C = 0xc2,
66 JBT_REG_SLEEP_IN_LCCNT_D = 0xc3,
67 JBT_REG_SLEEP_IN_LCCNT_E = 0xc4,
68 JBT_REG_SLEEP_IN_LCCNT_F = 0xc5,
69 JBT_REG_SLEEP_IN_LCCNT_G = 0xc6,
70
71 JBT_REG_GAMMA1_FINE_1 = 0xc7,
72 JBT_REG_GAMMA1_FINE_2 = 0xc8,
73 JBT_REG_GAMMA1_INCLINATION = 0xc9,
74 JBT_REG_GAMMA1_BLUE_OFFSET = 0xca,
75
76 /* VGA */
77 JBT_REG_BLANK_CONTROL = 0xcf,
78 JBT_REG_BLANK_TH_TV = 0xd0,
79 JBT_REG_CKV_ON_OFF = 0xd1,
80 JBT_REG_CKV_1_2 = 0xd2,
81 JBT_REG_OEV_TIMING = 0xd3,
82 JBT_REG_ASW_TIMING_1 = 0xd4,
83 JBT_REG_ASW_TIMING_2 = 0xd5,
84
85 /* QVGA */
86 JBT_REG_BLANK_CONTROL_QVGA = 0xd6,
87 JBT_REG_BLANK_TH_TV_QVGA = 0xd7,
88 JBT_REG_CKV_ON_OFF_QVGA = 0xd8,
89 JBT_REG_CKV_1_2_QVGA = 0xd9,
90 JBT_REG_OEV_TIMING_QVGA = 0xde,
91 JBT_REG_ASW_TIMING_1_QVGA = 0xdf,
92 JBT_REG_ASW_TIMING_2_QVGA = 0xe0,
93
94
95 JBT_REG_HCLOCK_VGA = 0xec,
96 JBT_REG_HCLOCK_QVGA = 0xed,
97
98 };
99
100 enum jbt_resolution {
101 JBT_RESOLUTION_VGA,
102 JBT_RESOLUTION_QVGA,
103 };
104
105 enum jbt_power_mode {
106 JBT_POWER_MODE_DEEP_STANDBY,
107 JBT_POWER_MODE_SLEEP,
108 JBT_POWER_MODE_NORMAL,
109 };
110
111 static const char *jbt_power_mode_names[] = {
112 [JBT_POWER_MODE_DEEP_STANDBY] = "deep-standby",
113 [JBT_POWER_MODE_SLEEP] = "sleep",
114 [JBT_POWER_MODE_NORMAL] = "normal",
115 };
116
117 static const char *jbt_resolution_names[] = {
118 [JBT_RESOLUTION_VGA] = "vga",
119 [JBT_RESOLUTION_QVGA] = "qvga",
120 };
121
122 struct jbt_info {
123 enum jbt_resolution resolution;
124 enum jbt_power_mode power_mode;
125 struct spi_device *spi_dev;
126 struct mutex lock; /* protects tx_buf and reg_cache */
127 struct notifier_block fb_notif;
128 u16 tx_buf[8];
129 u16 reg_cache[0xEE];
130 unsigned long last_sleep;
131 };
132
133 #define JBT_COMMAND 0x000
134 #define JBT_DATA 0x100
135
136 static int jbt_reg_write_nodata(struct jbt_info *jbt, u8 reg)
137 {
138 int rc;
139
140 jbt->tx_buf[0] = JBT_COMMAND | reg;
141 rc = spi_write(jbt->spi_dev, (u8 *)jbt->tx_buf,
142 1*sizeof(u16));
143 if (rc == 0)
144 jbt->reg_cache[reg] = 0;
145 else
146 dev_err(&jbt->spi_dev->dev, "jbt_reg_write_nodata spi_write ret %d\n",
147 rc);
148
149 return rc;
150 }
151
152
153 static int jbt_reg_write(struct jbt_info *jbt, u8 reg, u8 data)
154 {
155 int rc;
156
157 jbt->tx_buf[0] = JBT_COMMAND | reg;
158 jbt->tx_buf[1] = JBT_DATA | data;
159 rc = spi_write(jbt->spi_dev, (u8 *)jbt->tx_buf,
160 2*sizeof(u16));
161 if (rc == 0)
162 jbt->reg_cache[reg] = data;
163 else
164 dev_err(&jbt->spi_dev->dev, "jbt_reg_write spi_write ret %d\n", rc);
165
166 return rc;
167 }
168
169 static int jbt_reg_write16(struct jbt_info *jbt, u8 reg, u16 data)
170 {
171 int rc;
172
173 jbt->tx_buf[0] = JBT_COMMAND | reg;
174 jbt->tx_buf[1] = JBT_DATA | (data >> 8);
175 jbt->tx_buf[2] = JBT_DATA | (data & 0xff);
176
177 rc = spi_write(jbt->spi_dev, (u8 *)jbt->tx_buf,
178 3*sizeof(u16));
179 if (rc == 0)
180 jbt->reg_cache[reg] = data;
181 else
182 dev_err(&jbt->spi_dev->dev, "jbt_reg_write16 spi_write ret %d\n", rc);
183
184 return rc;
185 }
186
187 static int jbt_init_regs(struct jbt_info *jbt)
188 {
189 int rc;
190
191 dev_dbg(&jbt->spi_dev->dev, "entering %cVGA mode\n",
192 jbt->resolution == JBT_RESOLUTION_QVGA ? 'Q' : ' ');
193
194 rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE1, 0x01);
195 rc |= jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE2, 0x00);
196 rc |= jbt_reg_write(jbt, JBT_REG_RGB_FORMAT, 0x60);
197 rc |= jbt_reg_write(jbt, JBT_REG_DRIVE_SYSTEM, 0x10);
198 rc |= jbt_reg_write(jbt, JBT_REG_BOOSTER_OP, 0x56);
199 rc |= jbt_reg_write(jbt, JBT_REG_BOOSTER_MODE, 0x33);
200 rc |= jbt_reg_write(jbt, JBT_REG_BOOSTER_FREQ, 0x11);
201 rc |= jbt_reg_write(jbt, JBT_REG_OPAMP_SYSCLK, 0x02);
202 rc |= jbt_reg_write(jbt, JBT_REG_VSC_VOLTAGE, 0x2b);
203 rc |= jbt_reg_write(jbt, JBT_REG_VCOM_VOLTAGE, 0x40);
204 rc |= jbt_reg_write(jbt, JBT_REG_EXT_DISPL, 0x03);
205 rc |= jbt_reg_write(jbt, JBT_REG_DCCLK_DCEV, 0x04);
206 /*
207 * default of 0x02 in JBT_REG_ASW_SLEW responsible for 72Hz requirement
208 * to avoid red / blue flicker
209 */
210 rc |= jbt_reg_write(jbt, JBT_REG_ASW_SLEW, 0x04);
211 rc |= jbt_reg_write(jbt, JBT_REG_DUMMY_DISPLAY, 0x00);
212
213 rc |= jbt_reg_write(jbt, JBT_REG_SLEEP_OUT_FR_A, 0x11);
214 rc |= jbt_reg_write(jbt, JBT_REG_SLEEP_OUT_FR_B, 0x11);
215 rc |= jbt_reg_write(jbt, JBT_REG_SLEEP_OUT_FR_C, 0x11);
216 rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_D, 0x2040);
217 rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_E, 0x60c0);
218 rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_F, 0x1020);
219 rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_G, 0x60c0);
220
221 rc |= jbt_reg_write16(jbt, JBT_REG_GAMMA1_FINE_1, 0x5533);
222 rc |= jbt_reg_write(jbt, JBT_REG_GAMMA1_FINE_2, 0x00);
223 rc |= jbt_reg_write(jbt, JBT_REG_GAMMA1_INCLINATION, 0x00);
224 rc |= jbt_reg_write(jbt, JBT_REG_GAMMA1_BLUE_OFFSET, 0x00);
225
226 if (jbt->resolution != JBT_RESOLUTION_QVGA) {
227 rc |= jbt_reg_write16(jbt, JBT_REG_HCLOCK_VGA, 0x1f0);
228 rc |= jbt_reg_write(jbt, JBT_REG_BLANK_CONTROL, 0x02);
229 rc |= jbt_reg_write16(jbt, JBT_REG_BLANK_TH_TV, 0x0804);
230
231 rc |= jbt_reg_write(jbt, JBT_REG_CKV_ON_OFF, 0x01);
232 rc |= jbt_reg_write16(jbt, JBT_REG_CKV_1_2, 0x0000);
233
234 rc |= jbt_reg_write16(jbt, JBT_REG_OEV_TIMING, 0x0d0e);
235 rc |= jbt_reg_write16(jbt, JBT_REG_ASW_TIMING_1, 0x11a4);
236 rc |= jbt_reg_write(jbt, JBT_REG_ASW_TIMING_2, 0x0e);
237 } else {
238 rc |= jbt_reg_write16(jbt, JBT_REG_HCLOCK_QVGA, 0x00ff);
239 rc |= jbt_reg_write(jbt, JBT_REG_BLANK_CONTROL_QVGA, 0x02);
240 rc |= jbt_reg_write16(jbt, JBT_REG_BLANK_TH_TV_QVGA, 0x0804);
241
242 rc |= jbt_reg_write(jbt, JBT_REG_CKV_ON_OFF_QVGA, 0x01);
243 rc |= jbt_reg_write16(jbt, JBT_REG_CKV_1_2_QVGA, 0x0008);
244
245 rc |= jbt_reg_write16(jbt, JBT_REG_OEV_TIMING_QVGA, 0x050a);
246 rc |= jbt_reg_write16(jbt, JBT_REG_ASW_TIMING_1_QVGA, 0x0a19);
247 rc |= jbt_reg_write(jbt, JBT_REG_ASW_TIMING_2_QVGA, 0x0a);
248 }
249
250 return rc ? -EIO : 0;
251 }
252
253 static int standby_to_sleep(struct jbt_info *jbt)
254 {
255 int rc;
256
257 /* three times command zero */
258 rc = jbt_reg_write_nodata(jbt, 0x00);
259 mdelay(1);
260 rc |= jbt_reg_write_nodata(jbt, 0x00);
261 mdelay(1);
262 rc |= jbt_reg_write_nodata(jbt, 0x00);
263 mdelay(1);
264
265 /* deep standby out */
266 rc |= jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x11);
267 mdelay(1);
268 rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x28);
269
270 /* (re)initialize register set */
271 rc |= jbt_init_regs(jbt);
272
273 return rc ? -EIO : 0;
274 }
275
276 static int sleep_to_normal(struct jbt_info *jbt)
277 {
278 int rc;
279
280 /* Make sure we are 120 ms after SLEEP_OUT */
281 if (time_before(jiffies, jbt->last_sleep))
282 mdelay(jiffies_to_msecs(jbt->last_sleep - jiffies));
283
284 if (jbt->resolution == JBT_RESOLUTION_VGA) {
285 /* RGB I/F on, RAM wirte off, QVGA through, SIGCON enable */
286 rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x80);
287
288 /* Quad mode off */
289 rc |= jbt_reg_write(jbt, JBT_REG_QUAD_RATE, 0x00);
290 } else {
291 /* RGB I/F on, RAM wirte off, QVGA through, SIGCON enable */
292 rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x81);
293
294 /* Quad mode on */
295 rc |= jbt_reg_write(jbt, JBT_REG_QUAD_RATE, 0x22);
296 }
297
298 /* AVDD on, XVDD on */
299 rc |= jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x16);
300
301 /* Output control */
302 rc |= jbt_reg_write16(jbt, JBT_REG_OUTPUT_CONTROL, 0xfff9);
303
304 /* Turn on display */
305 rc |= jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_ON);
306
307 /* Sleep mode off */
308 rc |= jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_OUT);
309 jbt->last_sleep = jiffies + msecs_to_jiffies(120);
310
311 /* Allow the booster and display controller to restart stably */
312 mdelay(5);
313
314 return rc ? -EIO : 0;
315 }
316
317 static int normal_to_sleep(struct jbt_info *jbt)
318 {
319 int rc;
320
321 /* Make sure we are 120 ms after SLEEP_OUT */
322 if (time_before(jiffies, jbt->last_sleep))
323 mdelay(jiffies_to_msecs(jbt->last_sleep - jiffies));
324
325 rc = jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_OFF);
326 rc |= jbt_reg_write16(jbt, JBT_REG_OUTPUT_CONTROL, 0x8002);
327 rc |= jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_IN);
328 jbt->last_sleep = jiffies + msecs_to_jiffies(120);
329
330 /* Allow the internal circuits to stop automatically */
331 mdelay(5);
332
333 return rc ? -EIO : 0;
334 }
335
336 static int sleep_to_standby(struct jbt_info *jbt)
337 {
338 return jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x00);
339 }
340
341 /* frontend function */
342 int jbt6k74_enter_power_mode(struct jbt_info *jbt, enum jbt_power_mode new_mode)
343 {
344 int rc = -EINVAL;
345
346 dev_dbg(&jbt->spi_dev->dev, "entering (old_state=%s, new_state=%s)\n",
347 jbt_power_mode_names[jbt->power_mode],
348 jbt_power_mode_names[new_mode]);
349
350 mutex_lock(&jbt->lock);
351
352 switch (jbt->power_mode) {
353 case JBT_POWER_MODE_DEEP_STANDBY:
354 switch (new_mode) {
355 case JBT_POWER_MODE_DEEP_STANDBY:
356 rc = 0;
357 break;
358 case JBT_POWER_MODE_SLEEP:
359 rc = standby_to_sleep(jbt);
360 break;
361 case JBT_POWER_MODE_NORMAL:
362 /* first transition into sleep */
363 rc = standby_to_sleep(jbt);
364 /* then transition into normal */
365 rc |= sleep_to_normal(jbt);
366 break;
367 }
368 break;
369 case JBT_POWER_MODE_SLEEP:
370 switch (new_mode) {
371 case JBT_POWER_MODE_SLEEP:
372 rc = 0;
373 break;
374 case JBT_POWER_MODE_DEEP_STANDBY:
375 rc = sleep_to_standby(jbt);
376 break;
377 case JBT_POWER_MODE_NORMAL:
378 rc = sleep_to_normal(jbt);
379 break;
380 }
381 break;
382 case JBT_POWER_MODE_NORMAL:
383 switch (new_mode) {
384 case JBT_POWER_MODE_NORMAL:
385 rc = 0;
386 break;
387 case JBT_POWER_MODE_DEEP_STANDBY:
388 /* first transition into sleep */
389 rc = normal_to_sleep(jbt);
390 /* then transition into deep standby */
391 rc |= sleep_to_standby(jbt);
392 break;
393 case JBT_POWER_MODE_SLEEP:
394 rc = normal_to_sleep(jbt);
395 break;
396 }
397 }
398
399 if (rc == 0)
400 jbt->power_mode = new_mode;
401 else
402 dev_err(&jbt->spi_dev->dev, "Failed enter state '%s')\n",
403 jbt_power_mode_names[new_mode]);
404
405 mutex_unlock(&jbt->lock);
406
407 return rc;
408 }
409 EXPORT_SYMBOL_GPL(jbt6k74_enter_power_mode);
410
411 int jbt6k74_set_resolution(struct jbt_info *jbt, enum jbt_resolution new_resolution) {
412 int rc = 0;
413 enum jbt_resolution old_resolution;
414
415 mutex_lock(&jbt->lock);
416
417 if (jbt->resolution == new_resolution)
418 return 0;
419
420 if (new_resolution != JBT_RESOLUTION_VGA &&
421 new_resolution != JBT_RESOLUTION_QVGA)
422 return -EINVAL;
423
424 old_resolution = jbt->resolution;
425 jbt->resolution = new_resolution;
426
427 if (jbt->power_mode == JBT_POWER_MODE_NORMAL) {
428
429 /* first transition into sleep */
430 rc = normal_to_sleep(jbt);
431 /* second transition into deep standby */
432 /* rc |= sleep_to_standby(jbt);*/
433 /* third transition into sleep */
434 /* rc |= standby_to_sleep(jbt);*/
435 /* fourth transition into normal */
436 rc |= sleep_to_normal(jbt);
437
438 if (rc) {
439 jbt->resolution = old_resolution;
440 dev_err(&jbt->spi_dev->dev, "Failed to set resolution '%s')\n",
441 jbt_resolution_names[new_resolution]);
442 }
443 }
444
445 mutex_unlock(&jbt->lock);
446
447 return rc;
448 }
449 EXPORT_SYMBOL_GPL(jbt6k74_set_resolution);
450
451 static ssize_t power_mode_read(struct device *dev, struct device_attribute *attr,
452 char *buf)
453 {
454 struct jbt_info *jbt = dev_get_drvdata(dev);
455
456 if (jbt->power_mode >= ARRAY_SIZE(jbt_power_mode_names))
457 return -EIO;
458
459 return sprintf(buf, "%s\n", jbt_power_mode_names[jbt->power_mode]);
460 }
461
462 static ssize_t power_mode_write(struct device *dev, struct device_attribute *attr,
463 const char *buf, size_t count)
464 {
465 struct jbt_info *jbt = dev_get_drvdata(dev);
466 int i, rc;
467
468 for (i = 0; i < ARRAY_SIZE(jbt_power_mode_names); i++) {
469 if (!strncmp(buf, jbt_power_mode_names[i],
470 strlen(jbt_power_mode_names[i]))) {
471 rc = jbt6k74_enter_power_mode(jbt, i);
472 if (rc)
473 return rc;
474 return count;
475 }
476 }
477
478 return -EINVAL;
479 }
480
481 static DEVICE_ATTR(power_mode, 0644, power_mode_read, power_mode_write);
482
483 static ssize_t resolution_read(struct device *dev, struct device_attribute *attr,
484 char *buf)
485 {
486 struct jbt_info *jbt = dev_get_drvdata(dev);
487
488 if (jbt->resolution >= ARRAY_SIZE(jbt_resolution_names))
489 return -EIO;
490
491 return sprintf(buf, "%s\n", jbt_resolution_names[jbt->resolution]);
492 }
493
494 static ssize_t resolution_write(struct device *dev, struct device_attribute *attr,
495 const char *buf, size_t count)
496 {
497 struct jbt_info *jbt = dev_get_drvdata(dev);
498 int i, rc;
499
500 for (i = 0; i < ARRAY_SIZE(jbt_resolution_names); i++) {
501 if (!strncmp(buf, jbt_resolution_names[i],
502 strlen(jbt_resolution_names[i]))) {
503 rc = jbt6k74_set_resolution(jbt, i);
504 if (rc)
505 return rc;
506 return count;
507 }
508 }
509
510 return -EINVAL;
511 }
512
513 static DEVICE_ATTR(resolution, 0644, resolution_read, resolution_write);
514
515 static int reg_by_string(const char *name)
516 {
517 if (!strcmp(name, "gamma_fine1"))
518 return JBT_REG_GAMMA1_FINE_1;
519 else if (!strcmp(name, "gamma_fine2"))
520 return JBT_REG_GAMMA1_FINE_2;
521 else if (!strcmp(name, "gamma_inclination"))
522 return JBT_REG_GAMMA1_INCLINATION;
523 else
524 return JBT_REG_GAMMA1_BLUE_OFFSET;
525 }
526
527 static ssize_t gamma_read(struct device *dev, struct device_attribute *attr,
528 char *buf)
529 {
530 struct jbt_info *jbt = dev_get_drvdata(dev);
531 int reg = reg_by_string(attr->attr.name);
532 u16 val;
533
534 mutex_lock(&jbt->lock);
535 val = jbt->reg_cache[reg];
536 mutex_unlock(&jbt->lock);
537
538 return sprintf(buf, "0x%04x\n", val);
539 }
540
541 static ssize_t gamma_write(struct device *dev, struct device_attribute *attr,
542 const char *buf, size_t count)
543 {
544 struct jbt_info *jbt = dev_get_drvdata(dev);
545 int reg = reg_by_string(attr->attr.name);
546 unsigned long val = simple_strtoul(buf, NULL, 10);
547
548 dev_info(dev, "writing gama %lu\n", val & 0xff);
549
550 mutex_lock(&jbt->lock);
551 jbt_reg_write(jbt, reg, val & 0xff);
552 mutex_unlock(&jbt->lock);
553
554 return count;
555 }
556
557 static ssize_t reset_write(struct device *dev, struct device_attribute *attr,
558 const char *buf, size_t count)
559 {
560 int rc;
561 struct jbt_info *jbt = dev_get_drvdata(dev);
562 struct jbt6k74_platform_data *pdata = jbt->spi_dev->dev.platform_data;
563
564 dev_info(dev, "reset\n");
565
566 mutex_lock(&jbt->lock);
567
568 /* hard reset the jbt6k74 */
569 (pdata->reset)(0, 0);
570 mdelay(1);
571 (pdata->reset)(0, 1);
572 mdelay(120);
573
574 rc = jbt_reg_write_nodata(jbt, 0x01);
575 if (rc < 0)
576 dev_err(&jbt->spi_dev->dev, "cannot soft reset\n");
577 mdelay(120);
578
579 mutex_unlock(&jbt->lock);
580
581 jbt6k74_enter_power_mode(jbt, jbt->power_mode);
582
583 return count;
584 }
585
586 static DEVICE_ATTR(gamma_fine1, 0644, gamma_read, gamma_write);
587 static DEVICE_ATTR(gamma_fine2, 0644, gamma_read, gamma_write);
588 static DEVICE_ATTR(gamma_inclination, 0644, gamma_read, gamma_write);
589 static DEVICE_ATTR(gamma_blue_offset, 0644, gamma_read, gamma_write);
590 static DEVICE_ATTR(reset, 0600, NULL, reset_write);
591
592 static struct attribute *jbt_sysfs_entries[] = {
593 &dev_attr_power_mode.attr,
594 &dev_attr_resolution.attr,
595 &dev_attr_gamma_fine1.attr,
596 &dev_attr_gamma_fine2.attr,
597 &dev_attr_gamma_inclination.attr,
598 &dev_attr_gamma_blue_offset.attr,
599 &dev_attr_reset.attr,
600 NULL,
601 };
602
603 static struct attribute_group jbt_attr_group = {
604 .name = NULL,
605 .attrs = jbt_sysfs_entries,
606 };
607
608 static int fb_notifier_callback(struct notifier_block *self,
609 unsigned long event, void *data)
610 {
611 struct jbt_info *jbt;
612 struct fb_event *evdata = data;
613 struct fb_info *info;
614 int fb_blank;
615
616 jbt = container_of(self, struct jbt_info, fb_notif);
617
618 dev_dbg(&jbt->spi_dev->dev, "event=%lu\n", event);
619
620 switch (event) {
621 case FB_EVENT_MODE_CHANGE:
622 case FB_EVENT_MODE_CHANGE_ALL:
623 info = evdata->info;
624 if (info->var.xres == 240 &&
625 info->var.yres == 320) {
626 jbt6k74_set_resolution(jbt, JBT_RESOLUTION_QVGA);
627 } else if (info->var.xres == 480 &&
628 info->var.yres == 640) {
629 jbt6k74_set_resolution(jbt, JBT_RESOLUTION_VGA);
630 } else {
631 dev_err(&jbt->spi_dev->dev, "Unknown resolution. Entering sleep mode.\n");
632 jbt6k74_enter_power_mode(jbt, JBT_POWER_MODE_SLEEP);
633 }
634 break;
635 case FB_EVENT_BLANK:
636 case FB_EVENT_CONBLANK:
637 fb_blank = *(int *)evdata->data;
638 switch (fb_blank) {
639 case FB_BLANK_UNBLANK:
640 dev_dbg(&jbt->spi_dev->dev, "unblank\n");
641 jbt6k74_enter_power_mode(jbt, JBT_POWER_MODE_NORMAL);
642 break;
643 case FB_BLANK_NORMAL:
644 jbt6k74_enter_power_mode(jbt, JBT_POWER_MODE_SLEEP);
645 dev_dbg(&jbt->spi_dev->dev, "blank\n");
646 break;
647 case FB_BLANK_VSYNC_SUSPEND:
648 dev_dbg(&jbt->spi_dev->dev, "vsync suspend\n");
649 break;
650 case FB_BLANK_HSYNC_SUSPEND:
651 dev_dbg(&jbt->spi_dev->dev, "hsync suspend\n");
652 break;
653 case FB_BLANK_POWERDOWN:
654 dev_dbg(&jbt->spi_dev->dev, "powerdown\n");
655 jbt6k74_enter_power_mode(jbt, JBT_POWER_MODE_DEEP_STANDBY);
656 break;
657 }
658 }
659
660 return 0;
661 }
662
663 /* linux device model infrastructure */
664
665 static int __devinit jbt_probe(struct spi_device *spi)
666 {
667 int rc;
668 struct jbt_info *jbt;
669 struct jbt6k74_platform_data *pdata = spi->dev.platform_data;
670
671 /* the controller doesn't have a MISO pin; we can't do detection */
672
673 spi->mode = SPI_CPOL | SPI_CPHA;
674 spi->bits_per_word = 9;
675
676 rc = spi_setup(spi);
677 if (rc < 0) {
678 dev_err(&spi->dev,
679 "error during spi_setup of jbt6k74 driver\n");
680 return rc;
681 }
682
683 jbt = kzalloc(sizeof(*jbt), GFP_KERNEL);
684 if (!jbt)
685 return -ENOMEM;
686
687 jbt->spi_dev = spi;
688 jbt->resolution = JBT_RESOLUTION_VGA;
689 jbt->power_mode = JBT_POWER_MODE_DEEP_STANDBY;
690 jbt->last_sleep = jiffies + msecs_to_jiffies(120);
691 mutex_init(&jbt->lock);
692
693 dev_set_drvdata(&spi->dev, jbt);
694
695 rc = jbt6k74_enter_power_mode(jbt, JBT_POWER_MODE_NORMAL);
696 if (rc < 0) {
697 dev_err(&spi->dev, "cannot enter NORMAL state\n");
698 goto err_free_drvdata;
699 }
700
701 rc = sysfs_create_group(&spi->dev.kobj, &jbt_attr_group);
702 if (rc < 0) {
703 dev_err(&spi->dev, "cannot create sysfs group\n");
704 goto err_standby;
705 }
706
707 jbt->fb_notif.notifier_call = fb_notifier_callback;
708 rc = fb_register_client(&jbt->fb_notif);
709 if (rc < 0) {
710 dev_err(&spi->dev, "cannot register notifier\n");
711 goto err_sysfs;
712 }
713
714 if (pdata->probe_completed)
715 (pdata->probe_completed)(&spi->dev);
716
717 return 0;
718
719 err_sysfs:
720 sysfs_remove_group(&spi->dev.kobj, &jbt_attr_group);
721 err_standby:
722 jbt6k74_enter_power_mode(jbt, JBT_POWER_MODE_DEEP_STANDBY);
723 err_free_drvdata:
724 dev_set_drvdata(&spi->dev, NULL);
725 kfree(jbt);
726
727 return rc;
728 }
729
730 static int __devexit jbt_remove(struct spi_device *spi)
731 {
732 struct jbt_info *jbt = dev_get_drvdata(&spi->dev);
733
734 /* We don't want to switch off the display in case the user
735 * accidentially onloads the module (whose use count normally is 0) */
736 jbt6k74_enter_power_mode(jbt, JBT_POWER_MODE_NORMAL);
737
738 fb_unregister_client(&jbt->fb_notif);
739 sysfs_remove_group(&spi->dev.kobj, &jbt_attr_group);
740 dev_set_drvdata(&spi->dev, NULL);
741 kfree(jbt);
742
743 return 0;
744 }
745
746 #ifdef CONFIG_PM
747 static int jbt_suspend(struct spi_device *spi, pm_message_t state)
748 {
749 struct jbt_info *jbt = dev_get_drvdata(&spi->dev);
750
751 jbt6k74_enter_power_mode(jbt, JBT_POWER_MODE_DEEP_STANDBY);
752
753 dev_info(&spi->dev, "suspended\n");
754
755 return 0;
756 }
757
758 int jbt6k74_resume(struct spi_device *spi)
759 {
760 struct jbt_info *jbt = dev_get_drvdata(&spi->dev);
761 struct jbt6k74_platform_data *pdata = spi->dev.platform_data;
762
763 jbt6k74_enter_power_mode(jbt, jbt->power_mode);
764
765 if (pdata->resuming)
766 (pdata->resuming)(0);
767
768 dev_info(&spi->dev, "resumed\n");
769
770 return 0;
771 }
772 EXPORT_SYMBOL_GPL(jbt6k74_resume);
773
774 #else
775 #define jbt_suspend NULL
776 #define jbt6k74_resume NULL
777 #endif
778
779 static struct spi_driver jbt6k74_driver = {
780 .driver = {
781 .name = "jbt6k74",
782 .owner = THIS_MODULE,
783 },
784
785 .probe = jbt_probe,
786 .remove = __devexit_p(jbt_remove),
787 .suspend = jbt_suspend,
788 .resume = jbt6k74_resume,
789 };
790
791 static int __init jbt_init(void)
792 {
793 return spi_register_driver(&jbt6k74_driver);
794 }
795
796 static void __exit jbt_exit(void)
797 {
798 spi_unregister_driver(&jbt6k74_driver);
799 }
800
801 MODULE_DESCRIPTION("SPI driver for tpo JBT6K74-AS LCM control interface");
802 MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
803 MODULE_LICENSE("GPL");
804
805 module_init(jbt_init);
806 module_exit(jbt_exit);
This page took 0.084986 seconds and 5 git commands to generate.