[media] v4l2: blackfin: select proper pinctrl state in ppi_set_params if CONFIG_PINCT...
authorSonic Zhang <sonic.zhang@analog.com>
Wed, 23 Jul 2014 09:57:16 +0000 (06:57 -0300)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Sat, 26 Jul 2014 20:15:16 +0000 (17:15 -0300)
Multiple pinctrl states are defined for 8, 16 and 24 data pin groups in PPI peripheral.
The driver should select correct group before set up further PPI parameters.

Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
Acked-by: Scott Jiang <scott.jiang.linux@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
drivers/media/platform/blackfin/ppi.c
include/media/blackfin/ppi.h

index 90c4a936e3ae6689f72fb05163fda42e62eeb682..cff63e511e6d9a99434deb6a2d776058018eb34e 100644 (file)
@@ -206,6 +206,20 @@ static int ppi_set_params(struct ppi_if *ppi, struct ppi_params *params)
        int dma_config, bytes_per_line;
        int hcount, hdelay, samples_per_line;
 
+#ifdef CONFIG_PINCTRL
+       static const char * const pin_state[] = {"8bit", "16bit", "24bit"};
+       struct pinctrl *pctrl;
+       struct pinctrl_state *pstate;
+
+       if (params->dlen > 24 || params->dlen <= 0)
+               return -EINVAL;
+       pctrl = devm_pinctrl_get(ppi->dev);
+       pstate = pinctrl_lookup_state(pctrl,
+                                     pin_state[(params->dlen + 7) / 8 - 1]);
+       if (pinctrl_select_state(pctrl, pstate))
+               return -EINVAL;
+#endif
+
        bytes_per_line = params->width * params->bpp / 8;
        /* convert parameters unit from pixels to samples */
        hcount = params->width * params->bpp / params->dlen;
@@ -316,10 +330,12 @@ struct ppi_if *ppi_create_instance(struct platform_device *pdev,
        if (!info || !info->pin_req)
                return NULL;
 
+#ifndef CONFIG_PINCTRL
        if (peripheral_request_list(info->pin_req, KBUILD_MODNAME)) {
                dev_err(&pdev->dev, "request peripheral failed\n");
                return NULL;
        }
+#endif
 
        ppi = kzalloc(sizeof(*ppi), GFP_KERNEL);
        if (!ppi) {
@@ -329,6 +345,7 @@ struct ppi_if *ppi_create_instance(struct platform_device *pdev,
        }
        ppi->ops = &ppi_ops;
        ppi->info = info;
+       ppi->dev = &pdev->dev;
 
        pr_info("ppi probe success\n");
        return ppi;
index 61a283f2bd4b79e8e3009e78d155cf4d3d000cbc..4900baedd55af4518fd9d06ac4887f4dd65bf2bd 100644 (file)
@@ -83,6 +83,7 @@ struct ppi_info {
 };
 
 struct ppi_if {
+       struct device *dev;
        unsigned long ppi_control;
        const struct ppi_ops *ops;
        const struct ppi_info *info;