summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/drivers/video/wmt/devices/lcd.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/lcd.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/lcd.c')
-rwxr-xr-xANDROID_3.4.5/drivers/video/wmt/devices/lcd.c440
1 files changed, 440 insertions, 0 deletions
diff --git a/ANDROID_3.4.5/drivers/video/wmt/devices/lcd.c b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd.c
new file mode 100755
index 00000000..a6099294
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/video/wmt/devices/lcd.c
@@ -0,0 +1,440 @@
+/*++
+ * linux/drivers/video/wmt/lcd.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define LCD_C
+#undef DEBUG
+/* #define DEBUG */
+/* #define DEBUG_DETAIL */
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#include "../lcd.h"
+#include "../vout.h"
+#ifdef CONFIG_KERNEL
+#include <linux/gpio.h>
+#endif
+
+#ifdef CONFIG_VPP_SHENZHEN
+#include <mach/wmt_iomux.h>
+#endif
+
+/*----------------------- PRIVATE MACRO --------------------------------------*/
+/* #define LCD_XXXX xxxx *//*Example*/
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define LCD_XXXX 1 *//*Example*/
+
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx lcd_xxx_t; *//*Example*/
+struct lcd_device_t {
+ struct lcd_parm_t* (*get_parm)(int arg);
+};
+
+/*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/
+/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/
+/* int lcd_xxx; *//*Example*/
+struct lcd_device_t lcd_device_array[LCD_PANEL_MAX];
+int lcd_panel_on = 1;
+int lcd_pwm_enable;
+enum lcd_panel_t lcd_panel_id = LCD_PANEL_MAX;
+int lcd_panel_bpp = 24;
+
+struct vout_dev_t lcd_vout_dev_ops;
+
+/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/
+/* void lcd_xxx(void); *//*Example*/
+enum lcd_panel_t lcd_lvds_id = LCD_PANEL_MAX;
+int lcd_type;
+
+/*----------------------- Function Body --------------------------------------*/
+/*----------------------- Backlight --------------------------------------*/
+void lcd_set_type(int type)
+{
+ lcd_type = type; /* 0-LCD, 1-LVDS */
+}
+
+int lcd_get_type(void)
+{
+ return lcd_type;
+}
+
+#ifdef CONFIG_VPP_SHENZHEN
+
+#define MAX_LCD_GPIO_NUM 5
+
+static struct {
+ int gpio;
+ int active;
+} lcd_power[MAX_LCD_GPIO_NUM] = {{-1, 0}};
+
+static int parse_uboot_param(void)
+{
+ char buf[64];
+ unsigned int parm[32];
+ int l = sizeof(buf);
+ int ret, i, gpio_num;
+
+ for(i = 0; i < MAX_LCD_GPIO_NUM; i++)
+ lcd_power[i].gpio = -1;
+
+ /*
+ * In hardware, maybe there are several gpio to control LCD power
+ * We can set the wmt.lcd.power as follows:
+ * setenv wmt.lcd.power gpio0:active0,gpio1:active1,....,gpio4:active4
+ */
+ if (wmt_getsyspara("wmt.lcd.power", buf, &l)) {
+ pr_err("please set wmt.lcd.power\n");
+ return -EINVAL;
+ }
+
+ i = vpp_parse_param(buf, parm, 2 * MAX_LCD_GPIO_NUM, 0);
+ gpio_num = i / 2;
+
+ for(i = 0; i < gpio_num; i++) {
+
+ lcd_power[i].gpio = parm[i * 2];
+ lcd_power[i].active = parm[i * 2 + 1];
+
+ ret = gpio_request(lcd_power[i].gpio, "lcd power");
+ if (ret) {
+ pr_err("request gpio %d failed for lcd power\n",
+ lcd_power[i].gpio);
+ return ret;
+ }
+
+ DPRINT("lcd power%d: gpio%d, active %d\n",
+ i, lcd_power[i].gpio, lcd_power[i].active);
+ }
+
+ return 0;
+}
+
+void lcd_power_on(bool on)
+{
+ int i;
+
+ for(i = 0; i < MAX_LCD_GPIO_NUM; i++) {
+ if (lcd_power[i].gpio < 0)
+ return;
+
+ gpio_direction_output(lcd_power[i].gpio, on ?
+ lcd_power[i].active : !lcd_power[i].active);
+
+ DBG_MSG("lcd_power_on: i = %d, on = %d, gpio = %d, active = %d\n",
+ i, on, lcd_power[i].gpio, lcd_power[i].active);
+ }
+}
+#endif
+
+void lcd_set_lvds_id(int id)
+{
+ lcd_lvds_id = id;
+}
+
+int lcd_get_lvds_id(void)
+{
+ return lcd_lvds_id;
+}
+
+void lcd_set_parm(int id, int bpp)
+{
+ lcd_panel_id = id;
+ lcd_panel_bpp = bpp;
+}
+
+struct lcd_parm_t *lcd_get_parm(enum lcd_panel_t id, unsigned int arg)
+{
+ struct lcd_device_t *p;
+
+ p = &lcd_device_array[id];
+ if (p && p->get_parm)
+ return p->get_parm(arg);
+ return 0;
+}
+
+struct vout_dev_t *lcd_get_dev(void)
+{
+ if (lcd_panel_id >= LCD_PANEL_MAX)
+ return 0;
+ return &lcd_vout_dev_ops;
+}
+
+#ifdef CONFIG_KERNEL
+static DEFINE_SEMAPHORE(lcd_sem);
+#endif
+void lcd_set_mutex(int lock)
+{
+#ifdef CONFIG_KERNEL
+ if (lock)
+ down(&lcd_sem);
+ else
+ up(&lcd_sem);
+#endif
+}
+
+void lcd_set_enable(int enable)
+{
+ DBG_MSG("%d\n", enable);
+ if (!p_lcd)
+ return;
+
+ lcd_set_mutex(1);
+ if (enable) {
+ if (p_lcd->initial)
+ p_lcd->initial();
+ else {
+ lcd_enable_signal(1); /* singal enable */
+#ifndef CONFIG_VPP_SHENZHEN
+ outl(inl(GPIO_BASE_ADDR + 0x80) | 0x801,
+ GPIO_BASE_ADDR + 0x80);
+ outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x801,
+ GPIO_BASE_ADDR + 0xC0);
+#endif
+ }
+ } else {
+ if (p_lcd->uninitial)
+ p_lcd->uninitial();
+ else {
+ lcd_enable_signal(0); /* singal disable */
+#ifndef CONFIG_VPP_SHENZHEN
+ outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x801,
+ GPIO_BASE_ADDR + 0xC0);
+#endif
+ }
+ }
+ lcd_set_mutex(0);
+}
+
+void lcd_enable_signal(int enable)
+{
+ int hdmi_off;
+
+ DBG_MSG("%d\n", enable);
+ if (lcd_get_type()) { /* LVDS */
+ /* TODO */
+ } else { /* LCD */
+ govrh_set_dvo_enable(p_govrh2, enable);
+ }
+
+ hdmi_off = (govrh_get_MIF_enable(p_govrh)) ? 0 : 1;
+ vpp_set_clock_enable(DEV_DVO, (hdmi_off && !enable) ? 0 : 1, 1);
+}
+
+#ifdef __KERNEL__
+/*----------------------- LCD --------------------------------------*/
+static int __init lcd_arg_panel_id
+(
+ char *str /*!<; // argument string */
+)
+{
+ sscanf(str, "%d", (int *) &lcd_panel_id);
+ if (lcd_panel_id >= LCD_PANEL_MAX)
+ lcd_panel_id = LCD_PANEL_MAX;
+ DBGMSG(KERN_INFO "set lcd panel id = %d\n", lcd_panel_id);
+ return 1;
+} /* End of lcd_arg_panel_id */
+
+__setup("lcdid=", lcd_arg_panel_id);
+#endif
+int lcd_panel_register(int no, void (*get_parm)(int mode))
+{
+ struct lcd_device_t *p;
+
+ if (no >= LCD_PANEL_MAX) {
+ DBGMSG(KERN_ERR "*E* lcd device no max is %d !\n",
+ LCD_PANEL_MAX);
+ return -1;
+ }
+
+ p = &lcd_device_array[no];
+ if (p->get_parm) {
+ DBGMSG(KERN_ERR "*E* lcd device %d exist !\n", no);
+ return -1;
+ }
+ p->get_parm = (void *) get_parm;
+ return 0;
+} /* End of lcd_device_register */
+
+/*----------------------- vout device plugin --------------------------------*/
+void lcd_set_power_down(int enable)
+{
+#ifdef CONFIG_VPP_SHENZHEN
+ static int save_state = -1;
+
+ if (save_state != enable) {
+ /* lcd enable control by user */
+ lcd_power_on(enable ? false : true);
+ lcd_set_enable(enable ? false : true);
+ save_state = enable;
+ }
+#endif
+}
+
+static void wmt_config_govrh_polar(struct vout_t *vo)
+{
+ /* wmt.display.polar [clock polar]:[hsync polart]:[vsync polar]*/
+ char buf[64];
+ int l = sizeof(buf);
+ int clk_pol, hsync_pol, vsync_pol;
+ unsigned int parm[3];
+
+ if (wmt_getsyspara("wmt.display.polar", buf, &l))
+ return;
+
+ vpp_parse_param(buf, (unsigned int *)parm, 3, 0);
+ clk_pol = parm[0];
+ hsync_pol = parm[1];
+ vsync_pol = parm[2];
+ DBG_MSG("govrh polar: clk-pol %d, hsync %d, vsync %d\n",
+ clk_pol, hsync_pol, vsync_pol);
+ govrh_set_dvo_clock_delay(vo->govr, clk_pol ? 0 : 1, 0);
+ govrh_set_dvo_sync_polar(vo->govr,
+ hsync_pol ? 0 : 1, vsync_pol ? 0 : 1);
+}
+
+int lcd_set_mode(unsigned int *option)
+{
+ struct vout_t *vo;
+ enum vout_inf_mode_t inf_mode;
+
+ DBG_MSG("option %d,%d\n", option[0], option[1]);
+
+ vo = lcd_vout_dev_ops.vout;
+ inf_mode = vo->inf->mode;
+ if (option) {
+ unsigned int capability;
+
+ if (lcd_panel_id == 0)
+ p_lcd = lcd_get_oem_parm(vo->resx, vo->resy);
+ else
+ p_lcd = lcd_get_parm(lcd_panel_id, lcd_panel_bpp);
+
+ if (!p_lcd) {
+ DBG_ERR("lcd %d not support\n", lcd_panel_id);
+ return -1;
+ }
+ DBG_MSG("[%s] %s (id %d,bpp %d)\n", vout_inf_str[inf_mode],
+ p_lcd->vmode.name, lcd_panel_id, lcd_panel_bpp);
+ capability = p_lcd->capability;
+ switch (inf_mode) {
+ case VOUT_INF_LVDS:
+ lvds_set_sync_polar(
+ (capability & LCD_CAP_HSYNC_HI) ? 0 : 1,
+ (capability & LCD_CAP_VSYNC_HI) ? 0 : 1);
+ lvds_set_rgb_type(lcd_panel_bpp);
+ break;
+ case VOUT_INF_DVI:
+ govrh_set_dvo_clock_delay(vo->govr,
+ (capability & LCD_CAP_CLK_HI) ? 0 : 1, 0);
+ govrh_set_dvo_sync_polar(vo->govr,
+ (capability & LCD_CAP_HSYNC_HI) ? 0 : 1,
+ (capability & LCD_CAP_VSYNC_HI) ? 0 : 1);
+ switch (lcd_panel_bpp) {
+ case 15:
+ govrh_IGS_set_mode(vo->govr, 0, 1, 1);
+ break;
+ case 16:
+ govrh_IGS_set_mode(vo->govr, 0, 3, 1);
+ break;
+ case 18:
+ govrh_IGS_set_mode(vo->govr, 0, 2, 1);
+ break;
+ case 24:
+ govrh_IGS_set_mode(vo->govr, 0, 0, 0);
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ } else
+ p_lcd = 0;
+
+ wmt_config_govrh_polar(vo);
+ return 0;
+}
+
+int lcd_check_plugin(int hotplug)
+{
+ return (p_lcd) ? 1 : 0;
+}
+
+int lcd_get_edid(char *buf)
+{
+ return 1;
+}
+
+int lcd_config(struct vout_info_t *info)
+{
+ info->resx = p_lcd->vmode.xres;
+ info->resy = p_lcd->vmode.yres;
+ info->fps = p_lcd->vmode.refresh;
+ return 0;
+}
+
+int lcd_init(struct vout_t *vo)
+{
+ DBG_MSG("%d\n", lcd_panel_id);
+
+ /* vo_set_lcd_id(LCD_CHILIN_LW0700AT9003); */
+ if (lcd_panel_id >= LCD_PANEL_MAX)
+ return -1;
+
+ if (lcd_panel_id == 0)
+ p_lcd = lcd_get_oem_parm(vo->resx, vo->resy);
+ else
+ p_lcd = lcd_get_parm(lcd_panel_id, 24);
+
+ if (p_lcd == 0)
+ return -1;
+
+ /* set default parameters */
+ vo->resx = p_lcd->vmode.xres;
+ vo->resy = p_lcd->vmode.yres;
+ vo->pixclk = PICOS2KHZ(p_lcd->vmode.pixclock) * 1000;
+ return 0;
+}
+
+struct vout_dev_t lcd_vout_dev_ops = {
+ .name = "LCD",
+ .mode = VOUT_INF_DVI,
+ .capability = VOUT_DEV_CAP_FIX_RES + VOUT_DEV_CAP_FIX_PLUG,
+
+ .init = lcd_init,
+ .set_power_down = lcd_set_power_down,
+ .set_mode = lcd_set_mode,
+ .config = lcd_config,
+ .check_plugin = lcd_check_plugin,
+ .get_edid = lcd_get_edid,
+};
+
+int lcd_module_init(void)
+{
+ parse_uboot_param();
+
+ vout_device_register(&lcd_vout_dev_ops);
+ return 0;
+} /* End of lcd_module_init */
+module_init(lcd_module_init);
+/*--------------------End of Function Body -----------------------------------*/
+#undef LCD_C