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