123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458 |
- /* Copyright (c) 2009-2010, 2012 The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
- #include <linux/delay.h>
- #include <linux/gpio.h>
- #include "msm_fb.h"
- /* registers */
- #define GORDON_REG_NOP 0x00
- #define GORDON_REG_IMGCTL1 0x10
- #define GORDON_REG_IMGCTL2 0x11
- #define GORDON_REG_IMGSET1 0x12
- #define GORDON_REG_IMGSET2 0x13
- #define GORDON_REG_IVBP1 0x14
- #define GORDON_REG_IHBP1 0x15
- #define GORDON_REG_IVNUM1 0x16
- #define GORDON_REG_IHNUM1 0x17
- #define GORDON_REG_IVBP2 0x18
- #define GORDON_REG_IHBP2 0x19
- #define GORDON_REG_IVNUM2 0x1A
- #define GORDON_REG_IHNUM2 0x1B
- #define GORDON_REG_LCDIFCTL1 0x30
- #define GORDON_REG_VALTRAN 0x31
- #define GORDON_REG_AVCTL 0x33
- #define GORDON_REG_LCDIFCTL2 0x34
- #define GORDON_REG_LCDIFCTL3 0x35
- #define GORDON_REG_LCDIFSET1 0x36
- #define GORDON_REG_PCCTL 0x3C
- #define GORDON_REG_TPARAM1 0x40
- #define GORDON_REG_TLCDIF1 0x41
- #define GORDON_REG_TSSPB_ST1 0x42
- #define GORDON_REG_TSSPB_ED1 0x43
- #define GORDON_REG_TSCK_ST1 0x44
- #define GORDON_REG_TSCK_WD1 0x45
- #define GORDON_REG_TGSPB_VST1 0x46
- #define GORDON_REG_TGSPB_VED1 0x47
- #define GORDON_REG_TGSPB_CH1 0x48
- #define GORDON_REG_TGCK_ST1 0x49
- #define GORDON_REG_TGCK_ED1 0x4A
- #define GORDON_REG_TPCTL_ST1 0x4B
- #define GORDON_REG_TPCTL_ED1 0x4C
- #define GORDON_REG_TPCHG_ED1 0x4D
- #define GORDON_REG_TCOM_CH1 0x4E
- #define GORDON_REG_THBP1 0x4F
- #define GORDON_REG_TPHCTL1 0x50
- #define GORDON_REG_EVPH1 0x51
- #define GORDON_REG_EVPL1 0x52
- #define GORDON_REG_EVNH1 0x53
- #define GORDON_REG_EVNL1 0x54
- #define GORDON_REG_TBIAS1 0x55
- #define GORDON_REG_TPARAM2 0x56
- #define GORDON_REG_TLCDIF2 0x57
- #define GORDON_REG_TSSPB_ST2 0x58
- #define GORDON_REG_TSSPB_ED2 0x59
- #define GORDON_REG_TSCK_ST2 0x5A
- #define GORDON_REG_TSCK_WD2 0x5B
- #define GORDON_REG_TGSPB_VST2 0x5C
- #define GORDON_REG_TGSPB_VED2 0x5D
- #define GORDON_REG_TGSPB_CH2 0x5E
- #define GORDON_REG_TGCK_ST2 0x5F
- #define GORDON_REG_TGCK_ED2 0x60
- #define GORDON_REG_TPCTL_ST2 0x61
- #define GORDON_REG_TPCTL_ED2 0x62
- #define GORDON_REG_TPCHG_ED2 0x63
- #define GORDON_REG_TCOM_CH2 0x64
- #define GORDON_REG_THBP2 0x65
- #define GORDON_REG_TPHCTL2 0x66
- #define GORDON_REG_POWCTL 0x80
- static int lcdc_gordon_panel_off(struct platform_device *pdev);
- static int spi_cs;
- static int spi_sclk;
- static int spi_sdo;
- static int spi_sdi;
- static int spi_dac;
- static int bl_level;
- static unsigned char bit_shift[8] = { (1 << 7), /* MSB */
- (1 << 6),
- (1 << 5),
- (1 << 4),
- (1 << 3),
- (1 << 2),
- (1 << 1),
- (1 << 0) /* LSB */
- };
- struct gordon_state_type{
- boolean disp_initialized;
- boolean display_on;
- boolean disp_powered_up;
- };
- static struct gordon_state_type gordon_state = { 0 };
- static struct msm_panel_common_pdata *lcdc_gordon_pdata;
- static void serigo(uint16 reg, uint8 data)
- {
- unsigned int tx_val = ((0x00FF & reg) << 8) | data;
- unsigned char i, val = 0;
- /* Enable the Chip Select */
- gpio_set_value(spi_cs, 1);
- udelay(33);
- /* Transmit it in two parts, Higher Byte first, then Lower Byte */
- val = (unsigned char)((tx_val & 0xFF00) >> 8);
- /* Clock should be Low before entering ! */
- for (i = 0; i < 8; i++) {
- /* #1: Drive the Data (High or Low) */
- if (val & bit_shift[i])
- gpio_set_value(spi_sdi, 1);
- else
- gpio_set_value(spi_sdi, 0);
- /* #2: Drive the Clk High and then Low */
- udelay(33);
- gpio_set_value(spi_sclk, 1);
- udelay(33);
- gpio_set_value(spi_sclk, 0);
- }
- /* Idle state of SDO (MOSI) is Low */
- gpio_set_value(spi_sdi, 0);
- /* ..then Lower Byte */
- val = (uint8) (tx_val & 0x00FF);
- /* Before we enter here the Clock should be Low ! */
- for (i = 0; i < 8; i++) {
- /* #1: Drive the Data (High or Low) */
- if (val & bit_shift[i])
- gpio_set_value(spi_sdi, 1);
- else
- gpio_set_value(spi_sdi, 0);
- /* #2: Drive the Clk High and then Low */
- udelay(33);
- gpio_set_value(spi_sclk, 1);
- udelay(33);
- gpio_set_value(spi_sclk, 0);
- }
- /* Idle state of SDO (MOSI) is Low */
- gpio_set_value(spi_sdi, 0);
- /* Now Disable the Chip Select */
- udelay(33);
- gpio_set_value(spi_cs, 0);
- }
- static void spi_init(void)
- {
- /* Setting the Default GPIO's */
- spi_sclk = *(lcdc_gordon_pdata->gpio_num);
- spi_cs = *(lcdc_gordon_pdata->gpio_num + 1);
- spi_sdi = *(lcdc_gordon_pdata->gpio_num + 2);
- spi_sdo = *(lcdc_gordon_pdata->gpio_num + 3);
- /* Set the output so that we dont disturb the slave device */
- gpio_set_value(spi_sclk, 0);
- gpio_set_value(spi_sdi, 0);
- /* Set the Chip Select De-asserted */
- gpio_set_value(spi_cs, 0);
- }
- static void gordon_disp_powerup(void)
- {
- if (!gordon_state.disp_powered_up && !gordon_state.display_on) {
- /* Reset the hardware first */
- /* Include DAC power up implementation here */
- gordon_state.disp_powered_up = TRUE;
- }
- }
- static void gordon_init(void)
- {
- /* Image interface settings */
- serigo(GORDON_REG_IMGCTL2, 0x00);
- serigo(GORDON_REG_IMGSET1, 0x00);
- /* Exchange the RGB signal for J510(Softbank mobile) */
- serigo(GORDON_REG_IMGSET2, 0x12);
- serigo(GORDON_REG_LCDIFSET1, 0x00);
- /* Pre-charge settings */
- serigo(GORDON_REG_PCCTL, 0x09);
- serigo(GORDON_REG_LCDIFCTL2, 0x7B);
- mdelay(1);
- }
- static void gordon_disp_on(void)
- {
- if (gordon_state.disp_powered_up && !gordon_state.display_on) {
- gordon_init();
- mdelay(20);
- /* gordon_dispmode setting */
- serigo(GORDON_REG_TPARAM1, 0x30);
- serigo(GORDON_REG_TLCDIF1, 0x00);
- serigo(GORDON_REG_TSSPB_ST1, 0x8B);
- serigo(GORDON_REG_TSSPB_ED1, 0x93);
- serigo(GORDON_REG_TSCK_ST1, 0x88);
- serigo(GORDON_REG_TSCK_WD1, 0x00);
- serigo(GORDON_REG_TGSPB_VST1, 0x01);
- serigo(GORDON_REG_TGSPB_VED1, 0x02);
- serigo(GORDON_REG_TGSPB_CH1, 0x5E);
- serigo(GORDON_REG_TGCK_ST1, 0x80);
- serigo(GORDON_REG_TGCK_ED1, 0x3C);
- serigo(GORDON_REG_TPCTL_ST1, 0x50);
- serigo(GORDON_REG_TPCTL_ED1, 0x74);
- serigo(GORDON_REG_TPCHG_ED1, 0x78);
- serigo(GORDON_REG_TCOM_CH1, 0x50);
- serigo(GORDON_REG_THBP1, 0x84);
- serigo(GORDON_REG_TPHCTL1, 0x00);
- serigo(GORDON_REG_EVPH1, 0x70);
- serigo(GORDON_REG_EVPL1, 0x64);
- serigo(GORDON_REG_EVNH1, 0x56);
- serigo(GORDON_REG_EVNL1, 0x48);
- serigo(GORDON_REG_TBIAS1, 0x88);
- /* QVGA settings */
- serigo(GORDON_REG_TPARAM2, 0x28);
- serigo(GORDON_REG_TLCDIF2, 0x14);
- serigo(GORDON_REG_TSSPB_ST2, 0x49);
- serigo(GORDON_REG_TSSPB_ED2, 0x4B);
- serigo(GORDON_REG_TSCK_ST2, 0x4A);
- serigo(GORDON_REG_TSCK_WD2, 0x02);
- serigo(GORDON_REG_TGSPB_VST2, 0x02);
- serigo(GORDON_REG_TGSPB_VED2, 0x03);
- serigo(GORDON_REG_TGSPB_CH2, 0x2F);
- serigo(GORDON_REG_TGCK_ST2, 0x40);
- serigo(GORDON_REG_TGCK_ED2, 0x1E);
- serigo(GORDON_REG_TPCTL_ST2, 0x2C);
- serigo(GORDON_REG_TPCTL_ED2, 0x3A);
- serigo(GORDON_REG_TPCHG_ED2, 0x3C);
- serigo(GORDON_REG_TCOM_CH2, 0x28);
- serigo(GORDON_REG_THBP2, 0x4D);
- serigo(GORDON_REG_TPHCTL2, 0x1A);
- /* VGA settings */
- serigo(GORDON_REG_IVBP1, 0x02);
- serigo(GORDON_REG_IHBP1, 0x90);
- serigo(GORDON_REG_IVNUM1, 0xA0);
- serigo(GORDON_REG_IHNUM1, 0x78);
- /* QVGA settings */
- serigo(GORDON_REG_IVBP2, 0x02);
- serigo(GORDON_REG_IHBP2, 0x48);
- serigo(GORDON_REG_IVNUM2, 0x50);
- serigo(GORDON_REG_IHNUM2, 0x3C);
- /* Gordon Charge pump settings and ON */
- serigo(GORDON_REG_POWCTL, 0x03);
- mdelay(15);
- serigo(GORDON_REG_POWCTL, 0x07);
- mdelay(15);
- serigo(GORDON_REG_POWCTL, 0x0F);
- mdelay(15);
- serigo(GORDON_REG_AVCTL, 0x03);
- mdelay(15);
- serigo(GORDON_REG_POWCTL, 0x1F);
- mdelay(15);
- serigo(GORDON_REG_POWCTL, 0x5F);
- mdelay(15);
- serigo(GORDON_REG_POWCTL, 0x7F);
- mdelay(15);
- serigo(GORDON_REG_LCDIFCTL1, 0x02);
- mdelay(15);
- serigo(GORDON_REG_IMGCTL1, 0x00);
- mdelay(15);
- serigo(GORDON_REG_LCDIFCTL3, 0x00);
- mdelay(15);
- serigo(GORDON_REG_VALTRAN, 0x01);
- mdelay(15);
- serigo(GORDON_REG_LCDIFCTL1, 0x03);
- mdelay(1);
- gordon_state.display_on = TRUE;
- }
- }
- static int lcdc_gordon_panel_on(struct platform_device *pdev)
- {
- if (!gordon_state.disp_initialized) {
- /* Configure reset GPIO that drives DAC */
- lcdc_gordon_pdata->panel_config_gpio(1);
- spi_dac = *(lcdc_gordon_pdata->gpio_num + 4);
- gpio_set_value(spi_dac, 0);
- udelay(15);
- gpio_set_value(spi_dac, 1);
- spi_init(); /* LCD needs SPI */
- gordon_disp_powerup();
- gordon_disp_on();
- if (bl_level <= 1) {
- /* keep back light OFF */
- serigo(GORDON_REG_LCDIFCTL2, 0x0B);
- udelay(15);
- serigo(GORDON_REG_VALTRAN, 0x01);
- } else {
- /* keep back light ON */
- serigo(GORDON_REG_LCDIFCTL2, 0x7B);
- udelay(15);
- serigo(GORDON_REG_VALTRAN, 0x01);
- }
- gordon_state.disp_initialized = TRUE;
- }
- return 0;
- }
- static int lcdc_gordon_panel_off(struct platform_device *pdev)
- {
- if (gordon_state.disp_powered_up && gordon_state.display_on) {
- serigo(GORDON_REG_LCDIFCTL2, 0x7B);
- serigo(GORDON_REG_VALTRAN, 0x01);
- serigo(GORDON_REG_LCDIFCTL1, 0x02);
- serigo(GORDON_REG_LCDIFCTL3, 0x01);
- mdelay(20);
- serigo(GORDON_REG_VALTRAN, 0x01);
- serigo(GORDON_REG_IMGCTL1, 0x01);
- serigo(GORDON_REG_LCDIFCTL1, 0x00);
- mdelay(20);
- serigo(GORDON_REG_POWCTL, 0x1F);
- mdelay(40);
- serigo(GORDON_REG_POWCTL, 0x07);
- mdelay(40);
- serigo(GORDON_REG_POWCTL, 0x03);
- mdelay(40);
- serigo(GORDON_REG_POWCTL, 0x00);
- mdelay(40);
- lcdc_gordon_pdata->panel_config_gpio(0);
- gordon_state.display_on = FALSE;
- gordon_state.disp_initialized = FALSE;
- }
- return 0;
- }
- static void lcdc_gordon_set_backlight(struct msm_fb_data_type *mfd)
- {
- bl_level = mfd->bl_level;
- if (gordon_state.disp_initialized) {
- if (bl_level <= 1) {
- /* keep back light OFF */
- serigo(GORDON_REG_LCDIFCTL2, 0x0B);
- udelay(15);
- serigo(GORDON_REG_VALTRAN, 0x01);
- } else {
- /* keep back light ON */
- serigo(GORDON_REG_LCDIFCTL2, 0x7B);
- udelay(15);
- serigo(GORDON_REG_VALTRAN, 0x01);
- }
- }
- }
- static int __devinit gordon_probe(struct platform_device *pdev)
- {
- if (pdev->id == 0) {
- lcdc_gordon_pdata = pdev->dev.platform_data;
- return 0;
- }
- msm_fb_add_device(pdev);
- return 0;
- }
- static struct platform_driver this_driver = {
- .probe = gordon_probe,
- .driver = {
- .name = "lcdc_gordon_vga",
- },
- };
- static struct msm_fb_panel_data gordon_panel_data = {
- .on = lcdc_gordon_panel_on,
- .off = lcdc_gordon_panel_off,
- .set_backlight = lcdc_gordon_set_backlight,
- };
- static struct platform_device this_device = {
- .name = "lcdc_gordon_vga",
- .id = 1,
- .dev = {
- .platform_data = &gordon_panel_data,
- }
- };
- static int __init lcdc_gordon_panel_init(void)
- {
- int ret;
- struct msm_panel_info *pinfo;
- #ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
- if (msm_fb_detect_client("lcdc_gordon_vga"))
- return 0;
- #endif
- ret = platform_driver_register(&this_driver);
- if (ret)
- return ret;
- pinfo = &gordon_panel_data.panel_info;
- pinfo->xres = 480;
- pinfo->yres = 640;
- MSM_FB_SINGLE_MODE_PANEL(pinfo);
- pinfo->type = LCDC_PANEL;
- pinfo->pdest = DISPLAY_1;
- pinfo->wait_cycle = 0;
- pinfo->bpp = 24;
- pinfo->fb_num = 2;
- pinfo->clk_rate = 24500000;
- pinfo->bl_max = 4;
- pinfo->bl_min = 1;
- pinfo->lcdc.h_back_porch = 84;
- pinfo->lcdc.h_front_porch = 33;
- pinfo->lcdc.h_pulse_width = 60;
- pinfo->lcdc.v_back_porch = 0;
- pinfo->lcdc.v_front_porch = 2;
- pinfo->lcdc.v_pulse_width = 2;
- pinfo->lcdc.border_clr = 0; /* blk */
- pinfo->lcdc.underflow_clr = 0xff; /* blue */
- pinfo->lcdc.hsync_skew = 0;
- ret = platform_device_register(&this_device);
- if (ret)
- platform_driver_unregister(&this_driver);
- return ret;
- }
- module_init(lcdc_gordon_panel_init);
|