[RFC/PATCH 13/13] media: s5p-fimc: Add parallel video port pin configuration
Sylwester Nawrocki
s.nawrocki at samsung.com
Sat May 26 05:52:52 EST 2012
This patch adds parsing of 'samsung,fimc-camport-a-gpios' and
'samsung,fimc-camport-b-gpios' properties from 'camera' node
and configuration of camera parallel port pins. It can be
in future replaced with equivalent pinctrl API calls.
Signed-off-by: Sylwester Nawrocki <s.nawrocki at samsung.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
Signed-off-by: Kyugmin Park <kyungmin.park at samsung.com>
---
.../bindings/camera/soc/samsung-fimc.txt | 12 +++
drivers/media/video/s5p-fimc/fimc-mdevice.c | 87 ++++++++++++++++++++
drivers/media/video/s5p-fimc/fimc-mdevice.h | 10 +++
3 files changed, 109 insertions(+)
diff --git a/Documentation/devicetree/bindings/camera/soc/samsung-fimc.txt b/Documentation/devicetree/bindings/camera/soc/samsung-fimc.txt
index ffe09ac..efa5be5 100644
--- a/Documentation/devicetree/bindings/camera/soc/samsung-fimc.txt
+++ b/Documentation/devicetree/bindings/camera/soc/samsung-fimc.txt
@@ -23,6 +23,18 @@ Optional properties:
- csi-rx-controllers : an array of phandles to 'csis' device nodes,
it is required for sensors with MIPI-CSI2 bus;
+- samsung,camport-a-gpios, samsung,camport-b-gpios : gpio specifier list for
+ the parallel camera ports A and B respectively;
+
+ For 'video-itu-601-bus' the list length must be 13, for 'video-itu-656-bus'
+ at least 10 and for 'video-mipi-csi2-bus' the array should contain at least
+ one gpio (CLKOUT). The meaning of the gpios is as following: DATA[7:0], PCLK,
+ VSYNC, HREF, CLKOUT, FIELD. It is not required to list gpios exactly in that
+ order. All gpios listed here will be configured into camera port function.
+ In case of ITU-R BT.656 bus the VSYNC, HREF, and FIELD pins remain unused,
+ hence don't need to be specified here.
+
+
'fimc' device node
------------------
diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c
index faf5665..31bf852 100644
--- a/drivers/media/video/s5p-fimc/fimc-mdevice.c
+++ b/drivers/media/video/s5p-fimc/fimc-mdevice.c
@@ -1108,6 +1108,87 @@ static ssize_t fimc_md_sysfs_store(struct device *dev,
static DEVICE_ATTR(subdev_conf_mode, S_IWUSR | S_IRUGO,
fimc_md_sysfs_show, fimc_md_sysfs_store);
+static int __fimc_md_get_gpios(struct device_node *np,
+ struct fimc_video_port *port,
+ const char *prop_name)
+{
+ int i, err = -EINVAL;
+
+ for (i = 0; i < FIMC_MAX_PARALLEL_PORT_PINS; i++) {
+ port->gpios[i] = of_get_named_gpio(np, prop_name, i);
+ if (port->gpios[i] == -ENOENT && i > 0)
+ return 0;
+
+ if (gpio_is_valid(port->gpios[i])) {
+ err = gpio_request(port->gpios[i], "fimc");
+ if (!err)
+ continue;
+ }
+
+ pr_err("Failed to configure gpios: %s\n", prop_name);
+
+ while (--i >= 0) {
+ gpio_free(port->gpios[i]);
+ port->gpios[i] = -EINVAL;
+ }
+ break;
+ }
+
+ return err;
+}
+
+static int fimc_md_camport_setup(struct fimc_md *fmd, struct device_node *np)
+{
+ const char *gpio_props[] = { "samsung,camport-a-gpios",
+ "samsung,camport-b-gpios" };
+ struct fimc_video_port *pport;
+ unsigned int ret;
+ int i;
+
+ pport = devm_kzalloc(&fmd->pdev->dev, FIMC_MAX_PARALLEL_PORTS *
+ sizeof(*pport), GFP_KERNEL);
+ if (pport == NULL)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(gpio_props); i++) {
+ if (!of_find_property(np, gpio_props[i], NULL))
+ continue;
+ ret = __fimc_md_get_gpios(np, &pport[i], gpio_props[i]);
+ if (ret < 0)
+ return ret;
+ }
+
+ fmd->parallel_ports = pport;
+ return ret;
+}
+
+static void fimc_md_camport_release(struct fimc_md *fmd)
+{
+ struct fimc_video_port *pport = fmd->parallel_ports;
+ int port, i;
+
+ if (pport == NULL)
+ return;
+
+ for (port = 0; port < FIMC_MAX_PARALLEL_PORTS; port++, pport++) {
+ for (i = 0; i < FIMC_MAX_PARALLEL_PORT_PINS; i++) {
+ if (!gpio_is_valid(pport->gpios[i]))
+ continue;
+ gpio_free(pport->gpios[i]);
+ }
+ }
+}
+
+static int fimc_md_parse_dt(struct fimc_md *fmd)
+{
+ struct device_node *np = fmd->pdev->dev.of_node;
+
+ if (np == NULL)
+ return 0;
+
+ return fimc_md_camport_setup(fmd, np);
+}
+
static int fimc_md_probe(struct platform_device *pdev)
{
struct v4l2_device *v4l2_dev;
@@ -1155,11 +1236,16 @@ static int fimc_md_probe(struct platform_device *pdev)
if (ret)
goto err_unlock;
+ ret = fimc_md_parse_dt(fmd);
+ if (ret < 0)
+ goto err_unlock;
+
if (pdev->dev.platform_data || pdev->dev.of_node) {
ret = fimc_md_register_sensor_entities(fmd);
if (ret)
goto err_unlock;
}
+
ret = fimc_md_create_links(fmd);
if (ret)
goto err_unlock;
@@ -1196,6 +1282,7 @@ static int __devexit fimc_md_remove(struct platform_device *pdev)
fimc_md_unregister_entities(fmd);
media_device_unregister(&fmd->media_dev);
fimc_md_put_clocks(fmd);
+ fimc_md_camport_release(fmd);
return 0;
}
diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.h b/drivers/media/video/s5p-fimc/fimc-mdevice.h
index bba85bf..1f7ebf8 100644
--- a/drivers/media/video/s5p-fimc/fimc-mdevice.h
+++ b/drivers/media/video/s5p-fimc/fimc-mdevice.h
@@ -30,6 +30,10 @@
#define FIMC_MAX_SENSORS 8
#define FIMC_MAX_CAMCLKS 2
+/* Maximum number of supported parallel video ports */
+#define FIMC_MAX_PARALLEL_PORTS 2
+/* Maximum number of pins per 8-bit parallel port */
+#define FIMC_MAX_PARALLEL_PORT_PINS 13
struct fimc_csis_info {
struct v4l2_subdev *sd;
@@ -58,8 +62,13 @@ struct fimc_sensor_info {
bool clk_on;
};
+struct fimc_video_port {
+ int gpios[FIMC_MAX_PARALLEL_PORT_PINS];
+};
+
/**
* struct fimc_md - fimc media device information
+ * @parallel_ports: parallel video ports data
* @csis: MIPI CSIS subdevs data
* @sensor: array of registered sensor subdevs
* @num_sensors: actual number of registered sensors
@@ -72,6 +81,7 @@ struct fimc_sensor_info {
* @slock: spinlock protecting @sensor array
*/
struct fimc_md {
+ struct fimc_video_port *parallel_ports;
struct fimc_csis_info csis[CSIS_MAX_ENTITIES];
struct fimc_sensor_info sensor[FIMC_MAX_SENSORS];
int num_sensors;
--
1.7.10
More information about the devicetree-discuss
mailing list