OMAPDSS: Remove passive matrix LCD support (part 2)
[linux-3.10.git] / drivers / video / omap2 / displays / panel-picodlp.c
1 /*
2  * picodlp panel driver
3  * picodlp_i2c_driver: i2c_client driver
4  *
5  * Copyright (C) 2009-2011 Texas Instruments
6  * Author: Mythri P K <mythripk@ti.com>
7  * Mayuresh Janorkar <mayur@ti.com>
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License version 2 as published by
11  * the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  *
18  * You should have received a copy of the GNU General Public License along with
19  * this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <linux/module.h>
23 #include <linux/input.h>
24 #include <linux/platform_device.h>
25 #include <linux/interrupt.h>
26 #include <linux/firmware.h>
27 #include <linux/slab.h>
28 #include <linux/mutex.h>
29 #include <linux/i2c.h>
30 #include <linux/delay.h>
31 #include <linux/gpio.h>
32
33 #include <video/omapdss.h>
34 #include <video/omap-panel-picodlp.h>
35
36 #include "panel-picodlp.h"
37
38 struct picodlp_data {
39         struct mutex lock;
40         struct i2c_client *picodlp_i2c_client;
41 };
42
43 static struct i2c_board_info picodlp_i2c_board_info = {
44         I2C_BOARD_INFO("picodlp_i2c_driver", 0x1b),
45 };
46
47 struct picodlp_i2c_data {
48         struct mutex xfer_lock;
49 };
50
51 static struct i2c_device_id picodlp_i2c_id[] = {
52         { "picodlp_i2c_driver", 0 },
53 };
54
55 struct picodlp_i2c_command {
56         u8 reg;
57         u32 value;
58 };
59
60 static struct omap_video_timings pico_ls_timings = {
61         .x_res          = 864,
62         .y_res          = 480,
63         .hsw            = 7,
64         .hfp            = 11,
65         .hbp            = 7,
66
67         .pixel_clock    = 19200,
68
69         .vsw            = 2,
70         .vfp            = 3,
71         .vbp            = 14,
72 };
73
74 static inline struct picodlp_panel_data
75                 *get_panel_data(const struct omap_dss_device *dssdev)
76 {
77         return (struct picodlp_panel_data *) dssdev->data;
78 }
79
80 static u32 picodlp_i2c_read(struct i2c_client *client, u8 reg)
81 {
82         u8 read_cmd[] = {READ_REG_SELECT, reg}, data[4];
83         struct picodlp_i2c_data *picodlp_i2c_data = i2c_get_clientdata(client);
84         struct i2c_msg msg[2];
85
86         mutex_lock(&picodlp_i2c_data->xfer_lock);
87
88         msg[0].addr = client->addr;
89         msg[0].flags = 0;
90         msg[0].len = 2;
91         msg[0].buf = read_cmd;
92
93         msg[1].addr = client->addr;
94         msg[1].flags = I2C_M_RD;
95         msg[1].len = 4;
96         msg[1].buf = data;
97
98         i2c_transfer(client->adapter, msg, 2);
99         mutex_unlock(&picodlp_i2c_data->xfer_lock);
100         return (data[3] | (data[2] << 8) | (data[1] << 16) | (data[0] << 24));
101 }
102
103 static int picodlp_i2c_write_block(struct i2c_client *client,
104                                         u8 *data, int len)
105 {
106         struct i2c_msg msg;
107         int i, r, msg_count = 1;
108
109         struct picodlp_i2c_data *picodlp_i2c_data = i2c_get_clientdata(client);
110
111         if (len < 1 || len > 32) {
112                 dev_err(&client->dev,
113                         "too long syn_write_block len %d\n", len);
114                 return -EIO;
115         }
116         mutex_lock(&picodlp_i2c_data->xfer_lock);
117
118         msg.addr = client->addr;
119         msg.flags = 0;
120         msg.len = len;
121         msg.buf = data;
122         r = i2c_transfer(client->adapter, &msg, msg_count);
123         mutex_unlock(&picodlp_i2c_data->xfer_lock);
124
125         /*
126          * i2c_transfer returns:
127          * number of messages sent in case of success
128          * a negative error number in case of failure
129          */
130         if (r != msg_count)
131                 goto err;
132
133         /* In case of success */
134         for (i = 0; i < len; i++)
135                 dev_dbg(&client->dev,
136                         "addr %x bw 0x%02x[%d]: 0x%02x\n",
137                         client->addr, data[0] + i, i, data[i]);
138
139         return 0;
140 err:
141         dev_err(&client->dev, "picodlp_i2c_write error\n");
142         return r;
143 }
144
145 static int picodlp_i2c_write(struct i2c_client *client, u8 reg, u32 value)
146 {
147         u8 data[5];
148         int i;
149
150         data[0] = reg;
151         for (i = 1; i < 5; i++)
152                 data[i] = (value >> (32 - (i) * 8)) & 0xFF;
153
154         return picodlp_i2c_write_block(client, data, 5);
155 }
156
157 static int picodlp_i2c_write_array(struct i2c_client *client,
158                         const struct picodlp_i2c_command commands[],
159                         int count)
160 {
161         int i, r = 0;
162         for (i = 0; i < count; i++) {
163                 r = picodlp_i2c_write(client, commands[i].reg,
164                                                 commands[i].value);
165                 if (r)
166                         return r;
167         }
168         return r;
169 }
170
171 static int picodlp_wait_for_dma_done(struct i2c_client *client)
172 {
173         u8 trial = 100;
174
175         do {
176                 msleep(1);
177                 if (!trial--)
178                         return -ETIMEDOUT;
179         } while (picodlp_i2c_read(client, MAIN_STATUS) & DMA_STATUS);
180
181         return 0;
182 }
183
184 /**
185  * picodlp_i2c_init:    i2c_initialization routine
186  * client:      i2c_client for communication
187  *
188  * return
189  *              0       : Success, no error
190  *      error code      : Failure
191  */
192 static int picodlp_i2c_init(struct i2c_client *client)
193 {
194         int r;
195         static const struct picodlp_i2c_command init_cmd_set1[] = {
196                 {SOFT_RESET, 1},
197                 {DMD_PARK_TRIGGER, 1},
198                 {MISC_REG, 5},
199                 {SEQ_CONTROL, 0},
200                 {SEQ_VECTOR, 0x100},
201                 {DMD_BLOCK_COUNT, 7},
202                 {DMD_VCC_CONTROL, 0x109},
203                 {DMD_PARK_PULSE_COUNT, 0xA},
204                 {DMD_PARK_PULSE_WIDTH, 0xB},
205                 {DMD_PARK_DELAY, 0x2ED},
206                 {DMD_SHADOW_ENABLE, 0},
207                 {FLASH_OPCODE, 0xB},
208                 {FLASH_DUMMY_BYTES, 1},
209                 {FLASH_ADDR_BYTES, 3},
210                 {PBC_CONTROL, 0},
211                 {FLASH_START_ADDR, CMT_LUT_0_START_ADDR},
212                 {FLASH_READ_BYTES, CMT_LUT_0_SIZE},
213                 {CMT_SPLASH_LUT_START_ADDR, 0},
214                 {CMT_SPLASH_LUT_DEST_SELECT, CMT_LUT_ALL},
215                 {PBC_CONTROL, 1},
216         };
217
218         static const struct picodlp_i2c_command init_cmd_set2[] = {
219                 {PBC_CONTROL, 0},
220                 {CMT_SPLASH_LUT_DEST_SELECT, 0},
221                 {PBC_CONTROL, 0},
222                 {FLASH_START_ADDR, SEQUENCE_0_START_ADDR},
223                 {FLASH_READ_BYTES, SEQUENCE_0_SIZE},
224                 {SEQ_RESET_LUT_START_ADDR, 0},
225                 {SEQ_RESET_LUT_DEST_SELECT, SEQ_SEQ_LUT},
226                 {PBC_CONTROL, 1},
227         };
228
229         static const struct picodlp_i2c_command init_cmd_set3[] = {
230                 {PBC_CONTROL, 0},
231                 {SEQ_RESET_LUT_DEST_SELECT, 0},
232                 {PBC_CONTROL, 0},
233                 {FLASH_START_ADDR, DRC_TABLE_0_START_ADDR},
234                 {FLASH_READ_BYTES, DRC_TABLE_0_SIZE},
235                 {SEQ_RESET_LUT_START_ADDR, 0},
236                 {SEQ_RESET_LUT_DEST_SELECT, SEQ_DRC_LUT_ALL},
237                 {PBC_CONTROL, 1},
238         };
239
240         static const struct picodlp_i2c_command init_cmd_set4[] = {
241                 {PBC_CONTROL, 0},
242                 {SEQ_RESET_LUT_DEST_SELECT, 0},
243                 {SDC_ENABLE, 1},
244                 {AGC_CTRL, 7},
245                 {CCA_C1A, 0x100},
246                 {CCA_C1B, 0x0},
247                 {CCA_C1C, 0x0},
248                 {CCA_C2A, 0x0},
249                 {CCA_C2B, 0x100},
250                 {CCA_C2C, 0x0},
251                 {CCA_C3A, 0x0},
252                 {CCA_C3B, 0x0},
253                 {CCA_C3C, 0x100},
254                 {CCA_C7A, 0x100},
255                 {CCA_C7B, 0x100},
256                 {CCA_C7C, 0x100},
257                 {CCA_ENABLE, 1},
258                 {CPU_IF_MODE, 1},
259                 {SHORT_FLIP, 1},
260                 {CURTAIN_CONTROL, 0},
261                 {DMD_PARK_TRIGGER, 0},
262                 {R_DRIVE_CURRENT, 0x298},
263                 {G_DRIVE_CURRENT, 0x298},
264                 {B_DRIVE_CURRENT, 0x298},
265                 {RGB_DRIVER_ENABLE, 7},
266                 {SEQ_CONTROL, 0},
267                 {ACTGEN_CONTROL, 0x10},
268                 {SEQUENCE_MODE, SEQ_LOCK},
269                 {DATA_FORMAT, RGB888},
270                 {INPUT_RESOLUTION, WVGA_864_LANDSCAPE},
271                 {INPUT_SOURCE, PARALLEL_RGB},
272                 {CPU_IF_SYNC_METHOD, 1},
273                 {SEQ_CONTROL, 1}
274         };
275
276         r = picodlp_i2c_write_array(client, init_cmd_set1,
277                                                 ARRAY_SIZE(init_cmd_set1));
278         if (r)
279                 return r;
280
281         r = picodlp_wait_for_dma_done(client);
282         if (r)
283                 return r;
284
285         r = picodlp_i2c_write_array(client, init_cmd_set2,
286                                         ARRAY_SIZE(init_cmd_set2));
287         if (r)
288                 return r;
289
290         r = picodlp_wait_for_dma_done(client);
291         if (r)
292                 return r;
293
294         r = picodlp_i2c_write_array(client, init_cmd_set3,
295                                         ARRAY_SIZE(init_cmd_set3));
296         if (r)
297                 return r;
298
299         r = picodlp_wait_for_dma_done(client);
300         if (r)
301                 return r;
302
303         r = picodlp_i2c_write_array(client, init_cmd_set4,
304                                         ARRAY_SIZE(init_cmd_set4));
305         if (r)
306                 return r;
307
308         return 0;
309 }
310
311 static int picodlp_i2c_probe(struct i2c_client *client,
312                 const struct i2c_device_id *id)
313 {
314         struct picodlp_i2c_data *picodlp_i2c_data;
315
316         picodlp_i2c_data = kzalloc(sizeof(struct picodlp_i2c_data), GFP_KERNEL);
317
318         if (!picodlp_i2c_data)
319                 return -ENOMEM;
320
321         mutex_init(&picodlp_i2c_data->xfer_lock);
322         i2c_set_clientdata(client, picodlp_i2c_data);
323
324         return 0;
325 }
326
327 static int picodlp_i2c_remove(struct i2c_client *client)
328 {
329         struct picodlp_i2c_data *picodlp_i2c_data =
330                                         i2c_get_clientdata(client);
331         kfree(picodlp_i2c_data);
332         return 0;
333 }
334
335 static struct i2c_driver picodlp_i2c_driver = {
336         .driver = {
337                 .name   = "picodlp_i2c_driver",
338         },
339         .probe          = picodlp_i2c_probe,
340         .remove         = picodlp_i2c_remove,
341         .id_table       = picodlp_i2c_id,
342 };
343
344 static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
345 {
346         int r, trial = 100;
347         struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
348         struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
349
350         if (dssdev->platform_enable) {
351                 r = dssdev->platform_enable(dssdev);
352                 if (r)
353                         return r;
354         }
355
356         gpio_set_value(picodlp_pdata->pwrgood_gpio, 0);
357         msleep(1);
358         gpio_set_value(picodlp_pdata->pwrgood_gpio, 1);
359
360         while (!gpio_get_value(picodlp_pdata->emu_done_gpio)) {
361                 if (!trial--) {
362                         dev_err(&dssdev->dev, "emu_done signal not"
363                                                 " going high\n");
364                         return -ETIMEDOUT;
365                 }
366                 msleep(5);
367         }
368         /*
369          * As per dpp2600 programming guide,
370          * it is required to sleep for 1000ms after emu_done signal goes high
371          * then only i2c commands can be successfully sent to dpp2600
372          */
373         msleep(1000);
374         r = omapdss_dpi_display_enable(dssdev);
375         if (r) {
376                 dev_err(&dssdev->dev, "failed to enable DPI\n");
377                 goto err1;
378         }
379
380         r = picodlp_i2c_init(picod->picodlp_i2c_client);
381         if (r)
382                 goto err;
383
384         dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
385
386         return r;
387 err:
388         omapdss_dpi_display_disable(dssdev);
389 err1:
390         if (dssdev->platform_disable)
391                 dssdev->platform_disable(dssdev);
392
393         return r;
394 }
395
396 static void picodlp_panel_power_off(struct omap_dss_device *dssdev)
397 {
398         struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
399
400         omapdss_dpi_display_disable(dssdev);
401
402         gpio_set_value(picodlp_pdata->emu_done_gpio, 0);
403         gpio_set_value(picodlp_pdata->pwrgood_gpio, 0);
404
405         if (dssdev->platform_disable)
406                 dssdev->platform_disable(dssdev);
407 }
408
409 static int picodlp_panel_probe(struct omap_dss_device *dssdev)
410 {
411         struct picodlp_data *picod;
412         struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
413         struct i2c_adapter *adapter;
414         struct i2c_client *picodlp_i2c_client;
415         int r = 0, picodlp_adapter_id;
416
417         dssdev->panel.config = OMAP_DSS_LCD_ONOFF | OMAP_DSS_LCD_IHS |
418                                 OMAP_DSS_LCD_IVS;
419         dssdev->panel.acb = 0x0;
420         dssdev->panel.timings = pico_ls_timings;
421
422         picod =  kzalloc(sizeof(struct picodlp_data), GFP_KERNEL);
423         if (!picod)
424                 return -ENOMEM;
425
426         mutex_init(&picod->lock);
427
428         picodlp_adapter_id = picodlp_pdata->picodlp_adapter_id;
429
430         adapter = i2c_get_adapter(picodlp_adapter_id);
431         if (!adapter) {
432                 dev_err(&dssdev->dev, "can't get i2c adapter\n");
433                 r = -ENODEV;
434                 goto err;
435         }
436
437         picodlp_i2c_client = i2c_new_device(adapter, &picodlp_i2c_board_info);
438         if (!picodlp_i2c_client) {
439                 dev_err(&dssdev->dev, "can't add i2c device::"
440                                          " picodlp_i2c_client is NULL\n");
441                 r = -ENODEV;
442                 goto err;
443         }
444
445         picod->picodlp_i2c_client = picodlp_i2c_client;
446
447         dev_set_drvdata(&dssdev->dev, picod);
448         return r;
449 err:
450         kfree(picod);
451         return r;
452 }
453
454 static void picodlp_panel_remove(struct omap_dss_device *dssdev)
455 {
456         struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
457
458         i2c_unregister_device(picod->picodlp_i2c_client);
459         dev_set_drvdata(&dssdev->dev, NULL);
460         dev_dbg(&dssdev->dev, "removing picodlp panel\n");
461
462         kfree(picod);
463 }
464
465 static int picodlp_panel_enable(struct omap_dss_device *dssdev)
466 {
467         struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
468         int r;
469
470         dev_dbg(&dssdev->dev, "enabling picodlp panel\n");
471
472         mutex_lock(&picod->lock);
473         if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
474                 mutex_unlock(&picod->lock);
475                 return -EINVAL;
476         }
477
478         r = picodlp_panel_power_on(dssdev);
479         mutex_unlock(&picod->lock);
480
481         return r;
482 }
483
484 static void picodlp_panel_disable(struct omap_dss_device *dssdev)
485 {
486         struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
487
488         mutex_lock(&picod->lock);
489         /* Turn off DLP Power */
490         if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
491                 picodlp_panel_power_off(dssdev);
492
493         dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
494         mutex_unlock(&picod->lock);
495
496         dev_dbg(&dssdev->dev, "disabling picodlp panel\n");
497 }
498
499 static int picodlp_panel_suspend(struct omap_dss_device *dssdev)
500 {
501         struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
502
503         mutex_lock(&picod->lock);
504         /* Turn off DLP Power */
505         if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
506                 mutex_unlock(&picod->lock);
507                 dev_err(&dssdev->dev, "unable to suspend picodlp panel,"
508                                         " panel is not ACTIVE\n");
509                 return -EINVAL;
510         }
511
512         picodlp_panel_power_off(dssdev);
513
514         dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
515         mutex_unlock(&picod->lock);
516
517         dev_dbg(&dssdev->dev, "suspending picodlp panel\n");
518         return 0;
519 }
520
521 static int picodlp_panel_resume(struct omap_dss_device *dssdev)
522 {
523         struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
524         int r;
525
526         mutex_lock(&picod->lock);
527         if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
528                 mutex_unlock(&picod->lock);
529                 dev_err(&dssdev->dev, "unable to resume picodlp panel,"
530                         " panel is not ACTIVE\n");
531                 return -EINVAL;
532         }
533
534         r = picodlp_panel_power_on(dssdev);
535         mutex_unlock(&picod->lock);
536         dev_dbg(&dssdev->dev, "resuming picodlp panel\n");
537         return r;
538 }
539
540 static void picodlp_get_resolution(struct omap_dss_device *dssdev,
541                                         u16 *xres, u16 *yres)
542 {
543         *xres = dssdev->panel.timings.x_res;
544         *yres = dssdev->panel.timings.y_res;
545 }
546
547 static struct omap_dss_driver picodlp_driver = {
548         .probe          = picodlp_panel_probe,
549         .remove         = picodlp_panel_remove,
550
551         .enable         = picodlp_panel_enable,
552         .disable        = picodlp_panel_disable,
553
554         .get_resolution = picodlp_get_resolution,
555
556         .suspend        = picodlp_panel_suspend,
557         .resume         = picodlp_panel_resume,
558
559         .driver         = {
560                 .name   = "picodlp_panel",
561                 .owner  = THIS_MODULE,
562         },
563 };
564
565 static int __init picodlp_init(void)
566 {
567         int r = 0;
568
569         r = i2c_add_driver(&picodlp_i2c_driver);
570         if (r) {
571                 printk(KERN_WARNING "picodlp_i2c_driver" \
572                         " registration failed\n");
573                 return r;
574         }
575
576         r = omap_dss_register_driver(&picodlp_driver);
577         if (r)
578                 i2c_del_driver(&picodlp_i2c_driver);
579
580         return r;
581 }
582
583 static void __exit picodlp_exit(void)
584 {
585         i2c_del_driver(&picodlp_i2c_driver);
586         omap_dss_unregister_driver(&picodlp_driver);
587 }
588
589 module_init(picodlp_init);
590 module_exit(picodlp_exit);
591
592 MODULE_AUTHOR("Mythri P K <mythripk@ti.com>");
593 MODULE_DESCRIPTION("picodlp driver");
594 MODULE_LICENSE("GPL");