diff options
Diffstat (limited to 'drivers/video/wmt/devices')
-rw-r--r--[-rwxr-xr-x] | drivers/video/wmt/devices/Makefile | 12 | ||||
-rw-r--r--[-rwxr-xr-x] | drivers/video/wmt/devices/cs8556.c | 1244 | ||||
-rw-r--r--[-rwxr-xr-x] | drivers/video/wmt/devices/lcd-AUO-A080SN01.c | 8 | ||||
-rw-r--r--[-rwxr-xr-x] | drivers/video/wmt/devices/lcd-CHILIN-LW700at9003.c | 8 | ||||
-rw-r--r--[-rwxr-xr-x] | drivers/video/wmt/devices/lcd-EKING-EK08009-70135.c | 8 | ||||
-rw-r--r--[-rwxr-xr-x] | drivers/video/wmt/devices/lcd-HANNSTAR-HSD101PFW2.c | 8 | ||||
-rw-r--r--[-rwxr-xr-x] | drivers/video/wmt/devices/lcd-INNOLUX-AT070TN83.c | 64 | ||||
-rw-r--r--[-rwxr-xr-x] | drivers/video/wmt/devices/lcd-b079xan01.c | 378 | ||||
-rw-r--r--[-rwxr-xr-x] | drivers/video/wmt/devices/lcd-lvds-1024x600.c | 8 | ||||
-rw-r--r--[-rwxr-xr-x] | drivers/video/wmt/devices/lcd-oem.c | 189 | ||||
-rw-r--r--[-rwxr-xr-x] | drivers/video/wmt/devices/lcd.c | 528 | ||||
-rw-r--r--[-rwxr-xr-x] | drivers/video/wmt/devices/vt1625.c | 680 | ||||
-rw-r--r--[-rwxr-xr-x] | drivers/video/wmt/devices/vt1632.c | 8 |
13 files changed, 1303 insertions, 1840 deletions
diff --git a/drivers/video/wmt/devices/Makefile b/drivers/video/wmt/devices/Makefile index da55ae48..955c31ec 100755..100644 --- a/drivers/video/wmt/devices/Makefile +++ b/drivers/video/wmt/devices/Makefile @@ -10,17 +10,11 @@ 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-y += cs8556.o +obj-y += lcd-b079xan01.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_DVI_VT1632_WMT) += vt1632.o 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/drivers/video/wmt/devices/cs8556.c b/drivers/video/wmt/devices/cs8556.c index 72097685..c44fb336 100755..100644 --- a/drivers/video/wmt/devices/cs8556.c +++ b/drivers/video/wmt/devices/cs8556.c @@ -1,627 +1,617 @@ -/*++ - * 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 +/*++
+ * 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*/
+//#define CONFIG_CS8556_INTERRUPT
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define VT1632_XXXX 1 *//*Example*/
+#define CS8556_ADDR 0x3d
+#define CS8556_NAME "CS8556"
+
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx vt1632_xxx_t; *//*Example*/
+typedef struct {
+ unsigned int flag;
+ unsigned int gpiono;
+ unsigned int act;
+}avdetect_gpio_t;
+
+/*----------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 int s_irq_init;
+static 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
+
+ wmt_gpio_setpull(s_avdetect_gpio.gpiono, WMT_GPIO_PULL_UP); //enable pull and pull-up
+
+ wmt_gpio_mask_irq(s_avdetect_gpio.gpiono); //disable interrupt
+
+ wmt_gpio_set_irq_type(s_avdetect_gpio.gpiono, IRQ_TYPE_EDGE_BOTH); //rise edge and clear interrupt
+
+ 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)
+{
+ //printk("avdetect_irq_handler\n");
+
+ if(!gpio_irqstatus(s_avdetect_gpio.gpiono))
+ return IRQ_NONE;
+
+ wmt_gpio_ack_irq(s_avdetect_gpio.gpiono); //clear interrupt
+
+ //printk("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)
+{
+ //printk(cvbs_hotplug_irq_thread\n");
+
+ if(s_avdetect_gpio.act == 1) {
+ if(gpio_get_value(s_avdetect_gpio.gpiono))
+ printk("av plug in\n");
+ else
+ printk("av plug out\n");
+ }
+ else {
+ if(gpio_get_value(s_avdetect_gpio.gpiono))
+ printk("av plug out\n");
+ else
+ printk("av plug in\n");
+ }
+
+ return IRQ_HANDLED;
+}
+
+void cs8556_set_tv_mode(int ntsc)
+{
+ int ret;
+ unsigned char rbuf[256] = {0};
+
+ if( !s_cs8556_ready )
+ return;
+
+ ret = I2CMultiPageRead(CS8556_ADDR, 0x00, 0x00, 256, rbuf);
+ if(ret) {
+ DBG_ERR("I2C read Offset0 fail\n");
+ return;
+ }
+
+ if(ntsc < 0) {
+ if(memcmp(rbuf, s_CS8556_Original_Offset0, 0x11) != 0) {
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 256, s_CS8556_Original_Offset0);
+ if(ret)
+ DBG_ERR("I2C write Original_Offset0 fail\n");
+ else {
+ if(s_irq_init)
+ avdetect_irq_disable();
+ }
+ }
+
+ return;
+ }
+
+ if(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 write NTSC_Offset0 fail\n");
+ }
+ } else {
+ 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");
+ }
+ }
+
+}
+
+int cs8556_check_plugin(int hotplug)
+{
+ return 1;
+}
+
+int cs8556_init(struct vout_s *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;
+ vout_tvformat_t tvformat = TV_MAX;
+
+ DPRINT("cs8556_init\n");
+
+ if(wmt_getsyspara("wmt.display.tvformat", buf, &varlen) == 0) {
+ if(!strnicmp(buf, "PAL", 3))
+ tvformat = TV_PAL;
+ else if(!strnicmp(buf, "NTSC", 4))
+ tvformat = TV_NTSC;
+ else
+ tvformat = TV_UNDEFINED;
+ } else
+ tvformat = TV_UNDEFINED;
+
+
+ if(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 not 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 to 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 is error. param num = %d\n", num);
+ else {
+ if(s_avdetect_gpio.gpiono > 19)
+ DBG_ERR("invalid avdetect gpio no: %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("%s: irq request failed: %d\n", __func__, ret);
+ else {
+ s_irq_init = 1;
+ DPRINT("avdetect irq request 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;
+ }
+
+ //if(s_cs8556_ready) {
+ // DPRINT("cs8556_reinit");
+ switch(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;
+//err3:
+// cvbs_hotplug_irq_disable();
+// free_irq(IRQ_GPIO, s_cs8556_client);
+// cvbs_hotplug_irq_hw_free();
+//err2:
+// i2c_del_driver(&cs8556_i2c_driver);
+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;
+ vout_t *vo;
+ unsigned char rbuf[256] = {0};
+
+ if( !s_cs8556_ready )
+ return;
+
+ vo = vout_get_entry(VPP_VOUT_NUM_DVI);
+ if (vo->status & (VPP_VOUT_STS_BLANK + VPP_VOUT_STS_POWERDN)) {
+ enable = 1;
+ }
+
+ DPRINT("cs8556_set_power_down(%d)\n",enable);
+
+ ret = I2CMultiPageRead(CS8556_ADDR, 0x00, 0x00, 0x11, rbuf);
+ if(ret) {
+ DBG_ERR("I2C read Offset0 fail\n");
+ return;
+ }
+
+ if( enable ){
+ if(memcmp(rbuf, s_CS8556_Original_Offset0, 0x11) != 0) {
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 0x11, s_CS8556_Original_Offset0);
+ if(ret)
+ DBG_ERR("I2C write Offset0 to power down CS8556 fail\n");
+ else {
+ if(s_irq_init)
+ avdetect_irq_disable();
+ }
+ }
+ } else {
+ if(memcmp(rbuf, s_RGB888_To_PAL_Offset0, 0x11) != 0) {
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 0x11, s_RGB888_To_PAL_Offset0);
+ if(ret)
+ DBG_ERR("I2C write offset0 to power up CS8556 fail\n");
+ }
+ }
+}
+
+static int cs8556_config(vout_info_t *info)
+{
+ int ntsc;
+
+ if(!s_cs8556_ready)
+ return -1;
+
+ if(info->resx == 720 && (info->resy == 576 || info->resy == 480)) {
+ ntsc = (info->resy == 480) ? 1 : 0;
+
+ DPRINT("cs8556_config (%dx%d@%d) %s\n", info->resx, info->resy, info->fps, ntsc ? "NTSC" : "PAL");
+
+ cs8556_set_tv_mode(ntsc);
+ } else {
+
+ DPRINT("cs8556_config (%dx%d@%d)\n", info->resx, info->resy, info->fps);
+ cs8556_set_tv_mode(-1);
+ }
+
+ return 0;
+}
+
+static int cs8556_get_edid(char *buf)
+{
+ return -1;
+}
+
+#ifdef CONFIG_CS8556_INTERRUPT
+static int cs8556_interrupt(void)
+{
+ return cs8556_check_plugin(1);
+}
+#endif
+
+void cs8556_read(void)
+{
+ int i, ret;
+ unsigned char rbuf[256] = {0};
+
+ ret = I2CMultiPageRead(CS8556_ADDR, 0x00, 0x00, 256, rbuf);
+ if(!ret) {
+ printk("CS8556 Read offset0 data as follows:\n");
+ for(i = 0; i < 256;) {
+ printk("0x%02X,", rbuf[i]);
+ if((++i) % 16 == 0)
+ printk("\n");
+ }
+
+ }
+}
+
+/*----------------------- vout device plugin --------------------------------------*/
+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,
+#ifdef CONFIG_CS8556_INTERRUPT
+ .interrupt = cs8556_interrupt,
+#endif
+};
+
+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/drivers/video/wmt/devices/lcd-AUO-A080SN01.c b/drivers/video/wmt/devices/lcd-AUO-A080SN01.c index f4602a16..113438d8 100755..100644 --- a/drivers/video/wmt/devices/lcd-AUO-A080SN01.c +++ b/drivers/video/wmt/devices/lcd-AUO-A080SN01.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lcd-AUO-A080SN01.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * 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 @@ -40,7 +40,7 @@ static void lcd_a080sn01_initial(void); /*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ /* int lcd_xxx; *//*Example*/ -struct lcd_parm_t lcd_a080sn01_parm = { +lcd_parm_t lcd_a080sn01_parm = { .bits_per_pixel = 24, .capability = 0, .vmode = { @@ -59,8 +59,6 @@ struct lcd_parm_t lcd_a080sn01_parm = { .vmode = 0, .flag = 0, }, - .width = 162, - .height = 121, .initial = lcd_a080sn01_initial, }; @@ -75,7 +73,7 @@ static void lcd_a080sn01_initial(void) /* TODO */ } -struct lcd_parm_t *lcd_a080sn01_get_parm(int arg) +lcd_parm_t *lcd_a080sn01_get_parm(int arg) { return &lcd_a080sn01_parm; } diff --git a/drivers/video/wmt/devices/lcd-CHILIN-LW700at9003.c b/drivers/video/wmt/devices/lcd-CHILIN-LW700at9003.c index af9752b3..a9508f0b 100755..100644 --- a/drivers/video/wmt/devices/lcd-CHILIN-LW700at9003.c +++ b/drivers/video/wmt/devices/lcd-CHILIN-LW700at9003.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lcd-CHILIN-LW700at9003.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * 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 @@ -42,7 +42,7 @@ static void lcd_lw700at9003_power_off(void); /*----------------------- INTERNAL PRIVATE VARIABLES ------------------------*/ /* int lcd_xxx; *//*Example*/ -struct lcd_parm_t lcd_lw700at9003_parm = { +lcd_parm_t lcd_lw700at9003_parm = { .bits_per_pixel = 18, .capability = LCD_CAP_CLK_HI, .vmode = { @@ -61,8 +61,6 @@ struct lcd_parm_t lcd_lw700at9003_parm = { .vmode = 0, .flag = 0, }, - .width = 152, - .height = 91, .initial = lcd_lw700at9003_power_on, .uninitial = lcd_lw700at9003_power_off, }; @@ -84,7 +82,7 @@ static void lcd_lw700at9003_power_off(void) /* TODO */ } -struct lcd_parm_t *lcd_lw700at9003_get_parm(int arg) +lcd_parm_t *lcd_lw700at9003_get_parm(int arg) { lcd_lw700at9003_parm.bits_per_pixel = arg; return &lcd_lw700at9003_parm; diff --git a/drivers/video/wmt/devices/lcd-EKING-EK08009-70135.c b/drivers/video/wmt/devices/lcd-EKING-EK08009-70135.c index 1d401886..45ed2c2c 100755..100644 --- a/drivers/video/wmt/devices/lcd-EKING-EK08009-70135.c +++ b/drivers/video/wmt/devices/lcd-EKING-EK08009-70135.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lcd-EKING_EK08009-70135.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * 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 @@ -41,7 +41,7 @@ static void lcd_ek08009_power_off(void); /*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ /* int lcd_xxx; *//*Example*/ -struct lcd_parm_t lcd_ek08009_parm = { +lcd_parm_t lcd_ek08009_parm = { .bits_per_pixel = 18, .capability = LCD_CAP_CLK_HI, .vmode = { @@ -60,8 +60,6 @@ struct lcd_parm_t lcd_ek08009_parm = { .vmode = 0, .flag = 0, }, - .width = 162, - .height = 162, .initial = lcd_ek08009_power_on, .uninitial = lcd_ek08009_power_off, }; @@ -84,7 +82,7 @@ static void lcd_ek08009_power_off(void) /* TODO */ } -struct lcd_parm_t *lcd_ek08009_get_parm(int arg) +lcd_parm_t *lcd_ek08009_get_parm(int arg) { return &lcd_ek08009_parm; } diff --git a/drivers/video/wmt/devices/lcd-HANNSTAR-HSD101PFW2.c b/drivers/video/wmt/devices/lcd-HANNSTAR-HSD101PFW2.c index 438e3fee..6c1acfc9 100755..100644 --- a/drivers/video/wmt/devices/lcd-HANNSTAR-HSD101PFW2.c +++ b/drivers/video/wmt/devices/lcd-HANNSTAR-HSD101PFW2.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lcd-HANNSTAR-HSD101PFW2.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * 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 @@ -41,7 +41,7 @@ static void lcd_HSD101PFW2_power_off(void); /*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ /* int lcd_xxx; *//*Example*/ -struct lcd_parm_t lcd_HSD101PFW2_parm = { +lcd_parm_t lcd_HSD101PFW2_parm = { .bits_per_pixel = 18, .capability = 0, .vmode = { @@ -60,8 +60,6 @@ struct lcd_parm_t lcd_HSD101PFW2_parm = { .vmode = 0, .flag = 0, }, - .width = 222, - .height = 125, .initial = lcd_HSD101PFW2_power_on, .uninitial = lcd_HSD101PFW2_power_off, }; @@ -84,7 +82,7 @@ static void lcd_HSD101PFW2_power_off(void) /* TODO */ } -struct lcd_parm_t *lcd_HSD101PFW2_get_parm(int arg) +lcd_parm_t *lcd_HSD101PFW2_get_parm(int arg) { return &lcd_HSD101PFW2_parm; } diff --git a/drivers/video/wmt/devices/lcd-INNOLUX-AT070TN83.c b/drivers/video/wmt/devices/lcd-INNOLUX-AT070TN83.c index 7c1da494..a6db70e1 100755..100644 --- a/drivers/video/wmt/devices/lcd-INNOLUX-AT070TN83.c +++ b/drivers/video/wmt/devices/lcd-INNOLUX-AT070TN83.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lcd-INNOLUX-AT070TN83.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * 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 @@ -36,12 +36,12 @@ /* 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); +static void lcd_at070tn83_power_on(void); +static void lcd_at070tn83_power_off(void); /*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ /* int lcd_xxx; *//*Example*/ -struct lcd_parm_t lcd_at070tn83_parm = { +lcd_parm_t lcd_at070tn83_parm = { .bits_per_pixel = 18, .capability = LCD_CAP_CLK_HI, .vmode = { @@ -60,46 +60,50 @@ struct lcd_parm_t lcd_at070tn83_parm = { .vmode = 0, .flag = 0, }, - .width = 154, - .height = 85, - .initial = lcd_at070tn83_initial, - .uninitial = lcd_at070tn83_uninitial, + .initial = lcd_at070tn83_power_on, + .uninitial = lcd_at070tn83_power_off, }; /*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ /* void lcd_xxx(void); *//*Example*/ /*----------------------- Function Body --------------------------------------*/ -static void lcd_at070tn83_initial(void) +static void lcd_at070tn83_power_on(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) */ +/* DPRINT("lcd_at070tn83_power_on\n"); */ + + /* TODO */ +#if (WMT_CUR_PID == WMT_PID_8425) + vppif_reg32_write(GPIO_BASE_ADDR + 0x24, 0x7, 0, 0x7); /* gpio enable */ + vppif_reg32_write(GPIO_BASE_ADDR + 0x54, 0x7, 0, 0x7); /* output mode */ + vppif_reg32_write(GPIO_BASE_ADDR + 0x84, 0x7, 0, 0x0); /* output mode */ + vppif_reg32_write(GPIO_BASE_ADDR + 0x640, 0x707, 0, 0x707); /*pull en*/ + + vppif_reg32_write(GPIO_BASE_ADDR + 0x84, 0x2, 1, 0x1); /* VGL lo */ + mdelay(8); /* delay 5ms */ + vppif_reg32_write(GPIO_BASE_ADDR + 0x84, 0x1, 0, 0x1); /* AVDD hi */ + mdelay(6); /* delay 5ms */ + vppif_reg32_write(GPIO_BASE_ADDR + 0x84, 0x4, 2, 0x1); /* VGH hi */ + mdelay(10); /* delay 10ms */ #endif } -static void lcd_at070tn83_uninitial(void) +static void lcd_at070tn83_power_off(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); +/* DPRINT("lcd_at070tn83_power_off\n"); */ + + /* TODO */ +#if (WMT_CUR_PID == WMT_PID_8425) + mdelay(10); /* delay 10ms */ + vppif_reg32_write(GPIO_BASE_ADDR + 0x84, 0x4, 2, 0x0); /* VGH lo */ + mdelay(6); /* delay 5ms */ + vppif_reg32_write(GPIO_BASE_ADDR + 0x84, 0x1, 0, 0x0); /* AVDD lo */ + mdelay(8); /* delay 5ms */ + vppif_reg32_write(GPIO_BASE_ADDR + 0x84, 0x2, 1, 0x0); /* VGL lo */ #endif } -struct lcd_parm_t *lcd_at070tn83_get_parm(int arg) +lcd_parm_t *lcd_at070tn83_get_parm(int arg) { return &lcd_at070tn83_parm; } diff --git a/drivers/video/wmt/devices/lcd-b079xan01.c b/drivers/video/wmt/devices/lcd-b079xan01.c index 05a6e957..54e5921e 100755..100644 --- a/drivers/video/wmt/devices/lcd-b079xan01.c +++ b/drivers/video/wmt/devices/lcd-b079xan01.c @@ -1,82 +1,209 @@ -/*++
- * 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> +/*++ + linux/drivers/video/wmt/devices/lcd-b079xan01.c -#include <mach/hardware.h> + 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. + 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C. +--*/ + +#include <linux/delay.h> #include <linux/spi/spi.h> +#include <mach/hardware.h> #include <mach/wmt-spi.h> - #include <linux/gpio.h> #include <mach/wmt_iomux.h> - #include "../lcd.h" #define DRIVERNAME "ssd2828" +#define DELAY_MASK 0xff000000 + +#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) + +extern void lcd_power_on(bool on); + +struct ssd2828_chip { + struct spi_device *spi; + int id; + int gpio_reset; +}; + +static int wmt_lcd_panel_id(void) +{ + char buf[96]; + int len = sizeof(buf); + int type, id = 0; + + if (wmt_getsyspara("wmt.display.param", buf, &len)) { + return -ENODEV; + } -static struct lcd_parm_t lcd_b079xan01_parm = { - .bits_per_pixel = 24, - .capability = 0, + sscanf(buf, "%d:%d", &type, &id); + return id; +} + +// B079XAN01 + +static const uint32_t b079xan01_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, //sleep out cmd + + DELAY_MASK + 200, + + 0x700029, //display on + + DELAY_MASK + 200, + + 0x7000B7, 0x72030b, //video mode on +}; + +static 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, + .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, + .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) +static 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); -} +// BP080WX7 -struct ssd2828_chip { - struct spi_device *spi; - int gpio_reset; +static const uint32_t bp080wx7_init_sequence[] = { + 0x7000B1, 0x720202, // VSA=02 , HSA=02 + 0x7000B2, 0x720828, // VBP+VSA=8, HBP+HSA=40 + 0x7000B3, 0x72040A, // VFP=04 , HFP=10 + 0x7000B4, 0x720500, // HACT=1280 + 0x7000B5, 0x720320, // vACT=800 + 0x7000B6, 0x720007, // Non burst mode with sync event 24bpp + + //DELAY_MASK + 10, + + 0x7000DE, 0x720003, // 4lanes + 0x7000D6, 0x720005, // BGR + 0x7000B9, 0x720000, + + //DELAY_MASK + 10, + + 0x7000BA, 0x72C012, // PLL=24*16 = 384MHz + 0x7000BB, 0x720008, // LP CLK=8.3MHz + 0x7000B9, 0x720001, + + //DELAY_MASK + 200, + + 0x7000B8, 0x720000, // Virtual Channel 0 + 0x7000B7, 0x720342, // LP Mode + + //DELAY_MASK + 10, + + 0x7000BC, 0x720000, + 0x700011, //sleep out + + DELAY_MASK + 200, + + 0x7000BC, 0x720000, + 0x700029, //display on + + //DELAY_MASK + 50, + + 0x7000B7, 0x72034B, //Video Mode + + DELAY_MASK + 200, + + 0x7000BC, 0x720000, + 0x700029, //display on }; +//Timing parameter for 3.0" QVGA LCD +#define VBPD (6) +#define VFPD (4) +#define VSPW (2) + +#define HBPD (38) +#define HFPD (10) +#define HSPW (2) + +// setenv wmt.display.tmr 64800:0:8:47:1280:45:4:16:800:16 + +static lcd_parm_t lcd_bp080wx7_parm = { + .bits_per_pixel = 24, + .capability = 0, + .vmode = { + .name = "BP080WX7", + .refresh = 60, + .xres = 1280, + .yres = 800, + .pixclock = KHZ2PICOS(64800), + .left_margin = HBPD, + .right_margin = HFPD, + .upper_margin = VBPD, + .lower_margin = VFPD, + .hsync_len = HSPW, + .vsync_len = VSPW, + .sync = 0, + .vmode = 0, + .flag = 0, + }, +}; + +static lcd_parm_t *lcd_bp080wx7_get_parm(int arg) +{ + return &lcd_bp080wx7_parm; +} + +// SSD2828 api static int ssd2828_read(struct spi_device *spi, uint8_t reg) { int ret; @@ -88,13 +215,12 @@ static int ssd2828_read(struct spi_device *spi, uint8_t reg) ret = spi_write(spi, buf1, 3); if (ret) { pr_err("spi_write ret=%d\n", ret); - return -EIO; + return ret; } ret = spi_w8r16(spi, buf2[0]); if (ret < 0) { pr_err("spi_write ret=%d\n", ret); - return ret; } return ret; @@ -142,35 +268,7 @@ static inline int spi_write_24bit(struct spi_device *spi, uint32_t 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) +static inline void ssd2828_hw_reset(struct ssd2828_chip *chip) { lcd_power_on(1); msleep(10); @@ -178,16 +276,16 @@ static int ssd2828_hw_reset(struct ssd2828_chip *chip) gpio_direction_output(chip->gpio_reset, 1); msleep(10); gpio_direction_output(chip->gpio_reset, 0); - msleep(20); + msleep(200); gpio_direction_output(chip->gpio_reset, 1); - msleep(20); - return 0; + msleep(200); } static int ssd2828_hw_init(struct ssd2828_chip *chip) { - int ret = 0; - int i; + const uint32_t *init_sequence; + size_t n; + int i, ret = 0; ssd2828_hw_reset(chip); @@ -197,14 +295,27 @@ static int ssd2828_hw_init(struct ssd2828_chip *chip) 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; + switch (chip->id) { + case LCD_B079XAN01: + init_sequence = b079xan01_init_sequence; + n = ARRAY_SIZE(b079xan01_init_sequence); + break; + case LCD_BP080WX7: + init_sequence = bp080wx7_init_sequence; + n = ARRAY_SIZE(bp080wx7_init_sequence); + break; + default: + return -EINVAL; + } + + for (i = 0; i < n; i++) { + if ((init_sequence[i] & DELAY_MASK) == DELAY_MASK) { + msleep(init_sequence[i] & 0xff); + } else { + ret = spi_write_24bit(chip->spi, init_sequence[i]); + if (ret) + break; } - ret = spi_write_24bit(chip->spi, ssd2828_init_sequence[i]); - if (ret) - break; } return ret; @@ -232,7 +343,7 @@ static ssize_t option_port_testmode_show(struct device *dev, s += sprintf(s, "=========\n"); out: - return s - buf; + return (s - buf); } static ssize_t option_port_testmode_store(struct device *dev, @@ -246,7 +357,7 @@ static DEVICE_ATTR(testmode, S_IRUGO, option_port_testmode_show, option_port_testmode_store); -static int __devinit ssd2828_probe(struct spi_device *spi) +static int __devinit ssd2828_spi_probe(struct spi_device *spi) { struct ssd2828_chip *chip; int gpio = WMT_PIN_GP0_GPIO0; @@ -269,12 +380,14 @@ static int __devinit ssd2828_probe(struct spi_device *spi) return -ENOMEM; chip->spi = spi; + chip->id = wmt_lcd_panel_id(); chip->gpio_reset = gpio; spi_set_drvdata(spi, chip); ret = sysfs_create_file(&spi->dev.kobj, &dev_attr_testmode.attr); - if (unlikely(ret)) + if (unlikely(ret)) { pr_err("ssd2828 sysfs_create_file failed\n"); + } return ret; } @@ -287,15 +400,11 @@ static int ssd2828_spi_resume(struct spi_device *spi) static struct spi_driver ssd2828_driver = { .driver = { - .name = DRIVERNAME, - .owner = THIS_MODULE, + .name = DRIVERNAME, + .owner = THIS_MODULE, }, - .probe = ssd2828_probe, - .resume = ssd2828_spi_resume, -#if 0 - .remove = __devexit_p(ssd2828_remove), - .shutdown = ssd2828_shutdown, -#endif + .probe = ssd2828_spi_probe, + .resume = ssd2828_spi_resume, }; static struct spi_board_info ssd2828_spi_info[] __initdata = { @@ -309,25 +418,16 @@ static struct spi_board_info ssd2828_spi_info[] __initdata = { }, }; -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) +static int __init ssd2828_init(void) { int ret; - if (wmt_lcd_panel() != LCD_B079XAN01) { - pr_err("LCD B079XAN01 not found\n"); + switch (wmt_lcd_panel_id()) { + case LCD_B079XAN01: + case LCD_BP080WX7: + break; + default: + pr_warning("lcd for ssd2828 not found\n"); return -EINVAL; } @@ -341,23 +441,25 @@ static int __init b079xan01_init(void) ret = spi_register_driver(&ssd2828_driver); if (ret) { pr_err("spi_register_driver failed\n"); - return -EIO; + return ret; } - if (lcd_b079xan01_init()) { - spi_unregister_driver(&ssd2828_driver); - return -ENODEV; - } + lcd_panel_register(LCD_B079XAN01, (void *)lcd_b079xan01_get_parm); + lcd_panel_register(LCD_BP080WX7, (void *)lcd_bp080wx7_get_parm); pr_info("spi %s register success\n", DRIVERNAME); - return 0; } -static void b079xan01_exit(void) +static void ssd2828_exit(void) { spi_unregister_driver(&ssd2828_driver); } -module_init(b079xan01_init); -module_exit(b079xan01_exit); +module_init(ssd2828_init); +module_exit(ssd2828_exit); + +MODULE_AUTHOR("Sam Mei"); +MODULE_DESCRIPTION("WonderMedia Mipi LCD Driver"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/video/wmt/devices/lcd-lvds-1024x600.c b/drivers/video/wmt/devices/lcd-lvds-1024x600.c index 952a2761..f491cce4 100755..100644 --- a/drivers/video/wmt/devices/lcd-lvds-1024x600.c +++ b/drivers/video/wmt/devices/lcd-lvds-1024x600.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lcd-lvds-1024x600.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * 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 @@ -40,7 +40,7 @@ static void lcd_LVDS_1024x600_initial(void); /*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ /* int lcd_xxx; *//*Example*/ -struct lcd_parm_t lcd_LVDS_1024x600_parm = { +lcd_parm_t lcd_LVDS_1024x600_parm = { .bits_per_pixel = 24, .capability = LCD_CAP_VSYNC_HI, .vmode = { @@ -59,8 +59,6 @@ struct lcd_parm_t lcd_LVDS_1024x600_parm = { .vmode = 0, .flag = 0, }, - .width = 222, - .height = 125, .initial = lcd_LVDS_1024x600_initial, }; @@ -75,7 +73,7 @@ static void lcd_LVDS_1024x600_initial(void) /* TODO */ } -struct lcd_parm_t *lcd_LVDS_1024x600_get_parm(int arg) +lcd_parm_t *lcd_LVDS_1024x600_get_parm(int arg) { return &lcd_LVDS_1024x600_parm; } diff --git a/drivers/video/wmt/devices/lcd-oem.c b/drivers/video/wmt/devices/lcd-oem.c index c079505e..ed5f3407 100755..100644 --- a/drivers/video/wmt/devices/lcd-oem.c +++ b/drivers/video/wmt/devices/lcd-oem.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lcd-oem.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * 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 @@ -42,46 +42,21 @@ /*--------------------- 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); + REG32_VAL(GPIO_BASE_ADDR + 0x80) |= 0x801; + REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x801; lcd_enable_signal(1); } static void lcd_oem_uninitial(void) { - outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x801, GPIO_BASE_ADDR + 0xC0); + REG32_VAL(GPIO_BASE_ADDR + 0xC0) &= ~0x801; lcd_enable_signal(0); } -#endif -struct lcd_parm_t lcd_oem_parm = { +lcd_parm_t lcd_oem_parm = { .bits_per_pixel = 24, .capability = LCD_CAP_VSYNC_HI, .vmode = { @@ -100,42 +75,34 @@ struct lcd_parm_t lcd_oem_parm = { .vmode = 0, .flag = 0, }, - .width = 222, - .height = 125, -#ifndef CONFIG_VPP_SHENZHEN - .initial = lcd_oem_initial, - .uninitial = lcd_oem_uninitial -#endif +// .initial = lcd_oem_initial, +// .uninitial = lcd_oem_uninitial }; -#ifndef CONFIG_VPP_SHENZHEN static void lcd_oem_1024x600_initial(void) { - outl(inl(GPIO_BASE_ADDR + 0x80) | 0x801, GPIO_BASE_ADDR + 0x80); + REG32_VAL(GPIO_BASE_ADDR + 0x80) |= 0x801; /* GPIO enable */ /* DVDD */ - /* T2 > 0ms */ /* AVDD/VCOM( bit 0 ) */ - outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x01, GPIO_BASE_ADDR + 0xC0); + /* T2 > 0ms */ + REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x01; /* AVDD/VCOM( bit 0 ) */ /* 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); + REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x800; /* BL( bit 11 ) */ } static void lcd_oem_1024x600_uninitial(void) { - /* BL( bit 11 ) */ - outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x800, GPIO_BASE_ADDR + 0xC0); + REG32_VAL(GPIO_BASE_ADDR + 0xC0) &= ~0x800; /* BL( bit 11 ) */ 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); + REG32_VAL(GPIO_BASE_ADDR + 0xC0) &= ~0x01; /* AVDD/VCOM( bit 0 ) */ } -#endif -struct lcd_parm_t lcd_oem_parm_1024x600 = { +lcd_parm_t lcd_oem_parm_1024x600 = { .bits_per_pixel = 24, .capability = LCD_CAP_VSYNC_HI, .vmode = { @@ -171,13 +138,11 @@ struct lcd_parm_t lcd_oem_parm_1024x600 = { .flag = 0, #endif }, -#ifndef CONFIG_VPP_SHENZHEN - .initial = lcd_oem_1024x600_initial, - .uninitial = lcd_oem_1024x600_uninitial, -#endif +// .initial = lcd_oem_1024x600_initial, +// .uninitial = lcd_oem_1024x600_uninitial, }; -struct lcd_parm_t lcd_oem_parm_1024x768 = { +lcd_parm_t lcd_oem_parm_1024x768 = { .bits_per_pixel = 24, .capability = LCD_CAP_VSYNC_HI, .vmode = { @@ -196,15 +161,11 @@ struct lcd_parm_t lcd_oem_parm_1024x768 = { .vmode = 0, .flag = 0, }, - .width = 222, - .height = 125, -#ifndef CONFIG_VPP_SHENZHEN - .initial = lcd_oem_initial, - .uninitial = lcd_oem_uninitial -#endif +// .initial = lcd_oem_initial, +// .uninitial = lcd_oem_uninitial }; -struct lcd_parm_t lcd_oem_parm_1366x768 = { +lcd_parm_t lcd_oem_parm_1366x768 = { .bits_per_pixel = 18, .capability = LCD_CAP_CLK_HI, .vmode = { @@ -223,40 +184,11 @@ struct lcd_parm_t lcd_oem_parm_1366x768 = { .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 +// .initial = lcd_oem_initial, +// .uninitial = lcd_oem_uninitial }; -struct lcd_parm_t lcd_oem_parm_800x480 = { +lcd_parm_t lcd_oem_parm_800x480 = { .bits_per_pixel = 18, .capability = LCD_CAP_CLK_HI, .vmode = { @@ -275,41 +207,33 @@ struct lcd_parm_t lcd_oem_parm_800x480 = { .vmode = 0, .flag = 0, }, - .width = 154, - .height = 85, -#ifndef CONFIG_VPP_SHENZHEN - .initial = lcd_oem_initial, - .uninitial = lcd_oem_uninitial -#endif +// .initial = lcd_oem_initial, +// .uninitial = lcd_oem_uninitial }; -#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); + REG32_VAL(GPIO_BASE_ADDR + 0x80) |= 0x801; /* GPIO enable */ /* 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); + /* VGH,VGL low */ + REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x01; /* AVDD/VCOM( bit 0 ) */ mdelay(150); /* T5 > 120ms */ - outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x800, GPIO_BASE_ADDR + 0xC0); + REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x800; /* BL( bit 11 ) */ } static void lcd_oem_1280x800_uninitial(void) { - /* turn off backlight */ - outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x800, GPIO_BASE_ADDR + 0xC0); + REG32_VAL(GPIO_BASE_ADDR + 0xC0) &= ~0x800; /* turn off backlight */ mdelay(150); - /* turn off LCD */ - outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x01, GPIO_BASE_ADDR + 0xC0); + REG32_VAL(GPIO_BASE_ADDR + 0xC0) &= ~0x01; /* turn off LCD */ lcd_enable_signal(0); /* turn off singal */ } -#endif -struct lcd_parm_t lcd_oem_parm_800x1280 = { +lcd_parm_t lcd_oem_parm_800x1280 = { .bits_per_pixel = 24, .capability = LCD_CAP_CLK_HI, .vmode = { @@ -328,15 +252,11 @@ struct lcd_parm_t lcd_oem_parm_800x1280 = { .vmode = 0, .flag = 0, }, - .width = 135, - .height = 217, -#ifndef CONFIG_VPP_SHENZHEN - .initial = lcd_oem_1280x800_initial, - .uninitial = lcd_oem_1280x800_uninitial, -#endif +// .initial = lcd_oem_1280x800_initial, +// .uninitial = lcd_oem_1280x800_uninitial, }; -struct lcd_parm_t lcd_oem_parm_1280x800 = { +lcd_parm_t lcd_oem_parm_1280x800 = { .bits_per_pixel = 24, .capability = LCD_CAP_CLK_HI, .vmode = { @@ -355,37 +275,12 @@ struct lcd_parm_t lcd_oem_parm_1280x800 = { .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, - }, +// .initial = lcd_oem_1280x800_initial, +// .uninitial = lcd_oem_1280x800_uninitial, }; /*----------------------- Function Body --------------------------------------*/ -struct lcd_parm_t *lcd_oem_get_parm(int arg) +lcd_parm_t *lcd_oem_get_parm(int arg) { return &lcd_oem_parm; } @@ -399,20 +294,18 @@ int lcd_oem_init(void) } /* End of lcd_oem_init */ module_init(lcd_oem_init); -struct lcd_parm_t *lcd_get_oem_parm(int resx, int resy) +lcd_parm_t *lcd_get_oem_parm(int resx, int resy) { - struct lcd_parm_t *oem_parm[] = { - &lcd_oem_parm_480x800, + lcd_parm_t *oem_parm[] = { &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; + lcd_parm_t *p; int i; for (i = 0; ; i++) { diff --git a/drivers/video/wmt/devices/lcd.c b/drivers/video/wmt/devices/lcd.c index a6099294..195d3483 100755..100644 --- a/drivers/video/wmt/devices/lcd.c +++ b/drivers/video/wmt/devices/lcd.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lcd.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * 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 @@ -26,15 +26,9 @@ /* #define DEBUG */ /* #define DEBUG_DETAIL */ /*----------------------- DEPENDENCE -----------------------------------------*/ +#include <linux/gpio.h> #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*/ @@ -45,7 +39,7 @@ /*----------------------- PRIVATE TYPE --------------------------------------*/ /* typedef xxxx lcd_xxx_t; *//*Example*/ struct lcd_device_t { - struct lcd_parm_t* (*get_parm)(int arg); + lcd_parm_t* (*get_parm)(int arg); }; /*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/ @@ -54,127 +48,102 @@ struct lcd_device_t { 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; +lcd_panel_t lcd_panel_id = LCD_PANEL_MAX; int lcd_panel_bpp = 24; -struct vout_dev_t lcd_vout_dev_ops; +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; +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 */ + lcd_type = type; /* 0-LCD, 1-LVDS */ } int lcd_get_type(void) { - return lcd_type; + 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}}; + int gpio; + int active; +} lcd_power; +/*----------------------- Function Body --------------------------------------*/ 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; + char buf[64]; + size_t l = sizeof(buf); + int ret; + + if (wmt_getsyspara("wmt.lcd.power", buf, &l)) { + pr_err("please set wmt.lcd.power\n"); + return -EINVAL; + } + + ret = sscanf(buf, "%d:%d", &lcd_power.gpio, &lcd_power.active); + if (ret < 2) { + pr_err("Batt: bat env param: %s\n", buf); + return -EINVAL; + } + + printk("lcd power: gpio-%d, active %d\n", lcd_power.gpio, lcd_power.active); + + ret = gpio_request(lcd_power.gpio, "lcd power"); + if (ret) { + pr_err("request gpio %d failed\n", lcd_power.gpio); + return ret; + } + + 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); + if (lcd_power.gpio < 0) + return; - DBG_MSG("lcd_power_on: i = %d, on = %d, gpio = %d, active = %d\n", - i, on, lcd_power[i].gpio, lcd_power[i].active); - } + gpio_direction_output(lcd_power.gpio, on ? lcd_power.active : !lcd_power.active); } -#endif +/*----------------------- Backlight --------------------------------------*/ void lcd_set_lvds_id(int id) { - lcd_lvds_id = id; + lcd_lvds_id = id; } int lcd_get_lvds_id(void) { - return lcd_lvds_id; + return lcd_lvds_id; } void lcd_set_parm(int id, int bpp) { - lcd_panel_id = id; - lcd_panel_bpp = bpp; + lcd_panel_id = id; + lcd_panel_bpp = bpp; } -struct lcd_parm_t *lcd_get_parm(enum lcd_panel_t id, unsigned int arg) +lcd_parm_t *lcd_get_parm(lcd_panel_t id, unsigned int arg) { - struct lcd_device_t *p; + struct lcd_device_t *p; - p = &lcd_device_array[id]; - if (p && p->get_parm) - return p->get_parm(arg); - return 0; + 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) +vout_dev_t *lcd_get_dev(void) { - if (lcd_panel_id >= LCD_PANEL_MAX) - return 0; - return &lcd_vout_dev_ops; + if (lcd_panel_id >= LCD_PANEL_MAX) + return 0; + return &lcd_vout_dev_ops; } #ifdef CONFIG_KERNEL @@ -183,257 +152,270 @@ static DEFINE_SEMAPHORE(lcd_sem); void lcd_set_mutex(int lock) { #ifdef CONFIG_KERNEL - if (lock) - down(&lcd_sem); - else - up(&lcd_sem); + if (lock) + down(&lcd_sem); + else + up(&lcd_sem); #endif } + +/* #define CONFIG_PANEL_SET_CLOCK */ 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); +#ifdef CONFIG_PANEL_SET_CLOCK + int hdmi_off; #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); + + DBG_MSG("%d\n", enable); + if (!p_lcd) + return; + + lcd_set_mutex(1); +#ifdef CONFIG_PANEL_SET_CLOCK + /* enable NA12 in Panel on */ + hdmi_off = (govrh_get_MIF_enable(p_govrh)) ? 0 : 1; + if (hdmi_off && enable) + vpp_set_clock_enable(DEV_NA12, enable, 1); #endif - } - } - lcd_set_mutex(0); + + if (enable) { + if (p_lcd->initial) + p_lcd->initial(); + else { + lcd_enable_signal(1); /* singal enable */ + //REG32_VAL(GPIO_BASE_ADDR + 0x80) |= 0x801; + //REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x801; + } + } else { + if (p_lcd->uninitial) + p_lcd->uninitial(); + else { + lcd_enable_signal(0); /* singal disable */ + //REG32_VAL(GPIO_BASE_ADDR + 0xC0) &= ~0x801; + } + } + +#ifdef CONFIG_PANEL_SET_CLOCK + /* disable VPP & NA12 clock in Panel off */ + if (hdmi_off) { + vpp_set_clock_enable(DEV_VPP, enable, 1); + vpp_set_clock_enable(DEV_GOVRHD, enable, 1); + vpp_set_clock_enable(DEV_HDMILVDS, enable, 1); + if (enable == 0) + vpp_set_clock_enable(DEV_NA12, enable, 1); + } +#endif + lcd_set_mutex(0); } void lcd_enable_signal(int enable) { - int hdmi_off; + int hdmi_off; - DBG_MSG("%d\n", enable); - if (lcd_get_type()) { /* LVDS */ - /* TODO */ - } else { /* LCD */ - govrh_set_dvo_enable(p_govrh2, enable); - } + 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); + 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 */ + 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; + 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; + 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 --------------------------------*/ +/*----------------------- 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 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; + } } -static void wmt_config_govrh_polar(struct vout_t *vo) +static void wmt_config_govrh_polar(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); + /* wmt.display.polar [clock polar]:[hsync polart]:[vsync polar]*/ + char buf[64]; + size_t l = sizeof(buf); + int clk_pol, hsync_pol, vsync_pol; + + if (wmt_getsyspara("wmt.display.polar", buf, &l)) { + return; + } + + sscanf(buf, "%d:%d:%d", &clk_pol, &hsync_pol, &vsync_pol); + + printk("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; + vout_t *vo; + 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; + return (p_lcd) ? 1 : 0; } int lcd_get_edid(char *buf) { - return 1; + return 1; } -int lcd_config(struct vout_info_t *info) +int lcd_config(vout_info_t *info) { - info->resx = p_lcd->vmode.xres; - info->resy = p_lcd->vmode.yres; - info->fps = p_lcd->vmode.refresh; - return 0; + 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) +int lcd_init(vout_t *vo) { - DBG_MSG("%d\n", lcd_panel_id); + DBG_MSG("%d\n", lcd_panel_id); - /* vo_set_lcd_id(LCD_CHILIN_LW0700AT9003); */ - if (lcd_panel_id >= LCD_PANEL_MAX) - return -1; + /* 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 (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; + 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; + /* 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, +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(); + if (parse_uboot_param()) { + lcd_power.gpio = -1; + } - vout_device_register(&lcd_vout_dev_ops); - return 0; + vout_device_register(&lcd_vout_dev_ops); + return 0; } /* End of lcd_module_init */ module_init(lcd_module_init); /*--------------------End of Function Body -----------------------------------*/ diff --git a/drivers/video/wmt/devices/vt1625.c b/drivers/video/wmt/devices/vt1625.c index 83d1a403..892f287c 100755..100644 --- a/drivers/video/wmt/devices/vt1625.c +++ b/drivers/video/wmt/devices/vt1625.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/vt1625.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * 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 @@ -22,22 +22,15 @@ --*/ #define VT1625_C -/* #define DEBUG */ +#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_INTERRUPT #define CONFIG_VT1625_POWER -#define CONFIG_VM700 /*----------------------- PRIVATE CONSTANTS ----------------------------------*/ /* #define VT1625_XXXX 1 *//*Example*/ @@ -56,7 +49,7 @@ enum { 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, @@ -84,7 +77,7 @@ enum { VT1625_VERSION_ID = 0x1B, VT1625_DAC_OVERFLOW = 0x1C, - + /* test */ VT1625_TEST_0 = 0x1D, VT1625_TEST_1 = 0x1E, @@ -155,329 +148,53 @@ enum { /*----------------------- 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 */ +const char vt1625_ntsc_param[] = { + 0x03, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x88, /* 00 - 07 */ + 0x09, 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 + 0xF0, 0x21, 0x02, 0x50, 0x43, 0x80, 0x00, 0x10, /* 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 */ 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 + 0x59, 0xCF, 0x23, 0x0C, 0x02, 0x59, 0xCF, 0x7F, /* 50 - 57 */ + 0x23, 0x94, 0xD6, 0xFE, 0x78, 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 }; -enum vt1625_out_t { - VT1625_OUT_CVBS, - VT1625_OUT_YUV, - VT1625_OUT_VGA, - VT1625_OUT_MAX +const char vt1625_pal_param[] = { + 0x03, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x8f, /* 00 - 07 */ + 0x00, 0x01, 0x7A, 0x00, 0x55, 0x58, 0x37, 0xB7, /* 08 - 0f */ + 0x08, 0x80, 0x04, 0x08, 0x08, 0x90, 0xCB, 0x8A, /* 10 - 17 */ + 0x09, 0x2A, 0x06, 0x50, 0x41, 0x80, 0x00, 0x00, /* 18 - 1f */ + 0x17, 0x0C, 0x4E, 0x85, 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 */ + 0x00, 0x00, 0xC5, 0x0F, 0x00, 0x01, 0x10, 0x4C, /* 48 - 4f */ + 0x5f, 0xCF, 0x23, 0x70, 0x02, 0x5F, 0xD0, 0x7F, /* 50 - 57 */ + 0x23, 0x92, 0xCE, 0xDF, 0x86, 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_mode; - +int vt1625_vga_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) @@ -488,79 +205,49 @@ void vt1625_reg_dump(void) 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", + MSG("%d : 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", + 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) +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 (buf[0] && (vt1625_vga_mode != -1)) { 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); + DBG_MSG("tv %s,vga %d\n", (ntsc) ? "NTSC" : "PAL", vt1625_vga_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); + if (vt1625_vga_mode == -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]); + vt1625_vga_mode = (buf[0] & 0x7) ? 0 : 1; + DBG_MSG("get vga mode %d, 0x%x\n", vt1625_vga_mode, buf[0]); } - - if (vt1625_out_mode == VT1625_OUT_VGA) { + + if (vt1625_vga_mode) { 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; @@ -575,165 +262,80 @@ static void vt1625_set_tv_mode(int ntsc) } 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); + if (!g_vpp.virtual_display) { + 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); + buf[0] = (vt1625_vga_mode) ? 0x38 : 0x37; vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_POWER_MANAGEMENT, buf, 1); #endif +// vt1625_reg_dump(); } -static int vt1625_check_plugin(int hotplug) +int vt1625_check_plugin(int hotplug) { - char buf[2]; - char cur[1]; + char buf[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) + if (g_vpp.virtual_display) return 1; - vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_POWER_MANAGEMENT, - buf, 2); - plugin = ~buf[1] & (~buf[0] & 0x3F); + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_STATUS, buf, 1); + plugin = ((buf[0] & 0x3F) == 0x3F) ? 0 : 1; 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; + (buf[0] & 0x20) ? 1 : 0, (buf[0] & 0x10) ? 1 : 0, + (buf[0] & 0x08) ? 1 : 0, (buf[0] & 0x04) ? 1 : 0, + (buf[0] & 0x02) ? 1 : 0, (buf[0] & 0x01) ? 1 : 0); + return plugin; } -static int vt1625_init(struct vout_t *vo) +int vt1625_init(struct vout_s *vo) { - char buf[40]; - int varlen = 40; - char *endp; - unsigned int value; + char buf[5]; DBG_MSG("\n"); + // vt1625_vga_mode = -1; + vt1625_vga_mode = 0; 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; - + vo->option[0] = VDO_COL_FMT_ARGB; + vo->option[1] = VPP_DATAWIDHT_12; + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_INPUT_SELECTION, buf, 5); - if (buf[0]) + 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) +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) +void vt1625_set_power_down(int enable) { - struct vout_t *vo; + vout_t *vo; char buf[1]; char cur[1]; @@ -745,16 +347,16 @@ static void vt1625_set_power_down(int enable) bit 7 : IO pad */ vo = vout_get_entry(VPP_VOUT_NUM_DVI); - if (vo->status & (VPP_VOUT_STS_BLANK + VPP_VOUT_STS_POWERDN)) + 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) + if (vt1625_tv_mode == 0) /* power down for not support resolution */ buf[0] = 0xFF; + else if (vt1625_vga_mode == -1) + buf[0] = (enable) ? 0xFF : 0x37; else -//#endif - buf[0] = vt1625_get_dac_val(vt1625_out_mode); + buf[0] = (enable) ? 0xFF : ((vt1625_vga_mode) ? 0x38 : 0x37); vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_POWER_MANAGEMENT, cur, 1); @@ -769,8 +371,8 @@ static void vt1625_set_power_down(int enable) vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_POWER_MANAGEMENT, cur, 1); mdelay(3); - - cur[0] &= ~0x80; /* turn on IO pad */ + + cur[0] &= ~0x80; /* turn on IO pad */ vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_POWER_MANAGEMENT, cur, 1); mdelay(3); @@ -782,7 +384,7 @@ static void vt1625_set_power_down(int enable) #endif } -static int vt1625_config(struct vout_info_t *info) +int vt1625_config(vout_info_t *info) { int ntsc = -1; @@ -808,13 +410,12 @@ static int vt1625_config(struct vout_info_t *info) return 0; } -static int vt1625_get_edid(char *buf) +int vt1625_get_edid(char *buf) { return 0; } -#ifdef CONFIG_VT1625_INTERRUPT -static int vt1625_interrupt(void) +int vt1625_interrupt(void) { char buf[1]; @@ -827,69 +428,8 @@ static int vt1625_interrupt(void) 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 = { +vout_dev_t vt1625_vout_dev_ops = { .name = "VT1625", .mode = VOUT_INF_DVI, @@ -902,43 +442,11 @@ struct vout_dev_t vt1625_vout_dev_ops = { #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); diff --git a/drivers/video/wmt/devices/vt1632.c b/drivers/video/wmt/devices/vt1632.c index b3950c0f..3ece9d9e 100755..100644 --- a/drivers/video/wmt/devices/vt1632.c +++ b/drivers/video/wmt/devices/vt1632.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/vt1632.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * 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 @@ -62,7 +62,7 @@ int vt1632_check_plugin(int hotplug) return plugin; } -int vt1632_init(struct vout_t *vo) +int vt1632_init(struct vout_s *vo) { char buf[16]; @@ -119,7 +119,7 @@ void vt1632_set_power_down(int enable) vpp_i2c_write(VPP_DVI_I2C_ID, VT1632_ADDR, 0x8, buf, 1); } -int vt1632_config(struct vout_info_t *info) +int vt1632_config(vout_info_t *info) { return 0; } @@ -134,7 +134,7 @@ int vt1632_interrupt(void) return vt1632_check_plugin(1); } /*----------------------- vout device plugin ---------------------------------*/ -struct vout_dev_t vt1632_vout_dev_ops = { +vout_dev_t vt1632_vout_dev_ops = { .name = "VT1632", .mode = VOUT_INF_DVI, |