summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/drivers/video/wmt/devices/cs8556.c
diff options
context:
space:
mode:
authorKevin2014-11-15 10:00:36 +0800
committerKevin2014-11-15 10:00:36 +0800
commit9d40ac5867b9aefe0722bc1f110b965ff294d30d (patch)
treede942df665fac4bac0d9cb7ae86910fe937b0c1a /ANDROID_3.4.5/drivers/video/wmt/devices/cs8556.c
parent392e8802486cb573b916e746010e141a75f507e6 (diff)
downloadFOSSEE-netbook-kernel-source-9d40ac5867b9aefe0722bc1f110b965ff294d30d.tar.gz
FOSSEE-netbook-kernel-source-9d40ac5867b9aefe0722bc1f110b965ff294d30d.tar.bz2
FOSSEE-netbook-kernel-source-9d40ac5867b9aefe0722bc1f110b965ff294d30d.zip
add via modify part source code for wm8880 4.4 kitkat
Diffstat (limited to 'ANDROID_3.4.5/drivers/video/wmt/devices/cs8556.c')
-rwxr-xr-xANDROID_3.4.5/drivers/video/wmt/devices/cs8556.c627
1 files changed, 627 insertions, 0 deletions
diff --git a/ANDROID_3.4.5/drivers/video/wmt/devices/cs8556.c b/ANDROID_3.4.5/drivers/video/wmt/devices/cs8556.c
new file mode 100755
index 00000000..72097685
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/video/wmt/devices/cs8556.c
@@ -0,0 +1,627 @@
+/*++
+ * linux/drivers/video/wmt/cs8556.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2013 WonderMedia Technologies, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+/*********************************************************************
+* REVISON HISTORY
+*
+* VERSION | DATE | AUTHORS | DESCRIPTION
+* 1.0 | 2013/08/24 | Howay Huo | First Release
+**********************************************************************/
+
+#define CS8556_C
+/* #define DEBUG */
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#include <linux/i2c.h>
+#include <mach/hardware.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <mach/wmt_iomux.h>
+#include "../vout.h"
+
+/*----------------------- PRIVATE MACRO --------------------------------------*/
+/* #define VT1632_XXXX xxxx *//*Example*/
+
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define VT1632_XXXX 1 *//*Example*/
+#define CS8556_ADDR 0x3d
+#define CS8556_NAME "CS8556"
+
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx vt1632_xxx_t; *//*Example*/
+struct avdetect_gpio_t {
+ unsigned int flag;
+ unsigned int gpiono;
+ unsigned int act;
+};
+
+/*----------EXPORTED PRIVATE VARIABLES are defined in vt1632.h -------------*/
+/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/
+/* int vt1632_xxx; *//*Example*/
+static int s_cs8556_ready;
+static int s_cs8556_init;
+static struct i2c_client *s_cs8556_client;
+static enum vout_tvformat_t s_tvformat = TV_MAX;
+static int s_irq_init;
+static struct avdetect_gpio_t s_avdetect_gpio = {0, WMT_PIN_GP0_GPIO5, 1};
+
+static unsigned char s_CS8556_Original_Offset0[] = {
+ 0xF0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
+ 0x80, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static unsigned char s_RGB888_To_PAL_Offset0[] = {
+ 0x01, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x5F, 0x03, 0x3F, 0x00, 0x7D, 0x00, 0x53, 0x03,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x70, 0x02, 0x04, 0x00, 0x2E, 0x00, 0x62, 0x02,
+ 0x00, 0x00, 0x84, 0x00, 0x2B, 0x00, 0x36, 0x00,
+ 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xBF, 0x06, 0x7F, 0x00, 0xFE, 0x00, 0xA4, 0x06,
+ 0x00, 0x00, 0x2D, 0x11, 0x3C, 0x01, 0x3A, 0x01,
+ 0x70, 0x02, 0x04, 0x00, 0x12, 0x00, 0x34, 0x01,
+ 0x00, 0x00, 0x70, 0x70, 0x70, 0x00, 0x00, 0x00,
+ 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x41, 0x18, 0x09, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
+ 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,
+ 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x24, 0x1A, 0x00, 0x01, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x01, 0xA4, 0x06, 0x0B, 0x00, 0x07, 0x01,
+ 0xF0, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x01
+};
+
+static unsigned char s_RGB888_To_NTSC_Offset0[] = {
+ 0x01, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x59, 0x03, 0x3D, 0x00, 0x7E, 0x00, 0x49, 0x03,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x0C, 0x02, 0x05, 0x00, 0x21, 0x00, 0x03, 0x02,
+ 0x00, 0x00, 0x7A, 0x00, 0x23, 0x00, 0x16, 0x00,
+ 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xB3, 0x06, 0x7F, 0x00, 0x00, 0x01, 0xA4, 0x06,
+ 0x00, 0x00, 0x05, 0x50, 0x00, 0x01, 0x07, 0x01,
+ 0x0C, 0x02, 0x02, 0x00, 0x12, 0x00, 0x07, 0x01,
+ 0x00, 0x00, 0x70, 0x70, 0x70, 0x00, 0x00, 0x00,
+ 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x41, 0x18, 0x09, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
+ 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,
+ 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x24, 0x1A, 0x00, 0x01, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x01, 0xA4, 0x06, 0x0B, 0x00, 0x07, 0x01,
+ 0xF0, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00
+};
+
+/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/
+/* void vt1632_xxx(void); *//*Example*/
+static int I2CMultiPageRead(unsigned char maddr, unsigned char page,
+ unsigned char saddr, int number, unsigned char *value)
+{
+ int ret;
+ unsigned char wbuf[2];
+ struct i2c_msg rd[2];
+
+ wbuf[0] = page;
+ wbuf[1] = saddr;
+
+ rd[0].addr = maddr;
+ rd[0].flags = 0;
+ rd[0].len = 2;
+ rd[0].buf = wbuf;
+
+ rd[1].addr = maddr;
+ rd[1].flags = I2C_M_RD;
+ rd[1].len = number;
+ rd[1].buf = value;
+
+ ret = i2c_transfer(s_cs8556_client->adapter, rd, ARRAY_SIZE(rd));
+
+ if (ret != ARRAY_SIZE(rd)) {
+ DBG_ERR("fail\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int I2CMultiPageWrite(unsigned char maddr, unsigned char page,
+ unsigned char saddr, int number, unsigned char *value)
+{
+ int ret;
+ unsigned char *pbuf;
+ struct i2c_msg wr[1];
+
+ pbuf = kmalloc(number + 2, GFP_KERNEL);
+ if (!pbuf) {
+ DBG_ERR("alloc memory fail\n");
+ return -1;
+ }
+
+ *pbuf = page;
+ *(pbuf + 1) = saddr;
+
+ memcpy(pbuf + 2, value, number);
+
+ wr[0].addr = maddr;
+ wr[0].flags = 0;
+ wr[0].len = number + 2;
+ wr[0].buf = pbuf;
+
+ ret = i2c_transfer(s_cs8556_client->adapter, wr, ARRAY_SIZE(wr));
+
+ if (ret != ARRAY_SIZE(wr)) {
+ DBG_ERR("fail\n");
+ kfree(pbuf);
+ return -1;
+ }
+
+ kfree(pbuf);
+ return 0 ;
+}
+
+/************************ i2c device struct definition ************************/
+static int __devinit cs8556_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ DBGMSG("cs8556_i2c_probe\n");
+
+ return 0;
+}
+
+static int __devexit cs8556_i2c_remove(struct i2c_client *client)
+{
+ DBGMSG("cs8556_i2c_remove\n");
+
+ return 0;
+}
+
+
+static const struct i2c_device_id cs8556_i2c_id[] = {
+ {CS8556_NAME, 0},
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, cs8556_i2c_id);
+
+static struct i2c_board_info __initdata cs8556_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO(CS8556_NAME, CS8556_ADDR),
+ },
+};
+
+static struct i2c_driver cs8556_i2c_driver = {
+ .driver = {
+ .name = CS8556_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = cs8556_i2c_probe,
+ .remove = __devexit_p(cs8556_i2c_remove),
+ .id_table = cs8556_i2c_id,
+};
+
+/*----------------------- Function Body --------------------------------------*/
+static void avdetect_irq_enable(void)
+{
+ wmt_gpio_unmask_irq(s_avdetect_gpio.gpiono);
+}
+
+static void avdetect_irq_disable(void)
+{
+ wmt_gpio_mask_irq(s_avdetect_gpio.gpiono);
+}
+
+int avdetect_irq_hw_init(int resume)
+{
+ int ret;
+
+ if (!resume) {
+ ret = gpio_request(s_avdetect_gpio.gpiono,
+ "avdetect irq"); /* enable gpio */
+ if (ret < 0) {
+ DBG_ERR("gpio(%d) request fail for avdetect irq\n",
+ s_avdetect_gpio.gpiono);
+ return ret;
+ }
+ } else
+ gpio_re_enabled(s_avdetect_gpio.gpiono); /* re-enable gpio */
+
+ gpio_direction_input(s_avdetect_gpio.gpiono); /* gpio input */
+
+ /* enable pull and pull-up */
+ wmt_gpio_setpull(s_avdetect_gpio.gpiono, WMT_GPIO_PULL_UP);
+
+ /* disable interrupt */
+ wmt_gpio_mask_irq(s_avdetect_gpio.gpiono);
+
+ /* rise edge and clear interrupt */
+ wmt_gpio_set_irq_type(s_avdetect_gpio.gpiono, IRQ_TYPE_EDGE_BOTH);
+
+ return 0;
+}
+
+/*
+static void avdetect_irq_hw_free(void)
+{
+ gpio_free(AVDETECT_IRQ_PIN);
+
+}
+*/
+
+static irqreturn_t avdetect_irq_handler(int irq, void *dev_id)
+{
+ /* DPRINT("avdetect_irq_handler\n"); */
+
+ if (!gpio_irqstatus(s_avdetect_gpio.gpiono))
+ return IRQ_NONE;
+
+ wmt_gpio_ack_irq(s_avdetect_gpio.gpiono); /* clear interrupt */
+
+ /* DPRINT("cvbs hotplug interrupt\n"); */
+ if (!is_gpio_irqenable(s_avdetect_gpio.gpiono)) {
+ /* pr_err("avdetect irq is disabled\n"); */
+ return IRQ_HANDLED;
+ } else
+ return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t avdetect_irq_thread(int irq, void *dev)
+{
+ /* DPRINT(cvbs_hotplug_irq_thread\n"); */
+
+ if (s_avdetect_gpio.act == 1) {
+ if (gpio_get_value(s_avdetect_gpio.gpiono))
+ DPRINT("av plug in\n");
+ else
+ DPRINT("av plug out\n");
+ } else {
+ if (gpio_get_value(s_avdetect_gpio.gpiono))
+ DPRINT("av plug out\n");
+ else
+ DPRINT("av plug in\n");
+ }
+
+ return IRQ_HANDLED;
+}
+
+int cs8556_check_plugin(int hotplug)
+{
+ return 1;
+}
+
+int cs8556_init(struct vout_t *vo)
+{
+ int ret;
+ char buf[40] = {0};
+ int varlen = 40;
+ int no = 1; /* default i2c1 */
+ int num;
+ unsigned char rbuf[256] = {0};
+ struct i2c_adapter *adapter = NULL;
+
+ DPRINT("cs8556_init\n");
+
+ if (s_tvformat == TV_MAX) {
+ if (wmt_getsyspara("wmt.display.tvformat", buf, &varlen) == 0) {
+ if (!strnicmp(buf, "PAL", 3))
+ s_tvformat = TV_PAL;
+ else if (!strnicmp(buf, "NTSC", 4))
+ s_tvformat = TV_NTSC;
+ else
+ s_tvformat = TV_UNDEFINED;
+ } else
+ s_tvformat = TV_UNDEFINED;
+ }
+
+ if (s_tvformat == TV_UNDEFINED)
+ goto err0;
+
+ if (!s_cs8556_init) {
+ if (wmt_getsyspara("wmt.cs8556.i2c", buf, &varlen) == 0) {
+ if (strlen(buf) > 0)
+ no = buf[0] - '0';
+ }
+
+ adapter = i2c_get_adapter(no);
+ if (adapter == NULL) {
+ DBG_ERR("Can't get i2c adapter,client address error\n");
+ goto err0;
+ }
+
+ s_cs8556_client =
+ i2c_new_device(adapter, cs8556_i2c_board_info);
+ if (s_cs8556_client == NULL) {
+ DBG_ERR("allocate i2c client failed\n");
+ goto err0;
+ }
+
+ i2c_put_adapter(adapter);
+
+ ret = i2c_add_driver(&cs8556_i2c_driver);
+ if (ret != 0) {
+ DBG_ERR("Failed register CS8556 I2C driver: %d\n", ret);
+ goto err1;
+ }
+
+ if (wmt_getsyspara("wmt.io.avdetect", buf, &varlen) == 0) {
+ num = sscanf(buf, "%d:%d:%d", &s_avdetect_gpio.flag,
+ &s_avdetect_gpio.gpiono, &s_avdetect_gpio.act);
+
+ if (num != 3)
+ DBG_ERR("wmt.io.avdetect err. num = %d\n", num);
+ else {
+ if (s_avdetect_gpio.gpiono > 19)
+ DBG_ERR("invalid avdetect gpio : %d\n",
+ s_avdetect_gpio.gpiono);
+ else {
+ ret = avdetect_irq_hw_init(0);
+ if (!ret) {
+ ret = request_threaded_irq(
+ IRQ_GPIO,
+ avdetect_irq_handler,
+ avdetect_irq_thread,
+ IRQF_SHARED,
+ CS8556_NAME,
+ s_cs8556_client);
+
+ if (ret)
+ DBG_ERR("irq req %d\n",
+ ret);
+ else {
+ s_irq_init = 1;
+ DPRINT("avdetect irq");
+ DPRINT("req success\n");
+ }
+ }
+ }
+ }
+ }
+
+ s_cs8556_init = 1;
+ } else {
+ if (s_irq_init)
+ avdetect_irq_hw_init(1);
+ }
+
+ ret = I2CMultiPageRead(CS8556_ADDR, 0x00, 0x00, 256, rbuf);
+ if (ret) {
+ DBG_ERR("I2C address 0x%02X is not found\n", CS8556_ADDR);
+ goto err0;
+ }
+
+ switch (s_tvformat) {
+ case TV_PAL:
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 256,
+ s_RGB888_To_PAL_Offset0);
+ if (ret) {
+ DBG_ERR("PAL init fail\n");
+ goto err0;
+ }
+ break;
+ case TV_NTSC:
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 256,
+ s_RGB888_To_NTSC_Offset0);
+ if (ret) {
+ DBG_ERR("NTSC init fail\n");
+ goto err0;
+ }
+ break;
+ default:
+ goto err0;
+ break;
+ }
+
+ if (s_irq_init)
+ avdetect_irq_enable();
+
+ s_cs8556_ready = 1;
+
+ return 0;
+#if 0
+err3:
+ cvbs_hotplug_irq_disable();
+ free_irq(IRQ_GPIO, s_cs8556_client);
+ cvbs_hotplug_irq_hw_free();
+err2:
+ i2c_del_driver(&cs8556_i2c_driver);
+#endif
+err1:
+ i2c_unregister_device(s_cs8556_client);
+err0:
+ s_cs8556_ready = 0;
+ return -1;
+}
+
+static int cs8556_set_mode(unsigned int *option)
+{
+ if (!s_cs8556_ready)
+ return -1;
+
+ return 0;
+}
+
+static void cs8556_set_power_down(int enable)
+{
+ int ret;
+ unsigned char rbuf[256] = {0};
+
+ if (!s_cs8556_ready)
+ return;
+
+ DBGMSG("cs8556_set_power_down(%d)\n", enable);
+
+ if (enable) {
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 5,
+ s_CS8556_Original_Offset0);
+ if (ret)
+ DBG_ERR("I2C write Original_Offset0 fail\n");
+ else {
+ if (s_irq_init)
+ avdetect_irq_disable();
+ }
+ } else {
+ ret = I2CMultiPageRead(CS8556_ADDR, 0x00, 0x00, 256, rbuf);
+ if (ret) {
+ DBG_ERR("I2C read Offset0 fail\n");
+ return;
+ }
+
+ switch (s_tvformat) {
+ case TV_PAL:
+ if (memcmp(rbuf, s_RGB888_To_PAL_Offset0, 0x50) != 0) {
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00,
+ 0x00, 256, s_RGB888_To_PAL_Offset0);
+ if (ret)
+ DBG_ERR("I2C write PAL_Offset0 fail\n");
+ }
+ break;
+ case TV_NTSC:
+ if (memcmp(rbuf, s_RGB888_To_NTSC_Offset0, 0x50) != 0) {
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00,
+ 0x00, 256, s_RGB888_To_NTSC_Offset0);
+ if (ret)
+ DBG_ERR("I2C wr NTSC_Offset0 fail\n");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static int cs8556_config(struct vout_info_t *info)
+{
+ return 0;
+}
+
+static int cs8556_get_edid(char *buf)
+{
+ return -1;
+}
+
+/*
+static int cs8556_interrupt(void)
+{
+ return cs8556_check_plugin(1);
+}
+*/
+
+void cs8556_read(void)
+{
+ int i, ret;
+ unsigned char rbuf[256] = {0};
+
+ ret = I2CMultiPageRead(CS8556_ADDR, 0x00, 0x00, 256, rbuf);
+ if (!ret) {
+ DPRINT("CS8556 Read offset0 data as follows:\n");
+ for (i = 0; i < 256;) {
+ DPRINT("0x%02X,", rbuf[i]);
+ if ((++i) % 16 == 0)
+ DPRINT("\n");
+ }
+ }
+}
+
+int cvbs_is_ready(void)
+{
+ return s_cs8556_ready;
+}
+
+/*----------------------- vout device plugin ---------------------------------*/
+struct vout_dev_t cs8556_vout_dev_ops = {
+ .name = CS8556_NAME,
+ .mode = VOUT_INF_DVI,
+
+ .init = cs8556_init,
+ .set_power_down = cs8556_set_power_down,
+ .set_mode = cs8556_set_mode,
+ .config = cs8556_config,
+ .check_plugin = cs8556_check_plugin,
+ .get_edid = cs8556_get_edid,
+/* .interrupt = cs8556_interrupt, */
+};
+
+int cs8556_module_init(void)
+{
+ vout_device_register(&cs8556_vout_dev_ops);
+ return 0;
+} /* End of cs8556_module_init */
+module_init(cs8556_module_init);
+/*--------------------End of Function Body -----------------------------------*/
+#undef CS8556_C