summaryrefslogtreecommitdiff
path: root/patches.tizen/0722-V4L-s5k6a3-Add-support-for-asynchronous-subdev-regis.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches.tizen/0722-V4L-s5k6a3-Add-support-for-asynchronous-subdev-regis.patch')
-rw-r--r--patches.tizen/0722-V4L-s5k6a3-Add-support-for-asynchronous-subdev-regis.patch135
1 files changed, 135 insertions, 0 deletions
diff --git a/patches.tizen/0722-V4L-s5k6a3-Add-support-for-asynchronous-subdev-regis.patch b/patches.tizen/0722-V4L-s5k6a3-Add-support-for-asynchronous-subdev-regis.patch
new file mode 100644
index 00000000000..23ab2f5c17d
--- /dev/null
+++ b/patches.tizen/0722-V4L-s5k6a3-Add-support-for-asynchronous-subdev-regis.patch
@@ -0,0 +1,135 @@
+From 0732dec259f2cbad0efc11ae6f39388264bf75c9 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 28 Aug 2013 13:41:03 +0200
+Subject: [PATCH 0722/1302] V4L: s5k6a3: Add support for asynchronous subdev
+ registration
+
+This patch converts the driver to use v4l2 asynchronous subdev
+registration API an the clock API to control the external master
+clock directly.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+---
+Changes since v2:
+ - fixed error paths in probe().
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/s5k6a3.c | 43 +++++++++++++++++++++++++++++++++----------
+ 1 file changed, 33 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c
+index ba86e24..113751b 100644
+--- a/drivers/media/i2c/s5k6a3.c
++++ b/drivers/media/i2c/s5k6a3.c
+@@ -34,6 +34,7 @@
+ #define S5K6A3_DEFAULT_HEIGHT 732
+
+ #define S5K6A3_DRV_NAME "S5K6A3"
++#define S5K6A3_CLK_NAME "extclk"
+ #define S5K6A3_DEFAULT_CLK_FREQ 24000000U
+
+ #define S5K6A3_NUM_SUPPLIES 2
+@@ -56,6 +57,7 @@ struct s5k6a3 {
+ int gpio_reset;
+ struct mutex lock;
+ struct v4l2_mbus_framefmt format;
++ struct clk *clock;
+ u32 clock_frequency;
+ };
+
+@@ -181,19 +183,25 @@ static int s5k6a3_s_power(struct v4l2_subdev *sd, int on)
+ {
+ struct s5k6a3 *sensor = sd_to_s5k6a3(sd);
+ int gpio = sensor->gpio_reset;
+- int ret;
++ int ret = 0;
+
+ if (on) {
++ ret = clk_set_rate(sensor->clock, sensor->clock_frequency);
++ if (ret < 0)
++ return ret;
++
+ ret = pm_runtime_get(sensor->dev);
+ if (ret < 0)
+ return ret;
+
+ ret = regulator_bulk_enable(S5K6A3_NUM_SUPPLIES,
+ sensor->supplies);
+- if (ret < 0) {
+- pm_runtime_put(sensor->dev);
+- return ret;
+- }
++ if (ret < 0)
++ goto rpm_put;
++
++ ret = clk_prepare_enable(sensor->clock);
++ if (ret < 0)
++ goto reg_dis;
+
+ if (gpio_is_valid(gpio)) {
+ gpio_set_value(gpio, 1);
+@@ -209,10 +217,12 @@ static int s5k6a3_s_power(struct v4l2_subdev *sd, int on)
+ if (gpio_is_valid(gpio))
+ gpio_set_value(gpio, 0);
+
+- ret = regulator_bulk_disable(S5K6A3_NUM_SUPPLIES,
+- sensor->supplies);
+- if (!ret)
+- pm_runtime_put(sensor->dev);
++ clk_disable_unprepare(sensor->clock);
++reg_dis:
++ regulator_bulk_disable(S5K6A3_NUM_SUPPLIES,
++ sensor->supplies);
++rpm_put:
++ pm_runtime_put(sensor->dev);
+ }
+ return ret;
+ }
+@@ -240,6 +250,7 @@ static int s5k6a3_probe(struct i2c_client *client,
+
+ mutex_init(&sensor->lock);
+ sensor->gpio_reset = -EINVAL;
++ sensor->clock = ERR_PTR(-EINVAL);
+ sensor->dev = dev;
+
+ gpio = of_get_gpio_flags(dev->of_node, 0, NULL);
+@@ -266,6 +277,10 @@ static int s5k6a3_probe(struct i2c_client *client,
+ if (ret < 0)
+ return ret;
+
++ sensor->clock = devm_clk_get(dev, S5K6A3_CLK_NAME);
++ if (IS_ERR(sensor->clock))
++ return -EPROBE_DEFER;
++
+ sd = &sensor->subdev;
+ v4l2_i2c_subdev_init(sd, client, &s5k6a3_subdev_ops);
+ sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+@@ -282,7 +297,14 @@ static int s5k6a3_probe(struct i2c_client *client,
+ pm_runtime_no_callbacks(dev);
+ pm_runtime_enable(dev);
+
+- return 0;
++ ret = v4l2_async_register_subdev(sd);
++
++ if (ret < 0) {
++ pm_runtime_disable(&client->dev);
++ media_entity_cleanup(&sd->entity);
++ }
++
++ return ret;
+ }
+
+ static int s5k6a3_remove(struct i2c_client *client)
+@@ -290,6 +312,7 @@ static int s5k6a3_remove(struct i2c_client *client)
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ pm_runtime_disable(&client->dev);
++ v4l2_async_unregister_subdev(sd);
+ media_entity_cleanup(&sd->entity);
+ return 0;
+ }
+--
+1.8.3.2
+