diff mbox

[v8,5/8] exynos4-is: Add support for v4l2-flash subdevs

Message ID 1432131015-22397-6-git-send-email-j.anaszewski@samsung.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jacek Anaszewski May 20, 2015, 2:10 p.m. UTC
This patch adds support for external v4l2-flash devices.
The support includes parsing "samsung,flash-led" DT property
and asynchronous subdevice registration.

Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 drivers/media/platform/exynos4-is/media-dev.c |   39 +++++++++++++++++++++++--
 drivers/media/platform/exynos4-is/media-dev.h |   13 ++++++++-
 2 files changed, 49 insertions(+), 3 deletions(-)

Comments

Sakari Ailus May 21, 2015, 7:46 a.m. UTC | #1
Hi Jacek,

On Wed, May 20, 2015 at 04:10:12PM +0200, Jacek Anaszewski wrote:
> This patch adds support for external v4l2-flash devices.
> The support includes parsing "samsung,flash-led" DT property
> and asynchronous subdevice registration.
> 
> Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> Cc: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  drivers/media/platform/exynos4-is/media-dev.c |   39 +++++++++++++++++++++++--
>  drivers/media/platform/exynos4-is/media-dev.h |   13 ++++++++-
>  2 files changed, 49 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
> index f315ef9..80cecd8 100644
> --- a/drivers/media/platform/exynos4-is/media-dev.c
> +++ b/drivers/media/platform/exynos4-is/media-dev.c
> @@ -451,6 +451,28 @@ rpm_put:
>  	return ret;
>  }
>  
> +static void fimc_md_register_flash_entities(struct fimc_md *fmd)
> +{
> +	int i;
> +
> +	fmd->num_flashes = 0;
> +
> +	for (i = 0; i < fmd->num_sensors; i++) {
> +		const struct device_node *np =
> +					fmd->sensor[i].asd.match.of.node;
> +		const int nf = fmd->num_flashes;
> +
> +		np = of_parse_phandle(np, "samsung,flash-led", 0);
> +		if (!np)
> +			continue;
> +
> +		fmd->flash[nf].asd.match_type = V4L2_ASYNC_MATCH_OF;
> +		fmd->flash[nf].asd.match.of.node = np;
> +		fmd->async_subdevs[fmd->num_sensors + nf] = &fmd->flash[nf].asd;
> +		fmd->num_flashes++;
> +	}
> +}
> +
>  static int __of_get_csis_id(struct device_node *np)
>  {
>  	u32 reg = 0;
> @@ -1275,6 +1297,15 @@ static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
>  	struct fimc_sensor_info *si = NULL;
>  	int i;
>  
> +	/* Register flash subdev if detected any */
> +	for (i = 0; i < ARRAY_SIZE(fmd->flash); i++) {
> +		if (fmd->flash[i].asd.match.of.node == subdev->of_node) {

Does the index of a particular sub-device index matter? Could you just use
the next available one?

There would be no need to for the check anything here, please see how the
omap3isp driver does it --- it's in isp_subdev_notifier_bound()
drivers/media/platform/omap3isp/isp.c .

> +			fmd->flash[i].subdev = subdev;
> +			fmd->num_flashes++;
> +			return 0;
> +		}
> +	}
> +
>  	/* Find platform data for this sensor subdev */
>  	for (i = 0; i < ARRAY_SIZE(fmd->sensor); i++)
>  		if (fmd->sensor[i].asd.match.of.node == subdev->dev->of_node)
Jacek Anaszewski May 21, 2015, 9:39 a.m. UTC | #2
On 05/21/2015 09:46 AM, Sakari Ailus wrote:
> Hi Jacek,
>
> On Wed, May 20, 2015 at 04:10:12PM +0200, Jacek Anaszewski wrote:
>> This patch adds support for external v4l2-flash devices.
>> The support includes parsing "samsung,flash-led" DT property
>> and asynchronous subdevice registration.
>>
>> Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
>> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
>> Cc: Sylwester Nawrocki <s.nawrocki@samsung.com>
>> ---
>>   drivers/media/platform/exynos4-is/media-dev.c |   39 +++++++++++++++++++++++--
>>   drivers/media/platform/exynos4-is/media-dev.h |   13 ++++++++-
>>   2 files changed, 49 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
>> index f315ef9..80cecd8 100644
>> --- a/drivers/media/platform/exynos4-is/media-dev.c
>> +++ b/drivers/media/platform/exynos4-is/media-dev.c
>> @@ -451,6 +451,28 @@ rpm_put:
>>   	return ret;
>>   }
>>
>> +static void fimc_md_register_flash_entities(struct fimc_md *fmd)
>> +{
>> +	int i;
>> +
>> +	fmd->num_flashes = 0;
>> +
>> +	for (i = 0; i < fmd->num_sensors; i++) {
>> +		const struct device_node *np =
>> +					fmd->sensor[i].asd.match.of.node;
>> +		const int nf = fmd->num_flashes;
>> +
>> +		np = of_parse_phandle(np, "samsung,flash-led", 0);
>> +		if (!np)
>> +			continue;
>> +
>> +		fmd->flash[nf].asd.match_type = V4L2_ASYNC_MATCH_OF;
>> +		fmd->flash[nf].asd.match.of.node = np;
>> +		fmd->async_subdevs[fmd->num_sensors + nf] = &fmd->flash[nf].asd;
>> +		fmd->num_flashes++;
>> +	}
>> +}
>> +
>>   static int __of_get_csis_id(struct device_node *np)
>>   {
>>   	u32 reg = 0;
>> @@ -1275,6 +1297,15 @@ static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
>>   	struct fimc_sensor_info *si = NULL;
>>   	int i;
>>
>> +	/* Register flash subdev if detected any */
>> +	for (i = 0; i < ARRAY_SIZE(fmd->flash); i++) {
>> +		if (fmd->flash[i].asd.match.of.node == subdev->of_node) {
>
> Does the index of a particular sub-device index matter? Could you just use
> the next available one?

Having the positions of sensor sub-devices kept in synch with
the positions of associated flash sub-devices in the 'flash' array
allows to avoid the addition o a condition for checking if the element
of the flash array is available.

> There would be no need to for the check anything here, please see how the
> omap3isp driver does it --- it's in isp_subdev_notifier_bound()
> drivers/media/platform/omap3isp/isp.c .

This 'for' loop allows to detect that the sub-device being bound
is of flash type and basing on that we can exit the function
at this point. Otherwise some guards would have to be added in
the remaining part of the function.

>> +			fmd->flash[i].subdev = subdev;
>> +			fmd->num_flashes++;
>> +			return 0;
>> +		}
>> +	}
>> +
>>   	/* Find platform data for this sensor subdev */
>>   	for (i = 0; i < ARRAY_SIZE(fmd->sensor); i++)
>>   		if (fmd->sensor[i].asd.match.of.node == subdev->dev->of_node)
>
Sakari Ailus May 21, 2015, 10:38 a.m. UTC | #3
Hi Jacek,

On Thu, May 21, 2015 at 11:39:35AM +0200, Jacek Anaszewski wrote:
> 
> 
> On 05/21/2015 09:46 AM, Sakari Ailus wrote:
> >Hi Jacek,
> >
> >On Wed, May 20, 2015 at 04:10:12PM +0200, Jacek Anaszewski wrote:
> >>This patch adds support for external v4l2-flash devices.
> >>The support includes parsing "samsung,flash-led" DT property
> >>and asynchronous subdevice registration.
> >>
> >>Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
> >>Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> >>Cc: Sylwester Nawrocki <s.nawrocki@samsung.com>
> >>---
> >>  drivers/media/platform/exynos4-is/media-dev.c |   39 +++++++++++++++++++++++--
> >>  drivers/media/platform/exynos4-is/media-dev.h |   13 ++++++++-
> >>  2 files changed, 49 insertions(+), 3 deletions(-)
> >>
> >>diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
> >>index f315ef9..80cecd8 100644
> >>--- a/drivers/media/platform/exynos4-is/media-dev.c
> >>+++ b/drivers/media/platform/exynos4-is/media-dev.c
> >>@@ -451,6 +451,28 @@ rpm_put:
> >>  	return ret;
> >>  }
> >>
> >>+static void fimc_md_register_flash_entities(struct fimc_md *fmd)
> >>+{
> >>+	int i;
> >>+
> >>+	fmd->num_flashes = 0;
> >>+
> >>+	for (i = 0; i < fmd->num_sensors; i++) {
> >>+		const struct device_node *np =
> >>+					fmd->sensor[i].asd.match.of.node;
> >>+		const int nf = fmd->num_flashes;
> >>+
> >>+		np = of_parse_phandle(np, "samsung,flash-led", 0);
> >>+		if (!np)
> >>+			continue;
> >>+
> >>+		fmd->flash[nf].asd.match_type = V4L2_ASYNC_MATCH_OF;
> >>+		fmd->flash[nf].asd.match.of.node = np;
> >>+		fmd->async_subdevs[fmd->num_sensors + nf] = &fmd->flash[nf].asd;
> >>+		fmd->num_flashes++;
> >>+	}
> >>+}
> >>+
> >>  static int __of_get_csis_id(struct device_node *np)
> >>  {
> >>  	u32 reg = 0;
> >>@@ -1275,6 +1297,15 @@ static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
> >>  	struct fimc_sensor_info *si = NULL;
> >>  	int i;
> >>
> >>+	/* Register flash subdev if detected any */
> >>+	for (i = 0; i < ARRAY_SIZE(fmd->flash); i++) {
> >>+		if (fmd->flash[i].asd.match.of.node == subdev->of_node) {
> >
> >Does the index of a particular sub-device index matter? Could you just use
> >the next available one?
> 
> Having the positions of sensor sub-devices kept in synch with
> the positions of associated flash sub-devices in the 'flash' array
> allows to avoid the addition o a condition for checking if the element
> of the flash array is available.
> 
> >There would be no need to for the check anything here, please see how the
> >omap3isp driver does it --- it's in isp_subdev_notifier_bound()
> >drivers/media/platform/omap3isp/isp.c .
> 
> This 'for' loop allows to detect that the sub-device being bound
> is of flash type and basing on that we can exit the function
> at this point. Otherwise some guards would have to be added in
> the remaining part of the function.

You have that information in fimc_md_register_flash_entities() but you're
not storing that. A common struct for all async sub-device would help. I
think you could associate sensors to flashes the same way.
diff mbox

Patch

diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index f315ef9..80cecd8 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -451,6 +451,28 @@  rpm_put:
 	return ret;
 }
 
+static void fimc_md_register_flash_entities(struct fimc_md *fmd)
+{
+	int i;
+
+	fmd->num_flashes = 0;
+
+	for (i = 0; i < fmd->num_sensors; i++) {
+		const struct device_node *np =
+					fmd->sensor[i].asd.match.of.node;
+		const int nf = fmd->num_flashes;
+
+		np = of_parse_phandle(np, "samsung,flash-led", 0);
+		if (!np)
+			continue;
+
+		fmd->flash[nf].asd.match_type = V4L2_ASYNC_MATCH_OF;
+		fmd->flash[nf].asd.match.of.node = np;
+		fmd->async_subdevs[fmd->num_sensors + nf] = &fmd->flash[nf].asd;
+		fmd->num_flashes++;
+	}
+}
+
 static int __of_get_csis_id(struct device_node *np)
 {
 	u32 reg = 0;
@@ -1275,6 +1297,15 @@  static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
 	struct fimc_sensor_info *si = NULL;
 	int i;
 
+	/* Register flash subdev if detected any */
+	for (i = 0; i < ARRAY_SIZE(fmd->flash); i++) {
+		if (fmd->flash[i].asd.match.of.node == subdev->of_node) {
+			fmd->flash[i].subdev = subdev;
+			fmd->num_flashes++;
+			return 0;
+		}
+	}
+
 	/* Find platform data for this sensor subdev */
 	for (i = 0; i < ARRAY_SIZE(fmd->sensor); i++)
 		if (fmd->sensor[i].asd.match.of.node == subdev->dev->of_node)
@@ -1385,6 +1416,8 @@  static int fimc_md_probe(struct platform_device *pdev)
 		goto err_m_ent;
 	}
 
+	fimc_md_register_flash_entities(fmd);
+
 	mutex_unlock(&fmd->media_dev.graph_mutex);
 
 	ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode);
@@ -1401,12 +1434,14 @@  static int fimc_md_probe(struct platform_device *pdev)
 		goto err_attr;
 	}
 
