diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/mxc/ldb.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/drivers/video/mxc/ldb.c b/drivers/video/mxc/ldb.c index b3a75a5868c..983dbc957da 100644 --- a/drivers/video/mxc/ldb.c +++ b/drivers/video/mxc/ldb.c @@ -37,6 +37,7 @@ #include <linux/regulator/consumer.h> #include <linux/spinlock.h> #include <linux/fsl_devices.h> +#include <linux/of_gpio.h> #include <mach/hardware.h> #include <mach/clock.h> #include "mxc_dispdrv.h" @@ -407,11 +408,83 @@ static int ldb_ipu_ldb_route(int ipu, int di, struct ldb_data *ldb) return 0; } +static int of_get_ldb_data(struct platform_device *pdev, + struct fsl_mxc_ldb_platform_data *plat_data) +{ + struct device_node *np = pdev->dev.of_node; + uint32_t lvds0[2] = {0}, lvds1[2] = {0}; + const char *mode, *ext_ref; + int ret; + + if (!np) + return -EINVAL; + + ret = of_property_read_string(np, "mode", &mode); + if (ret < 0) + g_ldb_mode = LDB_SEP0; + else { + if (!strcmp(mode, "spl0")) + g_ldb_mode = LDB_SPL_DI0; + else if (!strcmp(mode, "spl1")) + g_ldb_mode = LDB_SPL_DI1; + else if (!strcmp(mode, "dul0")) + g_ldb_mode = LDB_DUL_DI0; + else if (!strcmp(mode, "dul1")) + g_ldb_mode = LDB_DUL_DI1; + else if (!strcmp(mode, "sin0")) + g_ldb_mode = LDB_SIN0; + else if (!strcmp(mode, "sin1")) + g_ldb_mode = LDB_SIN1; + else if (!strcmp(mode, "sep0")) + g_ldb_mode = LDB_SEP0; + else if (!strcmp(mode, "sep1")) + g_ldb_mode = LDB_SEP1; + } + + ret = of_property_read_string(np, "ext_ref", &ext_ref); + if (ret < 0) + plat_data->ext_ref = 1; + else if (!strcmp(ext_ref, "true")) + plat_data->ext_ref = 1; + + of_property_read_u32_array(np, "lvds0", + lvds0, ARRAY_SIZE(lvds0)); + of_property_read_u32_array(np, "lvds1", + lvds1, ARRAY_SIZE(lvds1)); + + if ((g_ldb_mode == LDB_SPL_DI0) || (g_ldb_mode == LDB_DUL_DI0)) { + plat_data->ipu_id = lvds0[0]; + plat_data->disp_id = 0; + } else if ((g_ldb_mode == LDB_SPL_DI1) || (g_ldb_mode == LDB_DUL_DI1)) { + plat_data->ipu_id = lvds0[0]; + plat_data->disp_id = 1; + } else if (g_ldb_mode == LDB_SIN0) { + plat_data->ipu_id = lvds0[0]; + plat_data->disp_id = lvds0[1]; + } else if (g_ldb_mode == LDB_SIN1) { + plat_data->ipu_id = lvds1[0]; + plat_data->disp_id = lvds1[1]; + } else if (g_ldb_mode == LDB_SEP0) { + plat_data->ipu_id = lvds0[0]; + plat_data->disp_id = lvds0[1]; + plat_data->sec_ipu_id = lvds1[0]; + plat_data->sec_disp_id = lvds1[1]; + } else if (g_ldb_mode == LDB_SEP1) { + plat_data->ipu_id = lvds1[0]; + plat_data->disp_id = lvds1[1]; + plat_data->sec_ipu_id = lvds0[0]; + plat_data->sec_disp_id = lvds0[1]; + } + + return 0; +} + static int ldb_disp_init(struct mxc_dispdrv_entry *disp) { int ret = 0, i; struct ldb_data *ldb = mxc_dispdrv_getdata(disp); struct mxc_dispdrv_setting *setting = mxc_dispdrv_getsetting(disp); + struct fsl_mxc_ldb_platform_data of_data; struct fsl_mxc_ldb_platform_data *plat_data = ldb->pdev->dev.platform_data; struct resource *res; uint32_t base_addr; @@ -424,6 +497,14 @@ static int ldb_disp_init(struct mxc_dispdrv_entry *disp) setting->if_fmt = IPU_PIX_FMT_RGB666; } + if (!plat_data) { + plat_data = &of_data; + if (of_get_ldb_data(ldb->pdev, plat_data) < 0) { + dev_err(&ldb->pdev->dev, "no platform data\n"); + return -EINVAL; + } + } + if (!ldb->inited) { char di_clk[] = "ipu1_di0_clk"; char ldb_clk[] = "ldb_di0_clk"; @@ -711,6 +792,24 @@ static struct mxc_dispdrv_driver ldb_drv = { .deinit = ldb_disp_deinit, }; +static void ldb_disp_pwr_up(struct platform_device *pdev) +{ + int ret, gpio_pwr; + struct device_node *np = pdev->dev.of_node; + + if (!np) + return; + + gpio_pwr = of_get_named_gpio(np, "disp-pwr-gpios", 0); + if (gpio_pwr < 0) + dev_warn(&pdev->dev, "no pwr gpio defined\n"); + else { + ret = gpio_request_one(gpio_pwr, GPIOF_OUT_INIT_HIGH, "disp-pwr"); + if (ret) + dev_warn(&pdev->dev, "fail to request pwr gpio\n"); + } +} + /*! * This function is called by the driver framework to initialize the LDB * device. @@ -737,6 +836,8 @@ static int ldb_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, ldb); + ldb_disp_pwr_up(pdev); + alloc_failed: return ret; } @@ -750,9 +851,15 @@ static int ldb_remove(struct platform_device *pdev) return 0; } +static const struct of_device_id mxc_ldb_dt_ids[] = { + { .compatible = "fsl,imx6q-ldb", }, + { /* sentinel */ } +}; + static struct platform_driver mxcldb_driver = { .driver = { .name = "mxc_ldb", + .of_match_table = mxc_ldb_dt_ids, }, .probe = ldb_probe, .remove = ldb_remove, |