msm_fb: display: Add LVDS display driver support for Chimei WXGA
Add LVDS display driver support for Chimei WXGA LVDS display panel
Signed-off-by: Ravishangar Kalyanam <rkalya@codeaurora.org>
Change-Id: If8830295814d0e27f49dfffdeb96db63f73809ba
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index 448194a..f261931 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -93,6 +93,10 @@
bool
default n
+config FB_MSM_LVDS
+ bool
+ default n
+
config FB_MSM_OVERLAY
depends on FB_MSM_MDP40 && ANDROID_PMEM
bool "MDP4 overlay support"
@@ -247,6 +251,11 @@
select FB_MSM_LCDC_PANEL
default n
+config FB_MSM_LVDS_CHIMEI_WXGA
+ bool
+ select FB_MSM_LVDS
+ default n
+
config FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT
bool
select FB_MSM_MIPI_DSI_TOSHIBA
@@ -389,6 +398,12 @@
---help---
Support for LCDC Samsung OLED PT (480x800) panel
+config FB_MSM_LVDS_CHIMEI_WXGA_PANEL
+ bool "LVDS Chimei WXGA Panel"
+ select FB_MSM_LVDS_CHIMEI_WXGA
+ ---help---
+ Support for LVDS Chimei WXGA(1366x768) panel
+
config FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
depends on FB_MSM_LCDC_HW
bool "MDDI Panel Auto Detect + LCDC Prism WVGA"
diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile
index dc02da4..2d40b15 100644
--- a/drivers/video/msm/Makefile
+++ b/drivers/video/msm/Makefile
@@ -56,6 +56,9 @@
# LCDC
obj-$(CONFIG_FB_MSM_LCDC) += lcdc.o
+# LVDS
+obj-$(CONFIG_FB_MSM_LVDS) += lvds.o
+
# MDDI
msm_mddi-objs := mddi.o mddihost.o mddihosti.o
obj-$(CONFIG_FB_MSM_MDDI) += msm_mddi.o
@@ -143,6 +146,7 @@
obj-$(CONFIG_FB_MSM_LCDC_SAMSUNG_OLED_PT) += lcdc_samsung_oled_pt.o
obj-$(CONFIG_FB_MSM_HDMI_ADV7520_PANEL) += adv7520.o
obj-$(CONFIG_FB_MSM_LCDC_ST15_WXGA) += lcdc_st15.o
+obj-$(CONFIG_FB_MSM_LVDS_CHIMEI_WXGA) += lvds_chimei_wxga.o
obj-$(CONFIG_FB_MSM_HDMI_MSM_PANEL) += hdmi_msm.o
obj-$(CONFIG_FB_MSM_EXT_INTERFACE_COMMON) += external_common.o
diff --git a/drivers/video/msm/lvds.c b/drivers/video/msm/lvds.c
new file mode 100644
index 0000000..7ef437c
--- /dev/null
+++ b/drivers/video/msm/lvds.c
@@ -0,0 +1,235 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <mach/clk.h>
+
+#include "msm_fb.h"
+
+static int lvds_probe(struct platform_device *pdev);
+static int lvds_remove(struct platform_device *pdev);
+
+static int lvds_off(struct platform_device *pdev);
+static int lvds_on(struct platform_device *pdev);
+
+static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
+static int pdev_list_cnt;
+
+static struct clk *lvds_clk;
+
+static struct platform_driver lvds_driver = {
+ .probe = lvds_probe,
+ .remove = lvds_remove,
+ .suspend = NULL,
+ .resume = NULL,
+ .shutdown = NULL,
+ .driver = {
+ .name = "lvds",
+ },
+};
+
+static struct lcdc_platform_data *lvds_pdata;
+
+static int lvds_off(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct msm_fb_data_type *mfd;
+
+ mfd = platform_get_drvdata(pdev);
+ ret = panel_next_off(pdev);
+
+ clk_disable(lvds_clk);
+
+ if (lvds_pdata && lvds_pdata->lcdc_power_save)
+ lvds_pdata->lcdc_power_save(0);
+
+ if (lvds_pdata && lvds_pdata->lcdc_gpio_config)
+ ret = lvds_pdata->lcdc_gpio_config(0);
+
+#ifdef CONFIG_MSM_BUS_SCALING
+ mdp_bus_scale_update_request(0);
+#endif
+
+ return ret;
+}
+
+static int lvds_on(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct msm_fb_data_type *mfd;
+ unsigned long panel_pixclock_freq = 0;
+ mfd = platform_get_drvdata(pdev);
+
+ if (lvds_pdata && lvds_pdata->lcdc_get_clk)
+ panel_pixclock_freq = lvds_pdata->lcdc_get_clk();
+
+ if (!panel_pixclock_freq)
+ panel_pixclock_freq = mfd->fbi->var.pixclock;
+#ifdef CONFIG_MSM_BUS_SCALING
+ mdp_bus_scale_update_request(2);
+#endif
+ mfd = platform_get_drvdata(pdev);
+
+ mfd->fbi->var.pixclock = clk_round_rate(lvds_clk,
+ mfd->fbi->var.pixclock);
+ ret = clk_set_rate(lvds_clk, mfd->fbi->var.pixclock);
+ if (ret) {
+ pr_err("%s: Can't set lvds clock to rate %u\n",
+ __func__, mfd->fbi->var.pixclock);
+ goto out;
+ }
+
+ clk_enable(lvds_clk);
+
+ if (lvds_pdata && lvds_pdata->lcdc_power_save)
+ lvds_pdata->lcdc_power_save(1);
+ if (lvds_pdata && lvds_pdata->lcdc_gpio_config)
+ ret = lvds_pdata->lcdc_gpio_config(1);
+
+ ret = panel_next_on(pdev);
+
+out:
+ return ret;
+}
+
+static int lvds_probe(struct platform_device *pdev)
+{
+ struct msm_fb_data_type *mfd;
+ struct fb_info *fbi;
+ struct platform_device *mdp_dev = NULL;
+ struct msm_fb_panel_data *pdata = NULL;
+ int rc;
+
+ if (pdev->id == 0) {
+ lvds_pdata = pdev->dev.platform_data;
+ return 0;
+ }
+
+ mfd = platform_get_drvdata(pdev);
+
+ if (!mfd)
+ return -ENODEV;
+
+ if (mfd->key != MFD_KEY)
+ return -EINVAL;
+
+ if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
+ return -ENOMEM;
+
+ mdp_dev = platform_device_alloc("mdp", pdev->id);
+ if (!mdp_dev)
+ return -ENOMEM;
+
+ /*
+ * link to the latest pdev
+ */
+ mfd->pdev = mdp_dev;
+ mfd->dest = DISPLAY_LCDC;
+
+ /*
+ * alloc panel device data
+ */
+ if (platform_device_add_data
+ (mdp_dev, pdev->dev.platform_data,
+ sizeof(struct msm_fb_panel_data))) {
+ pr_err("lvds_probe: platform_device_add_data failed!\n");
+ platform_device_put(mdp_dev);
+ return -ENOMEM;
+ }
+ /*
+ * data chain
+ */
+ pdata = (struct msm_fb_panel_data *)mdp_dev->dev.platform_data;
+ pdata->on = lvds_on;
+ pdata->off = lvds_off;
+ pdata->next = pdev;
+
+ /*
+ * get/set panel specific fb info
+ */
+ mfd->panel_info = pdata->panel_info;
+
+ if (mfd->index == 0)
+ mfd->fb_imgType = MSMFB_DEFAULT_TYPE;
+ else
+ mfd->fb_imgType = MDP_RGB_565;
+
+ fbi = mfd->fbi;
+ fbi->var.pixclock = clk_round_rate(lvds_clk,
+ mfd->panel_info.clk_rate);
+ fbi->var.left_margin = mfd->panel_info.lcdc.h_back_porch;
+ fbi->var.right_margin = mfd->panel_info.lcdc.h_front_porch;
+ fbi->var.upper_margin = mfd->panel_info.lcdc.v_back_porch;
+ fbi->var.lower_margin = mfd->panel_info.lcdc.v_front_porch;
+ fbi->var.hsync_len = mfd->panel_info.lcdc.h_pulse_width;
+ fbi->var.vsync_len = mfd->panel_info.lcdc.v_pulse_width;
+
+ /*
+ * set driver data
+ */
+ platform_set_drvdata(mdp_dev, mfd);
+ /*
+ * register in mdp driver
+ */
+ rc = platform_device_add(mdp_dev);
+ if (rc)
+ goto lvds_probe_err;
+
+ pdev_list[pdev_list_cnt++] = pdev;
+
+ return 0;
+
+lvds_probe_err:
+ platform_device_put(mdp_dev);
+ return rc;
+}
+
+static int lvds_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static int lvds_register_driver(void)
+{
+ return platform_driver_register(&lvds_driver);
+}
+
+static int __init lvds_driver_init(void)
+{
+ lvds_clk = clk_get(NULL, "lvds_clk");
+ if (IS_ERR(lvds_clk)) {
+ pr_err("Couldnt find lvds_clk\n");
+ return -EINVAL;
+ }
+
+ return lvds_register_driver();
+}
+
+module_init(lvds_driver_init);
diff --git a/drivers/video/msm/lvds_chimei_wxga.c b/drivers/video/msm/lvds_chimei_wxga.c
new file mode 100644
index 0000000..2c6b6d4
--- /dev/null
+++ b/drivers/video/msm/lvds_chimei_wxga.c
@@ -0,0 +1,124 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "msm_fb.h"
+
+static struct msm_panel_common_pdata *cm_pdata;
+static struct platform_device *cm_fbpdev;
+
+static int lvds_chimei_panel_on(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static int lvds_chimei_panel_off(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static void lvds_chimei_set_backlight(struct msm_fb_data_type *mfd)
+{
+}
+
+static int __devinit lvds_chimei_probe(struct platform_device *pdev)
+{
+ int rc = 0;
+
+ if (pdev->id == 0) {
+ cm_pdata = pdev->dev.platform_data;
+ if (cm_pdata == NULL)
+ pr_err("%s: no PWM gpio specified\n", __func__);
+ return 0;
+ }
+
+ cm_fbpdev = msm_fb_add_device(pdev);
+ if (!cm_fbpdev) {
+ dev_err(&pdev->dev, "failed to add msm_fb device\n");
+ rc = -ENODEV;
+ goto probe_exit;
+ }
+
+probe_exit:
+ return rc;
+}
+
+static struct platform_driver this_driver = {
+ .probe = lvds_chimei_probe,
+ .driver = {
+ .name = "lvds_chimei_wxga",
+ },
+};
+
+static struct msm_fb_panel_data lvds_chimei_panel_data = {
+ .on = lvds_chimei_panel_on,
+ .off = lvds_chimei_panel_off,
+ .set_backlight = lvds_chimei_set_backlight,
+};
+
+static struct platform_device this_device = {
+ .name = "lvds_chimei_wxga",
+ .id = 1,
+ .dev = {
+ .platform_data = &lvds_chimei_panel_data,
+ }
+};
+
+static int __init lvds_chimei_wxga_init(void)
+{
+ int ret;
+ struct msm_panel_info *pinfo;
+
+ if (msm_fb_detect_client("lvds_chimei_wxga"))
+ return 0;
+
+ ret = platform_driver_register(&this_driver);
+ if (ret)
+ return ret;
+
+ pinfo = &lvds_chimei_panel_data.panel_info;
+ pinfo->xres = 320;
+ pinfo->yres = 240;
+ MSM_FB_SINGLE_MODE_PANEL(pinfo);
+ pinfo->type = LVDS_PANEL;
+ pinfo->pdest = DISPLAY_1;
+ pinfo->wait_cycle = 0;
+ pinfo->bpp = 24;
+ pinfo->fb_num = 2;
+ pinfo->clk_rate = 75000000;
+ pinfo->bl_max = 15;
+ pinfo->bl_min = 1;
+
+ /*
+ * this panel is operated by de,
+ * vsycn and hsync are ignored
+ */
+ pinfo->lcdc.h_back_porch = 0;
+ pinfo->lcdc.h_front_porch = 194;
+ pinfo->lcdc.h_pulse_width = 40;
+ pinfo->lcdc.v_back_porch = 0;
+ pinfo->lcdc.v_front_porch = 38;
+ pinfo->lcdc.v_pulse_width = 20;
+ pinfo->lcdc.border_clr = 0xffff00;
+ pinfo->lcdc.underflow_clr = 0xff;
+ pinfo->lcdc.hsync_skew = 0;
+ pinfo->lvds.channel_mode = LVDS_SINGLE_CHANNEL_MODE;
+ pinfo->lcdc.xres_pad = 1046;
+ pinfo->lcdc.yres_pad = 528;
+
+ ret = platform_device_register(&this_device);
+ if (ret)
+ platform_driver_unregister(&this_driver);
+
+ return ret;
+}
+
+module_init(lvds_chimei_wxga_init);
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index b39e81c..f27bd49 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -1562,6 +1562,7 @@
#endif
case HDMI_PANEL:
case LCDC_PANEL:
+ case LVDS_PANEL:
pdata->on = mdp_lcdc_on;
pdata->off = mdp_lcdc_off;
mfd->hw_refresh = TRUE;
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index 88582e4..5f5d632 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -188,9 +188,9 @@
dsi_underflow_clr = mfd->panel_info.lcdc.underflow_clr;
dsi_hsync_skew = mfd->panel_info.lcdc.hsync_skew;
dsi_width = mfd->panel_info.xres +
- mfd->panel_info.mipi.xres_pad;
+ mfd->panel_info.lcdc.xres_pad;
dsi_height = mfd->panel_info.yres +
- mfd->panel_info.mipi.yres_pad;
+ mfd->panel_info.lcdc.yres_pad;
dsi_bpp = mfd->panel_info.bpp;
hsync_period = hsync_pulse_width + h_back_porch + dsi_width
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index 5ad6de3f..ebde23b 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -45,6 +45,73 @@
static struct mdp4_overlay_pipe *lcdc_pipe;
static struct completion lcdc_comp;
+static void lvds_init(struct msm_fb_data_type *mfd)
+{
+ unsigned int lvds_intf, lvds_phy_cfg0;
+
+ if (mfd->panel_info.bpp == 24) {
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc2014, 0x03040508);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2018, 0x00000102);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc201c, 0x0c0d1011);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2020, 0x00090a0b);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc2024, 0x1518191a);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2028, 0x00121314);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc202c, 0x0f16171b);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2030, 0x0006070e);
+
+ if (mfd->panel_info.lvds.channel_mode ==
+ LVDS_DUAL_CHANNEL_MODE) {
+ lvds_intf = 0x0001ff80;
+ lvds_phy_cfg0 = BIT(6) | BIT(7);
+ if (mfd->panel_info.lvds.channel_swap)
+ lvds_intf |= BIT(4);
+ } else {
+ lvds_intf = 0x00010f84;
+ lvds_phy_cfg0 = BIT(6);
+ }
+ } else if (mfd->panel_info.bpp == 18) {
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc2014, 0x03040508);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2018, 0x00000102);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc201c, 0x0c0d1011);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2020, 0x00090a0b);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc2024, 0x1518191a);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2028, 0x00121314);
+
+ if (mfd->panel_info.lvds.channel_mode ==
+ LVDS_DUAL_CHANNEL_MODE) {
+ lvds_intf = 0x00017788;
+ lvds_phy_cfg0 = BIT(6) | BIT(7);
+ if (mfd->panel_info.lvds.channel_swap)
+ lvds_intf |= BIT(4);
+ } else {
+ lvds_intf = 0x0001078c;
+ lvds_phy_cfg0 = BIT(6);
+ }
+ }
+
+ /* MDP_LVDSPHY_CFG0 */
+ MDP_OUTP(MDP_BASE + 0xc3100, lvds_phy_cfg0);
+ /* MDP_LCDC_LVDS_INTF_CTL */
+ MDP_OUTP(MDP_BASE + 0xc2000, lvds_intf);
+ lvds_phy_cfg0 |= BIT(4);
+ /* MDP_LVDSPHY_CFG0, enable serialization */
+ MDP_OUTP(MDP_BASE + 0xc3100, lvds_phy_cfg0);
+}
+
int mdp_lcdc_on(struct platform_device *pdev)
{
int lcdc_width;
@@ -165,8 +232,8 @@
lcdc_underflow_clr = mfd->panel_info.lcdc.underflow_clr;
lcdc_hsync_skew = mfd->panel_info.lcdc.hsync_skew;
- lcdc_width = var->xres;
- lcdc_height = var->yres;
+ lcdc_width = var->xres + mfd->panel_info.lcdc.xres_pad;
+ lcdc_height = var->yres + mfd->panel_info.lcdc.yres_pad;
lcdc_bpp = mfd->panel_info.bpp;
hsync_period =
@@ -237,6 +304,9 @@
#endif
mdp_histogram_ctrl(TRUE);
+ if (mfd->panel.type == LVDS_PANEL)
+ lvds_init(mfd);
+
ret = panel_next_on(pdev);
if (ret == 0) {
/* enable LCDC block */
diff --git a/drivers/video/msm/mipi_dsi.c b/drivers/video/msm/mipi_dsi.c
index aa210f1..f319072 100644
--- a/drivers/video/msm/mipi_dsi.c
+++ b/drivers/video/msm/mipi_dsi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -196,8 +196,8 @@
mipi = &mfd->panel_info.mipi;
if (mfd->panel_info.type == MIPI_VIDEO_PANEL) {
- dummy_xres = mfd->panel_info.mipi.xres_pad;
- dummy_yres = mfd->panel_info.mipi.yres_pad;
+ dummy_xres = mfd->panel_info.lcdc.xres_pad;
+ dummy_yres = mfd->panel_info.lcdc.yres_pad;
if (mdp_rev >= MDP_REV_41) {
MIPI_OUTP(MIPI_DSI_BASE + 0x20,
@@ -539,8 +539,8 @@
if (mfd->panel_info.type == MIPI_VIDEO_PANEL &&
!mfd->panel_info.clk_rate) {
- h_period += mfd->panel_info.mipi.xres_pad;
- v_period += mfd->panel_info.mipi.yres_pad;
+ h_period += mfd->panel_info.lcdc.xres_pad;
+ v_period += mfd->panel_info.lcdc.yres_pad;
if (lanes > 0) {
mfd->panel_info.clk_rate =
diff --git a/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c b/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c
index 2c02490..48bdb1d 100644
--- a/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c
+++ b/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -49,8 +49,8 @@
* include dummy(pad) data of 200 clk in addition to
* width and porch/sync width values
*/
- pinfo.mipi.xres_pad = 200;
- pinfo.mipi.yres_pad = 0;
+ pinfo.lcdc.xres_pad = 200;
+ pinfo.lcdc.yres_pad = 0;
pinfo.type = MIPI_VIDEO_PANEL;
pinfo.pdest = DISPLAY_1;
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 25faf61..bdfadd5 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -270,6 +270,9 @@
case HDMI_PANEL:
ret = snprintf(buf, PAGE_SIZE, "hdmi panel\n");
break;
+ case LVDS_PANEL:
+ ret = snprintf(buf, PAGE_SIZE, "lvds panel\n");
+ break;
case DTV_PANEL:
ret = snprintf(buf, PAGE_SIZE, "dtv panel\n");
break;
diff --git a/drivers/video/msm/msm_fb_panel.c b/drivers/video/msm/msm_fb_panel.c
index d8eaea2..8640116 100644
--- a/drivers/video/msm/msm_fb_panel.c
+++ b/drivers/video/msm/msm_fb_panel.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -106,6 +106,10 @@
snprintf(dev_name, sizeof(dev_name), "lcdc");
break;
+ case LVDS_PANEL:
+ snprintf(dev_name, sizeof(dev_name), "lvds");
+ break;
+
case DTV_PANEL:
snprintf(dev_name, sizeof(dev_name), "dtv");
break;
diff --git a/drivers/video/msm/msm_fb_panel.h b/drivers/video/msm/msm_fb_panel.h
index d66d802..903c865 100644
--- a/drivers/video/msm/msm_fb_panel.h
+++ b/drivers/video/msm/msm_fb_panel.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -38,6 +38,7 @@
#define MIPI_VIDEO_PANEL 8 /* MIPI */
#define MIPI_CMD_PANEL 9 /* MIPI */
#define WRITEBACK_PANEL 10 /* Wifi display */
+#define LVDS_PANEL 11 /* LVDS */
/* panel class */
typedef enum {
@@ -77,6 +78,10 @@
__u32 border_clr;
__u32 underflow_clr;
__u32 hsync_skew;
+ /* Pad width */
+ uint32 xres_pad;
+ /* Pad height */
+ uint32 yres_pad;
};
struct mddi_panel_info {
@@ -127,10 +132,17 @@
char no_max_pkt_size;
/* Clock required during LP commands */
char force_clk_lane_hs;
- /* Pad width */
- uint32 xres_pad;
- /* Pad height */
- uint32 yres_pad;
+};
+
+enum lvds_mode {
+ LVDS_SINGLE_CHANNEL_MODE,
+ LVDS_DUAL_CHANNEL_MODE,
+};
+
+struct lvds_panel_info {
+ enum lvds_mode channel_mode;
+ /* Channel swap in dual mode */
+ char channel_swap;
};
struct msm_panel_info {
@@ -156,8 +168,8 @@
struct mddi_panel_info mddi;
struct lcd_panel_info lcd;
struct lcdc_panel_info lcdc;
-
struct mipi_panel_info mipi;
+ struct lvds_panel_info lvds;
};
#define MSM_FB_SINGLE_MODE_PANEL(pinfo) \