-	if (fmd->num_sensors > 0) {
+	if (fmd->num_sensors > 0 || fmd->num_flashes > 0) {
 		fmd->subdev_notifier.subdevs = fmd->async_subdevs;
-		fmd->subdev_notifier.num_subdevs = fmd->num_sensors;
+		fmd->subdev_notifier.num_subdevs = fmd->num_sensors +
+							fmd->num_flashes;
 		fmd->subdev_notifier.bound = subdev_notifier_bound;
 		fmd->subdev_notifier.complete = subdev_notifier_complete;
 		fmd->num_sensors = 0;
+		fmd->num_flashes = 0;
 
 		ret = v4l2_async_notifier_register(&fmd->v4l2_dev,
 						&fmd->subdev_notifier);
diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h
index 0321454..d4eed34 100644
--- a/drivers/media/platform/exynos4-is/media-dev.h
+++ b/drivers/media/platform/exynos4-is/media-dev.h
@@ -34,6 +34,8 @@ 
 
 #define FIMC_MAX_SENSORS	4
 #define FIMC_MAX_CAMCLKS	2
+#define FIMC_MAX_FLASHES	4
+#define FIMC_MAX_ASYNC_SUBDEVS (FIMC_MAX_SENSORS + FIMC_MAX_FLASHES)
 #define DEFAULT_SENSOR_CLK_FREQ	24000000U
 
 /* LCD/ISP Writeback clocks (PIXELASYNCMx) */
@@ -93,6 +95,11 @@  struct fimc_sensor_info {
 	struct fimc_dev *host;
 };
 
+struct fimc_flash_info {
+	struct v4l2_subdev *subdev;
+	struct v4l2_async_subdev asd;
+};
+
 struct cam_clk {
 	struct clk_hw hw;
 	struct fimc_md *fmd;
@@ -104,6 +111,8 @@  struct cam_clk {
  * @csis: MIPI CSIS subdevs data
  * @sensor: array of registered sensor subdevs
  * @num_sensors: actual number of registered sensors
+ * @flash: array of registered flash subdevs
+ * @num_flashes: actual number of registered flashes
  * @camclk: external sensor clock information
  * @fimc: array of registered fimc devices
  * @fimc_is: fimc-is data structure
@@ -123,6 +132,8 @@  struct fimc_md {
 	struct fimc_csis_info csis[CSIS_MAX_ENTITIES];
 	struct fimc_sensor_info sensor[FIMC_MAX_SENSORS];
 	int num_sensors;
+	struct fimc_flash_info flash[FIMC_MAX_FLASHES];
+	int num_flashes;
 	struct fimc_camclk_info camclk[FIMC_MAX_CAMCLKS];
 	struct clk *wbclk[FIMC_MAX_WBCLKS];
 	struct fimc_lite *fimc_lite[FIMC_LITE_MAX_DEVS];
@@ -149,7 +160,7 @@  struct fimc_md {
 	} clk_provider;
 
 	struct v4l2_async_notifier subdev_notifier;
-	struct v4l2_async_subdev *async_subdevs[FIMC_MAX_SENSORS];
+	struct v4l2_async_subdev *async_subdevs[FIMC_MAX_ASYNC_SUBDEVS];
 
 	bool user_subdev_api;
 	spinlock_t slock;