diff options
Diffstat (limited to 'ANDROID_3.4.5/drivers/video/wmt/devices')
17 files changed, 6561 insertions, 0 deletions
diff --git a/ANDROID_3.4.5/drivers/video/wmt/devices/Makefile b/ANDROID_3.4.5/drivers/video/wmt/devices/Makefile new file mode 100755 index 00000000..da55ae48 --- /dev/null +++ b/ANDROID_3.4.5/drivers/video/wmt/devices/Makefile @@ -0,0 +1,26 @@ +# +# Makefile for the Wonder Media framebuffer driver +# + +# wmt external video device +obj-$(CONFIG_LCD_WMT) += lcd-oem.o +obj-$(CONFIG_LCD_CHILIN_LW0700AT9003) += lcd-CHILIN-LW700at9003.o +obj-$(CONFIG_LCD_INNOLUX_AT070TN83) += lcd-INNOLUX-AT070TN83.o +obj-$(CONFIG_LCD_AUO_A080SN01) += lcd-AUO-A080SN01.o +obj-$(CONFIG_LCD_EKING_EK08009) += lcd-EKING-EK08009-70135.o +obj-$(CONFIG_LCD_HANNSTAR_HSD101PFW2) += lcd-HANNSTAR-HSD101PFW2.o +obj-y += lcd-lvds-1024x600.o +obj-y += lcd-gl5001w.o +#obj-y += cs8556.o +#obj-y += lcd-b079xan01.o +obj-y += lcd-spi.o +obj-y += lcd-setup.o + +obj-$(CONFIG_LCD_WMT) += lcd.o +#obj-$(CONFIG_HDMI_SIL902X_WMT) += sil902x.o +#obj-$(CONFIG_HDCP_SIL902X_WMT) += sil9024/ +obj-$(CONFIG_DVI_VT1632_WMT) += vt1632.o +obj-$(CONFIG_TV_VT1625_WMT) += vt1625.o +#obj-$(CONFIG_HDMI_CAT6610_WMT) += cat6612.o cat6610/ +#obj-$(CONFIG_HDMI_AD9389_WMT) += ad9389.o +#obj-$(CONFIG_EXTTV_ADV7393_WMT) += ad7393.o diff --git a/ANDROID_3.4.5/drivers/video/wmt/devices/cs8556.c b/ANDROID_3.4.5/drivers/video/wmt/devices/cs8556.c new file mode 100755 index 00000000..72097685 --- /dev/null +++ b/ANDROID_3.4.5/drivers/video/wmt/devices/cs8556.c @@ -0,0 +1,627 @@ +/*++ + * linux/drivers/video/wmt/cs8556.c + * WonderMedia video post processor (VPP) driver + * + * Copyright c 2013 WonderMedia Technologies, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * WonderMedia Technologies, Inc. + * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C +--*/ +/********************************************************************* +* REVISON HISTORY +* +* VERSION | DATE | AUTHORS | DESCRIPTION +* 1.0 | 2013/08/24 | Howay Huo | First Release +**********************************************************************/ + +#define CS8556_C +/* #define DEBUG */ +/*----------------------- DEPENDENCE -----------------------------------------*/ +#include <linux/i2c.h> +#include <mach/hardware.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +#include <linux/gpio.h> +#include <mach/wmt_iomux.h> +#include "../vout.h" + +/*----------------------- PRIVATE MACRO --------------------------------------*/ +/* #define VT1632_XXXX xxxx *//*Example*/ + + +/*----------------------- PRIVATE CONSTANTS ----------------------------------*/ +/* #define VT1632_XXXX 1 *//*Example*/ +#define CS8556_ADDR 0x3d +#define CS8556_NAME "CS8556" + +/*----------------------- PRIVATE TYPE --------------------------------------*/ +/* typedef xxxx vt1632_xxx_t; *//*Example*/ +struct avdetect_gpio_t { + unsigned int flag; + unsigned int gpiono; + unsigned int act; +}; + +/*----------EXPORTED PRIVATE VARIABLES are defined in vt1632.h -------------*/ +/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ +/* int vt1632_xxx; *//*Example*/ +static int s_cs8556_ready; +static int s_cs8556_init; +static struct i2c_client *s_cs8556_client; +static enum vout_tvformat_t s_tvformat = TV_MAX; +static int s_irq_init; +static struct avdetect_gpio_t s_avdetect_gpio = {0, WMT_PIN_GP0_GPIO5, 1}; + +static unsigned char s_CS8556_Original_Offset0[] = { + 0xF0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, + 0x80, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char s_RGB888_To_PAL_Offset0[] = { + 0x01, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5F, 0x03, 0x3F, 0x00, 0x7D, 0x00, 0x53, 0x03, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x02, 0x04, 0x00, 0x2E, 0x00, 0x62, 0x02, + 0x00, 0x00, 0x84, 0x00, 0x2B, 0x00, 0x36, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xBF, 0x06, 0x7F, 0x00, 0xFE, 0x00, 0xA4, 0x06, + 0x00, 0x00, 0x2D, 0x11, 0x3C, 0x01, 0x3A, 0x01, + 0x70, 0x02, 0x04, 0x00, 0x12, 0x00, 0x34, 0x01, + 0x00, 0x00, 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x41, 0x18, 0x09, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x24, 0x1A, 0x00, 0x01, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x01, 0xA4, 0x06, 0x0B, 0x00, 0x07, 0x01, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x01 +}; + +static unsigned char s_RGB888_To_NTSC_Offset0[] = { + 0x01, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x59, 0x03, 0x3D, 0x00, 0x7E, 0x00, 0x49, 0x03, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x0C, 0x02, 0x05, 0x00, 0x21, 0x00, 0x03, 0x02, + 0x00, 0x00, 0x7A, 0x00, 0x23, 0x00, 0x16, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xB3, 0x06, 0x7F, 0x00, 0x00, 0x01, 0xA4, 0x06, + 0x00, 0x00, 0x05, 0x50, 0x00, 0x01, 0x07, 0x01, + 0x0C, 0x02, 0x02, 0x00, 0x12, 0x00, 0x07, 0x01, + 0x00, 0x00, 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x41, 0x18, 0x09, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x24, 0x1A, 0x00, 0x01, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x01, 0xA4, 0x06, 0x0B, 0x00, 0x07, 0x01, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00 +}; + +/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ +/* void vt1632_xxx(void); *//*Example*/ +static int I2CMultiPageRead(unsigned char maddr, unsigned char page, + unsigned char saddr, int number, unsigned char *value) +{ + int ret; + unsigned char wbuf[2]; + struct i2c_msg rd[2]; + + wbuf[0] = page; + wbuf[1] = saddr; + + rd[0].addr = maddr; + rd[0].flags = 0; + rd[0].len = 2; + rd[0].buf = wbuf; + + rd[1].addr = maddr; + rd[1].flags = I2C_M_RD; + rd[1].len = number; + rd[1].buf = value; + + ret = i2c_transfer(s_cs8556_client->adapter, rd, ARRAY_SIZE(rd)); + + if (ret != ARRAY_SIZE(rd)) { + DBG_ERR("fail\n"); + return -1; + } + + return 0; +} + +static int I2CMultiPageWrite(unsigned char maddr, unsigned char page, + unsigned char saddr, int number, unsigned char *value) +{ + int ret; + unsigned char *pbuf; + struct i2c_msg wr[1]; + + pbuf = kmalloc(number + 2, GFP_KERNEL); + if (!pbuf) { + DBG_ERR("alloc memory fail\n"); + return -1; + } + + *pbuf = page; + *(pbuf + 1) = saddr; + + memcpy(pbuf + 2, value, number); + + wr[0].addr = maddr; + wr[0].flags = 0; + wr[0].len = number + 2; + wr[0].buf = pbuf; + + ret = i2c_transfer(s_cs8556_client->adapter, wr, ARRAY_SIZE(wr)); + + if (ret != ARRAY_SIZE(wr)) { + DBG_ERR("fail\n"); + kfree(pbuf); + return -1; + } + + kfree(pbuf); + return 0 ; +} + +/************************ i2c device struct definition ************************/ +static int __devinit cs8556_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + DBGMSG("cs8556_i2c_probe\n"); + + return 0; +} + +static int __devexit cs8556_i2c_remove(struct i2c_client *client) +{ + DBGMSG("cs8556_i2c_remove\n"); + + return 0; +} + + +static const struct i2c_device_id cs8556_i2c_id[] = { + {CS8556_NAME, 0}, + { }, +}; +MODULE_DEVICE_TABLE(i2c, cs8556_i2c_id); + +static struct i2c_board_info __initdata cs8556_i2c_board_info[] = { + { + I2C_BOARD_INFO(CS8556_NAME, CS8556_ADDR), + }, +}; + +static struct i2c_driver cs8556_i2c_driver = { + .driver = { + .name = CS8556_NAME, + .owner = THIS_MODULE, + }, + .probe = cs8556_i2c_probe, + .remove = __devexit_p(cs8556_i2c_remove), + .id_table = cs8556_i2c_id, +}; + +/*----------------------- Function Body --------------------------------------*/ +static void avdetect_irq_enable(void) +{ + wmt_gpio_unmask_irq(s_avdetect_gpio.gpiono); +} + +static void avdetect_irq_disable(void) +{ + wmt_gpio_mask_irq(s_avdetect_gpio.gpiono); +} + +int avdetect_irq_hw_init(int resume) +{ + int ret; + + if (!resume) { + ret = gpio_request(s_avdetect_gpio.gpiono, + "avdetect irq"); /* enable gpio */ + if (ret < 0) { + DBG_ERR("gpio(%d) request fail for avdetect irq\n", + s_avdetect_gpio.gpiono); + return ret; + } + } else + gpio_re_enabled(s_avdetect_gpio.gpiono); /* re-enable gpio */ + + gpio_direction_input(s_avdetect_gpio.gpiono); /* gpio input */ + + /* enable pull and pull-up */ + wmt_gpio_setpull(s_avdetect_gpio.gpiono, WMT_GPIO_PULL_UP); + + /* disable interrupt */ + wmt_gpio_mask_irq(s_avdetect_gpio.gpiono); + + /* rise edge and clear interrupt */ + wmt_gpio_set_irq_type(s_avdetect_gpio.gpiono, IRQ_TYPE_EDGE_BOTH); + + return 0; +} + +/* +static void avdetect_irq_hw_free(void) +{ + gpio_free(AVDETECT_IRQ_PIN); + +} +*/ + +static irqreturn_t avdetect_irq_handler(int irq, void *dev_id) +{ + /* DPRINT("avdetect_irq_handler\n"); */ + + if (!gpio_irqstatus(s_avdetect_gpio.gpiono)) + return IRQ_NONE; + + wmt_gpio_ack_irq(s_avdetect_gpio.gpiono); /* clear interrupt */ + + /* DPRINT("cvbs hotplug interrupt\n"); */ + if (!is_gpio_irqenable(s_avdetect_gpio.gpiono)) { + /* pr_err("avdetect irq is disabled\n"); */ + return IRQ_HANDLED; + } else + return IRQ_WAKE_THREAD; +} + +static irqreturn_t avdetect_irq_thread(int irq, void *dev) +{ + /* DPRINT(cvbs_hotplug_irq_thread\n"); */ + + if (s_avdetect_gpio.act == 1) { + if (gpio_get_value(s_avdetect_gpio.gpiono)) + DPRINT("av plug in\n"); + else + DPRINT("av plug out\n"); + } else { + if (gpio_get_value(s_avdetect_gpio.gpiono)) + DPRINT("av plug out\n"); + else + DPRINT("av plug in\n"); + } + + return IRQ_HANDLED; +} + +int cs8556_check_plugin(int hotplug) +{ + return 1; +} + +int cs8556_init(struct vout_t *vo) +{ + int ret; + char buf[40] = {0}; + int varlen = 40; + int no = 1; /* default i2c1 */ + int num; + unsigned char rbuf[256] = {0}; + struct i2c_adapter *adapter = NULL; + + DPRINT("cs8556_init\n"); + + if (s_tvformat == TV_MAX) { + if (wmt_getsyspara("wmt.display.tvformat", buf, &varlen) == 0) { + if (!strnicmp(buf, "PAL", 3)) + s_tvformat = TV_PAL; + else if (!strnicmp(buf, "NTSC", 4)) + s_tvformat = TV_NTSC; + else + s_tvformat = TV_UNDEFINED; + } else + s_tvformat = TV_UNDEFINED; + } + + if (s_tvformat == TV_UNDEFINED) + goto err0; + + if (!s_cs8556_init) { + if (wmt_getsyspara("wmt.cs8556.i2c", buf, &varlen) == 0) { + if (strlen(buf) > 0) + no = buf[0] - '0'; + } + + adapter = i2c_get_adapter(no); + if (adapter == NULL) { + DBG_ERR("Can't get i2c adapter,client address error\n"); + goto err0; + } + + s_cs8556_client = + i2c_new_device(adapter, cs8556_i2c_board_info); + if (s_cs8556_client == NULL) { + DBG_ERR("allocate i2c client failed\n"); + goto err0; + } + + i2c_put_adapter(adapter); + + ret = i2c_add_driver(&cs8556_i2c_driver); + if (ret != 0) { + DBG_ERR("Failed register CS8556 I2C driver: %d\n", ret); + goto err1; + } + + if (wmt_getsyspara("wmt.io.avdetect", buf, &varlen) == 0) { + num = sscanf(buf, "%d:%d:%d", &s_avdetect_gpio.flag, + &s_avdetect_gpio.gpiono, &s_avdetect_gpio.act); + + if (num != 3) + DBG_ERR("wmt.io.avdetect err. num = %d\n", num); + else { + if (s_avdetect_gpio.gpiono > 19) + DBG_ERR("invalid avdetect gpio : %d\n", + s_avdetect_gpio.gpiono); + else { + ret = avdetect_irq_hw_init(0); + if (!ret) { + ret = request_threaded_irq( + IRQ_GPIO, + avdetect_irq_handler, + avdetect_irq_thread, + IRQF_SHARED, + CS8556_NAME, + s_cs8556_client); + + if (ret) + DBG_ERR("irq req %d\n", + ret); + else { + s_irq_init = 1; + DPRINT("avdetect irq"); + DPRINT("req success\n"); + } + } + } + } + } + + s_cs8556_init = 1; + } else { + if (s_irq_init) + avdetect_irq_hw_init(1); + } + + ret = I2CMultiPageRead(CS8556_ADDR, 0x00, 0x00, 256, rbuf); + if (ret) { + DBG_ERR("I2C address 0x%02X is not found\n", CS8556_ADDR); + goto err0; + } + + switch (s_tvformat) { + case TV_PAL: + ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 256, + s_RGB888_To_PAL_Offset0); + if (ret) { + DBG_ERR("PAL init fail\n"); + goto err0; + } + break; + case TV_NTSC: + ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 256, + s_RGB888_To_NTSC_Offset0); + if (ret) { + DBG_ERR("NTSC init fail\n"); + goto err0; + } + break; + default: + goto err0; + break; + } + + if (s_irq_init) + avdetect_irq_enable(); + + s_cs8556_ready = 1; + + return 0; +#if 0 +err3: + cvbs_hotplug_irq_disable(); + free_irq(IRQ_GPIO, s_cs8556_client); + cvbs_hotplug_irq_hw_free(); +err2: + i2c_del_driver(&cs8556_i2c_driver); +#endif +err1: + i2c_unregister_device(s_cs8556_client); +err0: + s_cs8556_ready = 0; + return -1; +} + +static int cs8556_set_mode(unsigned int *option) +{ + if (!s_cs8556_ready) + return -1; + + return 0; +} + +static void cs8556_set_power_down(int enable) +{ + int ret; + unsigned char rbuf[256] = {0}; + + if (!s_cs8556_ready) + return; + + DBGMSG("cs8556_set_power_down(%d)\n", enable); + + if (enable) { + ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 5, + s_CS8556_Original_Offset0); + if (ret) + DBG_ERR("I2C write Original_Offset0 fail\n"); + else { + if (s_irq_init) + avdetect_irq_disable(); + } + } else { + ret = I2CMultiPageRead(CS8556_ADDR, 0x00, 0x00, 256, rbuf); + if (ret) { + DBG_ERR("I2C read Offset0 fail\n"); + return; + } + + switch (s_tvformat) { + case TV_PAL: + if (memcmp(rbuf, s_RGB888_To_PAL_Offset0, 0x50) != 0) { + ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, + 0x00, 256, s_RGB888_To_PAL_Offset0); + if (ret) + DBG_ERR("I2C write PAL_Offset0 fail\n"); + } + break; + case TV_NTSC: + if (memcmp(rbuf, s_RGB888_To_NTSC_Offset0, 0x50) != 0) { + ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, + 0x00, 256, s_RGB888_To_NTSC_Offset0); + if (ret) + DBG_ERR("I2C wr NTSC_Offset0 fail\n"); + } + break; + default: + break; + } + } +} + +static int cs8556_config(struct vout_info_t *info) +{ + return 0; +} + +static int cs8556_get_edid(char *buf) +{ + return -1; +} + +/* +static int cs8556_interrupt(void) +{ + return cs8556_check_plugin(1); +} +*/ + +void cs8556_read(void) +{ + int i, ret; + unsigned char rbuf[256] = {0}; + + ret = I2CMultiPageRead(CS8556_ADDR, 0x00, 0x00, 256, rbuf); + if (!ret) { + DPRINT("CS8556 Read offset0 data as follows:\n"); + for (i = 0; i < 256;) { + DPRINT("0x%02X,", rbuf[i]); + if ((++i) % 16 == 0) + DPRINT("\n"); + } + } +} + +int cvbs_is_ready(void) +{ + return s_cs8556_ready; +} + +/*----------------------- vout device plugin ---------------------------------*/ +struct vout_dev_t cs8556_vout_dev_ops = { + .name = CS8556_NAME, + .mode = VOUT_INF_DVI, + + .init = cs8556_init, + .set_power_down = cs8556_set_power_down, + .set_mode = cs8556_set_mode, + .config = cs8556_config, + .check_plugin = cs8556_check_plugin, + .get_edid = cs8556_get_edid, +/* .interrupt = cs8556_interrupt, */ +}; + +int cs8556_module_init(void) +{ + vout_device_register(&cs8556_vout_dev_ops); + return 0; +} /* End of cs8556_module_init */ +module_init(cs8556_module_init); +/*--------------------End of Function Body -----------------------------------*/ +#undef CS8556_C diff --git a/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-AUO-A080SN01.c b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-AUO-A080SN01.c new file mode 100755 index 00000000..f4602a16 --- /dev/null +++ b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-AUO-A080SN01.c @@ -0,0 +1,95 @@ +/*++ + * linux/drivers/video/wmt/lcd-AUO-A080SN01.c + * WonderMedia video post processor (VPP) driver + * + * Copyright c 2014 WonderMedia Technologies, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * WonderMedia Technologies, Inc. + * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C +--*/ + +#define LCD_AUO_A080SN01_C +/* #define DEBUG */ +/*----------------------- DEPENDENCE -----------------------------------------*/ +#include "../lcd.h" + +/*----------------------- PRIVATE MACRO --------------------------------------*/ +/* #define LCD_A080SN01_XXXX xxxx *//*Example*/ + +/*----------------------- PRIVATE CONSTANTS ----------------------------------*/ +/* #define LCD_A080SN01_XXXX 1 *//*Example*/ + +/*----------------------- PRIVATE TYPE --------------------------------------*/ +/* typedef xxxx lcd_xxx_t; *//*Example*/ + +/*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/ +static void lcd_a080sn01_initial(void); + +/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ +/* int lcd_xxx; *//*Example*/ +struct lcd_parm_t lcd_a080sn01_parm = { + .bits_per_pixel = 24, + .capability = 0, + .vmode = { + .name = "AUO A080SN01", + .refresh = 60, + .xres = 800, + .yres = 600, + .pixclock = KHZ2PICOS(40000), + .left_margin = 88, + .right_margin = 40, + .upper_margin = 24, + .lower_margin = 1, + .hsync_len = 128, + .vsync_len = 3, + .sync = 0, + .vmode = 0, + .flag = 0, + }, + .width = 162, + .height = 121, + .initial = lcd_a080sn01_initial, +}; + +/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ +/* void lcd_xxx(void); *//*Example*/ + +/*----------------------- Function Body --------------------------------------*/ +static void lcd_a080sn01_initial(void) +{ + DPRINT("lcd_a080sn01_initial\n"); + + /* TODO */ +} + +struct lcd_parm_t *lcd_a080sn01_get_parm(int arg) +{ + return &lcd_a080sn01_parm; +} + +int lcd_a080sn01_init(void) +{ + int ret; + + ret = lcd_panel_register(LCD_AUO_A080SN01, + (void *) lcd_a080sn01_get_parm); + return ret; +} /* End of lcd_a080sn01_init */ +module_init(lcd_a080sn01_init); + +/*--------------------End of Function Body -----------------------------------*/ +#undef LCD_AUO_A080SN01_C + diff --git a/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-CHILIN-LW700at9003.c b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-CHILIN-LW700at9003.c new file mode 100755 index 00000000..af9752b3 --- /dev/null +++ b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-CHILIN-LW700at9003.c @@ -0,0 +1,104 @@ +/*++ + * linux/drivers/video/wmt/lcd-CHILIN-LW700at9003.c + * WonderMedia video post processor (VPP) driver + * + * Copyright c 2014 WonderMedia Technologies, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * WonderMedia Technologies, Inc. + * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C +--*/ + +#define LCD_CHILIN_LW700AT9003_C +/* #define DEBUG */ +/*----------------------- DEPENDENCE -----------------------------------------*/ +#include "../lcd.h" + +/*----------------------- PRIVATE MACRO --------------------------------------*/ +/* #define LCD_LW700AT9003_XXXX xxxx *//*Example*/ + + +/*----------------------- PRIVATE CONSTANTS ----------------------------------*/ +/* #define LCD_LW700AT9003_XXXX 1 *//*Example*/ + +/*----------------------- PRIVATE TYPE --------------------------------------*/ +/* typedef xxxx lcd_xxx_t; *//*Example*/ + +/*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/ +static void lcd_lw700at9003_power_on(void); +static void lcd_lw700at9003_power_off(void); + +/*----------------------- INTERNAL PRIVATE VARIABLES ------------------------*/ +/* int lcd_xxx; *//*Example*/ +struct lcd_parm_t lcd_lw700at9003_parm = { + .bits_per_pixel = 18, + .capability = LCD_CAP_CLK_HI, + .vmode = { + .name = "CHILIN LW700AT9003", + .refresh = 48, + .xres = 800, + .yres = 480, + .pixclock = KHZ2PICOS(33260), + .left_margin = 105, + .right_margin = 105, + .upper_margin = 23, + .lower_margin = 22, + .hsync_len = 40, + .vsync_len = 5, + .sync = 0, + .vmode = 0, + .flag = 0, + }, + .width = 152, + .height = 91, + .initial = lcd_lw700at9003_power_on, + .uninitial = lcd_lw700at9003_power_off, +}; + +/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ +/* void lcd_xxx(void); *//*Example*/ + +/*----------------------- Function Body --------------------------------------*/ +static void lcd_lw700at9003_power_on(void) +{ + DPRINT("lcd_lw700at9003_power_on\n"); + /* TODO */ +} + +static void lcd_lw700at9003_power_off(void) +{ + DPRINT("lcd_lw700at9003_power_off\n"); + + /* TODO */ +} + +struct lcd_parm_t *lcd_lw700at9003_get_parm(int arg) +{ + lcd_lw700at9003_parm.bits_per_pixel = arg; + return &lcd_lw700at9003_parm; +} + +int lcd_lw700at9003_init(void) +{ + int ret; + + ret = lcd_panel_register(LCD_CHILIN_LW0700AT9003, + (void *) lcd_lw700at9003_get_parm); + return ret; +} /* End of lcd_oem_init */ +module_init(lcd_lw700at9003_init); + +/*--------------------End of Function Body -----------------------------------*/ +#undef LCD_CHILIN_LW700AT9003_C diff --git a/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-EKING-EK08009-70135.c b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-EKING-EK08009-70135.c new file mode 100755 index 00000000..1d401886 --- /dev/null +++ b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-EKING-EK08009-70135.c @@ -0,0 +1,103 @@ +/*++ + * linux/drivers/video/wmt/lcd-EKING_EK08009-70135.c + * WonderMedia video post processor (VPP) driver + * + * Copyright c 2014 WonderMedia Technologies, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * WonderMedia Technologies, Inc. + * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C +--*/ + +#define LCD_EKING_EK08009_C +/* #define DEBUG */ +/*----------------------- DEPENDENCE -----------------------------------------*/ +#include "../lcd.h" + +/*----------------------- PRIVATE MACRO --------------------------------------*/ +/* #define LCD_EK08009_XXXX xxxx *//*Example*/ + +/*----------------------- PRIVATE CONSTANTS ----------------------------------*/ +/* #define LCD_EK08009_XXXX 1 *//*Example*/ + +/*----------------------- PRIVATE TYPE --------------------------------------*/ +/* typedef xxxx lcd_xxx_t; *//*Example*/ + +/*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/ +static void lcd_ek08009_power_on(void); +static void lcd_ek08009_power_off(void); + +/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ +/* int lcd_xxx; *//*Example*/ +struct lcd_parm_t lcd_ek08009_parm = { + .bits_per_pixel = 18, + .capability = LCD_CAP_CLK_HI, + .vmode = { + .name = "EKING EK08009", + .refresh = 60, + .xres = 800, + .yres = 600, + .pixclock = KHZ2PICOS(40000), + .left_margin = 46, + .right_margin = 210, + .upper_margin = 24, + .lower_margin = 12, + .hsync_len = 1, + .vsync_len = 1, + .sync = 0, + .vmode = 0, + .flag = 0, + }, + .width = 162, + .height = 162, + .initial = lcd_ek08009_power_on, + .uninitial = lcd_ek08009_power_off, +}; + +/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ +/* void lcd_xxx(void); *//*Example*/ + +/*----------------------- Function Body --------------------------------------*/ +static void lcd_ek08009_power_on(void) +{ + DPRINT("lcd_ek08009_power_on\n"); + + /* TODO */ +} + +static void lcd_ek08009_power_off(void) +{ + DPRINT("lcd_ek08009_power_off\n"); + + /* TODO */ +} + +struct lcd_parm_t *lcd_ek08009_get_parm(int arg) +{ + return &lcd_ek08009_parm; +} + +int lcd_ek08009_init(void) +{ + int ret; + + ret = lcd_panel_register(LCD_EKING_EK08009, + (void *) lcd_ek08009_get_parm); + return ret; +} /* End of lcd_oem_init */ +module_init(lcd_ek08009_init); + +/*--------------------End of Function Body -----------------------------------*/ +#undef LCD_EKING_EK08009_C diff --git a/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-HANNSTAR-HSD101PFW2.c b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-HANNSTAR-HSD101PFW2.c new file mode 100755 index 00000000..438e3fee --- /dev/null +++ b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-HANNSTAR-HSD101PFW2.c @@ -0,0 +1,103 @@ +/*++ + * linux/drivers/video/wmt/lcd-HANNSTAR-HSD101PFW2.c + * WonderMedia video post processor (VPP) driver + * + * Copyright c 2014 WonderMedia Technologies, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * WonderMedia Technologies, Inc. + * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C +--*/ + +#define LCD_EKING_HSD101PFW2_C +/* #define DEBUG */ +/*----------------------- DEPENDENCE -----------------------------------------*/ +#include "../lcd.h" + +/*----------------------- PRIVATE MACRO --------------------------------------*/ +/* #define LCD_HSD101PFW2_XXXX xxxx *//*Example*/ + +/*----------------------- PRIVATE CONSTANTS ----------------------------------*/ +/* #define LCD_HSD101PFW2_XXXX 1 *//*Example*/ + +/*----------------------- PRIVATE TYPE --------------------------------------*/ +/* typedef xxxx lcd_xxx_t; *//*Example*/ + +/*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/ +static void lcd_HSD101PFW2_power_on(void); +static void lcd_HSD101PFW2_power_off(void); + +/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ +/* int lcd_xxx; *//*Example*/ +struct lcd_parm_t lcd_HSD101PFW2_parm = { + .bits_per_pixel = 18, + .capability = 0, + .vmode = { + .name = "HANNSTAR HSD101PFW2", + .refresh = 60, + .xres = 1024, + .yres = 600, + .pixclock = KHZ2PICOS(45000), + .left_margin = 44, + .right_margin = 88, + .upper_margin = 10, + .lower_margin = 5, + .hsync_len = 44, + .vsync_len = 10, + .sync = FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .width = 222, + .height = 125, + .initial = lcd_HSD101PFW2_power_on, + .uninitial = lcd_HSD101PFW2_power_off, +}; + +/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ +/* void lcd_xxx(void); *//*Example*/ + +/*----------------------- Function Body --------------------------------------*/ +static void lcd_HSD101PFW2_power_on(void) +{ + DPRINT("lcd_HSD101PFW2_power_on\n"); + + /* TODO */ +} + +static void lcd_HSD101PFW2_power_off(void) +{ + DPRINT("lcd_HSD101PFW2_power_off\n"); + + /* TODO */ +} + +struct lcd_parm_t *lcd_HSD101PFW2_get_parm(int arg) +{ + return &lcd_HSD101PFW2_parm; +} + +int lcd_HSD101PFW2_init(void) +{ + int ret; + + ret = lcd_panel_register(LCD_HANNSTAR_HSD101PFW2, + (void *) lcd_HSD101PFW2_get_parm); + return ret; +} /* End of lcd_oem_init */ +module_init(lcd_HSD101PFW2_init); + +/*--------------------End of Function Body -----------------------------------*/ +#undef LCD_EKING_HSD101PFW2_C diff --git a/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-INNOLUX-AT070TN83.c b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-INNOLUX-AT070TN83.c new file mode 100755 index 00000000..7c1da494 --- /dev/null +++ b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-INNOLUX-AT070TN83.c @@ -0,0 +1,118 @@ +/*++ + * linux/drivers/video/wmt/lcd-INNOLUX-AT070TN83.c + * WonderMedia video post processor (VPP) driver + * + * Copyright c 2014 WonderMedia Technologies, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * WonderMedia Technologies, Inc. + * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C +--*/ + +#define LCD_INNOLUX_AT070TN83_C +/* #define DEBUG */ +/*----------------------- DEPENDENCE -----------------------------------------*/ +#include "../lcd.h" + +/*----------------------- PRIVATE MACRO --------------------------------------*/ +/* #define LCD_AT070TN83_XXXX xxxx *//*Example*/ + +/*----------------------- PRIVATE CONSTANTS ----------------------------------*/ +/* #define LCD_AT070TN83_XXXX 1 *//*Example*/ + +/*----------------------- PRIVATE TYPE --------------------------------------*/ +/* typedef xxxx lcd_xxx_t; *//*Example*/ + +/*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/ +static void lcd_at070tn83_initial(void); +static void lcd_at070tn83_uninitial(void); + +/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ +/* int lcd_xxx; *//*Example*/ +struct lcd_parm_t lcd_at070tn83_parm = { + .bits_per_pixel = 18, + .capability = LCD_CAP_CLK_HI, + .vmode = { + .name = "INNOLUX AT707TN83", + .refresh = 60, + .xres = 800, + .yres = 480, + .pixclock = KHZ2PICOS(33333), + .left_margin = 45, + .right_margin = 210, + .upper_margin = 22, + .lower_margin = 22, + .hsync_len = 1, + .vsync_len = 1, + .sync = 0, + .vmode = 0, + .flag = 0, + }, + .width = 154, + .height = 85, + .initial = lcd_at070tn83_initial, + .uninitial = lcd_at070tn83_uninitial, +}; + +/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ +/* void lcd_xxx(void); *//*Example*/ + +/*----------------------- Function Body --------------------------------------*/ +static void lcd_at070tn83_initial(void) +{ +#if 0 + outl(inl(GPIO_BASE_ADDR + 0x80) | BIT0, GPIO_BASE_ADDR + 0x80); + outl(inl(GPIO_BASE_ADDR + 0x4C) | BIT28, GPIO_BASE_ADDR + 0x4C); + outl(inl(GPIO_BASE_ADDR + 0x8C) | BIT28, GPIO_BASE_ADDR + 0x8C); + /* DVDD */ + /* T2 > 0ms */ /* AVDD/VCOM(NANDQS) */ + outl(inl(GPIO_BASE_ADDR + 0xCC) | BIT28, GPIO_BASE_ADDR + 0xCC); + /* T4 > 0ms */ + /* VGH */ + /* 0 < T6 <= 10ms */ + lcd_enable_signal(1); /* signal, DVO enable */ + lcd_oem_enable_backlight(200); /* T12 > 200ms, BL(bit0) */ +#endif +} + +static void lcd_at070tn83_uninitial(void) +{ +#if 0 + /* BL(bit0) */ + outl(inl(GPIO_BASE_ADDR + 0xC0) & ~BIT0, GPIO_BASE_ADDR + 0xC0); + mdelay(200); /* T12 > 200ms */ + lcd_enable_signal(0); /* singal, DVO enable */ + /* AVDD/VCOM(NANDQS) */ + outl(inl(GPIO_BASE_ADDR + 0xCC) & ~BIT28, GPIO_BASE_ADDR + 0xCC); +#endif +} + +struct lcd_parm_t *lcd_at070tn83_get_parm(int arg) +{ + return &lcd_at070tn83_parm; +} + +int lcd_at070tn83_init(void) +{ + int ret; + + ret = lcd_panel_register(LCD_INNOLUX_AT070TN83, + (void *) lcd_at070tn83_get_parm); + return ret; +} /* End of lcd_oem_init */ +module_init(lcd_at070tn83_init); + +/*--------------------End of Function Body -----------------------------------*/ +#undef LCD_INNOLUX_AT070TN83_C diff --git a/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-b079xan01.c b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-b079xan01.c new file mode 100755 index 00000000..05a6e957 --- /dev/null +++ b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-b079xan01.c @@ -0,0 +1,363 @@ +/*++
+ * linux/drivers/video/wmt/lcd-b079xan01.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#include <linux/delay.h> + +#include <mach/hardware.h> +#include <linux/spi/spi.h> +#include <mach/wmt-spi.h> + +#include <linux/gpio.h> +#include <mach/wmt_iomux.h> + +#include "../lcd.h" + +#define DRIVERNAME "ssd2828" + +static struct lcd_parm_t lcd_b079xan01_parm = { + .bits_per_pixel = 24, + .capability = 0, + .vmode = { + .name = "B079XAN01", + .refresh = 60, + .xres = 768, + .yres = 1024, + .pixclock = KHZ2PICOS(64800), + .left_margin = 56, + .right_margin = 60, + .upper_margin = 30, + .lower_margin = 36, + .hsync_len = 64, + .vsync_len = 50, + .sync = 0, /* FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT, */ + .vmode = 0, + .flag = 0, + }, + .width = 120, + .height = 160, +#if 0 + .initial = lcd_power_on, + .uninitial = lcd_power_off, +#endif +}; + +static struct lcd_parm_t *lcd_b079xan01_get_parm(int arg) +{ + return &lcd_b079xan01_parm; +} + +static int lcd_b079xan01_init(void) +{ + return lcd_panel_register(LCD_B079XAN01, + (void *) lcd_b079xan01_get_parm); +} + +struct ssd2828_chip { + struct spi_device *spi; + int gpio_reset; +}; + +static int ssd2828_read(struct spi_device *spi, uint8_t reg) +{ + int ret; + uint8_t buf1[3] = { 0x70, 0x00, 0x00 }; + uint8_t buf2[3] = { 0x73, 0x00, 0x00 }; + + buf1[2] = reg; + + ret = spi_write(spi, buf1, 3); + if (ret) { + pr_err("spi_write ret=%d\n", ret); + return -EIO; + } + + ret = spi_w8r16(spi, buf2[0]); + if (ret < 0) { + pr_err("spi_write ret=%d\n", ret); + return ret; + } + + return ret; +} + +#if 0 +static int ssd2828_write(struct spi_device *spi, uint8_t reg, uint16_t data) +{ + int ret; + uint8_t buf_reg[3] = { 0x70, 0x00, 0x00 }; + uint8_t buf_data[3] = { 0x72, 0x00, 0x00 }; + + buf_reg[2] = reg; + + buf_data[1] = (data >> 8) & 0xff; + buf_data[2] = data & 0xff; + + ret = spi_write(spi, buf_reg, 3); + if (ret) { + pr_err("spi_write ret=%d,w cmd=0x%06x\n", ret, data); + return ret; + } + + ret = spi_write(spi, buf_data, 3); + if (ret) + pr_err("spi_write ret=%d,w cmd=0x%06x\n", ret, data); + + return ret; +} +#endif + +static inline int spi_write_24bit(struct spi_device *spi, uint32_t data) +{ + int ret; + uint8_t buf[3]; + + buf[0] = (data >> 16) & 0xff; + buf[1] = (data >> 8) & 0xff; + buf[2] = data & 0xff; + + ret = spi_write(spi, buf, 3); + if (ret) + pr_err("spi_write ret=%d,w cmd=0x%06x\n", ret, data); + + return ret; +} + +static const uint32_t ssd2828_init_sequence[] = { + 0x7000B1, 0x723240, /* VSA=50, HAS=64 */ + 0x7000B2, 0x725078, /* VBP=30+50, HBP=56+64 */ + 0x7000B3, 0x72243C, /* VFP=36, HFP=60 */ + 0x7000B4, 0x720300, /* HACT=768 */ + 0x7000B5, 0x720400, /* VACT=1024 */ + 0x7000B6, 0x72000b, /* burst mode, 24bpp loosely packed */ + 0x7000DE, 0x720003, /* no of lane=4 */ + 0x7000D6, 0x720005, /* RGB order and packet number in blanking period */ + 0x7000B9, 0x720000, /* disable PLL */ + + /* lane speed=576 (24MHz * 24 = 576) */ + /* may modify according to requirement, 500Mbps to 560Mbps */ + /* LP clock : 576 / 9 / 8 = 8 MHz */ + 0x7000BA, 0x728018, + 0x7000BB, 0x720008, + + 0x7000B9, 0x720001, /* enable PPL */ + 0x7000C4, 0x720001, /* enable BTA */ + 0x7000B7, 0x720342, /* enter LP mode */ + 0x7000B8, 0x720000, /* VC */ + 0x7000BC, 0x720000, /* set packet size */ + + 0x700011, 0xff0000 + 200, /* sleep out cmd */ + 0x700029, 0xff0000 + 200, /* display on */ + 0x7000B7, 0x72030b, /* video mode on */ +}; + +static int ssd2828_hw_reset(struct ssd2828_chip *chip) +{ + lcd_power_on(1); + msleep(10); + + gpio_direction_output(chip->gpio_reset, 1); + msleep(10); + gpio_direction_output(chip->gpio_reset, 0); + msleep(20); + gpio_direction_output(chip->gpio_reset, 1); + msleep(20); + return 0; +} + +static int ssd2828_hw_init(struct ssd2828_chip *chip) +{ + int ret = 0; + int i; + + ssd2828_hw_reset(chip); + + ret = ssd2828_read(chip->spi, 0xB0); + if (ret < 0 || ret != 0x2828) { + pr_err("Error: SSD2828 not found!\n"); + return -ENODEV; + } + + for (i = 0; i < ARRAY_SIZE(ssd2828_init_sequence); i++) { + if (ssd2828_init_sequence[i] & 0xff000000) { + msleep(ssd2828_init_sequence[i] & 0xff); + continue; + } + ret = spi_write_24bit(chip->spi, ssd2828_init_sequence[i]); + if (ret) + break; + } + + return ret; +} + +static ssize_t option_port_testmode_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + char *s = buf; + int ret; + int reg; + + struct spi_device *spi = container_of(dev, struct spi_device, dev); + + s += sprintf(s, "register value\n"); + + for (reg = 0xb0; reg <= 0xff; reg++) { + ret = ssd2828_read(spi, (uint8_t)reg); + if (ret < 0) + goto out; + s += sprintf(s, "reg 0x%02X : 0x%04x\n", reg, ret); + } + + s += sprintf(s, "=========\n"); + +out: + return s - buf; +} + +static ssize_t option_port_testmode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return 0; +} + +static DEVICE_ATTR(testmode, S_IRUGO, + option_port_testmode_show, + option_port_testmode_store); + +static int __devinit ssd2828_probe(struct spi_device *spi) +{ + struct ssd2828_chip *chip; + int gpio = WMT_PIN_GP0_GPIO0; + int ret; + + ret = gpio_request(gpio, "SSD2828 Reset"); + if (ret) { + dev_err(&spi->dev, "can not open GPIO %d\n", gpio); + return ret; + } + + ret = ssd2828_read(spi, 0xB0); + if (ret < 0 || ret != 0x2828) { + pr_err("Error: SSD2828 not found!\n"); + return -ENODEV; + } + + chip = kzalloc(sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + chip->spi = spi; + chip->gpio_reset = gpio; + spi_set_drvdata(spi, chip); + + ret = sysfs_create_file(&spi->dev.kobj, &dev_attr_testmode.attr); + if (unlikely(ret)) + pr_err("ssd2828 sysfs_create_file failed\n"); + + return ret; +} + +static int ssd2828_spi_resume(struct spi_device *spi) +{ + struct ssd2828_chip *chip = dev_get_drvdata(&spi->dev); + return ssd2828_hw_init(chip); +} + +static struct spi_driver ssd2828_driver = { + .driver = { + .name = DRIVERNAME, + .owner = THIS_MODULE, + }, + .probe = ssd2828_probe, + .resume = ssd2828_spi_resume, +#if 0 + .remove = __devexit_p(ssd2828_remove), + .shutdown = ssd2828_shutdown, +#endif +}; + +static struct spi_board_info ssd2828_spi_info[] __initdata = { + { + .modalias = DRIVERNAME, + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 12000000, + .irq = -1, + .mode = SPI_CLK_MODE3, + }, +}; + +static int wmt_lcd_panel(void) +{ + char buf[96]; + int len = sizeof(buf); + int type, id = 0; + + if (wmt_getsyspara("wmt.display.param", buf, &len)) + return -ENODEV; + + sscanf(buf, "%d:%d", &type, &id); + return id; +} + +static int __init b079xan01_init(void) +{ + int ret; + + if (wmt_lcd_panel() != LCD_B079XAN01) { + pr_err("LCD B079XAN01 not found\n"); + return -EINVAL; + } + + ret = spi_register_board_info(ssd2828_spi_info, + ARRAY_SIZE(ssd2828_spi_info)); + if (ret) { + pr_err("spi_register_board_info failed\n"); + return ret; + } + + ret = spi_register_driver(&ssd2828_driver); + if (ret) { + pr_err("spi_register_driver failed\n"); + return -EIO; + } + + if (lcd_b079xan01_init()) { + spi_unregister_driver(&ssd2828_driver); + return -ENODEV; + } + + pr_info("spi %s register success\n", DRIVERNAME); + + return 0; +} + +static void b079xan01_exit(void) +{ + spi_unregister_driver(&ssd2828_driver); +} + +module_init(b079xan01_init); +module_exit(b079xan01_exit); diff --git a/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-gl5001w.c b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-gl5001w.c new file mode 100755 index 00000000..03e3de29 --- /dev/null +++ b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-gl5001w.c @@ -0,0 +1,1412 @@ +/*++ + * linux/drivers/video/wmt/devices/lcd-gl5001w.c + * WonderMedia video post processor (VPP) driver + * + * Copyright c 2012 WonderMedia Technologies, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * WonderMedia Technologies, Inc. + * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C +--*/ + + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/err.h> +#include <linux/power_supply.h> +#include <linux/i2c.h> +#include <linux/slab.h> +#include <linux/interrupt.h> +#include <linux/proc_fs.h> +#include <linux/gpio.h>//wangaq+ +#include "../lcd.h" + +//#include <mach/gpio-cs.h> +//#include <mach/wmt_env.h> +#include <mach/wmt_iomux.h>//wangaq+ + + +#include "../lcd.h"//yangchen add + +#define DRIVER_NAME "tc358768" +#define I2C_ADDR 0x0E +#define I2C_ADAPTER 0 + +#define DTYPE_DCS_SWRITE_0P 0X05 +#define DTYPE_DCS_SWRITE_1P 0X15 +#define DTYPE_DCS_LWRITE 0X39 +#define DTYPE_GEN_LWRITE 0X29 +#define DTYPE_GEN_SWRITE_2P 0X23 +#define DTYPE_GEN_SWRITE_1P 0X13 +#define DTYPE_GEN_SWRITE_0P 0X03 + + +#define Gl5001w_Reset_Port WMT_PIN_GP62_SUSGPIO0 +#define Tc358768_Reset_Port WMT_PIN_GP1_GPIO8 +//#define BackLight_Power_PORT WMT_PIN_GP0_GPIO0 + +static void lcd_set_power(int status); +static int save=1; +//static struct work_struct cw500_resume_work; +struct cw500_data { + struct work_struct cw500_resume_work; +}; +struct cw500_data *data; + +#if 0 +#define lcd_debug printk +#else +#define lcd_debug(fmt...) do { } while (0) +#endif + +#define __unused __attribute__ ((unused)) + +static bool lcd_init_gl500 = false; + + +typedef enum { + //LCD_BTL504880, + LCD_YT50F62C6, + LCD_BT050TN, + LCD_ILI9806, + LCD_OTM8019A, + LCD_MAX +} lcd_panel_enum; + +struct lcd_deviceid_struct{ + unsigned short id; + unsigned char addr; + unsigned char read_start; + unsigned char len; +}; + +static struct lcd_deviceid_struct lcd_deviceid[LCD_MAX]={ + //{0x8009,0xa1,6,2}, + {0x9805,0xd3,5,2}, + {0x8009,0xa1,6,2}, + {0x9816,0xd3,5,2}, + {0x8019,0xa1,6,2} +}; + +//LCD_YT50F62C6 +static unsigned char LCD_YT50F62C6_CMD_FF_3DATA[] = {0xFF,0xFF,0x98,0x05}; //EXTC Command Set enable register +static unsigned char LCD_YT50F62C6_CMD_FD_4DATA[] = {0xFD,0x03,0x13,0x44,0x00}; +static unsigned char LCD_YT50F62C6_CMD_F8_15DATA[] = {0xF8,0x15,0x02,0x02,0x15,0x02,0x02,0x30,0x01,0x01,0x30,0x01,0x01,0x30,0x01,0x01}; +static unsigned char LCD_YT50F62C6_CMD_B8_1DATA[] = {0xB8,0x73}; //DBI Type B Interface Setting +static unsigned char LCD_YT50F62C6_CMD_F1_1DATA[] = {0xF1,0x00}; //Gate Modulation +static unsigned char LCD_YT50F62C6_CMD_F2_3DATA[] = {0xF2,0x00,0x58,0x41}; //CR/EQ/PC +static unsigned char LCD_YT50F62C6_CMD_FC_3DATA[] = {0xFC,0x04,0x0F,0x01}; +static unsigned char LCD_YT50F62C6_CMD_FE_1DATA[] = {0xFE,0x19}; //SRAM Repair +static unsigned char LCD_YT50F62C6_CMD_EB_2DATA[] = {0xEB,0x08,0x0F}; // 3 Gamma & Dithering +static unsigned char LCD_YT50F62C6_CMD_E0_16DATA[] = {0xE0,0x00,0x02,0x07,0x10,0x10,0x1D,0x0F,0x0B,0x00,0x03,0x02,0x0B,0x0C,0x33,0x2F,0x00}; //P-Gamma +static unsigned char LCD_YT50F62C6_CMD_E1_16DATA[] = {0xE1,0x00,0x02,0x07,0x10,0x10,0x17,0x0B,0x0B,0x00,0x03,0x02,0x0B,0x0C,0x33,0x2F,0x00}; //N-Gamma +static unsigned char LCD_YT50F62C6_CMD_C1_4DATA[] = {0xC1,0x13,0x26,0x06,0x26}; //Power Control 1 +static unsigned char LCD_YT50F62C6_CMD_C7_1DATA[] = {0xC7,0xC4}; +static unsigned char LCD_YT50F62C6_CMD_B1_3DATA[] = {0xB1,0x00,0x12,0x14}; //Frame Rate Control +static unsigned char LCD_YT50F62C6_CMD_B4_1DATA[] = {0xB4,0x02}; // 2 Dot Inversion +static unsigned char LCD_YT50F62C6_CMD_36_1DATA[] = {0x36,0x0A}; //Memory Access +static unsigned char LCD_YT50F62C6_CMD_3A_1DATA[] = {0x3A,0x77}; //16 & 18 & 24 bits +static unsigned char LCD_YT50F62C6_CMD_21_0DATA[] = {0x21}; //Display Inv-On +static unsigned char LCD_YT50F62C6_CMD_B0_1DATA[] = {0xB0,0x00}; //RGB I/F Polarity +static unsigned char LCD_YT50F62C6_CMD_B6_1DATA[] = {0xB6,0x01}; //CPU/RGB I/F Select +static unsigned char LCD_YT50F62C6_CMD_C2_1DATA[] = {0xC2,0x11}; +static unsigned char LCD_YT50F62C6_CMD_11_0DATA[] = {0x11}; //Sleep out +static unsigned char LCD_YT50F62C6_CMD_29_0DATA[] = {0x29}; //Display on +static unsigned char LCD_YT50F62C6_CMD_2C_0DATA[] = {0x2C}; //Memory write + +//LCD_BT050TN +static unsigned char LCD_BT050TN_CMD_FF00_0DATA[] = {0x00,0x00}; +static unsigned char LCD_BT050TN_CMD_FF00_3DATA[] = {0xFF,0x80,0x09,0x01}; +static unsigned char LCD_BT050TN_CMD_FF80_0DATA[] = {0x00,0x80}; +static unsigned char LCD_BT050TN_CMD_FF80_2DATA[] = {0xFF,0x80,0x09}; +static unsigned char LCD_BT050TN_CMD_FF03_0DATA[] = {0x00,0x03}; +static unsigned char LCD_BT050TN_CMD_FF03_1DATA[] = {0xFF,0x01}; +static unsigned char LCD_BT050TN_CMD_2100_0DATA[] = {0x00,0x00}; +static unsigned char LCD_BT050TN_CMD_2100_1DATA[] = {0x21,0x00}; +static unsigned char LCD_BT050TN_CMD_D800_0DATA[] = {0x00,0x00}; +static unsigned char LCD_BT050TN_CMD_D800_2DATA[] = {0xD8,0x6F,0x6F}; +static unsigned char LCD_BT050TN_CMD_C582_0DATA[] = {0x00,0x82}; +static unsigned char LCD_BT050TN_CMD_C582_1DATA[] = {0xC5,0xA3}; +static unsigned char LCD_BT050TN_CMD_C181_0DATA[] = {0x00,0x81}; +static unsigned char LCD_BT050TN_CMD_C181_1DATA[] = {0xC1,0x66}; +static unsigned char LCD_BT050TN_CMD_C1A1_0DATA[] = {0x00,0xA1}; +static unsigned char LCD_BT050TN_CMD_C1A1_1DATA[] = {0xC1,0x08}; +static unsigned char LCD_BT050TN_CMD_B4C0_0DATA[] = {0x00,0xB4}; +static unsigned char LCD_BT050TN_CMD_B4C0_1DATA[] = {0xC0,0x50}; +static unsigned char LCD_BT050TN_CMD_C0A3_0DATA[] = {0x00,0xA3}; +static unsigned char LCD_BT050TN_CMD_C0A3_1DATA[] = {0xC0,0x00}; +static unsigned char LCD_BT050TN_CMD_C489_0DATA[] = {0x00,0x89}; +static unsigned char LCD_BT050TN_CMD_C489_1DATA[] = {0xC4,0x08}; +static unsigned char LCD_BT050TN_CMD_C481_0DATA[] = {0x00,0x81}; +static unsigned char LCD_BT050TN_CMD_C481_1DATA[] = {0xC4,0x83}; +static unsigned char LCD_BT050TN_CMD_C590_0DATA[] = {0x00,0x90}; +static unsigned char LCD_BT050TN_CMD_C590_3DATA[] = {0xC5,0x96,0xA7,0x01}; +static unsigned char LCD_BT050TN_CMD_C5B1_0DATA[] = {0x00,0xB1}; +static unsigned char LCD_BT050TN_CMD_C5B1_1DATA[] = {0xC5,0xA9}; +static unsigned char LCD_BT050TN_CMD_D900_0DATA[] = {0x00,0x00}; +static unsigned char LCD_BT050TN_CMD_D900_1DATA[] = {0xD9,0x15}; +static unsigned char LCD_BT050TN_CMD_E100_0DATA[] = {0x00,0x00}; +static unsigned char LCD_BT050TN_CMD_E100_16DATA[] = {0xE1,0x02,0x08,0x0E,0x10,0x09,0x1D,0x0E,0x0E,0x00,0x05,0x02,0x07,0x0E,0x24,0x23,0x1D}; +static unsigned char LCD_BT050TN_CMD_E200_0DATA[] = {0x00,0x00}; +static unsigned char LCD_BT050TN_CMD_E200_16DATA[] = {0xE2,0x02,0x08,0x0E,0x0F,0x09,0x1D,0x0E,0x0D,0x00,0x04,0x02,0x07,0x0E,0x25,0x23,0x1D}; +static unsigned char LCD_BT050TN_CMD_0000_0DATA[] = {0x00,0x00}; +static unsigned char LCD_BT050TN_CMD_0000_1DATA[] = {0x00,0x00}; +static unsigned char LCD_BT050TN_CMD_B3A1_0DATA[] = {0x00,0xA1}; +static unsigned char LCD_BT050TN_CMD_B3A1_1DATA[] = {0xB3,0x10}; +static unsigned char LCD_BT050TN_CMD_B3A7_0DATA[] = {0x00,0xA7}; +static unsigned char LCD_BT050TN_CMD_B3A7_1DATA[] = {0xB3,0x10}; +static unsigned char LCD_BT050TN_CMD_C090_0DATA[] = {0x00,0x90}; +static unsigned char LCD_BT050TN_CMD_C090_6DATA[] = {0xC0,0x00,0x44,0x00,0x00,0x00,0x03}; +static unsigned char LCD_BT050TN_CMD_C1A6_0DATA[] = {0x00,0xA6}; +static unsigned char LCD_BT050TN_CMD_C1A6_3DATA[] = {0xC1,0x00,0x00,0x00}; +static unsigned char LCD_BT050TN_CMD_CE80_0DATA[] = {0x00,0x80}; +static unsigned char LCD_BT050TN_CMD_CE80_6DATA[] = {0xCE,0x87,0x03,0x00,0x86,0x03,0x00}; +static unsigned char LCD_BT050TN_CMD_CE90_0DATA[] = {0x00,0x90}; +static unsigned char LCD_BT050TN_CMD_CE90_6DATA[] = {0xCE,0x33,0x1E,0x00,0x33,0x1F,0x00}; +static unsigned char LCD_BT050TN_CMD_CEA0_0DATA[] = {0x00,0xA0}; +static unsigned char LCD_BT050TN_CMD_CEA0_14DATA[] = {0xCE,0x38,0x03,0x03,0x20,0x00,0x00,0x00,0x38,0x02,0x03,0x21,0x00,0x00,0x00}; +static unsigned char LCD_BT050TN_CMD_CEB0_0DATA[] = {0x00,0xb0}; +static unsigned char LCD_BT050TN_CMD_CEB0_14DATA[] = {0xCE,0x38,0x01,0x03,0x22,0x00,0x00,0x00,0x38,0x00,0x03,0x23,0x00,0x00,0x00}; +static unsigned char LCD_BT050TN_CMD_CEC0_0DATA[] = {0x00,0xC0}; +static unsigned char LCD_BT050TN_CMD_CEC0_14DATA[] = {0xCE,0x30,0x00,0x03,0x24,0x00,0x00,0x00,0x30,0x01,0x03,0x25,0x00,0x00,0x00}; +static unsigned char LCD_BT050TN_CMD_CED0_0DATA[] = {0x00,0xD0}; +static unsigned char LCD_BT050TN_CMD_CED0_14DATA[] = {0xCE,0x30,0x02,0x03,0x26,0x00,0x00,0x00,0x30,0x03,0x03,0x27,0x00,0x00,0x00}; +static unsigned char LCD_BT050TN_CMD_CFC6_0DATA[] = {0x00,0xC6}; +static unsigned char LCD_BT050TN_CMD_CFC6_2DATA[] = {0xCF,0x01,0x80}; +static unsigned char LCD_BT050TN_CMD_CFC9_0DATA[] = {0x00,0xC9}; +static unsigned char LCD_BT050TN_CMD_CFC9_1DATA[] = {0xCF,0x00}; +static unsigned char LCD_BT050TN_CMD_CBC0_0DATA[] = {0x00,0xC0}; +static unsigned char LCD_BT050TN_CMD_CBC0_15DATA[] = {0xCB,0x00,0x04,0x04,0x04,0x04,0x00,0x00,0x04,0x04,0x04,0x04,0x00,0x00,0x00,0x00}; +static unsigned char LCD_BT050TN_CMD_CBD0_0DATA[] = {0x00,0xD0}; +static unsigned char LCD_BT050TN_CMD_CBD0_15DATA[] = {0xCB,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x04,0x00,0x00,0x04,0x04,0x04}; +static unsigned char LCD_BT050TN_CMD_CBE0_0DATA[] = {0x00,0xE0}; +static unsigned char LCD_BT050TN_CMD_CBE0_10DATA[] = {0xCB,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; +static unsigned char LCD_BT050TN_CMD_CC80_0DATA[] = {0x00,0x80}; +static unsigned char LCD_BT050TN_CMD_CC80_10DATA[] = {0xCC,0x00,0x26,0x25,0x02,0x06,0x00,0x00,0x0A,0x0E,0x0C}; +static unsigned char LCD_BT050TN_CMD_CC90_0DATA[] = {0x00,0x90}; +static unsigned char LCD_BT050TN_CMD_CC90_15DATA[] = {0xCC,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x26,0x25,0x01,0x05}; +static unsigned char LCD_BT050TN_CMD_CCA0_0DATA[] = {0x00,0xA0}; +static unsigned char LCD_BT050TN_CMD_CCA0_15DATA[] = {0xCC,0x00,0x00,0x09,0x0d,0x0b,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; +static unsigned char LCD_BT050TN_CMD_CCB0_0DATA[] = {0x00,0xB0}; +static unsigned char LCD_BT050TN_CMD_CCB0_10DATA[] = {0xCC,0x00,0x25,0x26,0x05,0x01,0x00,0x00,0x0F,0x0B,0x0D}; +static unsigned char LCD_BT050TN_CMD_CCC0_0DATA[] = {0x00,0xC0}; +static unsigned char LCD_BT050TN_CMD_CCC0_15DATA[] = {0xCC,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x26,0x06,0x02}; +static unsigned char LCD_BT050TN_CMD_CCD0_0DATA[] = {0x00,0xD0}; +static unsigned char LCD_BT050TN_CMD_CCD0_15DATA[] = {0xCC,0x00,0x00,0x10,0x0c,0x0e,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; +static unsigned char LCD_BT050TN_CMD_21_0DATA[] = {0x21}; +static unsigned char LCD_BT050TN_CMD_36_0DATA[] = {0x36}; +static unsigned char LCD_BT050TN_CMD_00_0DATA[] = {0x00}; +static unsigned char LCD_BT050TN_CMD_11_0DATA[] = {0x11}; +static unsigned char LCD_BT050TN_CMD_29_0DATA[] = {0x29}; +static unsigned char LCD_BT050TN_CMD_2C_0DATA[] = {0x2C}; + + +//LCD_ILI9806 +static unsigned char LCD_ILI9806_CMD_FF_3DATA[] = {0xFF,0xFF,0x98,0x16}; +static unsigned char LCD_ILI9806_CMD_BA_1DATA[] = {0xBA,0x60}; +static unsigned char LCD_ILI9806_CMD_F3_1DATA[] = {0xF3,0x70}; +static unsigned char LCD_ILI9806_CMD_F9_3DATA[] = {0xF9,0x04,0xFB,0x84}; +static unsigned char LCD_ILI9806_CMD_B0_1DATA[] = {0xB0,0x01}; +static unsigned char LCD_ILI9806_CMD_BC_23DATA[] = {0xBC,0x01,0x0F,0x61,0xFE,0x01,0x01,0x0B,0x11,0x6C,0x63,0xFF,0xFF,0x01,0x01,0x00,0x00,0x55,0x53,0x01,0x00,0x00,0x43,0x0B}; +static unsigned char LCD_ILI9806_CMD_BD_8DATA[] = {0xBD,0x01,0x23,0x45,0x67,0x01,0x23,0x45,0x67}; +static unsigned char LCD_ILI9806_CMD_BE_17DATA[] = {0xBE,0x13,0x11,0x00,0x22,0x22,0xBA,0xAB,0x22,0x22,0x22,0x66,0x22,0x22,0x22,0x22,0x22,0x22}; +static unsigned char LCD_ILI9806_CMD_ED_2DATA[] = {0xED,0x7F,0x0F}; +static unsigned char LCD_ILI9806_CMD_B4_3DATA[] = {0xB4,0x02,0x02,0x02}; +static unsigned char LCD_ILI9806_CMD_B5_4DATA[] = {0xB5,0x14,0x14,0x04,0x00}; +static unsigned char LCD_ILI9806_CMD_C0_3DATA[] = {0xC0,0x7F,0x0B,0x04}; +static unsigned char LCD_ILI9806_CMD_C1_4DATA[] = {0xC1,0x17,0x78,0x78,0x20}; +static unsigned char LCD_ILI9806_CMD_D7_1DATA[] = {0xD7,0x2A}; +static unsigned char LCD_ILI9806_CMD_D8_1DATA[] = {0xD8,0x28}; +static unsigned char LCD_ILI9806_CMD_FC_1DATA[] = {0xFC,0x05}; +static unsigned char LCD_ILI9806_CMD_E0_16DATA[] = {0xE0,0x00,0x03,0x0A,0x0E,0x11,0x15,0x0A,0x08,0x04,0x09,0x07,0x0D,0x0D,0x2E,0x28,0x00}; +static unsigned char LCD_ILI9806_CMD_E1_16DATA[] = {0xE1,0x00,0x02,0x09,0x0E,0x11,0x15,0x0A,0x09,0x04,0x09,0x08,0x0C,0x0D,0x2F,0x28,0x00}; +static unsigned char LCD_ILI9806_CMD_D5_8DATA[] = {0xD5,0x09,0x0A,0x0D,0x0B,0xCB,0xA5,0x01,0x04}; +static unsigned char LCD_ILI9806_CMD_F7_1DATA[] = {0xF7,0x89}; +static unsigned char LCD_ILI9806_CMD_C7_1DATA[] = {0xC7,0x43}; +static unsigned char LCD_ILI9806_CMD_36_1DATA[] = {0x36,0x00}; +static unsigned char LCD_ILI9806_CMD_51_1DATA[] = {0x51,0xFF}; +static unsigned char LCD_ILI9806_CMD_53_1DATA[] = {0x53,0x24}; +static unsigned char LCD_ILI9806_CMD_55_1DATA[] = {0x55,0x03}; +static unsigned char LCD_ILI9806_CMD_11_0DATA[] = {0x11}; +static unsigned char LCD_ILI9806_CMD_29_0DATA[] = {0x29}; +static unsigned char LCD_ILI9806_CMD_2C_0DATA[] = {0x2C}; //Memory write + +//OTM8019A +static unsigned char LCD_OTM8019A_CMD_1[]= {0x00,0x00}; +static unsigned char LCD_OTM8019A_CMD_2[]= {0xFF,0x80,0x19,0x01}; +static unsigned char LCD_OTM8019A_CMD_3[]= {0x00,0x80}; +static unsigned char LCD_OTM8019A_CMD_4[]= {0xFF,0x80,0x19}; +static unsigned char LCD_OTM8019A_CMD_5[]= {0x00,0x90}; +static unsigned char LCD_OTM8019A_CMD_6[]= {0xB3,0x02}; +static unsigned char LCD_OTM8019A_CMD_7[]= {0x00,0x92}; +static unsigned char LCD_OTM8019A_CMD_8[]= {0xB3,0x45}; +static unsigned char LCD_OTM8019A_CMD_9[]= {0x00,0xA2}; +static unsigned char LCD_OTM8019A_CMD_10[]= {0xC0,0x04,0x00,0x02}; +static unsigned char LCD_OTM8019A_CMD_11[]= {0x00,0x80}; +static unsigned char LCD_OTM8019A_CMD_12[]= {0xC0,0x00,0x58,0x00,0x14,0x16}; +static unsigned char LCD_OTM8019A_CMD_13[]= {0x00,0x90}; +static unsigned char LCD_OTM8019A_CMD_14[]= {0xC0,0x00,0x15,0x00,0x00,0x00,0x03}; +static unsigned char LCD_OTM8019A_CMD_15[]= {0x00,0xB4}; +static unsigned char LCD_OTM8019A_CMD_16[]= {0xC0,0x70};//1+2 dot inversion +static unsigned char LCD_OTM8019A_CMD_17[]= {0x00,0x81}; +static unsigned char LCD_OTM8019A_CMD_18[]= {0xC1,0x33}; +static unsigned char LCD_OTM8019A_CMD_19[]= {0x00,0x80}; +static unsigned char LCD_OTM8019A_CMD_20[]= {0xC4,0x30,0x83}; +static unsigned char LCD_OTM8019A_CMD_21[]= {0x00,0x89}; +static unsigned char LCD_OTM8019A_CMD_22[]= {0xC4,0x08}; +static unsigned char LCD_OTM8019A_CMD_23[]= {0x00,0x82}; +static unsigned char LCD_OTM8019A_CMD_24[]= {0xC5,0xB0}; +static unsigned char LCD_OTM8019A_CMD_25[]= {0x00,0x90}; +static unsigned char LCD_OTM8019A_CMD_26[]= {0xC5,0x4E,0x79,0x01,0x03}; +static unsigned char LCD_OTM8019A_CMD_27[]= {0x00,0xB1}; +static unsigned char LCD_OTM8019A_CMD_28[]= {0xC5,0xA9}; +static unsigned char LCD_OTM8019A_CMD_29[]= {0x00,0x80}; +static unsigned char LCD_OTM8019A_CMD_30[]= {0xCE,0x87,0x03,0x00,0x85,0x03,0x00,0x86,0x03,0x00,0x84,0x03,0x00}; +static unsigned char LCD_OTM8019A_CMD_31[]= {0x00,0xA0}; +static unsigned char LCD_OTM8019A_CMD_32[]= {0xCE,0x38,0x03,0x03,0x58,0x00,0x00,0x00,0x38,0x02,0x03,0x59,0x00,0x00,0x00}; +static unsigned char LCD_OTM8019A_CMD_33[]= {0x00,0xB0}; +static unsigned char LCD_OTM8019A_CMD_34[]= {0xCE,0x38,0x01,0x03,0x5A,0x00,0x00,0x00,0x38,0x00,0x03,0x5B,0x00,0x00,0x00}; +static unsigned char LCD_OTM8019A_CMD_35[]= {0x00,0xC0}; +static unsigned char LCD_OTM8019A_CMD_36[]= {0xCE,0x30,0x00,0x03,0x5C,0x00,0x00,0x00,0x30,0x01,0x03,0x5D,0x00,0x00,0x00}; +static unsigned char LCD_OTM8019A_CMD_37[]= {0x00,0xD0}; +static unsigned char LCD_OTM8019A_CMD_38[]= {0xCE,0x30,0x02,0x03,0x5E,0x00,0x00,0x00,0x30,0x03,0x03,0x5F,0x00,0x00,0x00}; +static unsigned char LCD_OTM8019A_CMD_39[]= {0x00,0xC7}; +static unsigned char LCD_OTM8019A_CMD_40[]= {0xCF,0x00}; +static unsigned char LCD_OTM8019A_CMD_41[]= {0x00,0xC9}; +static unsigned char LCD_OTM8019A_CMD_42[]= {0xCF,0x00}; +static unsigned char LCD_OTM8019A_CMD_43[]= {0x00,0xC4}; +static unsigned char LCD_OTM8019A_CMD_44[]= {0xCB,0x01,0x01,0x01,0x01,0x01,0x01}; +static unsigned char LCD_OTM8019A_CMD_45[]= {0x00,0xD9}; +static unsigned char LCD_OTM8019A_CMD_46[]= {0xCB,0x00,0x00,0x01,0x01,0x01,0x01}; +static unsigned char LCD_OTM8019A_CMD_47[]= {0x00,0xE0}; +static unsigned char LCD_OTM8019A_CMD_48[]= {0xCB,0x01,0x01}; +static unsigned char LCD_OTM8019A_CMD_49[]= {0x00,0x84}; +static unsigned char LCD_OTM8019A_CMD_50[]= {0xCC,0x0C,0x0A,0x10,0x0E,0x03,0x04}; +static unsigned char LCD_OTM8019A_CMD_51[]= {0x00,0x9E}; +static unsigned char LCD_OTM8019A_CMD_52[]= {0xCC,0x00}; +static unsigned char LCD_OTM8019A_CMD_53[]= {0x00,0xA0}; +static unsigned char LCD_OTM8019A_CMD_54[]= {0xCC,0x00,0x02,0x01,0x0d,0x0f,0x09,0x0b}; +static unsigned char LCD_OTM8019A_CMD_55[]= {0x00,0xB4}; +static unsigned char LCD_OTM8019A_CMD_56[]= {0xCC,0x0D,0x0F,0x09,0x0B,0x02,0x01}; +static unsigned char LCD_OTM8019A_CMD_57[]= {0x00,0xCE}; +static unsigned char LCD_OTM8019A_CMD_58[]= {0xCC,0x85}; +static unsigned char LCD_OTM8019A_CMD_59[]= {0x00,0xD0}; +static unsigned char LCD_OTM8019A_CMD_60[]= {0xCC,0x05,0x03,0x04,0x0c,0x0a,0x10,0x0e}; +static unsigned char LCD_OTM8019A_CMD_61[]= {0x00,0x00}; +static unsigned char LCD_OTM8019A_CMD_62[]= {0xD8,0x85,0x85}; +static unsigned char LCD_OTM8019A_CMD_63[]= {0x00,0x00}; +static unsigned char LCD_OTM8019A_CMD_64[]= {0xD9,0x61}; +static unsigned char LCD_OTM8019A_CMD_65[]= {0x00,0x00}; +static unsigned char LCD_OTM8019A_CMD_66[]= {0xE1,0x00,0x03,0x0a,0x1d,0x33,0x49,0x54,0x89,0x7a,0x8e,0x79,0x69,0x81,0x6d,0x73,0x6d,0x66,0x5d,0x52,0x00}; +static unsigned char LCD_OTM8019A_CMD_67[]= {0x00,0x00}; +static unsigned char LCD_OTM8019A_CMD_68[]= {0xE2,0x00,0x04,0x0a,0x1d,0x33,0x49,0x54,0x89,0x7a,0x8e,0x79,0x69,0x81,0x6d,0x73,0x6d,0x66,0x5d,0x52,0x00}; +static unsigned char LCD_OTM8019A_CMD_69[]= {0x00,0x80}; +static unsigned char LCD_OTM8019A_CMD_70[]= {0xC4,0x30}; +static unsigned char LCD_OTM8019A_CMD_71[]= {0x00,0x98}; +static unsigned char LCD_OTM8019A_CMD_72[]= {0xC0,0x00}; +static unsigned char LCD_OTM8019A_CMD_73[]= {0x00,0xa9}; +static unsigned char LCD_OTM8019A_CMD_74[]= {0xC0,0x06}; +static unsigned char LCD_OTM8019A_CMD_75[]= {0x00,0xb0}; +static unsigned char LCD_OTM8019A_CMD_76[]= {0xC1,0x20,0x00,0x00}; +static unsigned char LCD_OTM8019A_CMD_77[]= {0x00,0xe1}; +static unsigned char LCD_OTM8019A_CMD_78[]= {0xC0,0x40,0x18}; +static unsigned char LCD_OTM8019A_CMD_79[]= {0x00,0x80}; +static unsigned char LCD_OTM8019A_CMD_80[]= {0xC1,0x03,0x33}; +static unsigned char LCD_OTM8019A_CMD_81[]= {0x00,0xA0}; +static unsigned char LCD_OTM8019A_CMD_82[]= {0xC1,0xe8}; +static unsigned char LCD_OTM8019A_CMD_83[]= {0x00,0x90}; +static unsigned char LCD_OTM8019A_CMD_84[]= {0xb6,0xb4}; +static unsigned char LCD_OTM8019A_CMD_85[]= {0x00,0x00}; +static unsigned char LCD_OTM8019A_CMD_86[]= {0xfb,0x01}; +static unsigned char LCD_OTM8019A_CMD_87[]= {0x00,0x00}; +static unsigned char LCD_OTM8019A_CMD_88[]= {0xFF,0xFF,0xFF,0xFF}; +static unsigned char LCD_OTM8019A_CMD_89[]= {0x11,0x00}; +static unsigned char LCD_OTM8019A_CMD_90[]= {0x29,0x00}; +//End of +static struct i2c_client *tc358768_client; + +static inline int tc358768_rd_reg_32bits(uint32_t reg_addr) +{ + int ret; + struct i2c_msg msgs[2]; + uint8_t buf[4]; + struct i2c_client *client = tc358768_client; + + buf[0] = (reg_addr >> 8) & 0xff; + buf[1] = reg_addr & 0xff; + + msgs[0].addr = client->addr; + msgs[0].flags = 0; + msgs[0].len = 2; + msgs[0].buf = buf; + + msgs[1].addr = client->addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = 2; + msgs[1].buf = buf; + + ret = i2c_transfer(client->adapter, msgs, 2); + if (ret < 0) { + printk("%s:i2c_transfer fail =%d\n", __func__, ret); + return -1; + } + + ret = (buf[0] << 8) | buf[1]; + + return ret; +} + +static inline int tc358768_wr_reg_32bits(uint32_t value) +{ + struct i2c_msg msgs; + int ret = -1; + uint8_t buf[4]; + struct i2c_client *client = tc358768_client; + + buf[0] = value>>24; + buf[1] = value>>16; + buf[2] = value>>8; + buf[3] = value; + + msgs.addr = client->addr; + msgs.flags = 0; + msgs.len = 4; + msgs.buf = buf; + + ret = i2c_transfer(client->adapter, &msgs, 1); + if(ret < 0) + printk("%d:i2c_transfer fail = %d\n",__LINE__, ret); + + return ret; +} + +static int _tc358768_wr_regs_32bits(unsigned int reg_array[], int n) +{ + + int i = 0; + lcd_debug("%s:%d\n", __func__, n); + for(i = 0; i < n; i++) { + if(reg_array[i] < 0x00020000) { + if(reg_array[i] < 20000) + udelay(reg_array[i]); + else { + mdelay(reg_array[i]/1000); + } + } else { + tc358768_wr_reg_32bits(reg_array[i]); + } + } + return 0; +} + +#define tc358768_wr_regs_32bits(reg_array) \ + _tc358768_wr_regs_32bits(reg_array, ARRAY_SIZE(reg_array)) + +static uint32_t initialize[] = { + // ************************************************** + // Initizlize -> Display On after power-on + // ************************************************** + // ************************************************** + // Power on TC358768XBG according to recommended power-on sequence + // Relase reset (RESX="H") + // Start input REFCK and PCLK + // ************************************************** + // ************************************************** + // TC358768XBG Software Reset + // ************************************************** + 0x00020001, //SYSctl, S/W Reset + 10, + 0x00020000, //SYSctl, S/W Reset release + + // ************************************************** + // TC358768XBG PLL,Clock Setting + // ************************************************** + 0x00160063, //PLL Control Register 0 (PLL_PRD,PLL_FBD) + 0x00180603, //PLL_FRS,PLL_LBWS, PLL oscillation enable + 1000, + 0x00180613, //PLL_FRS,PLL_LBWS, PLL clock out enable + + // ************************************************** + // TC358768XBG DPI Input Control + // ************************************************** + 0x00060064, //FIFO Control Register + + // ************************************************** + // TC358768XBG D-PHY Setting + // ************************************************** + 0x01400000, //D-PHY Clock lane enable + 0x01420000, // + 0x01440000, //D-PHY Data lane0 enable + 0x01460000, // + 0x01480000, //D-PHY Data lane1 enable + 0x014A0000, // + 0x014C0001, // + 0x014E0001, // + 0x01500001, // + 0x01520001, // + + 0x01000002, // + 0x01020000, // + 0x01040000, // + 0x01060002, // + 0x01080002, // + 0x010A0000, // + 0x010C0002, // + 0x010E0000, // + 0x01100002, // + 0x01120000, // + // ************************************************** + // TC358768XBG DSI-TX PPI Control + // ************************************************** + 0x02100A5A, //LINEINITCNT + 0x02120000, // + 0x02140002, //LPTXTIMECNT + 0x02160000, // + 0x02180E02, //TCLK_HEADERCNT + 0x021A0000, // + 0x021C0000, //TCLK_TRAILCNT + 0x021E0000, // + 0x02200002, //THS_HEADERCNT + 0x02220000, // + 0x02244650, //TWAKEUPCNT + 0x02260000, // + 0x02280000, //TCLK_POSTCNT + 0x022A0000, // + 0x022C0001, //THS_TRAILCNT + 0x022E0000, // + 0x02300005, //HSTXVREGCNT + 0x02320000, // + 0x02340007, //HSTXVREGEN enable + 0x02360000, // + 0x02380001, //DSI clock Enable/Disable during LP + 0x023A0000, // + 0x023C0002, //BTACNTRL1 + 0x023E0002, // + 0x02040001, //STARTCNTRL + 0x02060000, // + + // ************************************************** + // TC358768XBG DSI-TX Timing Control + // ************************************************** + 0x06200001, //Sync Event mode setting Event mode + 0x06220014, //V Control Register1 VBP + 0x0624000C, //V Control Register2 not used + 0x06260356, //V Control Register3 800 + 0x0628005E, //H Control Register1 + 0x062A003F, //H Control Register2 + //0x062C0438, //H Control Register3 (480*18)/8=1080 + 0x062C05A0, //H Control Register3 (480*24)/8=1440 + + 0x05180001, //DSI Start + 0x051A0000, // +}; + +static uint32_t start_dsi_hs_mode[] = { + + // ************************************************** + // Set to HS mode + // ************************************************** + 0x05000083, //DSI lane setting, DSI mode=HS + 0x0502A300, //bit set + 0x05008000, //Switch to DSI mode + 0x0502C300, // + + // ************************************************** + // Host: RGB(DPI) input start + // ************************************************** + + //0x00080047, //DSI-TX Format setting: RGB666 + 0x00080037, //DSI-TX Format setting//3 RGB888;4 RGB666 + //0x0050001E, //DSI-TX Pixel stream packet Data Type setting + 0x0050003E, //Packed Pixel Stream, 24-bit RGB, 8-8-8 Format + 0x00320000, //HSYNC Polarity + + 0x00040040, //Configuration Control Register + +}; + +static inline void mipi_dsi_init(void) +{ + tc358768_wr_regs_32bits(initialize); +} + +static inline void mipi_dsi_hs_start(void) +{ + tc358768_wr_regs_32bits(start_dsi_hs_mode); +} + +static void tc_print(u32 addr) +{ + lcd_debug("+++addr->%04x: %04x\n", addr, tc358768_rd_reg_32bits(addr)); +} + +static int tc358768_command_tx_less8bytes(unsigned char type, + unsigned char *regs, int n) +{ + int i = 0; + unsigned int command[] = { + 0x06020000, + 0x06040000, + 0x06100000, + 0x06120000, + 0x06140000, + 0x06160000, + }; + + if(n <= 2) + command[0] |= 0x1000; //short packet + else { + command[0] |= 0x4000; //long packet + command[1] |= n; //word count byte + } + command[0] |= type; //data type + + lcd_debug("*cmd:\n"); + lcd_debug("0x%08x\n", command[0]); + lcd_debug("0x%08x\n", command[1]); + + for(i = 0; i < (n + 1)/2; i++) { + command[i+2] |= regs[i*2]; + if((i*2 + 1) < n) + command[i+2] |= regs[i*2 + 1] << 8; + lcd_debug("0x%08x\n", command[i+2]); + } + + _tc358768_wr_regs_32bits(command, (n + 1)/2 + 2); + tc358768_wr_reg_32bits(0x06000001); //Packet Transfer + if(regs[0] == 0x29){ + //tc358768_wr_reg_32bits(0x06000001); + } + //wait until packet is out + i = 100; + while(tc358768_rd_reg_32bits(0x0600) & 0x01) { + if(i-- == 0) + break; + tc_print(0x0600); + } + + //udelay(50); + return 0; +} + +static int __unused tc358768_command_tx_more8bytes_hs(unsigned char type, + unsigned char regs[], int n) +{ + + int i = 0; + unsigned int dbg_data = 0x00E80000, temp = 0; + unsigned int command[] = { + 0x05000080, // HS data 4 lane, EOT is added + 0x0502A300, + 0x00080001, + 0x00500000, // Data ID setting + 0x00220000, // Transmission byte count= byte + 0x00E08000, // Enable I2C/SPI write to VB + 0x00E20048, // Total word count = 0x48 (max 0xFFF). + // This value should be adjusted considering + // trade off between transmission time and + // transmission start/stop time delay + 0x00E4007F, // Vertical blank line = 0x7F + }; + + + command[3] |= type; //data type + command[4] |= n & 0xffff; //Transmission byte count + + tc358768_wr_regs_32bits(command); + + for(i = 0; i < (n + 1)/2; i++) { + temp = dbg_data | regs[i*2]; + if((i*2 + 1) < n) + temp |= (regs[i*2 + 1] << 8); + lcd_debug("0x%08x\n", temp); + tc358768_wr_reg_32bits(temp); + } + if((n % 4 == 1) || (n % 4 == 2)) //4 bytes align + tc358768_wr_reg_32bits(dbg_data); + + tc358768_wr_reg_32bits(0x00E0C000); //Start command transmisison + tc358768_wr_reg_32bits(0x00E00000); //Stop command transmission. This setting should be done just after above setting to prevent multiple output + udelay(200); + //Re-Initialize + //tc358768_wr_regs_32bits(re_initialize); + return 0; +} + +static int tc358768_command_tx_more8bytes_lp(unsigned char type, + unsigned char regs[], int n) +{ + + int i = 0; + unsigned int dbg_data = 0x00E80000, temp = 0; + unsigned int command[] = { + 0x00080001, + 0x00500000, //Data ID setting + 0x00220000, //Transmission byte count= byte + 0x00E08000, //Enable I2C/SPI write to VB + }; + + command[1] |= type; //data type + command[2] |= n & 0xffff; //Transmission byte count + + tc358768_wr_regs_32bits(command); + + for(i = 0; i < (n + 1)/2; i++) { + temp = dbg_data | regs[i*2]; + if((i*2 + 1) < n) + temp |= (regs[i*2 + 1] << 8); + lcd_debug("0x%08x\n", temp); + tc358768_wr_reg_32bits(temp); + + } + if((n % 4 == 1) || (n % 4 == 2)) //4 bytes align + tc358768_wr_reg_32bits(dbg_data); + + tc358768_wr_reg_32bits(0x00E0E000); //Start command transmisison + udelay(1000); + tc358768_wr_reg_32bits(0x00E02000); //Keep Mask High to prevent short packets send out + tc358768_wr_reg_32bits(0x00E00000); //Stop command transmission. This setting should be done just after above setting to prevent multiple output + udelay(10); + return 0; +} + +int _tc358768_send_packet(unsigned char type, unsigned char regs[], int n) { + + if(n <= 8) { + tc358768_command_tx_less8bytes(type, regs, n); + } else { + //tc358768_command_tx_more8bytes_hs(type, regs, n); + tc358768_command_tx_more8bytes_lp(type, regs, n); + } + return 0; +} + +/* + * The DCS is separated into two functional areas: + * the User Command Set and the Manufacturer Command Set. + * Each command is an eight-bit code with 00h to AFh assigned to + * the User Command Set and all other codes assigned to + * the Manufacturer Command Set. + */ +int _mipi_dsi_send_dcs_packet(unsigned char regs[], int n) { + + unsigned char type = 0; + if(n == 1) { + type = DTYPE_DCS_SWRITE_0P; + } else if (n == 2) { + type = DTYPE_DCS_SWRITE_1P; + } else if (n > 2) { + type = DTYPE_DCS_LWRITE; + } + _tc358768_send_packet(type, regs, n); + return 0; +} + +static int tc358768_command_read_bytes(unsigned char addr,unsigned char *regs, int n) +{ + unsigned short *data = (unsigned short *)regs,i; + unsigned int command[] = { + 0x06021037, + 0x06040000, + 0x06100000, + 0x06000001, + 0x06021000, + 0x06040000, + 0x06100000, + 0x06000001, + }; + + lcd_debug("%s start addr=0x%x\n",__FUNCTION__,addr); + + command[2] |= 32; + command[4] |= 0x14; + command[6] |= addr; + + _tc358768_wr_regs_32bits(command,4); + udelay(100); + tc358768_wr_reg_32bits(0x05040010); + tc358768_wr_reg_32bits(0x05060000); + udelay(100); + _tc358768_wr_regs_32bits(&command[4],4); + + while(n-- > 0){ + *data = (unsigned short)tc358768_rd_reg_32bits(0x0430); + //printf("%s *data=0x%x\n",__FUNCTION__,*data); + data++; + *data = (unsigned short)tc358768_rd_reg_32bits(0x0432); + //printf("%s *data=0x%x\n",__FUNCTION__,*data); + data++; + udelay(100); + } + + return 0; +} + +static lcd_panel_enum tc358768_check_lcd_type(void) +{ + unsigned char data[50]={0},i=0; + int lcd_id; + for(i=0;i<LCD_MAX;i++) + { + tc358768_command_read_bytes(lcd_deviceid[i].addr,data,9); + lcd_id = (data[lcd_deviceid[i].read_start]<<8) + data[lcd_deviceid[i].read_start+1]; + printk("%s lcd_id=0x%x,0x%x\n",__FUNCTION__,lcd_id,lcd_deviceid[i].id); + if(lcd_id == lcd_deviceid[i].id) + break; + } + return i; +} + +#define mipi_dsi_send_packet(type, regs) \ + _tc358768_send_packet(type, regs, ARRAY_SIZE(regs)) + +#define mipi_dsi_send_dcs_packet(regs) \ + _mipi_dsi_send_dcs_packet(regs, ARRAY_SIZE(regs)) + +static int gl5001w_reset(void) +{ + printk("wangaq:gl5001w_reset\n"); + + gpio_direction_output(Gl5001w_Reset_Port,1); + mdelay(2); + gpio_direction_output(Gl5001w_Reset_Port,0); + mdelay(15); + gpio_direction_output(Gl5001w_Reset_Port,1); + mdelay(5); + + return 0; +} + +static int tc358768_reset(void) +{ + printk("wangaq:tc358768_reset\n"); + + + + gpio_direction_output(Tc358768_Reset_Port,0); + mdelay(20); + gpio_direction_output(Tc358768_Reset_Port,1); + mdelay(20); + + + return 0; +} + +static void set_backlight_power(int on) +{ + printk("set_backlight_power value=%d\n",on); + //gpio_direction_output(BackLight_Power_PORT,on ? 1 : 0); + + printk("set_backlight_power oniff=%d\n",on ? 1 : 0); +} + +static void inline backlight_on(void) +{ + set_backlight_power(1); +} + +static void inline backlight_off(void) +{ + set_backlight_power(0); +} + +static int gl5001w_hw_init(void) +{ + lcd_panel_enum lcd_id; + + mipi_dsi_init(); + lcd_id = tc358768_check_lcd_type(); + //lcd init + //Start of xiaogang.zhang modified on 2013-4-22 14:22 1.0 + if(lcd_id==LCD_YT50F62C6) + { + printk("gl5001w_hw_init LCD_YT50F62C6\n"); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_FF_3DATA); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_FD_4DATA); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_F8_15DATA); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_B8_1DATA); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_F1_1DATA); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_F2_3DATA); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_FC_3DATA); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_FE_1DATA); + msleep(360); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_EB_2DATA); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_E0_16DATA); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_E1_16DATA); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_C1_4DATA); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_C7_1DATA); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_B1_3DATA); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_B4_1DATA); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_36_1DATA); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_3A_1DATA); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_21_0DATA); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_B0_1DATA); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_B6_1DATA); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_C2_1DATA); + + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_11_0DATA); + msleep(120); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_29_0DATA); + + msleep(20); + mipi_dsi_send_dcs_packet(LCD_YT50F62C6_CMD_2C_0DATA); + } + else if(lcd_id==LCD_BT050TN) + { + printk("gl5001w_hw_init LCD_BT050TN\n"); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_FF00_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_FF00_3DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_FF80_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_FF80_2DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_FF03_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_FF03_1DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_2100_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_2100_1DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_D800_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_D800_2DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C582_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C582_1DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C181_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C181_1DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C1A1_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C1A1_1DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_B4C0_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_B4C0_1DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C0A3_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C0A3_1DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C489_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C489_1DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C481_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C481_1DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C590_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C590_3DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C5B1_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C5B1_1DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_D900_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_D900_1DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_E100_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_E100_16DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_E200_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_E200_16DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_0000_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_0000_1DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_B3A1_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_B3A1_1DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_B3A7_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_B3A7_1DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C090_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C090_6DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C1A6_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_C1A6_3DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CE80_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CE80_6DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CE90_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CE90_6DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CEA0_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CEA0_14DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CEB0_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CEB0_14DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CEC0_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CEC0_14DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CED0_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CED0_14DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CFC6_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CFC6_2DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CFC9_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CFC9_1DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CBC0_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CBC0_15DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CBD0_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CBD0_15DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CBE0_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CBE0_10DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CC80_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CC80_10DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CC90_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CC90_15DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CCA0_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CCA0_15DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CCB0_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CCB0_10DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CCC0_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CCC0_15DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CCD0_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_CCD0_15DATA); + + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_21_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_36_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_00_0DATA); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_11_0DATA); + msleep(120); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_29_0DATA); + msleep(20); + mipi_dsi_send_dcs_packet(LCD_BT050TN_CMD_2C_0DATA); + } + else if(lcd_id==LCD_ILI9806) + { + printk("gl5001w_hw_init LCD_ILI9806\n"); + + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_FF_3DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_BA_1DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_F3_1DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_F9_3DATA); + msleep(10); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_B0_1DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_BC_23DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_BD_8DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_BE_17DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_ED_2DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_B4_3DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_B5_4DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_C0_3DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_C1_4DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_D7_1DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_D8_1DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_FC_1DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_E0_16DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_E1_16DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_D5_8DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_F7_1DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_C7_1DATA); + msleep(10); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_36_1DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_51_1DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_53_1DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_55_1DATA); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_11_0DATA); + msleep(120); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_29_0DATA); + msleep(20); + mipi_dsi_send_dcs_packet(LCD_ILI9806_CMD_2C_0DATA); + } + else if(lcd_id==LCD_OTM8019A) + { + printk("gl5001w_hw_init LCD_OTM8019A\n"); + + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_1); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_2); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_3); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_4); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_5); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_6); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_7); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_8); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_9); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_10); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_11); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_12); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_13); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_14); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_15); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_16); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_17); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_18); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_19); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_20); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_21); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_22); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_23); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_24); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_25); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_26); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_27); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_28); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_29); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_30); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_31); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_32); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_33); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_34); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_35); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_36); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_37); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_38); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_39); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_40); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_41); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_42); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_43); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_44); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_45); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_46); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_47); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_48); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_49); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_50); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_51); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_52); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_53); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_54); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_55); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_56); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_57); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_58); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_59); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_60); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_61); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_62); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_63); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_64); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_65); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_66); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_67); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_68); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_69); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_70); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_71); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_72); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_73); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_74); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_76); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_77); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_78); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_79); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_80); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_81); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_82); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_83); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_84); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_85); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_86); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_87); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_88); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_89); + msleep(120); + mipi_dsi_send_dcs_packet(LCD_OTM8019A_CMD_90); + msleep(120); + + } + else + { + printk("gl5001w_hw_init can't find lcd-\n"); + return 0; + } + msleep(1); + mipi_dsi_hs_start(); + msleep(10); + + return 0; +} + + +static void lcd_gl5001w_power_on(void) +{ + int ret; + + printk("lcd_gl5001w_power_on\n"); + gl5001w_reset(); + tc358768_reset(); + + ret = tc358768_rd_reg_32bits(0); + if(ret == 0x4401) { + printk("+TC358768AXBG works ok\n"); + } else { + printk("+TC358768AXBG error , read:0x%0x\n", ret); + return; + } + + gl5001w_hw_init(); +} + +static void lcd_gl5001w_power_off(void) +{ + printk("lcd_gl5001w_power_off\n"); + + gpio_direction_output(Gl5001w_Reset_Port,0); + + lcd_init_gl500 = true; +} + +static int tc358768_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + int ret = 0; + + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); + return -EIO; + } + + tc358768_client = client; + return ret; +} + +static int tc358768_remove(struct i2c_client *client) +{ + return 0; +} + +static const struct i2c_device_id tc358768_id[] = { + { DRIVER_NAME, 0 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, tc358768_id); + + + + + + +static void cw500_resume_work_func(struct work_struct *work) +{ + save=0; + //printk("-cw500_resume_work_func-\n"); + lcd_set_enable(1); + lcd_gl5001w_power_on(); + return NULL; +} + + +static int get_gpio_lcd_gl5001w(void) +{ + int ret = 0; + ret = gpio_request(Gl5001w_Reset_Port,"Gl5001w_Reset_Port"); + if (ret){ + printk("gpio_request Gl5001w_Reset_Port for GL5001W failed\n"); + goto err_get; + } + + ret = gpio_request(Tc358768_Reset_Port,"Tc358768_Reset_Port"); + if (ret){ + printk("gpio_request Tc358768_Reset_Port for Tc358768 failed\n"); + goto err_get; + } + //ret = gpio_request(BackLight_Power_PORT,"BackLight_Power_PORT"); + //if (ret){ + // printk("gpio_request BackLight_Power_PORT for backlight failed\n"); + // goto err_get; + //} + return 0; +err_get: + return -1; +} +static void put_gpio_lcd_gl5001w(void) +{ + gpio_free(Gl5001w_Reset_Port); + gpio_free(Tc358768_Reset_Port); + //gpio_free(BackLight_Power_PORT); + return; +} + + +static int cw500_gl5001_suspend(struct i2c_client *c, pm_message_t state) +{ + save=1; + printk("-cw500_gl5001_suspend-\n"); + put_gpio_lcd_gl5001w(); + return 0; +} + + +static int cw500_gl5001_resume(struct i2c_client *c) +{ + + printk("-cw500_gl5001_resume\n"); + get_gpio_lcd_gl5001w(); + schedule_work(&data->cw500_resume_work); + return 0; +} + +static struct i2c_driver tc358768_driver = { + .driver = { + .name = DRIVER_NAME, + }, + .probe = tc358768_probe, + .remove = __devexit_p(tc358768_remove), + .id_table = tc358768_id, + .resume= cw500_gl5001_resume, + .suspend= cw500_gl5001_suspend, +}; + +static void lcd_set_power(int status) +{ + + + if (!lcd_init_gl500) { + return; + } + + if (save==0) { + return; + } + + if (status == LCD_POWER_ON) + { + lcd_gl5001w_power_on(); + lcd_init_gl500 = false; + } +} + +static struct lcd_parm_t lcd_gl5001w_parm = { + //.name = "GL5001W", + //.fps = 60, /* frame per second */ + .bits_per_pixel = 24, + .capability = 0, + .width = 480, + .height = 854, + .vmode = { + .name = "GL5001W", // mipi_480x800 + .refresh = 60, + .xres = 480, + .yres = 854, + .pixclock = KHZ2PICOS(26000), //pixel_clock + .left_margin = 20, //hbp + .right_margin = 30, //hfp + .upper_margin = 12, //vbp + .lower_margin = 8, //vfp + .hsync_len = 10, //hsync + .vsync_len = 8, //vsync + .sync = 0, //? + .vmode = 0, + .flag = 0, + }, + //.initial = dummy_call_path, + //.uninitial = lcd_gl5001w_power_off, + //.set_power = lcd_set_power, +}; + +static struct lcd_parm_t *lcd_gl5001w_get_parm(int arg) +{ + return &lcd_gl5001w_parm; +} + +static int wmt_check_devices(void) +{ + int ret = 0; + int param[7]; + char buf[96] = {0}; + int len = sizeof(buf); + + ret = wmt_getsyspara("wmt.display.fb0", buf, &len); + if (ret) { + pr_err("Read wmt.display.param Failed.\n"); + return -ENODEV; + } + + ret = vpp_parse_param(buf, param, 6, 0); + if (ret < 2) + return -ENODEV; + + if (param[3] != LCD_GL5001W) + return -ENODEV; + + return 0; +} + +static struct i2c_board_info i2c_board_info = { + I2C_BOARD_INFO(DRIVER_NAME, I2C_ADDR), +}; + +#if 0 +static int tc358768_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + lcd_gl5001w_power_on(); + return 0; +} +#endif + +static int __init gl5001w_init(void) +{ + int ret; + struct i2c_client *client; + struct i2c_adapter *adap; + unsigned char buf[40]; + int buflen = 40; + unsigned int value; + char *endp; + + if(wmt_getsyspara("wmt.support.lcd.gl5001w", buf, &buflen) == 0) { + value = simple_strtoul(buf, &endp, 0); + if(value == 0) + return -1; + } else + return -1; + + ret = gpio_request(Gl5001w_Reset_Port,"Gl5001w_Reset_Port"); + if (ret){ + printk("gpio_request Gl5001w_Reset_Port for GL5001W failed\n"); + goto err_get; + } + + ret = gpio_request(Tc358768_Reset_Port,"Tc358768_Reset_Port"); + if (ret){ + printk("gpio_request Tc358768_Reset_Port for Tc358768 failed\n"); + goto err_get; + } + //ret = gpio_request(BackLight_Power_PORT,"BackLight_Power_PORT"); + //if (ret){ + // printk("gpio_request BackLight_Power_PORT for backlight failed\n"); + // goto err_get; + //} + + data = kzalloc(sizeof(struct cw500_data), GFP_KERNEL); + + INIT_WORK(&data->cw500_resume_work, cw500_resume_work_func); + + ret = wmt_check_devices(); + if (ret) { + pr_info("LCD GL5001W not found\n"); + return -ENODEV; + } + + adap = i2c_get_adapter(I2C_ADAPTER); + if (!adap) + return -ENODEV; + client = i2c_new_device(adap, &i2c_board_info); + i2c_put_adapter(adap); + if (!client) { + printk("i2c_new_device error\n"); + return -ENODEV; + } + + ret = i2c_add_driver(&tc358768_driver); + if (ret) { + return -EIO; + } + + ret = lcd_panel_register(LCD_GL5001W,(void *) lcd_gl5001w_get_parm); + if (ret) { + i2c_del_driver(&tc358768_driver); + return -ENODEV; + } + + /* for debug */ + //create_proc_read_entry(DRIVER_NAME, 0666, NULL, tc358768_proc, NULL); + return 0; +err_get: + return -1; +} + +static void __exit gl5001w_exit(void) +{ + struct i2c_client *client = tc358768_client; + gpio_free(Gl5001w_Reset_Port); + gpio_free(Tc358768_Reset_Port); + //gpio_free(BackLight_Power_PORT); + i2c_unregister_device(client); + return i2c_del_driver(&tc358768_driver); +} + +module_init(gl5001w_init); +module_exit(gl5001w_exit); + +MODULE_DESCRIPTION("WonderMedia GL5001W LCD Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("i2c:gl5001w"); + diff --git a/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-lvds-1024x600.c b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-lvds-1024x600.c new file mode 100755 index 00000000..952a2761 --- /dev/null +++ b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-lvds-1024x600.c @@ -0,0 +1,94 @@ +/*++ + * linux/drivers/video/wmt/lcd-lvds-1024x600.c + * WonderMedia video post processor (VPP) driver + * + * Copyright c 2014 WonderMedia Technologies, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * WonderMedia Technologies, Inc. + * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C +--*/ + +#define LCD_LVDS_1024x600_C +/* #define DEBUG */ +/*----------------------- DEPENDENCE -----------------------------------------*/ +#include "../lcd.h" + +/*----------------------- PRIVATE MACRO --------------------------------------*/ +/* #define LCD_LVDS_1024x600_XXX xxxx *//*Example*/ + +/*----------------------- PRIVATE CONSTANTS ----------------------------------*/ +/* #define LCD_LVDS_1024x600_XXXX 1 *//*Example*/ + +/*----------------------- PRIVATE TYPE --------------------------------------*/ +/* typedef xxxx lcd_xxx_t; *//*Example*/ + +/*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/ +static void lcd_LVDS_1024x600_initial(void); + +/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ +/* int lcd_xxx; *//*Example*/ +struct lcd_parm_t lcd_LVDS_1024x600_parm = { + .bits_per_pixel = 24, + .capability = LCD_CAP_VSYNC_HI, + .vmode = { + .name = "ePAD 1024x600", /* LVDS_1024x600 */ + .refresh = 60, + .xres = 1024, + .yres = 600, + .pixclock = KHZ2PICOS(45000), + .left_margin = 50, + .right_margin = 50, + .upper_margin = 10, + .lower_margin = 10, + .hsync_len = 4, + .vsync_len = 4, + .sync = FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .width = 222, + .height = 125, + .initial = lcd_LVDS_1024x600_initial, +}; + +/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ +/* void lcd_xxx(void); *//*Example*/ + +/*----------------------- Function Body --------------------------------------*/ +static void lcd_LVDS_1024x600_initial(void) +{ + DPRINT("lcd_LVDS_1024x600_initial\n"); + + /* TODO */ +} + +struct lcd_parm_t *lcd_LVDS_1024x600_get_parm(int arg) +{ + return &lcd_LVDS_1024x600_parm; +} + +int lcd_LVDS_1024x600_init(void) +{ + int ret; + + ret = lcd_panel_register(LCD_LVDS_1024x600, + (void *) lcd_LVDS_1024x600_get_parm); + return ret; +} /* End of lcd_oem_init */ +module_init(lcd_LVDS_1024x600_init); + +/*--------------------End of Function Body -----------------------------------*/ +#undef LCD_1024x600_C diff --git a/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-oem.c b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-oem.c new file mode 100755 index 00000000..c079505e --- /dev/null +++ b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-oem.c @@ -0,0 +1,430 @@ +/*++ + * linux/drivers/video/wmt/lcd-oem.c + * WonderMedia video post processor (VPP) driver + * + * Copyright c 2014 WonderMedia Technologies, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * WonderMedia Technologies, Inc. + * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C +--*/ + +#define LCD_OEM_C +/* #define DEBUG */ +/*----------------------- DEPENDENCE -----------------------------------------*/ +#include "../lcd.h" + +/*----------------------- PRIVATE MACRO --------------------------------------*/ +/* #define LCD_OEM_XXXX xxxx *//*Example*/ + +/*----------------------- PRIVATE CONSTANTS ----------------------------------*/ +/* #define LCD_OEM_XXXX 1 *//*Example*/ + +/*----------------------- PRIVATE TYPE --------------------------------------*/ +/* typedef xxxx lcd_xxx_t; *//*Example*/ + +/*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/ + +/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ +/* int lcd_xxx; *//*Example*/ + +/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ +/* void lcd_xxx(void); *//*Example*/ +#ifdef CONFIG_UBOOT +int lcd_bl_time; +void lcd_uboot_set_backlight(void) +{ + int cur; + do { + wmt_read_ostc(&cur); + } while (cur < lcd_bl_time); + REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x800; /* BL( bit 11 ) */ +} + +#endif + +void lcd_oem_enable_backlight(int wait_ms) +{ +#ifdef CONFIG_UBOOT + wmt_read_ostc(&lcd_bl_time); + lcd_bl_time += (wait_ms * 1000); +#else + mdelay(wait_ms); + REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x800; +#endif +} + +#ifndef CONFIG_VPP_SHENZHEN +static void lcd_oem_initial(void) +{ + outl(inl(GPIO_BASE_ADDR + 0x80) | 0x801, GPIO_BASE_ADDR + 0x80); + outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x801, GPIO_BASE_ADDR + 0xC0); + lcd_enable_signal(1); +} + +static void lcd_oem_uninitial(void) +{ + outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x801, GPIO_BASE_ADDR + 0xC0); + lcd_enable_signal(0); +} +#endif + +struct lcd_parm_t lcd_oem_parm = { + .bits_per_pixel = 24, + .capability = LCD_CAP_VSYNC_HI, + .vmode = { + .name = "WonderMedia OEM LCD (VGA 1024x768)", + .refresh = 60, + .xres = 1024, + .yres = 768, + .pixclock = KHZ2PICOS(63500), + .left_margin = 152, + .right_margin = 48, + .upper_margin = 23, + .lower_margin = 3, + .hsync_len = 104, + .vsync_len = 4, + .sync = FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .width = 222, + .height = 125, +#ifndef CONFIG_VPP_SHENZHEN + .initial = lcd_oem_initial, + .uninitial = lcd_oem_uninitial +#endif +}; + +#ifndef CONFIG_VPP_SHENZHEN +static void lcd_oem_1024x600_initial(void) +{ + outl(inl(GPIO_BASE_ADDR + 0x80) | 0x801, GPIO_BASE_ADDR + 0x80); + + /* DVDD */ + /* T2 > 0ms */ /* AVDD/VCOM( bit 0 ) */ + outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x01, GPIO_BASE_ADDR + 0xC0); + /* T4 > 0ms */ + /* VGH */ + /* 0 < T6 <= 10ms */ + lcd_enable_signal(1); /* singal, DVO enable */ + mdelay(200); /* T12 > 200ms */ + outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x800, GPIO_BASE_ADDR + 0xC0); +} + +static void lcd_oem_1024x600_uninitial(void) +{ + /* BL( bit 11 ) */ + outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x800, GPIO_BASE_ADDR + 0xC0); + mdelay(200); /* T12 > 200ms */ + lcd_enable_signal(0); /* singal, DVO enable */ + /* AVDD/VCOM( bit 0 ) */ + outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x01, GPIO_BASE_ADDR + 0xC0); +} +#endif + +struct lcd_parm_t lcd_oem_parm_1024x600 = { + .bits_per_pixel = 24, + .capability = LCD_CAP_VSYNC_HI, + .vmode = { +#if 1 /* 7" HHX070ML208CP21A */ + .name = "HHX070ML208CP21A", + .refresh = 60, + .xres = 1024, + .yres = 600, + .pixclock = KHZ2PICOS(51200), + .left_margin = 140, + .right_margin = 160, + .upper_margin = 20, + .lower_margin = 12, + .hsync_len = 20, + .vsync_len = 3, + .sync = FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, +#else + .name = "ePAD 1024x600", /* HannStar HSD070PFW3 */ + .refresh = 60, + .xres = 1024, + .yres = 600, + .pixclock = KHZ2PICOS(45000), + .left_margin = 50, + .right_margin = 50, + .upper_margin = 10, + .lower_margin = 10, + .hsync_len = 4, + .vsync_len = 4, + .sync = FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, +#endif + }, +#ifndef CONFIG_VPP_SHENZHEN + .initial = lcd_oem_1024x600_initial, + .uninitial = lcd_oem_1024x600_uninitial, +#endif +}; + +struct lcd_parm_t lcd_oem_parm_1024x768 = { + .bits_per_pixel = 24, + .capability = LCD_CAP_VSYNC_HI, + .vmode = { + .name = "OEM 1024x768", /* VGA 1024x768 */ + .refresh = 60, + .xres = 1024, + .yres = 768, + .pixclock = KHZ2PICOS(63500), + .left_margin = 152, + .right_margin = 48, + .upper_margin = 23, + .lower_margin = 3, + .hsync_len = 104, + .vsync_len = 4, + .sync = FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .width = 222, + .height = 125, +#ifndef CONFIG_VPP_SHENZHEN + .initial = lcd_oem_initial, + .uninitial = lcd_oem_uninitial +#endif +}; + +struct lcd_parm_t lcd_oem_parm_1366x768 = { + .bits_per_pixel = 18, + .capability = LCD_CAP_CLK_HI, + .vmode = { + .name = "OEM 1366X768", + .refresh = 60, + .xres = 1366, + .yres = 768, + .pixclock = KHZ2PICOS(75440), + .left_margin = 98, + .right_margin = 31, + .upper_margin = 22, + .lower_margin = 4, + .hsync_len = 65, + .vsync_len = 12, + .sync = 0, + .vmode = 0, + .flag = 0, + }, + .width = 293, + .height = 164, +#ifndef CONFIG_VPP_SHENZHEN + .initial = lcd_oem_initial, + .uninitial = lcd_oem_uninitial +#endif +}; + +struct lcd_parm_t lcd_oem_parm_480x800 = { + .bits_per_pixel = 18, + .capability = LCD_CAP_CLK_HI, + .vmode = { + .name = "OEM 480x800", + .refresh = 60, + .xres = 480, + .yres = 800, + .pixclock = KHZ2PICOS(27000), + .left_margin = 78, + .right_margin = 78, + .upper_margin = 60, + .lower_margin = 60, + .hsync_len = 4, + .vsync_len = 4, + .sync = 0, + .vmode = 0, + .flag = 0, + }, +#ifndef CONFIG_VPP_SHENZHEN + .initial = lcd_oem_initial, + .uninitial = lcd_oem_uninitial +#endif +}; + +struct lcd_parm_t lcd_oem_parm_800x480 = { + .bits_per_pixel = 18, + .capability = LCD_CAP_CLK_HI, + .vmode = { + .name = "OEM 800x480", + .refresh = 48, + .xres = 800, + .yres = 480, + .pixclock = KHZ2PICOS(27000), + .left_margin = 50, + .right_margin = 50, + .upper_margin = 17, + .lower_margin = 16, + .hsync_len = 10, + .vsync_len = 5, + .sync = 0, + .vmode = 0, + .flag = 0, + }, + .width = 154, + .height = 85, +#ifndef CONFIG_VPP_SHENZHEN + .initial = lcd_oem_initial, + .uninitial = lcd_oem_uninitial +#endif +}; + +#ifndef CONFIG_VPP_SHENZHEN +static void lcd_oem_1280x800_initial(void) +{ + DBG_MSG("lcd 10 power sequence\n"); + outl(inl(GPIO_BASE_ADDR + 0x80) | 0x801, GPIO_BASE_ADDR + 0x80); + + /* VDD on */ + /* 0 < T < 50ms */ + lcd_enable_signal(1); /* singal on */ + /* VGH,VGL low */ /* AVDD/VCOM( bit 0 ) */ + outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x01, GPIO_BASE_ADDR + 0xC0); + mdelay(150); /* T5 > 120ms */ + outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x800, GPIO_BASE_ADDR + 0xC0); +} + +static void lcd_oem_1280x800_uninitial(void) +{ + /* turn off backlight */ + outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x800, GPIO_BASE_ADDR + 0xC0); + mdelay(150); + /* turn off LCD */ + outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x01, GPIO_BASE_ADDR + 0xC0); + lcd_enable_signal(0); /* turn off singal */ +} +#endif + +struct lcd_parm_t lcd_oem_parm_800x1280 = { + .bits_per_pixel = 24, + .capability = LCD_CAP_CLK_HI, + .vmode = { + .name = "WY101ML369IN30A", + .refresh = 60, + .xres = 800, + .yres = 1280, + .pixclock = KHZ2PICOS(71100), + .left_margin = 70, + .right_margin = 80, + .upper_margin = 10, + .lower_margin = 10, + .hsync_len = 10, + .vsync_len = 3, + .sync = 0, + .vmode = 0, + .flag = 0, + }, + .width = 135, + .height = 217, +#ifndef CONFIG_VPP_SHENZHEN + .initial = lcd_oem_1280x800_initial, + .uninitial = lcd_oem_1280x800_uninitial, +#endif +}; + +struct lcd_parm_t lcd_oem_parm_1280x800 = { + .bits_per_pixel = 24, + .capability = LCD_CAP_CLK_HI, + .vmode = { + .name = "WY101ML369IN30A", + .refresh = 60, + .xres = 1280, + .yres = 800, + .pixclock = KHZ2PICOS(71100), + .left_margin = 70, + .right_margin = 80, + .upper_margin = 10, + .lower_margin = 10, + .hsync_len = 10, + .vsync_len = 3, + .sync = 0, + .vmode = 0, + .flag = 0, + }, + .width = 217, + .height = 135, +#ifndef CONFIG_VPP_SHENZHEN + .initial = lcd_oem_1280x800_initial, + .uninitial = lcd_oem_1280x800_uninitial, +#endif +}; + +struct lcd_parm_t lcd_oem_parm_768x1024 = { + .bits_per_pixel = 24, + .capability = LCD_CAP_CLK_HI, + .vmode = { + .name = "oem_768x1024", + .refresh = 60, + .xres = 768, + .yres = 1024, + .pixclock = KHZ2PICOS(59300), + .left_margin = 80, + .right_margin = 80, + .upper_margin = 23, + .lower_margin = 18, + .hsync_len = 7, + .vsync_len = 5, + .sync = 0, + .vmode = 0, + .flag = 0, + }, +}; + +/*----------------------- Function Body --------------------------------------*/ +struct lcd_parm_t *lcd_oem_get_parm(int arg) +{ + return &lcd_oem_parm; +} + +int lcd_oem_init(void) +{ + int ret; + + ret = lcd_panel_register(LCD_WMT_OEM, (void *)lcd_oem_get_parm); + return ret; +} /* End of lcd_oem_init */ +module_init(lcd_oem_init); + +struct lcd_parm_t *lcd_get_oem_parm(int resx, int resy) +{ + struct lcd_parm_t *oem_parm[] = { + &lcd_oem_parm_480x800, + &lcd_oem_parm_1024x600, + &lcd_oem_parm_1024x768, + &lcd_oem_parm_1366x768, + &lcd_oem_parm_800x480, + &lcd_oem_parm_800x1280, + &lcd_oem_parm_1280x800, + &lcd_oem_parm_768x1024, + 0 + }; + struct lcd_parm_t *p; + int i; + + for (i = 0; ; i++) { + p = oem_parm[i]; + if (p == 0) { + p = oem_parm[0]; + break; + } + if ((resx == p->vmode.xres) && (resy == p->vmode.yres)) + break; + } + return p; +} +/*--------------------End of Function Body -----------------------------------*/ +#undef LCD_OEM_C diff --git a/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-setup.c b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-setup.c new file mode 100755 index 00000000..798f020e --- /dev/null +++ b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-setup.c @@ -0,0 +1,311 @@ +/* + * ========================================================================== + * + * Filename: lcd-setup.c + * + * Description: + * + * Version: 0.01 + * Created: 2014.6.6 + * + * Author: SamMei + * Company: + * + * ========================================================================== + */ + +#include <linux/delay.h> +#include <linux/spi/spi.h> +#include <linux/i2c.h> +#include <mach/hardware.h> +#include <mach/wmt-spi.h> +#include <linux/gpio.h> +#include <mach/wmt_iomux.h> +#include "../lcd.h" + +#define DRIVERNAME "lcd-setup" + +#undef pr_err +#undef pr_info +#undef pr_warning +#define pr_err(fmt, args...) printk("[" DRIVERNAME "] " fmt, ##args) +#define pr_info(fmt, args...) printk("[" DRIVERNAME "] " fmt, ##args) +#define pr_warning(fmt, args...) printk("[" DRIVERNAME "] " fmt, ##args) + +enum { + LCD_SETUP_TS8224B, /* spi init */ + LCD_SETUP_CHUNGHWA, /* i2c init */ + LCD_SETUP_MAX, +}; + +static int lcd_setup_id = -1; +struct spi_device *g_spi_device; + +static int wmt_lcd_setup_id(void) +{ + char buf[32]; + int len = sizeof(buf); + int id; + + if (wmt_getsyspara("wmt.lcd.setup", buf, &len)) + id = -ENODEV; + sscanf(buf, "%d", &id); + return id; +} + +static inline void spi_ctrl_9bit_tx(u8 val, int cmd_data) +{ + uint8_t buf[2]; + + if (cmd_data) + buf[0] = (val >> 1) | BIT7; + else + buf[0] = (val >> 1) & 0x7f; + + buf[1] = (val << 7); + + spi_write(g_spi_device, buf, sizeof(buf)); +} + +static inline void spi_9bit_tx(u8 val, int cmd_data) +{ + spi_ctrl_9bit_tx(val, cmd_data); +} + +static inline int ts8224b_cmd(u8 cmd) +{ + spi_9bit_tx(cmd, 0); + return 0; +} + +static inline int ts8224b_data(u8 data) +{ + spi_9bit_tx(data, 1); + return 0; +} + +static int ts8224b_init(void) +{ + static uint16_t settings[] = { + #include "ts8224b.h" + }; + int i; + + printk(" ## %s, %d\n", __func__, __LINE__); + + for (i = 0; i < ARRAY_SIZE(settings); i += 2) { + ts8224b_cmd(settings[i] >> 8); + ts8224b_data(settings[i+1]); + } + + ts8224b_cmd(0x11); + msleep(120); + + ts8224b_cmd(0x29); + msleep(50); + ts8224b_cmd(0x2c); + return 0; +} + +extern void lcd_power_on(bool on); + +//int lcd_spi_resume(struct spi_device *spi) +int lcd_spi_resume(void) +{ + //printk(" ## %s, %d\n", __func__, __LINE__); + switch (lcd_setup_id) { + case LCD_SETUP_TS8224B: + printk(" ## %s, %d\n", __func__, __LINE__); + lcd_power_on(1); + mdelay(5); + return ts8224b_init(); + default: + return 0; + } +} + +static int __devinit lcd_spi_probe(struct spi_device *spi) +{ + g_spi_device = spi; + + //lcd_spi_resume(); + + return 0; +} + +static struct spi_driver lcd_spi_driver = { + .driver = { + .name = DRIVERNAME, + .owner = THIS_MODULE, + }, + .probe = lcd_spi_probe, + //.resume = lcd_spi_resume, +}; + +static struct spi_board_info lcd_spi_info[] __initdata = { + { + .modalias = DRIVERNAME, + .bus_num = 0, + .chip_select = 0, + .max_speed_hz = 12000000, + .irq = -1, + .mode = SPI_CLK_MODE1, + }, +}; + + +// I2C + +static int lcd_i2c_resume(struct i2c_client *client) +{ + static uint8_t init_data[] = { + 0x4b, 0x01, + 0x0c, 0x01, + 0x05, 0x03, + 0x41, 0x03, + 0x10, 0x06, + 0x11, 0xE0, + 0x12, 0x00, + 0x13, 0x3C, + 0x14, 0x06, + 0x15, 0x40, + 0x16, 0x03, + 0x17, 0x9E, + 0x18, 0x00, + 0x19, 0x10, + 0x1a, 0x03, + 0x1b, 0x84, + 0x1c, 0x80, + 0x1d, 0x0A, + 0x1e, 0x80, + 0x1f, 0x06, + 0x3c, 0x17, + 0x3e, 0x16, + 0x36, 0x00, + 0x31, 0x00, + 0x35, 0x41, + 0x30, 0xB0, + 0x30, 0xB1, + 0x00, 0x0B, + }; + + int i, ret; + + printk(" ## %s, %d\n", __FUNCTION__, __LINE__); + for (i = 0; i < ARRAY_SIZE(init_data); i += 2) { + ret = i2c_master_send(client, &init_data[i], 2); + if (ret < 0) + return ret; + } + return 0; +} + +static int __devinit lcd_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + printk(" ## %s, %d\n", __FUNCTION__, __LINE__); + return 0; +} + +static const struct i2c_device_id lcd_i2c_id[] = { + { "lcd-i2c", 0 }, + { }, +}; + +static struct i2c_driver lcd_i2c_driver = { + .driver = { + .name = "lcd-i2c", + .owner = THIS_MODULE, + }, + .probe = lcd_i2c_probe, +// .remove = __devexit_p(lcd_i2c_remove), +// .suspend = lcd_i2c_suspend, + .resume = lcd_i2c_resume, +// .shutdown = lcd_i2c_shutdown, + .id_table = lcd_i2c_id, +}; + +static struct i2c_board_info lcd_i2c_board_info = { + .type = "lcd-i2c", + .flags = 0x00, + .addr = 0xe0 >> 1, + .platform_data = NULL, + .archdata = NULL, + .irq = -1, +}; + +static struct i2c_client *i2c_client; +static struct i2c_adapter *i2c_adap; + +static int __init lcd_setup_init(void) +{ + int ret; + + lcd_setup_id = wmt_lcd_setup_id(); + switch (lcd_setup_id) { + + // SPI + case LCD_SETUP_TS8224B: + ret = spi_register_board_info(lcd_spi_info, ARRAY_SIZE(lcd_spi_info)); + if (ret) { + pr_err("spi_register_board_info failed\n"); + return ret; + } + + ret = spi_register_driver(&lcd_spi_driver); + if (ret) { + pr_err("spi_register_driver failed\n"); + return ret; + } + + pr_info("spi %s register success\n", DRIVERNAME); + return 0; + + // I2C + case LCD_SETUP_CHUNGHWA: + printk(" ## %s, %d\n", __FUNCTION__, __LINE__); + i2c_adap = i2c_get_adapter(1); + if (!i2c_adap) { + pr_err("Cannot get i2c adapter 1\n"); + return -ENODEV; + } + + i2c_client = i2c_new_device(i2c_adap, &lcd_i2c_board_info); + if (!i2c_client) { + pr_err("Unable to add I2C device for 0x%x\n", + lcd_i2c_board_info.addr); + return -ENODEV; + } + + return i2c_add_driver(&lcd_i2c_driver); + + // INVALID + default: + return -EINVAL; + } +} + +static void lcd_setup_exit(void) +{ + switch (lcd_setup_id) { + + // SPI + case LCD_SETUP_TS8224B: + spi_unregister_driver(&lcd_spi_driver); + break; + + // I2C + case LCD_SETUP_CHUNGHWA: + i2c_put_adapter(i2c_adap); + i2c_del_driver(&lcd_i2c_driver); + i2c_unregister_device(i2c_client); + break; + + // INVALID + default: + return; + } +} + +module_init(lcd_setup_init); +module_exit(lcd_setup_exit); diff --git a/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-spi.c b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-spi.c new file mode 100755 index 00000000..2782806a --- /dev/null +++ b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd-spi.c @@ -0,0 +1,786 @@ +#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/irq.h>
+#include <linux/jiffies.h>
+#include <linux/uaccess.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/miscdevice.h>
+#include <linux/spinlock.h>
+
+#include <mach/hardware.h>
+
+#include <linux/spi/spi.h>
+#include <mach/wmt_iomux.h>
+
+#define wmt_spi_lcd_err(fmt, args...) printk("[%s-%d] %s: " fmt, __FILE__,__LINE__,__FUNCTION__, ## args)
+#define wmt_spi_lcd_printk(fmt, ...) wmt_spi_lcd_err(fmt, ##__VA_ARGS__)
+
+#define WMT_SPI_READ_BUF_MAX_LEN 200
+#define WMT_SPI_LCD_SPI_MODE SPI_MODE_0
+
+#define WMT_SPI_LCD_A0_PIN WMT_PIN_GP1_GPIO10
+
+#define WMT_LCD_POWER_PIN WMT_PIN_GP0_GPIO0
+#define WMT_WIFI_POWER_PIN WMT_PIN_GP1_GPIO14
+#define WMT_AIT_POWER_PIN WMT_PIN_GP1_GPIO12
+#define WMT_PRINT_POWER_PIN WMT_PIN_GP62_WAKEUP4
+#define WMT_OTG_PRINT_SWITCH_PIN WMT_PIN_GP21_HDMIDCSDA
+
+#if 0
+typedef enum{
+ WMT_SPI_LCD_STATE_NULL,
+ WMT_SPI_LCD_STATE_HAPPY,
+ WMT_SPI_LCD_STATE_SUN,
+ WMT_SPI_LCD_STATE_CLOUDY,
+ WMT_SPI_LCD_STATE_SAD,
+ WMT_SPI_LCD_STATE_PRINT,
+ WMT_SPI_LCD_STATE_MESSAGE,
+ WMT_SPI_LCD_STATE_MAX
+}wmt_sub_lcd_state;
+#endif
+#define WMT_SPI_LCD_IOCTL_MAGIC 0x11
+#define WMT_SPI_LCD_STATE_HAPPY _IOW(WMT_SPI_LCD_IOCTL_MAGIC, 0, int)
+#define WMT_SPI_LCD_STATE_SUN _IOW(WMT_SPI_LCD_IOCTL_MAGIC, 1, int)
+#define WMT_SPI_LCD_STATE_CLOUDY _IOW(WMT_SPI_LCD_IOCTL_MAGIC, 2, int)
+#define WMT_SPI_LCD_STATE_SAD _IOW(WMT_SPI_LCD_IOCTL_MAGIC, 3, int)
+#define WMT_SPI_LCD_STATE_PRINT _IOW(WMT_SPI_LCD_IOCTL_MAGIC, 4, int)
+#define WMT_SPI_LCD_STATE_MESSAGE _IOW(WMT_SPI_LCD_IOCTL_MAGIC, 5, int)
+
+#define WMT_WIFI_POWER _IOW(WMT_SPI_LCD_IOCTL_MAGIC, 20, int)
+#define WMT_AIT_POWER _IOW(WMT_SPI_LCD_IOCTL_MAGIC, 21, int)
+#define WMT_PRINT_POWER _IOW(WMT_SPI_LCD_IOCTL_MAGIC, 22, int)
+#define WMT_SWITCH_OTG_PRINT _IOW(WMT_SPI_LCD_IOCTL_MAGIC, 23, int)
+
+#define WMT_GET_LCD_POWER _IOW(WMT_SPI_LCD_IOCTL_MAGIC, 30, int)
+#define WMT_GET_WIFI_POWER _IOW(WMT_SPI_LCD_IOCTL_MAGIC, 31, int)
+#define WMT_GET_AIT_POWER _IOW(WMT_SPI_LCD_IOCTL_MAGIC, 32, int)
+#define WMT_GET_PRINT_POWER _IOW(WMT_SPI_LCD_IOCTL_MAGIC, 33, int)
+#define WMT_GET_OTG_PRINT_STATE _IOW(WMT_SPI_LCD_IOCTL_MAGIC, 34, int)
+
+static int wmt_sub_lcd_display_state=WMT_SPI_LCD_STATE_HAPPY;
+
+struct wmt_spi_lcd_dev {
+ wait_queue_head_t read_wq;
+ struct mutex read_mutex;
+ struct spi_device *spi;
+ struct miscdevice sub_lcd_misc_device;
+ struct kobject *kobj;
+ bool irq_enabled;
+ spinlock_t irq_enabled_lock;
+ int lcd_val;
+ int wifi_val;
+ int ait_val;
+ int print_val;
+ int otg_print_state;
+};
+
+struct wmt_spi_lcd_dev *wmt_spi_lcd_pContext;
+
+const char wmt_spi_lcd_display_happy[][64]={
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0xE0,
+ 0xF0,0xF0,0xF8,0xF8,0xF8,0x7C,0x7C,0x7C,0x3E,0x3E,0x3E,0x3E,0x1E,0x1F,0x1F,0x1F,
+ 0x1F,0x1F,0x1F,0x1E,0x3E,0x3E,0x3E,0x3E,0x7E,0x7C,0x7C,0xFC,0xF8,0xF8,0xF0,0xF0,
+ 0xE0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0xF0,0xF8,0xFC,0xFE,0x7F,0x3F,0x1F,0x0F,0x07,
+ 0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x03,
+ 0x07,0x0F,0x0F,0x1F,0x3F,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x80,0xF0,0xFC,0xFF,0xFF,0xFF,0x1F,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xC0,0xF0,0xF0,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF0,0xE0,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0xC0,0xF0,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF0,0xE0,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07,0x1F,0x7F,0xFF,0xFF,0xFC,0xF0,0x80,0x00,
+ 0xF0,0xFF,0xFF,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x07,0x1F,0x1F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x1F,0x0F,0x01,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x0F,0x1F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x1F,0x0F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xFF,0xFF,0xFF,0xFF,0xF8,
+ 0x0F,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0xFF,0x3F,
+ 0x00,0x01,0x0F,0x3F,0xFF,0xFF,0xFE,0xF8,0xE0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x07,0x0F,0x3F,0x7F,0x7F,0xFC,0xF8,0xF0,0xF0,0xE0,0xE0,0xE0,0xE0,
+ 0xE0,0xE0,0xE0,0xF0,0xF0,0xF8,0xFC,0x7F,0x7F,0x3F,0x0F,0x07,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xF0,0xFE,0xFF,0xFF,0x7F,0x1F,0x03,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x0F,0x3F,0x7F,0xFF,0xFC,0xF8,0xF0,0xE0,0xC0,
+ 0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,
+ 0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0x7F,0x3F,0x1F,0x07,0x03,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x03,0x07,0x07,
+ 0x0F,0x1F,0x1F,0x3F,0x3E,0x3E,0x7E,0x7C,0x7C,0x7C,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,
+ 0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0x7C,0x7C,0x7C,0x7C,0x3E,0x3E,0x3F,0x1F,0x1F,0x0F,
+ 0x0F,0x07,0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+};
+
+char wmt_spi_lcd_display_sad[][64]={
+ /* ͼÏñ C:\Users\admin\Desktop\androd camera\yuhao\sad.bmp 64x64 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0xE0,
+ 0xF0,0xF0,0xF8,0xF8,0x7C,0x7C,0x7E,0x3E,0x3E,0x3E,0x1E,0x1F,0x1F,0x1F,0x1F,0x1F,
+ 0x1F,0x1F,0x1F,0x1F,0x1F,0x1E,0x3E,0x3E,0x3E,0x7E,0x7C,0x7C,0xF8,0xF8,0xF0,0xF0,
+ 0xE0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0xC0,0xE0,0xF0,0xFC,0xFE,0xFF,0x3F,0x1F,0x0F,0x07,0x07,
+ 0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,
+ 0x07,0x07,0x0F,0x1F,0x3F,0xFF,0xFE,0xFC,0xF0,0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0xC0,0xF0,0xFC,0xFF,0xFF,0x7F,0x0F,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xE0,0xF0,0xF8,0xF8,0xFC,0xFC,0xFC,0xF8,0xF8,0xF0,0xE0,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0xE0,0xF0,0xF8,0xF8,0xFC,0xFC,0xFC,0xF8,0xF8,0xF0,0xE0,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07,0x0F,0x7F,0xFF,0xFF,0xFC,0xF0,0xC0,0x00,
+ 0xF8,0xFF,0xFF,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x07,0x1F,0x1F,0x3F,0x3F,0x3F,0x3F,0x3F,0x1F,0x1F,0x07,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x07,0x1F,0x1F,0x3F,0x3F,0x3F,0x3F,0x3F,0x1F,0x1F,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0xFF,0xFF,0xF8,
+ 0x1F,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0xC0,0xE0,0xE0,0xE0,0xE0,
+ 0xE0,0xE0,0xC0,0xC0,0xC0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0xFF,0x1F,
+ 0x00,0x03,0x0F,0x3F,0xFF,0xFF,0xFE,0xF0,0xE0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x40,0xF0,0xFC,0xFE,0xFF,0x7F,0x1F,0x0F,0x07,0x07,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x07,0x07,0x0F,0x1F,0x3F,0xFF,0xFE,0xFC,0xF8,0x60,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0xF0,0xFE,0xFF,0xFF,0x3F,0x0F,0x03,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x0F,0x3F,0x7F,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,
+ 0xC0,0x80,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x80,0xC0,
+ 0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0x7F,0x3F,0x1F,0x07,0x03,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x03,0x07,0x07,
+ 0x0F,0x1F,0x1F,0x1F,0x3E,0x3E,0x7E,0x7C,0x7C,0x7C,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,
+ 0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0x7C,0x7C,0x7C,0x7E,0x3E,0x3E,0x1F,0x1F,0x1F,0x0F,
+ 0x07,0x07,0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+char wmt_spi_lcd_display_print[][64]={
+ /* ͼÏñ C:\Users\admin\Desktop\androd camera\yuhao\print.bmp 64x64 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0xFF,0xFF,0xFF,0x1F,
+ 0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
+ 0x1F,0x1F,0x1F,0x1F,0x1F,0xFF,0xFF,0xFF,0x1E,0x3C,0x78,0xF0,0xF0,0xE0,0xC0,0x80,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xE0,0xE0,0xE0,0xE0,0xE1,0xE3,0xE7,0xEF,
+ 0xFF,0xFE,0xFC,0xF8,0xF0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xF0,0xFC,0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFE,0xFC,0xF8,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x03,0x03,0x03,0x03,0x03,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x03,0x03,0x03,0x03,0x03,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0x0F,
+ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+ 0x0F,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0x01,0x07,0x0F,0x1F,0x1F,0x3F,0x3F,0x3F,0x3F,0x3F,0xBF,0xFF,0xFF,0xFF,0xFF,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0xFF,0xFF,0xFF,0xFF,0xBF,0x3F,0x3F,0x3F,0x3F,0x3F,0x1F,0x1F,0x0F,0x07,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xF0,
+ 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
+ 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
+ 0xF0,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+char wmt_spi_lcd_display_message[][64]={
+ /* ͼÏñ C:\Users\admin\Desktop\androd camera\yuhao\message.bmp 64x64 */
+ 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,
+ 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,0xBF,0x3F,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x3F,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFC,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x07,0x0F,0x1F,0x1F,0x3F,0x7F,0xFF,0xFF,
+ 0xFE,0xFC,0xFC,0xF8,0xF0,0xF0,0xE0,0xC0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0xE0,0xF0,0xF8,0xF8,0xFC,0xFE,0xFF,
+ 0xFF,0x7F,0x3F,0x3F,0x1F,0x0F,0x07,0x07,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x03,0x03,0x07,0x0F,0x1F,0x1F,0x3F,0x7F,0x7F,0xFF,0xFE,0xFC,0xFC,0xF8,0xF0,
+ 0xF8,0xF8,0xFC,0xFE,0xFF,0xFF,0x7F,0x3F,0x3F,0x1F,0x0F,0x07,0x07,0x03,0x01,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x03,0x07,0x07,
+ 0x07,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0x3F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,
+ 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,
+ 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,
+ 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+
+const char wmt_spi_lcd_display_sun[][64]={
+ /* ͼÏñ C:\Users\admin\Desktop\androd camera\yuhao\sun.bmp 64x64 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,
+ 0xF0,0xF0,0xF0,0xE0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFE,0xFF,
+ 0xFF,0xFE,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0xF0,0xF0,0xF0,
+ 0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x03,0x0F,0x3F,0x7F,0x7F,0x7E,0x78,0x00,0x00,0x00,0x00,0x80,0x80,0x87,0x8F,0x8F,
+ 0x8F,0x8F,0x87,0x80,0x80,0x00,0x00,0x00,0x30,0x7C,0x7F,0x7F,0x7F,0x3F,0x0F,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x07,0x0F,0x0F,0x1F,0x1F,0x3F,0x7E,0x7E,0x7C,0x7C,0x78,0x00,
+ 0x00,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0x7E,0x3F,0x3F,0x1F,0x1F,0x0F,0x0F,0x0F,0x0F,
+ 0x0F,0x0F,0x0F,0x0F,0x1F,0x1F,0x3F,0x7F,0x7E,0xFC,0xFC,0xF8,0xF0,0xE0,0x80,0x00,
+ 0x30,0x78,0x7C,0x7C,0x7E,0x3F,0x3F,0x1F,0x1F,0x0F,0x0F,0x07,0x00,0x00,0x00,0x00,
+ 0x80,0xC0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xC0,0x00,0x00,0x00,0xF8,
+ 0xFF,0xFF,0xFF,0xFF,0x0F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x1F,0xFF,0xFF,0xFF,0xFE,
+ 0xF8,0x00,0x00,0x80,0xC0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xC0,0x80,
+ 0x01,0x03,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x03,0x03,0x00,0x00,0x00,0x1F,
+ 0xFF,0xFF,0xFF,0xFF,0xF0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xF8,0xFF,0xFF,0xFF,0x7F,
+ 0x1F,0x00,0x00,0x01,0x03,0x03,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x03,0x03,0x01,
+ 0x00,0x00,0x00,0x00,0xE0,0xF0,0xF0,0xF8,0xFC,0xFC,0x7E,0x7E,0x3F,0x3F,0x1E,0x00,
+ 0x00,0x01,0x07,0x0F,0x1F,0x3F,0x3F,0x7E,0x7E,0xFC,0xF8,0xF8,0xF0,0xF0,0xF0,0xF0,
+ 0xF0,0xF0,0xF0,0xF8,0xF8,0xF8,0xFC,0x7E,0x7F,0x3F,0x1F,0x1F,0x0F,0x03,0x01,0x00,
+ 0x0C,0x1E,0x3F,0x3F,0x7E,0x7E,0xFC,0xF8,0xF8,0xF0,0xF0,0xE0,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
+ 0xE0,0xF0,0xFC,0xFE,0xFF,0x7F,0x1E,0x00,0x00,0x00,0x00,0x01,0x01,0xE1,0xF1,0xF9,
+ 0xF9,0xF1,0xE1,0x01,0x01,0x00,0x00,0x00,0x0C,0x3E,0x7F,0xFF,0xFE,0xFC,0xF0,0xC0,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+ 0x0F,0x0F,0x0F,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x7F,0xFF,
+ 0xFF,0x7F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07,0x0F,0x0F,0x0F,
+ 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+const char wmt_spi_lcd_display_cloudy[][64]={
+ /* ͼÏñ C:\Users\admin\Desktop\androd camera\yuhao\cloudy.bmp 64x64 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xE0,0xE0,0xE0,0xC0,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x87,0x8F,0x87,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0xC0,0xE0,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x80,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC1,0xC1,0x81,0x80,0x80,0x18,0x38,
+ 0x3C,0x1E,0x1E,0x0F,0x0F,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x0F,0x0F,0x1E,0x3E,
+ 0x7C,0xF8,0xF0,0xE0,0xC0,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xF0,0xF8,0x7C,0x3C,0x1E,0x0F,0x0F,
+ 0x07,0x07,0x03,0x03,0x03,0x03,0x01,0x01,0x03,0x03,0x03,0x03,0x07,0x07,0x0F,0x0F,
+ 0x1E,0x3C,0x7C,0xF8,0xF0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x03,0xFF,0xFF,0xFF,0xF0,0x00,0x00,0x00,0x20,0x70,0x70,0x70,0x70,0x20,
+ 0x00,0x00,0x00,0x80,0xC0,0xE0,0xFC,0xFF,0xFF,0x0F,0x01,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x01,0x0F,0x1F,0x1F,0x0E,0x0F,0x0F,0x07,0x07,0x0F,0x0F,0x0F,0x1E,
+ 0x1E,0x3C,0x78,0xF9,0xF3,0xC7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xF8,0xFE,0xFF,0x1F,0x07,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x81,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x03,0x0F,0x1F,0x3F,0x7C,0xF0,0xF0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
+ 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
+ 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xF0,
+ 0xF0,0x78,0x3E,0x3F,0x0F,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
+
+void wmt_spi_lcd_write_n_data(const char *wbuf,int wbuf_len)
+{
+ if(wbuf_len>=WMT_SPI_READ_BUF_MAX_LEN)
+ {
+ wmt_spi_lcd_err("error!!");
+ return;
+ }
+ gpio_direction_output(WMT_SPI_LCD_A0_PIN,1);
+ spi_write_then_read(wmt_spi_lcd_pContext->spi, wbuf, wbuf_len, NULL, 0);
+}
+
+void wmt_spi_lcd_write_data(unsigned char c)
+{
+ wmt_spi_lcd_write_n_data(&c,1);
+}
+
+
+//-------------------------------------------------------------------------------
+//×Ó³ÌÐòÃû³Æ:lcdwc(unsigned char c).
+//¹¦ÄÜ:ÏòÒº¾§ÏÔʾ¿ØÖÆÆ÷ËÍÖ¸Áî.
+//-------------------------------------------------------------------------------
+void wmt_spi_lcd_write_command(unsigned char c)
+{
+ gpio_direction_output(WMT_SPI_LCD_A0_PIN,0);
+ spi_write_then_read(wmt_spi_lcd_pContext->spi, &c, 1, NULL, 0);
+}
+
+void wmt_spi_lcd_reset(void) //Òº¾§ÏÔʾ¿ØÖÆÆ÷³õʼ»¯×Ó³ÌÐò
+{
+ #if 0
+ gpio_direction_output(WMT_SPI_LCD_RESET_PIN,0);
+ mdelay(200);
+ gpio_direction_output(WMT_SPI_LCD_RESET_PIN,1);
+ mdelay(200);
+ #endif
+ wmt_spi_lcd_write_command(0xe2);
+ mdelay(100);
+
+ wmt_spi_lcd_write_command(0x2c);/////set booster on
+ wmt_spi_lcd_write_command(0x2e); ////voltage regulator circuit on
+ wmt_spi_lcd_write_command(0x2f);//// voltage follower circuit on
+
+ wmt_spi_lcd_write_command(0xa0);//
+ wmt_spi_lcd_write_command(0xa6);//
+ mdelay(3);
+ wmt_spi_lcd_write_command(0xc8);//
+ mdelay(3);
+ wmt_spi_lcd_write_command(0xa2);//
+ mdelay(3);
+
+ wmt_spi_lcd_write_command(0xf8); //set booster ratio
+ mdelay(2);
+ wmt_spi_lcd_write_command(0x00); //set X2 X3 X4
+ mdelay(2);
+
+ wmt_spi_lcd_write_command(0x24);
+ mdelay(2);
+ wmt_spi_lcd_write_command(0x81);
+ mdelay(2);
+ wmt_spi_lcd_write_command(0x28);
+ mdelay(2);
+ wmt_spi_lcd_write_command(0xac);
+ mdelay(2);
+ wmt_spi_lcd_write_command(0x00);
+ mdelay(2);
+
+ wmt_spi_lcd_write_command(0xaf);
+ wmt_spi_lcd_write_command(0xA4);
+ mdelay(2);
+}
+
+
+void wmt_spi_lcd_display_picture(const char *picture)
+{
+ int page,k;
+ int skip=0;
+ for(page=0xB0;page<0xB8;page++)
+ {
+ wmt_spi_lcd_write_command(page);
+ wmt_spi_lcd_write_command(0x10);
+ wmt_spi_lcd_write_command(0x00);
+
+ for(k=0;k<8;k++)
+ wmt_spi_lcd_write_n_data(picture+skip+k*8,8);
+
+ skip+=64;
+ }
+}
+
+void wmt_spi_lcd_display_state_picture(void)
+{
+ switch(wmt_sub_lcd_display_state){
+ case WMT_SPI_LCD_STATE_HAPPY:
+ wmt_spi_lcd_display_picture(wmt_spi_lcd_display_happy[0]);
+ break;
+ case WMT_SPI_LCD_STATE_SUN:
+ wmt_spi_lcd_display_picture(wmt_spi_lcd_display_sun[0]);
+ break;
+ case WMT_SPI_LCD_STATE_CLOUDY:
+ wmt_spi_lcd_display_picture(wmt_spi_lcd_display_cloudy[0]);
+ break;
+ case WMT_SPI_LCD_STATE_SAD:
+ wmt_spi_lcd_display_picture(wmt_spi_lcd_display_sad[0]);
+ break;
+ case WMT_SPI_LCD_STATE_PRINT:
+ wmt_spi_lcd_display_picture(wmt_spi_lcd_display_print[0]);
+ break;
+ case WMT_SPI_LCD_STATE_MESSAGE:
+ wmt_spi_lcd_display_picture(wmt_spi_lcd_display_message[0]);
+ break;
+
+ default:
+ wmt_spi_lcd_printk("%s default wmt_sub_lcd_display_state=%d\n", __func__,wmt_sub_lcd_display_state);
+ }
+}
+
+
+static int wmt_spi_lcd_open(struct inode *inode, struct file *filp)
+{
+ struct wmt_spi_lcd_dev *spi_dev = container_of(filp->private_data,
+ struct wmt_spi_lcd_dev,
+ sub_lcd_misc_device);
+ filp->private_data = spi_dev;
+ wmt_spi_lcd_display_state_picture();
+ // mdelay(3000);
+
+ return 0;
+}
+
+static long wmt_spi_lcd_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ int interval, val;
+ struct wmt_spi_lcd_dev *spi_dev = file->private_data;
+
+ wmt_sub_lcd_display_state = cmd;
+ wmt_spi_lcd_display_state_picture();
+
+ switch(cmd){
+ case WMT_WIFI_POWER:
+ if(copy_from_user(&val, argp, sizeof(val)))
+ return -EFAULT;
+ if(val > 1)
+ return -EINVAL;
+ if(val)
+ {
+ gpio_direction_output(WMT_WIFI_POWER_PIN,1);
+ }
+ else
+ {
+ gpio_direction_output(WMT_WIFI_POWER_PIN,0);
+ }
+ wmt_spi_lcd_printk("wmt_spi_lcd_ioctl WMT_WIFI_POWER_PIN val=%d\n",val);
+ break;
+ case WMT_AIT_POWER:
+ if(copy_from_user(&val, argp, sizeof(val)))
+ return -EFAULT;
+ if(val > 1)
+ return -EINVAL;
+ if(val)
+ {
+ gpio_direction_output(WMT_AIT_POWER_PIN,1);
+ }
+ else
+ {
+ gpio_direction_output(WMT_AIT_POWER_PIN,0);
+ }
+ wmt_spi_lcd_printk("wmt_spi_lcd_ioctl WMT_AIT_POWER_PIN val=%d\n",val);
+ break;
+ case WMT_PRINT_POWER:
+ if(copy_from_user(&val, argp, sizeof(val)))
+ return -EFAULT;
+ if(val > 1)
+ return -EINVAL;
+ if(val)
+ {
+ gpio_direction_output(WMT_PRINT_POWER_PIN,1);
+ }
+ else
+ {
+ gpio_direction_output(WMT_PRINT_POWER_PIN,0);
+ }
+
+ wmt_spi_lcd_printk("wmt_spi_lcd_ioctl WMT_PRINT_POWER_PIN val=%d\n",val);
+ break;
+ case WMT_SWITCH_OTG_PRINT:
+ if(copy_from_user(&val, argp, sizeof(val)))
+ return -EFAULT;
+ if(val > 1)
+ return -EINVAL;
+ if(val)
+ {
+ gpio_direction_output(WMT_OTG_PRINT_SWITCH_PIN,1);
+ }
+ else
+ {
+ gpio_direction_output(WMT_OTG_PRINT_SWITCH_PIN,0);
+ }
+ wmt_spi_lcd_printk("wmt_spi_lcd_ioctl WMT_OTG_PRINT_SWITCH_PIN val=%d\n",val);
+ break;
+ case WMT_GET_LCD_POWER:
+ spi_dev->lcd_val = wmt_gpio_getpull(WMT_LCD_POWER_PIN);
+ wmt_spi_lcd_printk("wmt_spi_lcd_ioctl WMT_GET_LCD_POWER=%d\n", spi_dev->lcd_val);
+ interval = spi_dev->lcd_val;
+ if(copy_to_user(argp, &interval, sizeof(interval)))
+ {
+ wmt_spi_lcd_printk("wmt_spi_lcd_ioctl WMT_GET_LCD_POWER fail\n");
+ return -EFAULT;
+ }
+ break;
+
+ case WMT_GET_WIFI_POWER:
+ spi_dev->wifi_val = wmt_gpio_getpull(WMT_WIFI_POWER_PIN);
+ wmt_spi_lcd_printk("wmt_spi_lcd_ioctl WMT_GET_WIFI_POWER=%d\n", spi_dev->wifi_val);
+ interval = spi_dev->wifi_val;
+ if(copy_to_user(argp, &interval, sizeof(interval)))
+ {
+ wmt_spi_lcd_printk("wmt_spi_lcd_ioctl WMT_GET_WIFI_POWER fail\n");
+ return -EFAULT;
+ }
+ break;
+
+ case WMT_GET_AIT_POWER:
+ spi_dev->ait_val = wmt_gpio_getpull(WMT_AIT_POWER_PIN);
+ wmt_spi_lcd_printk("wmt_spi_lcd_ioctl WMT_GET_AIT_POWER=%d\n", spi_dev->ait_val);
+ interval = spi_dev->ait_val;
+ if(copy_to_user(argp, &interval, sizeof(interval)))
+ {
+ wmt_spi_lcd_printk("wmt_spi_lcd_ioctl WMT_GET_AIT_POWER fail\n");
+ return -EFAULT;
+ }
+ break;
+
+ case WMT_GET_PRINT_POWER:
+ spi_dev->print_val = wmt_gpio_getpull(WMT_PRINT_POWER_PIN);
+ wmt_spi_lcd_printk("wmt_spi_lcd_ioctl WMT_GET_PRINT_POWER=%d\n", spi_dev->print_val);
+ interval = spi_dev->print_val;
+ if(copy_to_user(argp, &interval, sizeof(interval)))
+ {
+ wmt_spi_lcd_printk("wmt_spi_lcd_ioctl WMT_GET_PRINT_POWER fail\n");
+ return -EFAULT;
+ }
+ break;
+ case WMT_GET_OTG_PRINT_STATE:
+ spi_dev->otg_print_state = wmt_gpio_getpull(WMT_OTG_PRINT_SWITCH_PIN);
+ wmt_spi_lcd_printk("wmt_spi_lcd_ioctl WMT_OTG_PRINT_SWITCH_PIN=%d\n", spi_dev->otg_print_state);
+ interval = spi_dev->otg_print_state;
+ if(copy_to_user(argp, &interval, sizeof(interval)))
+ {
+ wmt_spi_lcd_printk("wmt_spi_lcd_ioctl WMT_OTG_PRINT_SWITCH_PIN fail\n");
+ return -EFAULT;
+ }
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+static const struct file_operations wmt_spi_lcd_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .open = wmt_spi_lcd_open,
+ .unlocked_ioctl = wmt_spi_lcd_ioctl,
+};
+
+
+static ssize_t wmt_spi_lcd_cat_dbg(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", wmt_sub_lcd_display_state);
+}
+
+static ssize_t wmt_spi_lcd_echo_dbg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ sscanf(buf,"%d", &wmt_sub_lcd_display_state);
+ wmt_sub_lcd_display_state += WMT_SPI_LCD_STATE_HAPPY;
+ wmt_spi_lcd_display_state_picture();
+ return count;
+}
+
+static DEVICE_ATTR(dbg, S_IRUGO | S_IWUSR, wmt_spi_lcd_cat_dbg, wmt_spi_lcd_echo_dbg);
+
+static struct attribute *sub_lcd_attributes[] = {
+ &dev_attr_dbg.attr,
+ NULL
+};
+
+static const struct attribute_group wmt_spi_lcd_group = {
+ .attrs = sub_lcd_attributes,
+};
+
+static int wmt_spi_lcd_sysfs_create_group(struct wmt_spi_lcd_dev *spi_dev, const struct attribute_group *group)
+{
+ int err;
+
+ spi_dev->kobj = kobject_create_and_add("wmt_spi_lcd", NULL) ;
+ if(!spi_dev->kobj){
+ wmt_spi_lcd_printk("kobj create failed.\n");
+ return -ENOMEM;
+ }
+
+ /* Register sysfs hooks */
+ err = sysfs_create_group(spi_dev->kobj, group);
+ if (err < 0){
+ kobject_del(spi_dev->kobj);
+ wmt_spi_lcd_printk("Create sysfs group failed!\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void wmt_spi_lcd_sysfs_remove_group(struct wmt_spi_lcd_dev *spi_dev, const struct attribute_group *group)
+{
+ sysfs_remove_group(spi_dev->kobj, group);
+ kobject_del(spi_dev->kobj);
+ return;
+}
+static int wmt_spi_lcd_probe(struct spi_device *spi)
+{
+ struct wmt_spi_lcd_dev *spi_dev = NULL;
+ int ret = 0;
+
+ ret = gpio_request(WMT_SPI_LCD_A0_PIN, "sub_lcd_control");
+ if (ret)
+ goto err_exit;
+
+ spi_dev = kzalloc(sizeof(*spi_dev), GFP_KERNEL);
+ if (spi_dev == NULL) {
+ wmt_spi_lcd_printk("failed to allocate memory for module data\n");
+ return -ENOMEM;
+ }
+
+ spi_dev->spi = spi;
+ spi_set_drvdata(spi, spi_dev);
+
+ ret = wmt_spi_lcd_sysfs_create_group(spi_dev, &wmt_spi_lcd_group);
+ if(ret < 0){
+ wmt_spi_lcd_printk("create sysfs group failed.\n");
+ goto exit_create_group;
+ }
+
+ /* init mutex and queues */
+ init_waitqueue_head(&spi_dev->read_wq);
+ mutex_init(&spi_dev->read_mutex);
+ spin_lock_init(&spi_dev->irq_enabled_lock);
+
+ spi_dev->sub_lcd_misc_device.minor = MISC_DYNAMIC_MINOR;
+ spi_dev->sub_lcd_misc_device.name = "wmt_spi_lcd";
+ spi_dev->sub_lcd_misc_device.fops = &wmt_spi_lcd_fops;
+
+ ret = misc_register(&spi_dev->sub_lcd_misc_device);
+ if (ret) {
+ wmt_spi_lcd_printk("%s : misc_register failed\n", __FILE__);
+ goto err_misc_register;
+ }
+
+ wmt_spi_lcd_pContext = spi_dev;
+
+ return 0;
+
+err_misc_register:
+ mutex_destroy(&spi_dev->read_mutex);
+ kfree(spi_dev);
+err_exit:
+ gpio_free(WMT_SPI_LCD_A0_PIN);
+exit_create_group:
+ destroy_workqueue(&spi_dev->read_wq);
+
+ return ret;
+}
+
+static int wmt_spi_lcd_remove(struct spi_device *spi)
+{
+ struct wmt_spi_lcd_dev *spi_dev = wmt_spi_lcd_pContext;
+ misc_deregister(&spi_dev->sub_lcd_misc_device);
+ mutex_destroy(&spi_dev->read_mutex);
+ gpio_free(WMT_SPI_LCD_A0_PIN);
+
+ wmt_spi_lcd_sysfs_remove_group(spi_dev, &wmt_spi_lcd_group);
+ kfree(spi_dev);
+
+ return 0;
+}
+
+static int wmt_spi_lcd_suspend(struct spi_device *spi, pm_message_t mesg)
+{
+ printk("%s\n",__func__);
+
+ return 0;
+}
+
+static int wmt_spi_lcd_resume(struct spi_device *spi)
+{
+ printk("%s\n",__func__);
+ wmt_spi_lcd_reset();
+ wmt_spi_lcd_display_state_picture();
+ return 0;
+}
+
+
+static struct spi_driver wmt_spi_lcd_driver = {
+ .driver = {
+ .name = "wmt_spi_lcd",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+ .probe = wmt_spi_lcd_probe,
+ .remove = wmt_spi_lcd_remove,
+ .suspend = wmt_spi_lcd_suspend,
+ .resume = wmt_spi_lcd_resume,
+};
+
+static struct spi_board_info wmt_spi_lcd_board_info[] __initdata = {
+ {
+ .modalias = "wmt_spi_lcd",
+ .bus_num = 0,
+ .chip_select = 0,
+ .max_speed_hz = 12000000,
+ .irq = -1,
+ .mode = SPI_MODE_0,
+ .controller_data = NULL,
+ },
+};
+
+static int wmt_spi_lcd_register_device (void)
+{
+ int ret = 0;
+ ret = spi_register_board_info(wmt_spi_lcd_board_info, ARRAY_SIZE(wmt_spi_lcd_board_info));
+ return ret;
+}
+
+static int wmt_spi_lcd_init(void)
+{
+ int ret = 0;
+ unsigned char buf[40];
+ int buflen = 40;
+ unsigned int value;
+ char *endp;
+
+ if(wmt_getsyspara("wmt.support.lcd.spi", buf, &buflen) == 0) {
+ value = simple_strtoul(buf, &endp, 0);
+ if(value == 0)
+ return -1;
+ } else
+ return -1;
+
+ if (wmt_spi_lcd_register_device()<0)
+ {
+ wmt_spi_lcd_printk(" Error to run wmt_spi_lcd_register_device()!\n");
+ return -1;
+ }
+
+ ret = spi_register_driver(&wmt_spi_lcd_driver);
+ if (ret != 0)
+ {
+ wmt_spi_lcd_printk("failed to register wmt_spi_lcd SPI driver: %d\n", ret);
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+static void wmt_spi_lcd_exit(void)
+{
+ wmt_spi_lcd_printk("Unloading wmt_spi_lcd driver\n");
+ spi_unregister_driver(&wmt_spi_lcd_driver);
+}
+
+module_init(wmt_spi_lcd_init);
+module_exit(wmt_spi_lcd_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/ANDROID_3.4.5/drivers/video/wmt/devices/lcd.c b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd.c new file mode 100755 index 00000000..a6099294 --- /dev/null +++ b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd.c @@ -0,0 +1,440 @@ +/*++ + * linux/drivers/video/wmt/lcd.c + * WonderMedia video post processor (VPP) driver + * + * Copyright c 2014 WonderMedia Technologies, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * WonderMedia Technologies, Inc. + * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C +--*/ + +#define LCD_C +#undef DEBUG +/* #define DEBUG */ +/* #define DEBUG_DETAIL */ +/*----------------------- DEPENDENCE -----------------------------------------*/ +#include "../lcd.h" +#include "../vout.h" +#ifdef CONFIG_KERNEL +#include <linux/gpio.h> +#endif + +#ifdef CONFIG_VPP_SHENZHEN +#include <mach/wmt_iomux.h> +#endif + +/*----------------------- PRIVATE MACRO --------------------------------------*/ +/* #define LCD_XXXX xxxx *//*Example*/ + +/*----------------------- PRIVATE CONSTANTS ----------------------------------*/ +/* #define LCD_XXXX 1 *//*Example*/ + +/*----------------------- PRIVATE TYPE --------------------------------------*/ +/* typedef xxxx lcd_xxx_t; *//*Example*/ +struct lcd_device_t { + struct lcd_parm_t* (*get_parm)(int arg); +}; + +/*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/ +/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ +/* int lcd_xxx; *//*Example*/ +struct lcd_device_t lcd_device_array[LCD_PANEL_MAX]; +int lcd_panel_on = 1; +int lcd_pwm_enable; +enum lcd_panel_t lcd_panel_id = LCD_PANEL_MAX; +int lcd_panel_bpp = 24; + +struct vout_dev_t lcd_vout_dev_ops; + +/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ +/* void lcd_xxx(void); *//*Example*/ +enum lcd_panel_t lcd_lvds_id = LCD_PANEL_MAX; +int lcd_type; + +/*----------------------- Function Body --------------------------------------*/ +/*----------------------- Backlight --------------------------------------*/ +void lcd_set_type(int type) +{ + lcd_type = type; /* 0-LCD, 1-LVDS */ +} + +int lcd_get_type(void) +{ + return lcd_type; +} + +#ifdef CONFIG_VPP_SHENZHEN + +#define MAX_LCD_GPIO_NUM 5 + +static struct { + int gpio; + int active; +} lcd_power[MAX_LCD_GPIO_NUM] = {{-1, 0}}; + +static int parse_uboot_param(void) +{ + char buf[64]; + unsigned int parm[32]; + int l = sizeof(buf); + int ret, i, gpio_num; + + for(i = 0; i < MAX_LCD_GPIO_NUM; i++) + lcd_power[i].gpio = -1; + + /* + * In hardware, maybe there are several gpio to control LCD power + * We can set the wmt.lcd.power as follows: + * setenv wmt.lcd.power gpio0:active0,gpio1:active1,....,gpio4:active4 + */ + if (wmt_getsyspara("wmt.lcd.power", buf, &l)) { + pr_err("please set wmt.lcd.power\n"); + return -EINVAL; + } + + i = vpp_parse_param(buf, parm, 2 * MAX_LCD_GPIO_NUM, 0); + gpio_num = i / 2; + + for(i = 0; i < gpio_num; i++) { + + lcd_power[i].gpio = parm[i * 2]; + lcd_power[i].active = parm[i * 2 + 1]; + + ret = gpio_request(lcd_power[i].gpio, "lcd power"); + if (ret) { + pr_err("request gpio %d failed for lcd power\n", + lcd_power[i].gpio); + return ret; + } + + DPRINT("lcd power%d: gpio%d, active %d\n", + i, lcd_power[i].gpio, lcd_power[i].active); + } + + return 0; +} + +void lcd_power_on(bool on) +{ + int i; + + for(i = 0; i < MAX_LCD_GPIO_NUM; i++) { + if (lcd_power[i].gpio < 0) + return; + + gpio_direction_output(lcd_power[i].gpio, on ? + lcd_power[i].active : !lcd_power[i].active); + + DBG_MSG("lcd_power_on: i = %d, on = %d, gpio = %d, active = %d\n", + i, on, lcd_power[i].gpio, lcd_power[i].active); + } +} +#endif + +void lcd_set_lvds_id(int id) +{ + lcd_lvds_id = id; +} + +int lcd_get_lvds_id(void) +{ + return lcd_lvds_id; +} + +void lcd_set_parm(int id, int bpp) +{ + lcd_panel_id = id; + lcd_panel_bpp = bpp; +} + +struct lcd_parm_t *lcd_get_parm(enum lcd_panel_t id, unsigned int arg) +{ + struct lcd_device_t *p; + + p = &lcd_device_array[id]; + if (p && p->get_parm) + return p->get_parm(arg); + return 0; +} + +struct vout_dev_t *lcd_get_dev(void) +{ + if (lcd_panel_id >= LCD_PANEL_MAX) + return 0; + return &lcd_vout_dev_ops; +} + +#ifdef CONFIG_KERNEL +static DEFINE_SEMAPHORE(lcd_sem); +#endif +void lcd_set_mutex(int lock) +{ +#ifdef CONFIG_KERNEL + if (lock) + down(&lcd_sem); + else + up(&lcd_sem); +#endif +} + +void lcd_set_enable(int enable) +{ + DBG_MSG("%d\n", enable); + if (!p_lcd) + return; + + lcd_set_mutex(1); + if (enable) { + if (p_lcd->initial) + p_lcd->initial(); + else { + lcd_enable_signal(1); /* singal enable */ +#ifndef CONFIG_VPP_SHENZHEN + outl(inl(GPIO_BASE_ADDR + 0x80) | 0x801, + GPIO_BASE_ADDR + 0x80); + outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x801, + GPIO_BASE_ADDR + 0xC0); +#endif + } + } else { + if (p_lcd->uninitial) + p_lcd->uninitial(); + else { + lcd_enable_signal(0); /* singal disable */ +#ifndef CONFIG_VPP_SHENZHEN + outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x801, + GPIO_BASE_ADDR + 0xC0); +#endif + } + } + lcd_set_mutex(0); +} + +void lcd_enable_signal(int enable) +{ + int hdmi_off; + + DBG_MSG("%d\n", enable); + if (lcd_get_type()) { /* LVDS */ + /* TODO */ + } else { /* LCD */ + govrh_set_dvo_enable(p_govrh2, enable); + } + + hdmi_off = (govrh_get_MIF_enable(p_govrh)) ? 0 : 1; + vpp_set_clock_enable(DEV_DVO, (hdmi_off && !enable) ? 0 : 1, 1); +} + +#ifdef __KERNEL__ +/*----------------------- LCD --------------------------------------*/ +static int __init lcd_arg_panel_id +( + char *str /*!<; // argument string */ +) +{ + sscanf(str, "%d", (int *) &lcd_panel_id); + if (lcd_panel_id >= LCD_PANEL_MAX) + lcd_panel_id = LCD_PANEL_MAX; + DBGMSG(KERN_INFO "set lcd panel id = %d\n", lcd_panel_id); + return 1; +} /* End of lcd_arg_panel_id */ + +__setup("lcdid=", lcd_arg_panel_id); +#endif +int lcd_panel_register(int no, void (*get_parm)(int mode)) +{ + struct lcd_device_t *p; + + if (no >= LCD_PANEL_MAX) { + DBGMSG(KERN_ERR "*E* lcd device no max is %d !\n", + LCD_PANEL_MAX); + return -1; + } + + p = &lcd_device_array[no]; + if (p->get_parm) { + DBGMSG(KERN_ERR "*E* lcd device %d exist !\n", no); + return -1; + } + p->get_parm = (void *) get_parm; + return 0; +} /* End of lcd_device_register */ + +/*----------------------- vout device plugin --------------------------------*/ +void lcd_set_power_down(int enable) +{ +#ifdef CONFIG_VPP_SHENZHEN + static int save_state = -1; + + if (save_state != enable) { + /* lcd enable control by user */ + lcd_power_on(enable ? false : true); + lcd_set_enable(enable ? false : true); + save_state = enable; + } +#endif +} + +static void wmt_config_govrh_polar(struct vout_t *vo) +{ + /* wmt.display.polar [clock polar]:[hsync polart]:[vsync polar]*/ + char buf[64]; + int l = sizeof(buf); + int clk_pol, hsync_pol, vsync_pol; + unsigned int parm[3]; + + if (wmt_getsyspara("wmt.display.polar", buf, &l)) + return; + + vpp_parse_param(buf, (unsigned int *)parm, 3, 0); + clk_pol = parm[0]; + hsync_pol = parm[1]; + vsync_pol = parm[2]; + DBG_MSG("govrh polar: clk-pol %d, hsync %d, vsync %d\n", + clk_pol, hsync_pol, vsync_pol); + govrh_set_dvo_clock_delay(vo->govr, clk_pol ? 0 : 1, 0); + govrh_set_dvo_sync_polar(vo->govr, + hsync_pol ? 0 : 1, vsync_pol ? 0 : 1); +} + +int lcd_set_mode(unsigned int *option) +{ + struct vout_t *vo; + enum vout_inf_mode_t inf_mode; + + DBG_MSG("option %d,%d\n", option[0], option[1]); + + vo = lcd_vout_dev_ops.vout; + inf_mode = vo->inf->mode; + if (option) { + unsigned int capability; + + if (lcd_panel_id == 0) + p_lcd = lcd_get_oem_parm(vo->resx, vo->resy); + else + p_lcd = lcd_get_parm(lcd_panel_id, lcd_panel_bpp); + + if (!p_lcd) { + DBG_ERR("lcd %d not support\n", lcd_panel_id); + return -1; + } + DBG_MSG("[%s] %s (id %d,bpp %d)\n", vout_inf_str[inf_mode], + p_lcd->vmode.name, lcd_panel_id, lcd_panel_bpp); + capability = p_lcd->capability; + switch (inf_mode) { + case VOUT_INF_LVDS: + lvds_set_sync_polar( + (capability & LCD_CAP_HSYNC_HI) ? 0 : 1, + (capability & LCD_CAP_VSYNC_HI) ? 0 : 1); + lvds_set_rgb_type(lcd_panel_bpp); + break; + case VOUT_INF_DVI: + govrh_set_dvo_clock_delay(vo->govr, + (capability & LCD_CAP_CLK_HI) ? 0 : 1, 0); + govrh_set_dvo_sync_polar(vo->govr, + (capability & LCD_CAP_HSYNC_HI) ? 0 : 1, + (capability & LCD_CAP_VSYNC_HI) ? 0 : 1); + switch (lcd_panel_bpp) { + case 15: + govrh_IGS_set_mode(vo->govr, 0, 1, 1); + break; + case 16: + govrh_IGS_set_mode(vo->govr, 0, 3, 1); + break; + case 18: + govrh_IGS_set_mode(vo->govr, 0, 2, 1); + break; + case 24: + govrh_IGS_set_mode(vo->govr, 0, 0, 0); + break; + default: + break; + } + break; + default: + break; + } + } else + p_lcd = 0; + + wmt_config_govrh_polar(vo); + return 0; +} + +int lcd_check_plugin(int hotplug) +{ + return (p_lcd) ? 1 : 0; +} + +int lcd_get_edid(char *buf) +{ + return 1; +} + +int lcd_config(struct vout_info_t *info) +{ + info->resx = p_lcd->vmode.xres; + info->resy = p_lcd->vmode.yres; + info->fps = p_lcd->vmode.refresh; + return 0; +} + +int lcd_init(struct vout_t *vo) +{ + DBG_MSG("%d\n", lcd_panel_id); + + /* vo_set_lcd_id(LCD_CHILIN_LW0700AT9003); */ + if (lcd_panel_id >= LCD_PANEL_MAX) + return -1; + + if (lcd_panel_id == 0) + p_lcd = lcd_get_oem_parm(vo->resx, vo->resy); + else + p_lcd = lcd_get_parm(lcd_panel_id, 24); + + if (p_lcd == 0) + return -1; + + /* set default parameters */ + vo->resx = p_lcd->vmode.xres; + vo->resy = p_lcd->vmode.yres; + vo->pixclk = PICOS2KHZ(p_lcd->vmode.pixclock) * 1000; + return 0; +} + +struct vout_dev_t lcd_vout_dev_ops = { + .name = "LCD", + .mode = VOUT_INF_DVI, + .capability = VOUT_DEV_CAP_FIX_RES + VOUT_DEV_CAP_FIX_PLUG, + + .init = lcd_init, + .set_power_down = lcd_set_power_down, + .set_mode = lcd_set_mode, + .config = lcd_config, + .check_plugin = lcd_check_plugin, + .get_edid = lcd_get_edid, +}; + +int lcd_module_init(void) +{ + parse_uboot_param(); + + vout_device_register(&lcd_vout_dev_ops); + return 0; +} /* End of lcd_module_init */ +module_init(lcd_module_init); +/*--------------------End of Function Body -----------------------------------*/ +#undef LCD_C diff --git a/ANDROID_3.4.5/drivers/video/wmt/devices/ts8224b.h b/ANDROID_3.4.5/drivers/video/wmt/devices/ts8224b.h new file mode 100755 index 00000000..87866284 --- /dev/null +++ b/ANDROID_3.4.5/drivers/video/wmt/devices/ts8224b.h @@ -0,0 +1,446 @@ +#ifndef _TS8224B_H_ +#define _TS8224B_H_ + +//Enable Page1 hsd4.0 +0xFF00, 0x55, +0xFF01, 0xAA, +0xFF02, 0x52, +0xFF03, 0x08, +0xFF04, 0x80, + +0xF200, 0x00, +0xF201, 0x84, +0xF202, 0x02, + +0xF40A, 0x13, + +0xF000, 0x55, +0xF001, 0xAA, +0xF002, 0x52, +0xF003, 0x08, +0xF004, 0x01, + +0xB000, 0x0D, +0xB001, 0x0D, +0xB002, 0x0D, + +0xB600, 0x34, +0xB601, 0x34, +0xB602, 0x34, + +0xB100, 0x0D, +0xB101, 0x0D, +0xB102, 0x0D, + +// AVEE: manual, -6V : -2.5xVCI) +0xB700, 0x34, +0xB701, 0x34, +0xB702, 0x34, + +//Power Control for VCL +0xB200, 0x00, +0xB201, 0x00, +0xB202, 0x00, + +0xB800, 0x24, +0xB801, 0x24, +0xB802, 0x24, + +// VGH: Clamp Enable, 2*AVDD-AVEE, //11V +0xBF00, 0X01, + +0xB300, 0x0F, +0xB301, 0x0F, +0xB302, 0x0F, + +0xB900, 0x34,//34 +0xB901, 0x34, +0xB902, 0x34, + +// VGL_REG(VGLO):-10V +0xB500, 0x08, +0xB501, 0x08, +0xB502, 0x08, + +0xC200, 0x03, + +//VGL(LVGL): +0xBA00, 0x24, +0xBA01, 0x24, +0xBA02, 0x24, + + +// VGMP/VGSP: 4.8v +0xBC00, 0X00, +0xBC01, 0x78, +0xBC02, 0X00, + +// VGMN/VGSN -4.8v +0xBD00, 0x00, +0xBD01, 0x78, +0xBD02, 0x00, + +// VCOM=-0.1 +0xBE00, 0x00, +0xBE01, 0x80, //2f +//R+ +0xD100, 0x00, +0xD101, 0x05, +0xD102, 0x00, +0xD103, 0x06, +0xD104, 0x00, +0xD105, 0x0E, +0xD106, 0x00, +0xD107, 0x19, +0xD108, 0x00, +0xD109, 0x29, +0xD10A, 0x00, +0xD10B, 0x55, +0xD10C, 0x00, +0xD10D, 0x80, +0xD10E, 0x00, +0xD10F, 0xC7, +0xD110, 0x00, +0xD111, 0xFC, +0xD112, 0x01, +0xD113, 0x48, +0xD114, 0x01, +0xD115, 0x7C, +0xD116, 0x01, +0xD117, 0xC5, +0xD118, 0x01, +0xD119, 0xFE, +0xD11A, 0x02, +0xD11B, 0x00, +0xD11C, 0x02, +0xD11D, 0x30, +0xD11E, 0x02, +0xD11F, 0x60, +0xD120, 0x02, +0xD121, 0x7A, +0xD122, 0x02, +0xD123, 0x9A, +0xD124, 0x02, +0xD125, 0xAC, +0xD126, 0x02, +0xD127, 0xC4, +0xD128, 0x02, +0xD129, 0xD3, +0xD12A, 0x02, +0xD12B, 0xE9, +0xD12C, 0x02, +0xD12D, 0xF8, +0xD12E, 0x03, +0xD12F, 0x0D, +0xD130, 0x03, +0xD131, 0x3B, +0xD132, 0x05, +0xD133, 0xB5, +//G+ +0xD200, 0x00, +0xD201, 0x05, +0xD202, 0x00, +0xD203, 0x06, +0xD204, 0x00, +0xD205, 0x0E, +0xD206, 0x00, +0xD207, 0x19, +0xD208, 0x00, +0xD209, 0x29, +0xD20A, 0x00, +0xD20B, 0x55, +0xD20C, 0x00, +0xD20D, 0x80, +0xD20E, 0x00, +0xD20F, 0xC7, +0xD210, 0x00, +0xD211, 0xFC, +0xD212, 0x01, +0xD213, 0x48, +0xD214, 0x01, +0xD215, 0x7C, +0xD216, 0x01, +0xD217, 0xC5, +0xD218, 0x01, +0xD219, 0xFE, +0xD21A, 0x02, +0xD21B, 0x00, +0xD21C, 0x02, +0xD21D, 0x30, +0xD21E, 0x02, +0xD21F, 0x60, +0xD220, 0x02, +0xD221, 0x7A, +0xD222, 0x02, +0xD223, 0x9A, +0xD224, 0x02, +0xD225, 0xAC, +0xD226, 0x02, +0xD227, 0xC4, +0xD228, 0x02, +0xD229, 0xD3, +0xD22A, 0x02, +0xD22B, 0xE9, +0xD22C, 0x02, +0xD22D, 0xF8, +0xD22E, 0x03, +0xD22F, 0x0D, +0xD230, 0x03, +0xD231, 0x3B, +0xD232, 0x05, +0xD233, 0xB5, +//B+ +0xD300, 0x00, +0xD301, 0x05, +0xD302, 0x00, +0xD303, 0x06, +0xD304, 0x00, +0xD305, 0x0E, +0xD306, 0x00, +0xD307, 0x19, +0xD308, 0x00, +0xD309, 0x29, +0xD30A, 0x00, +0xD30B, 0x55, +0xD30C, 0x00, +0xD30D, 0x80, +0xD30E, 0x00, +0xD30F, 0xC7, +0xD310, 0x00, +0xD311, 0xFC, +0xD312, 0x01, +0xD313, 0x48, +0xD314, 0x01, +0xD315, 0x7C, +0xD316, 0x01, +0xD317, 0xC5, +0xD318, 0x01, +0xD319, 0xFE, +0xD31A, 0x02, +0xD31B, 0x00, +0xD31C, 0x02, +0xD31D, 0x30, +0xD31E, 0x02, +0xD31F, 0x60, +0xD320, 0x02, +0xD321, 0x7A, +0xD322, 0x02, +0xD323, 0x9A, +0xD324, 0x02, +0xD325, 0xAC, +0xD326, 0x02, +0xD327, 0xC4, +0xD328, 0x02, +0xD329, 0xD3, +0xD32A, 0x02, +0xD32B, 0xE9, +0xD32C, 0x02, +0xD32D, 0xF8, +0xD32E, 0x03, +0xD32F, 0x0D, +0xD330, 0x03, +0xD331, 0x3B, +0xD332, 0x05, +0xD333, 0xB5, +//R- +0xD400, 0x00, +0xD401, 0x05, +0xD402, 0x00, +0xD403, 0x06, +0xD404, 0x00, +0xD405, 0x0E, +0xD406, 0x00, +0xD407, 0x19, +0xD408, 0x00, +0xD409, 0x29, +0xD40A, 0x00, +0xD40B, 0x55, +0xD40C, 0x00, +0xD40D, 0x80, +0xD40E, 0x00, +0xD40F, 0xC7, +0xD410, 0x00, +0xD411, 0xFC, +0xD412, 0x01, +0xD413, 0x48, +0xD414, 0x01, +0xD415, 0x7C, +0xD416, 0x01, +0xD417, 0xC5, +0xD418, 0x01, +0xD419, 0xFE, +0xD41A, 0x02, +0xD41B, 0x00, +0xD41C, 0x02, +0xD41D, 0x30, +0xD41E, 0x02, +0xD41F, 0x60, +0xD420, 0x02, +0xD421, 0x7A, +0xD422, 0x02, +0xD423, 0x9A, +0xD424, 0x02, +0xD425, 0xAC, +0xD426, 0x02, +0xD427, 0xC4, +0xD428, 0x02, +0xD429, 0xD3, +0xD42A, 0x02, +0xD42B, 0xE9, +0xD42C, 0x02, +0xD42D, 0xF8, +0xD42E, 0x03, +0xD42F, 0x0D, +0xD430, 0x03, +0xD431, 0x3B, +0xD432, 0x05, +0xD433, 0xB5, +//G- +0xD500, 0x00, +0xD501, 0x05, +0xD502, 0x00, +0xD503, 0x06, +0xD504, 0x00, +0xD505, 0x0E, +0xD506, 0x00, +0xD507, 0x19, +0xD508, 0x00, +0xD509, 0x29, +0xD50A, 0x00, +0xD50B, 0x55, +0xD50C, 0x00, +0xD50D, 0x80, +0xD50E, 0x00, +0xD50F, 0xC7, +0xD510, 0x00, +0xD511, 0xFC, +0xD512, 0x01, +0xD513, 0x48, +0xD514, 0x01, +0xD515, 0x7C, +0xD516, 0x01, +0xD517, 0xC5, +0xD518, 0x01, +0xD519, 0xFE, +0xD51A, 0x02, +0xD51B, 0x00, +0xD51C, 0x02, +0xD51D, 0x30, +0xD51E, 0x02, +0xD51F, 0x60, +0xD520, 0x02, +0xD521, 0x7A, +0xD522, 0x02, +0xD523, 0x9A, +0xD524, 0x02, +0xD525, 0xAC, +0xD526, 0x02, +0xD527, 0xC4, +0xD528, 0x02, +0xD529, 0xD3, +0xD52A, 0x02, +0xD52B, 0xE9, +0xD52C, 0x02, +0xD52D, 0xF8, +0xD52E, 0x03, +0xD52F, 0x0D, +0xD530, 0x03, +0xD531, 0x3B, +0xD532, 0x05, +0xD533, 0xB5, +//B- +0xD600, 0x00, +0xD601, 0x05, +0xD602, 0x00, +0xD603, 0x06, +0xD604, 0x00, +0xD605, 0x0E, +0xD606, 0x00, +0xD607, 0x19, +0xD608, 0x00, +0xD609, 0x29, +0xD60A, 0x00, +0xD60B, 0x55, +0xD60C, 0x00, +0xD60D, 0x80, +0xD60E, 0x00, +0xD60F, 0xC7, +0xD610, 0x00, +0xD611, 0xFC, +0xD612, 0x01, +0xD613, 0x48, +0xD614, 0x01, +0xD615, 0x7C, +0xD616, 0x01, +0xD617, 0xC5, +0xD618, 0x01, +0xD619, 0xFE, +0xD61A, 0x02, +0xD61B, 0x00, +0xD61C, 0x02, +0xD61D, 0x30, +0xD61E, 0x02, +0xD61F, 0x60, +0xD620, 0x02, +0xD621, 0x7A, +0xD622, 0x02, +0xD623, 0x9A, +0xD624, 0x02, +0xD625, 0xAC, +0xD626, 0x02, +0xD627, 0xC4, +0xD628, 0x02, +0xD629, 0xD3, +0xD62A, 0x02, +0xD62B, 0xE9, +0xD62C, 0x02, +0xD62D, 0xF8, +0xD62E, 0x03, +0xD62F, 0x0D, +0xD630, 0x03, +0xD631, 0x3B, +0xD632, 0x05, +0xD633, 0xB5, + +//Enable Page0 +0xF000, 0x55, +0xF001, 0xAA, +0xF002, 0x52, +0xF003, 0x08, +0xF004, 0x00, + + +0xB100, 0xcc, +0xB101, 0x00, + +0xB600, 0x05, + +//// Gate EQ: +0xB700, 0x70, +0xB701, 0x70, + +//// Source EQ: +0xB800, 0x01, +0xB801, 0x03, +0xB802, 0x03, +0xB803, 0x03, + +// #Inversion mode (2-dot) +0xBC00, 0x02, +0xBC01, 0x00, +0xBC02, 0x00, + +// Timing control 4H w/ 4-delay +0xC900, 0xD0, +0xC901, 0x02, +0xC902, 0x50, +0xC903, 0x50, +0xC904, 0x50, +// Display Timing: + +0x3600, 0x00, +0x3500, 0x00, + +0x3a00, 0x66, + +#endif diff --git a/ANDROID_3.4.5/drivers/video/wmt/devices/vt1625.c b/ANDROID_3.4.5/drivers/video/wmt/devices/vt1625.c new file mode 100755 index 00000000..83d1a403 --- /dev/null +++ b/ANDROID_3.4.5/drivers/video/wmt/devices/vt1625.c @@ -0,0 +1,946 @@ +/*++ + * linux/drivers/video/wmt/vt1625.c + * WonderMedia video post processor (VPP) driver + * + * Copyright c 2014 WonderMedia Technologies, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * WonderMedia Technologies, Inc. + * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C +--*/ + +#define VT1625_C +/* #define DEBUG */ +/* #define DEBUG_DETAIL */ +/*----------------------- DEPENDENCE -----------------------------------------*/ +#include "../vout.h" + +#ifdef CONFIG_KERNEL +#include <linux/workqueue.h> +#endif + +/*----------------------- PRIVATE MACRO --------------------------------------*/ +/* #define VT1625_XXXX xxxx *//*Example*/ +#ifdef CONFIG_KERNEL +#define CONFIG_VT1625_INTERRUPT +#endif +#define CONFIG_VT1625_POWER +#define CONFIG_VM700 + +/*----------------------- PRIVATE CONSTANTS ----------------------------------*/ +/* #define VT1625_XXXX 1 *//*Example*/ +#define VT1625_ADDR 0x40 + +enum { + VT1625_INPUT_SELECTION = 0x00, + VT1625_SYNC_SELECTION_0 = 0x01, + VT1625_SYNC_SELECTION_1 = 0x02, + VT1625_FILTER_SELECTION = 0x03, + VT1625_OUTPUT_MODE = 0x04, + VT1625_CLOCK_CONTROL = 0x05, + + /* start position & overflow */ + VT1625_OVERFLOW = 0x06, + VT1625_START_ACTIVE_VIDEO = 0x07, + VT1625_START_HORIZONTAL_POSITION = 0x08, + VT1625_START_VERTICAL_POSITION = 0x09, + + /* amplitude factor */ + VT1625_CR_AMPLITUDE_FACTOR = 0x0A, + VT1625_BLACK_LEVEL = 0x0B, + VT1625_Y_AMPLITUDE_FACTOR = 0x0C, + VT1625_CB_AMPLITUDE_FACTOR = 0x0D, + + VT1625_POWER_MANAGEMENT = 0x0E, + VT1625_STATUS = 0x0F, + + /* Hue */ + VT1625_HUE_ADJUSTMENT = 0x10, + VT1625_OVERFLOW_MISC = 0x11, + + /* PLL */ + VT1625_PLL_P2 = 0x12, + VT1625_PLL_D = 0x13, + VT1625_PLL_N = 0x14, + VT1625_PLL_OVERFLOW = 0x15, + + /* Sub Carrier */ + VT1625_SUBCARRIER_VALUE_0 = 0x16, + VT1625_SUBCARRIER_VALUE_1 = 0x17, + VT1625_SUBCARRIER_VALUE_2 = 0x18, + VT1625_SUBCARRIER_VALUE_3 = 0x19, + + VT1625_VERSION_ID = 0x1B, + VT1625_DAC_OVERFLOW = 0x1C, + + /* test */ + VT1625_TEST_0 = 0x1D, + VT1625_TEST_1 = 0x1E, + + VT1625_FILTER_SWITCH = 0x1F, + VT1625_TV_SYNC_STEP = 0x20, + VT1625_TV_BURST_ENVELOPE_STEP = 0x21, + VT1625_TV_SUB_CARRIER_PHASE_ADJUST = 0x22, + VT1625_TV_BLANK_LEVEL = 0x23, + VT1625_TV_SIGNAL_OVERFLOW = 0x24, + + /* DAC & GPO */ + VT1625_DAC_SELECTION_0 = 0x4A, + VT1625_DAC_SELECTION_1 = 0x4B, + VT1625_GPO = 0x4C, + + VT1625_COLBAR_LUMA_DELAY = 0x4D, + VT1625_UV_DELAY = 0x4E, + VT1625_BURST_MAX_AMPLITUDE = 0x4F, + + /* Graphic timing */ + VT1625_GRAPHIC_H_TOTAL = 0x50, + VT1625_GRAPHIC_H_ACTIVE = 0x51, + VT1625_GRAPHIC_H_OVERFLOW = 0x52, + VT1625_GRAPHIC_V_TOTAL = 0x53, + VT1625_GRAPHIC_V_OVERFLOW = 0x54, + + /* TV timing */ + VT1625_TV_H_TOTAL = 0x55, + VT1625_TV_H_ACTIVE = 0x56, + VT1625_TV_H_SYNC_WIDTH = 0x57, + VT1625_TV_H_OVERFLOW = 0x58, + VT1625_TV_BURST_START = 0x59, + VT1625_TV_BURST_END = 0x5A, + VT1625_TV_VIDEO_START = 0x5B, + VT1625_TV_VIDEO_END = 0x5C, + VT1625_TV_VIDEO_OVERFLOW = 0x5D, + + /* scale factor */ + VT1625_V_SCALE_FACTOR = 0x5E, + VT1625_H_SCALE_FACTOR = 0x5F, + VT1625_SCALE_OVERFLOW = 0x60, + VT1625_H_BLUR_SCALE_OVERFLOW = 0x61, + VT1625_ADAPTIVE_DEFLICKER_THR = 0x62, + VT1625_SCALE_H_TOTAL = 0x63, + VT1625_SCALE_H_TOTAL_OVERFLOW = 0x64, + + /* Amplitude factor */ + VT1625_PY_AMP_FACTOR = 0x65, + VT1625_PB_AMP_FACTOR = 0x66, + VT1625_PR_AMP_FACTOR = 0x67, + + VT1625_POST_ADJUST = 0x68, + VT1625_AUTO_CORRECT_SENSE = 0x69, + + /* WSS 0x6A - 0x73 */ + VT1625_INT_WSS_2 = 0x71, + + /* Close Caption 0x74 - 0x7A */ + + /* Signature Value 0x7B - 0x82 */ +} vt1625_reg_t; + +/*----------------------- PRIVATE TYPE --------------------------------------*/ +/* typedef xxxx vt1625_xxx_t; *//*Example*/ + +/*----------EXPORTED PRIVATE VARIABLES are defined in vt1625.h -------------*/ +/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ +/* int vt1625_xxx; *//*Example*/ + +static char vt1625_ntsc_param[] = { + 0x03, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x82, /* 00 - 07 */ +#ifdef CONFIG_VM700 + 0x14, 0x05, 0x6E, 0x15, 0x51, 0x50, 0x37, 0xB7, /* 08 - 0f */ + 0x00, 0x80, 0x04, 0x08, 0x08, 0x90, 0xD6, 0x7B, /* 10 - 17 */ +#else + 0x14, 0x05, 0x6E, 0x15, 0x52, 0x4E, 0x37, 0xB7, /* 08 - 0f */ + 0x08, 0x80, 0x04, 0x08, 0x08, 0x90, 0xD6, 0x7B, /* 10 - 17 */ +#endif + 0xF0, 0x21, 0x02, 0x50, 0x43, 0x80, 0x00, 0xFC, /* 18 - 1f */ + 0x16, 0x08, 0xDC, 0x7D, 0x02, 0x56, 0x33, 0x8F, /* 20 - 27 */ + 0x58, 0x00, 0x00, 0xA6, 0x29, 0xD4, 0x81, 0x00, /* 28 - 2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 - 37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38 - 3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 40 - 47 */ +#ifdef CONFIG_VM700 + 0x00, 0x00, 0xC5, 0x0F, 0x08, 0x01, 0x01, 0x43, /* 48 - 4f */ +#else + 0x00, 0x00, 0xC5, 0x0F, 0x00, 0x01, 0x10, 0x44, /* 48 - 4f */ +#endif + 0x59, 0xCF, 0x23, 0x0C, 0x02, 0x59, 0xCF, 0x7F, /* 50 - 57 */ + 0x23, 0x94, 0xD6, 0x00, 0x9C, 0x06, 0x00, 0x00, /* 58 - 5f */ + 0x80, 0x28, 0xFF, 0x59, 0x03, 0x55, 0x56, 0x56, /* 60 - 67 */ + 0x00, 0x90, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, /* 68 - 6f */ + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 70 - 77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78 - 7f */ + 0x00, 0x00, 0x00 +}; + +static char vt1625_pal_param[] = { + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x8C, /* 00 - 07 */ +#ifdef CONFIG_VM700 + 0x0E, 0x01, 0x6E, 0x00, 0x51, 0x50, 0x37, 0xB7, /* 08 - 0f */ + 0x00, 0x80, 0x04, 0x08, 0x08, 0x90, 0xCB, 0x8A, /* 10 - 17 */ +#else + 0x0E, 0x01, 0x7a, 0x00, 0x55, 0x58, 0x37, 0xB7, /* 08 - 0f */ + 0xff, 0x87, 0x04, 0x08, 0x08, 0x90, 0xCB, 0x8A, /* 10 - 17 */ +#endif + 0x09, 0x2A, 0x06, 0x50, 0x41, 0x80, 0x00, 0xFC, /* 18 - 1f */ + 0x17, 0x0C, 0x4E, 0x76, 0x02, 0x5F, 0x34, 0x8C, /* 20 - 27 */ + 0x4F, 0x5E, 0x15, 0xA2, 0x22, 0x80, 0xD3, 0x10, /* 28 - 2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 - 37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38 - 3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 40 - 47 */ +#ifdef CONFIG_VM700 + 0x00, 0x00, 0xC5, 0x0F, 0x08, 0x02, 0x01, 0x43, /* 48 - 4f */ +#else + 0x00, 0x00, 0xC5, 0x0F, 0x00, 0x02, 0x10, 0x4C, /* 48 - 4f */ +#endif + 0x5f, 0xCF, 0x23, 0x70, 0x02, 0x5F, 0xD0, 0x7F, /* 50 - 57 */ + 0x23, 0x92, 0xCE, 0xDF, 0xA0, 0x06, 0x00, 0x00, /* 58 - 5f */ + 0x80, 0x20, 0xFF, 0x5F, 0x03, 0x5f, 0x00, 0x00, /* 60 - 67 */ + 0x00, 0x90, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, /* 68 - 6f */ + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 70 - 77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78 - 7f */ + 0x00, 0x00, 0x00 +}; + +enum vt1625_out_t { + VT1625_OUT_CVBS, + VT1625_OUT_YUV, + VT1625_OUT_VGA, + VT1625_OUT_MAX +}; + +enum vt1625_out_t vt1625_out_mode; + +int vt1625_tv_mode; +vdo_color_fmt vt1625_colfmt; + +static int pre_plugin; + +/* +* VT1625 U-Boot Env to Set Register +*/ +typedef struct { + unsigned char offset; + unsigned char value; +} vt1625_reg_env_t; + +#define VT1625_REG_MAX_OFFSET 0x82 /* Register Offset: 0x00 ~ 0x82 */ +/* +* setenv wmt.vt1625.pal.reg regOffset1=regValue1,regOffset2=regValue2,... +* for example: +* setenv wmt.vt1625.pal.reg 0a=75,0c=53,23=7a,4f=48 +* setenv wmt.vt1625.ntsc.reg 0a=75,0c=53,23=7a,4f=48 +*/ +#define VT1625_PAL_REG_ENV "wmt.vt1625.pal.reg" +#define VT1625_NTSC_REG_ENV "wmt.vt1625.ntsc.reg" + +/* +* setenv wmt.vt1625.cvbs.always.turnon 1 +* The cvbs is always turned on event if the av line is pluged out +* setenv wmt.vt1625.cvbs.always.turnon 0 +* The cvbs is turned on if the av line is pluged in. +* And the cvbs is turned off if the av line is pluged out +*/ +#define VT1625_CVBS_ALWAYS_TURNON "wmt.vt1625.cvbs.always.turnon" + +static int vt1625_cvbs_always_turnon; + +#ifdef CONFIG_KERNEL +/* +* VT1625 Timer to Monitor Register +*/ +/* +* Monitor the vt1625 register for avoiding the register is cleared. +* setenv wmt.vt1625.reg.monitor 1 +* +* If the wmt.vt1625.reg.monitor is Not set or set to 0, +* it will not monitor the register +* +*/ +#define VT1625_REG_MONITOR_ENV "wmt.vt1625.reg.monitor" + +#define VT1625_TIMER_INTERVAL 1000 // 1000 ms + +static struct timer_list vt1625_timer; +static struct work_struct vt1625_work; + +static void vt1625_set_tv_mode(int ntsc); + +#endif + +#ifdef CONFIG_UBOOT +#define msleep mdelay +#endif + +/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ +/* void vt1625_xxx(void); *//*Example*/ + +/*----------------------- Function Body --------------------------------------*/ +/* +* Function: register_is_right() +* Parametr: +* ntsc = 0: PAL +* ntsc = 1: NTSC +* Return : +* 0: the register's values is wrong +* 1: the register's values is right +*/ +static int register_is_right(int ntsc) +{ + int i; + char buf[32]; + + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_INPUT_SELECTION, buf, 32); + + for(i = 0; i < 32; i++) { + /* + * reg 0x0E is power management register. Skip it + * reg 0x0F is status register. it is volatile. Skip it + */ + if(i == 14 || i == 15) + continue; + + + if(i == 0) { + if(vt1625_colfmt == VDO_COL_FMT_YUV444) { + if(buf[0] != 0x3A) + break; + } else { + if(buf[0] != 0x03) + break; + } + } else { + if(ntsc) { + /* + * NTSC + */ + if(buf[i] != vt1625_ntsc_param[i]) + break; + } else { + /* + * PAL + */ + if(buf[i] != vt1625_pal_param[i]) + break; + } + } + } + + if(i != 32) + return 0; + else + return 1; +} + +#ifdef CONFIG_KERNEL +static void vt1625_reconfig(struct work_struct *work) +{ + int right; + + if(vt1625_tv_mode) { + right = register_is_right((vt1625_tv_mode == 1) ? 1 : 0); + if(right == 0) { + DBG_ERR("VT1625 Reg Error, re-init the register\n"); + + vt1625_set_tv_mode((vt1625_tv_mode == 1) ? 1 : 0); + } + } + + mod_timer(&vt1625_timer, jiffies + msecs_to_jiffies(VT1625_TIMER_INTERVAL)); +} + +static DECLARE_WORK(vt1625_work, vt1625_reconfig); + +static void vt1625_config_timer(unsigned long fcontext) +{ + schedule_work(&vt1625_work); +} + +static void init_vt1625_timer(void) +{ + char buf[40]; + int varlen = 40; + char *endp; + int value, reg_monitor; + + reg_monitor = 0; + + if (wmt_getsyspara(VT1625_REG_MONITOR_ENV, buf, &varlen) == 0) { + value = simple_strtoul(buf, &endp, 0); + if( value != 0) + reg_monitor = 1; + } + + if(reg_monitor) { + init_timer(&vt1625_timer); + vt1625_timer.function = vt1625_config_timer; + vt1625_timer.data = 0; + } else + vt1625_timer.function = NULL; + +} + +static void start_vt1625_timer(void) +{ + if(vt1625_timer.function) + mod_timer(&vt1625_timer, jiffies + msecs_to_jiffies(VT1625_TIMER_INTERVAL)); +} + +static void stop_vt1625_timer(void) +{ + if(vt1625_timer.function) + del_timer_sync(&vt1625_timer); +} +#endif + +/* +* Function : vt1625_parse_reg_env +* Parameter: +* p_env : env name +* p_reg : store the vt1625 register offset and value +* p_regnum: register number +* Return: +* 0 : the env is set and the env's value is available +* -1 : the env is Not set or the env's value is wrong +* -12 : no memory for parsing register env +*/ +static int vt1625_parse_reg_env(char *p_env, + vt1625_reg_env_t *p_reg, int *p_regnum) +{ + int i; + char *buf; + int buflen = 1024; + unsigned int value; + const char *p; + char *endp; + + buf = kmalloc(buflen, GFP_KERNEL); + if(buf == NULL) { + DBG_ERR("kzalloc fail\n"); + return -12; + } + + if(wmt_getsyspara(p_env, buf, &buflen) != 0) { + kfree(buf); + return -1; + } + + *p_regnum = 0; + p = buf; + + for(i = 0; i <= VT1625_REG_MAX_OFFSET; i++) { + value = simple_strtoul(p, &endp, 16); + if(value > VT1625_REG_MAX_OFFSET) { + DBG_ERR("wrong register offset\n"); + kfree(buf); + return -1; + } + (p_reg + i)->offset = value; + /* + * reg_offset must be followed reg_value + * If reg_offset is NOT followed any reg_value, It is wrong format + */ + if(*endp == '\0'|| *(endp + 1) == '\0') { + DBG_ERR("wrong env(%s) format\n", p_env); + kfree(buf); + return -1; + } + + p = endp + 1; + + value = simple_strtoul(p, &endp, 16); + if(value > 0xFF) { + DBG_ERR("wrong register value\n"); + kfree(buf); + return -1; + } + (p_reg + i)->value = value; + *p_regnum = *p_regnum + 1; + + if(*endp == '\0') + break; + + p = endp + 1; + } + + kfree(buf); + return 0; +} + +/*the define and struct i2c_msg were declared int linux/i2c.h*/ +void vt1625_reg_dump(void) +{ + int i; + char buf[256]; + + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_INPUT_SELECTION, + buf, 128); + for (i = 0; i < 128; i += 8) { + MSG("0x%02X : 0x%02X,0x%02X,0x%02X,0x%02X", + i, buf[i], buf[i + 1], buf[i + 2], buf[i + 3]); + MSG(",0x%02X,0x%02X,0x%02X,0x%02X\n", + buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]); + } +} + +static char vt1625_get_dac_val(enum vt1625_out_t mode) +{ + char ret; + + switch (mode) { + case VT1625_OUT_CVBS: + ret = 0x37; + break; + case VT1625_OUT_VGA: + ret = 0x38; + break; + case VT1625_OUT_YUV: + default: + ret = 0x0; + break; + } + return ret; +} + +static void vt1625_set_tv_mode(int ntsc) +{ + char *p; + char buf[10]; + +/* + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_INPUT_SELECTION, buf, 5); + DBG_MSG("ntsc %d, 0x%x, 0x%x\n", ntsc, buf[0], buf[4]); + vt1625_tv_mode = (ntsc) ? 1 : 2; +#ifdef CONFIG_KERNEL + if (buf[0] && (vt1625_out_mode != VT1625_OUT_MAX)) { + if (ntsc && !(buf[4] & BIT0)) + return; + if (!ntsc && (buf[4] & BIT0)) + return; + } +#endif +*/ + vt1625_tv_mode = (ntsc) ? 1 : 2; + if(register_is_right(ntsc)) + return; + + DBG_MSG("tv %s,mode %d\n", (ntsc) ? "NTSC" : "PAL", vt1625_out_mode); + + p = (char *)((ntsc) ? vt1625_ntsc_param : vt1625_pal_param); + vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_INPUT_SELECTION, + &p[VT1625_INPUT_SELECTION], 0x71); + if (vt1625_out_mode == VT1625_OUT_MAX) { /* not stable so no use */ + buf[0] = 0x0; + vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_POWER_MANAGEMENT, buf, 1); + mdelay(10); + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_STATUS, buf, 1); + vt1625_out_mode = (buf[0] & 0x7) ? + VT1625_OUT_CVBS : VT1625_OUT_VGA; + DBG_MSG("get out mode %d, 0x%x\n", vt1625_out_mode, buf[0]); + } + + if (vt1625_out_mode == VT1625_OUT_VGA) { + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_SYNC_SELECTION_1, buf, 1); + buf[0] |= 0xA0; + vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_SYNC_SELECTION_1, buf, 1); + + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_DAC_OVERFLOW, buf, 1); + buf[0] |= 0x20; + vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_DAC_OVERFLOW, buf, 1); + + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_TEST_1, buf, 1); + buf[0] |= 0x40; + vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_TEST_1, buf, 1); + } else { +#ifdef CONFIG_VT1625_INTERRUPT + /* interrupt (VGA no work) */ + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_INT_WSS_2, buf, 1); + buf[0] |= 0xA0; /* enable sense interrupt */ + vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_INT_WSS_2, buf, 1); +#endif + } + + if (vt1625_colfmt == VDO_COL_FMT_YUV444) { + /* + * Force write reg0x00 and reg0x4C + */ + buf[0] = 0x3A; + vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_INPUT_SELECTION, buf, 1); + buf[0] = 0x08; + vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_GPO, buf, 1); + } + +#ifdef CONFIG_VT1625_POWER + buf[0] = vt1625_get_dac_val(vt1625_out_mode); + vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_POWER_MANAGEMENT, buf, 1); +#endif +} + +static int vt1625_check_plugin(int hotplug) +{ + char buf[2]; + char cur[1]; + int plugin; + + /* + * Enable VT1625 Power First + */ + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_POWER_MANAGEMENT, cur, 1); + + buf[0] = vt1625_get_dac_val(vt1625_out_mode); + + if(cur[0] != buf[0]) { + vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_POWER_MANAGEMENT, buf, 1); + + msleep(10); + } + + if((vt1625_out_mode == VT1625_OUT_CVBS) && vt1625_cvbs_always_turnon) + return 1; + + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_POWER_MANAGEMENT, + buf, 2); + plugin = ~buf[1] & (~buf[0] & 0x3F); + DBG_MSG("[VT1625] DAC A %d, B %d, C %d, D %d, E %d, F %d\n", + (plugin & 0x20) ? 1 : 0, (plugin & 0x10) ? 1 : 0, + (plugin & 0x08) ? 1 : 0, (plugin & 0x04) ? 1 : 0, + (plugin & 0x02) ? 1 : 0, (plugin & 0x01) ? 1 : 0); + return (plugin) ? 1 : 0; +} + +static int vt1625_init(struct vout_t *vo) +{ + char buf[40]; + int varlen = 40; + char *endp; + unsigned int value; + + DBG_MSG("\n"); + if (vt1625_tv_mode) { /* resume reinit */ + MSG("[VT1625] DVI reinit\n"); + vt1625_set_tv_mode((vt1625_tv_mode == 1) ? 1 : 0); + if (govrh_get_dvo_enable(p_govrh2) == 0) + govrh_set_dvo_enable(p_govrh2, VPP_FLAG_ENABLE); + pre_plugin = 0; + return 0; + } + + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_VERSION_ID, buf, 1); + if (buf[0] != 0x50) /* check version id */ + return -1; + + if (wmt_getsyspara("wmt.display.vt1625.mode", buf, &varlen) == 0) { + if (memcmp(buf, "yuv", 3) == 0) + vt1625_out_mode = VT1625_OUT_YUV; + else if (memcmp(buf, "vga", 3) == 0) + vt1625_out_mode = VT1625_OUT_VGA; + else + vt1625_out_mode = VT1625_OUT_CVBS; + DPRINT("[VT1625] mode %d\n", vt1625_out_mode); + } else + vt1625_out_mode = VT1625_OUT_CVBS; /* VT1625_OUT_MAX; */ + +#ifdef CONFIG_VM700 + vt1625_colfmt = VDO_COL_FMT_YUV444; +#else + vt1625_colfmt = VDO_COL_FMT_ARGB; +#endif + if (wmt_getsyspara("wmt.display.vt1625.colfmt", buf, &varlen) == 0) { + if (memcmp(buf, "yuv", 3) == 0) + vt1625_colfmt = VDO_COL_FMT_YUV444; + else if (memcmp(buf, "rgb", 3) == 0) + vt1625_colfmt = VDO_COL_FMT_ARGB; + } + + vo->option[0] = (unsigned int) vt1625_colfmt; + vo->option[1] = (unsigned int) VPP_DATAWIDHT_12; + + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_INPUT_SELECTION, buf, 5); + if (buf[0]) + vt1625_tv_mode = (buf[4]) ? 2 : 1; + + p_govrh2->fb_p->csc_mode = VPP_CSC_RGB2YUV_SDTV_0_255; + + if (wmt_getsyspara(VT1625_CVBS_ALWAYS_TURNON, buf, &varlen) == 0) { + value = simple_strtoul(buf, &endp, 0); + if(value != 0) + vt1625_cvbs_always_turnon = 1; + else + vt1625_cvbs_always_turnon = 0; + } else + vt1625_cvbs_always_turnon = 0; + +#ifdef CONFIG_KERNEL + vt1625_set_tv_mode((vt1625_tv_mode == 1) ? 1 : 0); + + start_vt1625_timer(); +#endif + + MSG("[VT1625] DVI ext device\n"); + return 0; +} + +static int vt1625_set_mode(unsigned int *option) +{ +#ifdef CONFIG_VT1625_INTERRUPT + char buf[1]; +#endif + + DBG_MSG("\n"); +#ifdef CONFIG_VT1625_INTERRUPT + if (!g_vpp.dvi_int_disable) { + vout_set_int_type(1); + vout_set_int_enable(1); + + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_INT_WSS_2, buf, 1); + buf[0] |= 0xA0; /* enable sense interrupt */ + vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_INT_WSS_2, buf, 1); + } +#endif + return 0; +} + +static void vt1625_set_power_down(int enable) +{ + struct vout_t *vo; + char buf[1]; + char cur[1]; + + /* + bit 0-2 : DAC D/E/F - VGA + bit 3 : DAC C - CVBS + bit 3-5 : DAC A/B/C - YPbPr + bit 6 : PLL + bit 7 : IO pad + */ + vo = vout_get_entry(VPP_VOUT_NUM_DVI); + if (vo->status & (VPP_VOUT_STS_BLANK + VPP_VOUT_STS_POWERDN)) + enable = 1; + + /* power down for not support resolution */ +//#ifndef CONFIG_VT1625_INTERRUPT + if ((vt1625_tv_mode != 0) && enable && g_vpp.dvi_int_disable) + buf[0] = 0xFF; + else +//#endif + buf[0] = vt1625_get_dac_val(vt1625_out_mode); + + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_POWER_MANAGEMENT, cur, 1); + + if (cur[0] == buf[0]) + return; + + DBG_MSG("enable %d,cur 0x%x,new 0x%x\n", enable, cur[0], buf[0]); +#if 1 + if (enable == 0) { + cur[0] &= ~0x40; /* turn on PLL */ + vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_POWER_MANAGEMENT, cur, 1); + mdelay(3); + + cur[0] &= ~0x80; /* turn on IO pad */ + vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_POWER_MANAGEMENT, cur, 1); + mdelay(3); + } +#endif +#ifdef CONFIG_VT1625_POWER + vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_POWER_MANAGEMENT, buf, 1); +#endif +} + +static int vt1625_config(struct vout_info_t *info) +{ + int ntsc = -1; + + DBG_MSG("%d,%d\n", info->resx, info->resy); + if (info->resx == 720) { + switch (info->resy) { + case 480: + ntsc = 1; + break; + case 576: + ntsc = 0; + break; + default: + break; + } + } + + if (ntsc != -1) + vt1625_set_tv_mode(ntsc); + else + vt1625_tv_mode = 0; + DBG_MSG("end\n"); + return 0; +} + +static int vt1625_get_edid(char *buf) +{ + return 0; +} + +#ifdef CONFIG_VT1625_INTERRUPT +static int vt1625_interrupt(void) +{ + char buf[1]; + + vppif_reg32_write(GPIO_BASE_ADDR + 0x4c0, 0x1 << VPP_VOINT_NO, + VPP_VOINT_NO, 0x0); /* GPIO pull-up */ + /* interrupt */ + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_INT_WSS_2, buf, 1); + DBG_MSG("0x%x\n", buf[0]); + buf[0] &= ~0x40; /* clear interrupt */ + vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_INT_WSS_2, buf, 1); + return vt1625_check_plugin(1); +} +#endif + +static void vt1625_poll(void) +{ + int plugin; + char buf[1]; + char cur[1]; + + if (govrh_get_dvo_enable(p_govrh2) == 0) + govrh_set_dvo_enable(p_govrh2, VPP_FLAG_ENABLE); + + plugin = vt1625_check_plugin(0); + if (plugin != pre_plugin) { + struct vout_t *vo; + + vo = vout_get_entry(VPP_VOUT_NUM_DVI); + vout_change_status(vo, VPP_VOUT_STS_PLUGIN, plugin); +#ifdef CONFIG_KERNEL + vpp_netlink_notify_plug(VPP_VOUT_NUM_DVI, plugin); +#endif + pre_plugin = plugin; + DMSG("%d\n", plugin); + } + + /* + * Disable VT1625 Power if CVBS Not plugin + */ + if(plugin == 0) { + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_POWER_MANAGEMENT, cur, 1); + + buf[0] = 0xFF; + + if(cur[0] != buf[0]) { + vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_POWER_MANAGEMENT, buf, 1); + } + } +} + +static int vt1625_suspend(void) +{ + DMSG("\n"); + +#ifdef CONFIG_KERNEL + stop_vt1625_timer(); +#endif + + return 0; +} + +static int vt1625_resume(void) +{ + DMSG("\n"); + +#ifdef CONFIG_KERNEL + start_vt1625_timer(); +#endif + return 0; +} + +/*----------------------- vout device plugin ---------------------------------*/ +struct vout_dev_t vt1625_vout_dev_ops = { + .name = "VT1625", + .mode = VOUT_INF_DVI, + + .init = vt1625_init, + .set_power_down = vt1625_set_power_down, + .set_mode = vt1625_set_mode, + .config = vt1625_config, + .check_plugin = vt1625_check_plugin, + .get_edid = vt1625_get_edid, +#ifdef CONFIG_VT1625_INTERRUPT + .interrupt = vt1625_interrupt, +#endif + .poll = vt1625_poll, + .suspend = vt1625_suspend, + .resume = vt1625_resume, +}; + +int vt1625_module_init(void) +{ + vt1625_reg_env_t *p_reg; + int i, ret, regnum; + + p_reg = kmalloc((VT1625_REG_MAX_OFFSET + 1) * sizeof(vt1625_reg_env_t), + GFP_KERNEL); + if(p_reg) { + ret = vt1625_parse_reg_env(VT1625_PAL_REG_ENV, p_reg, ®num); + if(ret == 0) { + for(i = 0; i < regnum; i++) + vt1625_pal_param[(p_reg + i)->offset] = + (p_reg + i)->value; + } + + ret = vt1625_parse_reg_env(VT1625_NTSC_REG_ENV, p_reg, ®num); + if(ret == 0) { + for(i = 0; i < regnum; i++) + vt1625_ntsc_param[(p_reg + i)->offset] = + (p_reg + i)->value; + } + + kfree(p_reg); + } else + DBG_ERR("kzalloc fail\n"); + +#ifdef CONFIG_KERNEL + init_vt1625_timer(); +#endif + + vout_device_register(&vt1625_vout_dev_ops); + + return 0; +} +module_init(vt1625_module_init); +/*--------------------End of Function Body -----------------------------------*/ +#undef VT1625_C diff --git a/ANDROID_3.4.5/drivers/video/wmt/devices/vt1632.c b/ANDROID_3.4.5/drivers/video/wmt/devices/vt1632.c new file mode 100755 index 00000000..b3950c0f --- /dev/null +++ b/ANDROID_3.4.5/drivers/video/wmt/devices/vt1632.c @@ -0,0 +1,157 @@ +/*++ + * linux/drivers/video/wmt/vt1632.c + * WonderMedia video post processor (VPP) driver + * + * Copyright c 2014 WonderMedia Technologies, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * WonderMedia Technologies, Inc. + * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C +--*/ + +#define VT1632_C +/* #define DEBUG */ +/*----------------------- DEPENDENCE -----------------------------------------*/ +#include "../vout.h" + +/*----------------------- PRIVATE MACRO --------------------------------------*/ +/* #define VT1632_XXXX xxxx *//*Example*/ + +/*----------------------- PRIVATE CONSTANTS ----------------------------------*/ +/* #define VT1632_XXXX 1 *//*Example*/ +#define VT1632_ADDR 0x10 + +/*----------------------- PRIVATE TYPE --------------------------------------*/ +/* typedef xxxx vt1632_xxx_t; *//*Example*/ + +/*----------EXPORTED PRIVATE VARIABLES are defined in vt1632.h -------------*/ +/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ +/* int vt1632_xxx; *//*Example*/ +static int vt1632_not_ready; + +/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ +/* void vt1632_xxx(void); *//*Example*/ + +/*----------------------- Function Body --------------------------------------*/ + +/*the define and struct i2c_msg were declared int linux/i2c.h*/ +int vt1632_check_plugin(int hotplug) +{ + char buf[1]; + int plugin; + + if (vt1632_not_ready) + return 1; + + vpp_i2c_read(VPP_DVI_I2C_ID, VT1632_ADDR, 0x9, buf, 1); + plugin = (buf[0] & 0x4) ? 1 : 0; + DPRINT("[VT1632] DVI plug%s\n", (plugin) ? "in" : "out"); + vout_set_int_type(4); + return plugin; +} + +int vt1632_init(struct vout_t *vo) +{ + char buf[16]; + + vt1632_not_ready = 1; + vpp_i2c_read(VPP_DVI_I2C_ID, VT1632_ADDR, 0x0, buf, 2); + if ((buf[0] != 0x06) || (buf[1] != 0x11)) /* check vender id */ + return -1; + vt1632_not_ready = 0; + + buf[0x0] = 0x37; + buf[0x1] = 0x20; + vpp_i2c_write(VPP_DVI_I2C_ID, VT1632_ADDR, 0x8, buf, 2); + DPRINT("[VT1632] DVI ext device\n"); + return 0; +} + +int vt1632_set_mode(unsigned int *option) +{ + char buf[1]; + vpp_datawidht_t dwidth; + + if (vt1632_not_ready) + return -1; + + dwidth = option[1] & BIT0; + DBGMSG("vt1632_set_mode(%d)\n", (dwidth) ? 24 : 12); + + vpp_i2c_read(VPP_DVI_I2C_ID, VT1632_ADDR, 0x8, buf, 1); + if (dwidth == VPP_DATAWIDHT_12) { + buf[0] &= ~BIT2; + buf[0] |= BIT3; + } else { + buf[0] |= BIT2; + buf[0] &= ~BIT3; + } + vpp_i2c_write(VPP_DVI_I2C_ID, VT1632_ADDR, 0x8, buf, 1); + return 0; +} + +void vt1632_set_power_down(int enable) +{ + char buf[1]; + + if (vt1632_not_ready) + return; + + DBGMSG("vt1632_set_power_down(%d)\n", enable); + + vpp_i2c_read(VPP_DVI_I2C_ID, VT1632_ADDR, 0x8, buf, 1); + if (enable) + buf[0] &= ~BIT0; + else + buf[0] |= BIT0; + vpp_i2c_write(VPP_DVI_I2C_ID, VT1632_ADDR, 0x8, buf, 1); +} + +int vt1632_config(struct vout_info_t *info) +{ + return 0; +} + +int vt1632_get_edid(char *buf) +{ + return 0; +} + +int vt1632_interrupt(void) +{ + return vt1632_check_plugin(1); +} +/*----------------------- vout device plugin ---------------------------------*/ +struct vout_dev_t vt1632_vout_dev_ops = { + .name = "VT1632", + .mode = VOUT_INF_DVI, + + .init = vt1632_init, + .set_power_down = vt1632_set_power_down, + .set_mode = vt1632_set_mode, + .config = vt1632_config, + .check_plugin = vt1632_check_plugin, + .get_edid = vt1632_get_edid, + .interrupt = vt1632_interrupt, +}; + +int vt1632_module_init(void) +{ + vout_device_register(&vt1632_vout_dev_ops); + return 0; +} /* End of vt1632_module_init */ +module_init(vt1632_module_init); +/*--------------------End of Function Body -----------------------------------*/ +#undef VT1632_C |