From 902086a4880e8a6d6d017ccf03b36a21593267f1 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen <tomi.valkeinen@ti.com> Date: Tue, 30 Jul 2013 10:34:16 +0300 Subject: [PATCH 16/23] OMAPDSS: panel-dsi-cm: Add DT support XXX ULPS and backlight missing. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/omap2/displays-new/panel-dsi-cm.c | 87 +++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/drivers/video/omap2/displays-new/panel-dsi-cm.c b/drivers/video/omap2/displays-new/panel-dsi-cm.c index aaaea64..f65ea4d 100644 --- a/drivers/video/omap2/displays-new/panel-dsi-cm.c +++ b/drivers/video/omap2/displays-new/panel-dsi-cm.c @@ -22,6 +22,8 @@ #include <linux/sched.h> #include <linux/slab.h> #include <linux/workqueue.h> +#include <linux/of_device.h> +#include <linux/of_gpio.h> #include <video/omapdss.h> #include <video/omap-panel-data.h> @@ -1156,6 +1158,79 @@ static int dsicm_probe_pdata(struct platform_device *pdev) return 0; } +static int dsicm_probe_of(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct panel_drv_data *ddata = platform_get_drvdata(pdev); + struct omap_dss_device *in; + struct property *prop; + struct device_node *src_node; + u32 lane_arr[10]; + int gpio, len, num_pins; + int r, i; + + src_node = of_parse_phandle(node, "video-source", 0); + if (!src_node) { + dev_err(&pdev->dev, "failed to parse video source\n"); + return -ENODEV; + } + + in = omap_dss_find_output_by_node(src_node); + if (in == NULL) { + dev_err(&pdev->dev, "failed to find video source\n"); + return -EPROBE_DEFER; + } + ddata->in = in; + + gpio = of_get_gpio(node, 0); + if (!gpio_is_valid(gpio)) { + dev_err(&pdev->dev, "failed to parse reset gpio\n"); + return gpio; + } + ddata->reset_gpio = gpio; + + if (of_gpio_count(node) > 1) { + gpio = of_get_gpio(node, 1); + + if (gpio_is_valid(gpio) || gpio == -ENOENT) { + ddata->ext_te_gpio = gpio; + } else { + dev_err(&pdev->dev, "failed to parse TE gpio\n"); + return gpio; + } + } else { + ddata->ext_te_gpio = -1; + } + + prop = of_find_property(node, "lanes", &len); + if (prop == NULL) { + dev_err(&pdev->dev, "failed to find lane data\n"); + return -EINVAL; + } + + num_pins = len / sizeof(u32); + + if (num_pins < 4 || num_pins % 2 != 0 + || num_pins > ARRAY_SIZE(lane_arr)) { + dev_err(&pdev->dev, "bad number of lanes\n"); + return -EINVAL; + } + + r = of_property_read_u32_array(node, "lanes", lane_arr, num_pins); + if (r) { + dev_err(&pdev->dev, "failed to read lane data\n"); + return r; + } + + ddata->pin_config.num_pins = num_pins; + for (i = 0; i < num_pins; ++i) + ddata->pin_config.pins[i] = (int)lane_arr[i]; + + /* TODO: ulps, backlight */ + + return 0; +} + static int dsicm_probe(struct platform_device *pdev) { struct backlight_properties props; @@ -1178,6 +1253,10 @@ static int dsicm_probe(struct platform_device *pdev) r = dsicm_probe_pdata(pdev); if (r) return r; + } else if (pdev->dev.of_node) { + r = dsicm_probe_of(pdev); + if (r) + return r; } else { return -ENODEV; } @@ -1320,12 +1399,20 @@ static int __exit dsicm_remove(struct platform_device *pdev) return 0; } +static const struct of_device_id dsicm_of_match[] = { + { .compatible = "panel-dsi-cm", }, + {}, +}; + +MODULE_DEVICE_TABLE(of, dsicm_of_match); + static struct platform_driver dsicm_driver = { .probe = dsicm_probe, .remove = __exit_p(dsicm_remove), .driver = { .name = "panel-dsi-cm", .owner = THIS_MODULE, + .of_match_table = dsicm_of_match, }, }; -- 1.8.4.rc3