From 9b31708c665581b4c8aba9952ce87180ff5c7853 Mon Sep 17 00:00:00 2001 From: zwl Date: Tue, 12 Aug 2014 23:18:33 +0800 Subject: [PATCH] rk312x lvds: fix get pinctrl pins null pointer for RGB output --- .../video/rockchip/transmitter/rk31xx_lvds.c | 48 ++++++++++++++++--- .../video/rockchip/transmitter/rk31xx_lvds.h | 3 ++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/drivers/video/rockchip/transmitter/rk31xx_lvds.c b/drivers/video/rockchip/transmitter/rk31xx_lvds.c index f111b2a97050..50cfdab62f2a 100755 --- a/drivers/video/rockchip/transmitter/rk31xx_lvds.c +++ b/drivers/video/rockchip/transmitter/rk31xx_lvds.c @@ -117,9 +117,18 @@ static int rk31xx_lvds_disable(void) rk31xx_lvds_pwr_off(); rk31xx_lvds_clk_disable(lvds); - /*if (lvds->screen.type == SCREEN_RGB) - pinctrl_select_state(lvds->dev->pins->p, - lvds->dev->pins->sleep_state);*/ + +#if !defined(CONFIG_RK_FPGA) + if (lvds->screen.type == SCREEN_RGB) { + if (lvds->dev->pins) { + pinctrl_select_state(lvds->dev->pins->p, + lvds->dev->pins->sleep_state); + } else if (lvds->pins && !IS_ERR(lvds->pins->sleep_state)) { + pinctrl_select_state(lvds->pins->p, + lvds->pins->sleep_state); + } + } +#endif lvds->sys_state = false; return 0; } @@ -171,17 +180,16 @@ static void rk31xx_output_lvttl(struct rk_lvds_device *lvds, struct rk_screen *screen) { u32 val = 0; - //struct pinctrl_state *lcdc_state; /* iomux to lcdc */ -#if 1 /* defined(CONFIG_RK_FPGA) */ +#if defined(CONFIG_RK_FPGA) grf_writel(0xffff5555, RK312X_GRF_GPIO2B_IOMUX); grf_writel(0x00ff0055, RK312X_GRF_GPIO2C_IOMUX); grf_writel(0x77771111, 0x00e8); /* RK312X_GRF_GPIO2C_IOMUX2 */ grf_writel(0x700c1004, RK312X_GRF_GPIO2D_IOMUX); #else - lcdc_state = pinctrl_lookup_state(lvds->dev->pins->p, "lcdc"); - pinctrl_select_state(lvds->dev->pins->p, lcdc_state); + if (lvds->pins && !IS_ERR(lvds->pins->default_state)) + pinctrl_select_state(lvds->pins->p, lvds->pins->default_state); #endif val |= v_LVDSMODE_EN(0) | v_MIPIPHY_TTL_EN(1); /* enable lvds mode */ @@ -275,6 +283,32 @@ static int rk31xx_lvds_probe(struct platform_device *pdev) platform_set_drvdata(pdev, lvds); dev_set_name(lvds->dev, "rk31xx-lvds"); + if (lvds->dev->pins == NULL && lvds->screen.type == SCREEN_RGB) { + lvds->pins = devm_kzalloc(lvds->dev, sizeof(*(lvds->pins)), + GFP_KERNEL); + if (!lvds->pins) { + dev_err(lvds->dev, "kzalloc lvds pins failed\n"); + return -ENOMEM; + } + + lvds->pins->p = devm_pinctrl_get(lvds->dev); + if (IS_ERR(lvds->pins->p)) { + dev_info(lvds->dev, "no pinctrl handle\n"); + devm_kfree(lvds->dev, lvds->pins); + lvds->pins = NULL; + } else { + lvds->pins->default_state = + pinctrl_lookup_state(lvds->pins->p, "lcdc"); + lvds->pins->sleep_state = + pinctrl_lookup_state(lvds->pins->p, "sleep"); + if (IS_ERR(lvds->pins->default_state)) { + dev_info(lvds->dev, "no default pinctrl state\n"); + devm_kfree(lvds->dev, lvds->pins); + lvds->pins = NULL; + } + } + } + /* lvds regs on MIPIPHY_REG */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); lvds->regbase = devm_ioremap_resource(&pdev->dev, res); diff --git a/drivers/video/rockchip/transmitter/rk31xx_lvds.h b/drivers/video/rockchip/transmitter/rk31xx_lvds.h index 7178bf9c1d54..36c1f92a31a1 100755 --- a/drivers/video/rockchip/transmitter/rk31xx_lvds.h +++ b/drivers/video/rockchip/transmitter/rk31xx_lvds.h @@ -106,6 +106,9 @@ struct rk_lvds_device { struct rk_screen screen; bool clk_on; bool sys_state; +#ifdef CONFIG_PINCTRL + struct dev_pin_info *pins; +#endif }; static inline int lvds_writel(struct rk_lvds_device *lvds, u32 offset, u32 val) -- 2.34.1