aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/i2c/soc_camera
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2012-12-21 11:01:55 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-06-21 15:32:36 -0400
commit9aea470b399d797e88be08985c489855759c6c60 (patch)
treecbcc6f1c80ee9da8b0da54e2d793f63e920527ee /drivers/media/i2c/soc_camera
parente9e310491bdbc8c0f33ea0e2ce65eff345a01f71 (diff)
[media] soc-camera: switch I2C subdevice drivers to use v4l2-clk
Instead of centrally enabling and disabling subdevice master clocks in soc-camera core, let subdevice drivers do that themselves, using the V4L2 clock API and soc-camera convenience wrappers. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Acked-by: Hans Verkuil <hans.verkuil@cisco.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/i2c/soc_camera')
-rw-r--r--drivers/media/i2c/soc_camera/imx074.c18
-rw-r--r--drivers/media/i2c/soc_camera/mt9m001.c17
-rw-r--r--drivers/media/i2c/soc_camera/mt9m111.c20
-rw-r--r--drivers/media/i2c/soc_camera/mt9t031.c19
-rw-r--r--drivers/media/i2c/soc_camera/mt9t112.c25
-rw-r--r--drivers/media/i2c/soc_camera/mt9v022.c17
-rw-r--r--drivers/media/i2c/soc_camera/ov2640.c19
-rw-r--r--drivers/media/i2c/soc_camera/ov5642.c20
-rw-r--r--drivers/media/i2c/soc_camera/ov6650.c17
-rw-r--r--drivers/media/i2c/soc_camera/ov772x.c15
-rw-r--r--drivers/media/i2c/soc_camera/ov9640.c17
-rw-r--r--drivers/media/i2c/soc_camera/ov9640.h1
-rw-r--r--drivers/media/i2c/soc_camera/ov9740.c18
-rw-r--r--drivers/media/i2c/soc_camera/rj54n1cb0c.c17
-rw-r--r--drivers/media/i2c/soc_camera/tw9910.c24
15 files changed, 228 insertions, 36 deletions
diff --git a/drivers/media/i2c/soc_camera/imx074.c b/drivers/media/i2c/soc_camera/imx074.c
index a315d4386c8e..2d8367891801 100644
--- a/drivers/media/i2c/soc_camera/imx074.c
+++ b/drivers/media/i2c/soc_camera/imx074.c
@@ -18,6 +18,7 @@
18#include <linux/module.h> 18#include <linux/module.h>
19 19
20#include <media/soc_camera.h> 20#include <media/soc_camera.h>
21#include <media/v4l2-clk.h>
21#include <media/v4l2-subdev.h> 22#include <media/v4l2-subdev.h>
22 23
23/* IMX074 registers */ 24/* IMX074 registers */
@@ -76,6 +77,7 @@ struct imx074_datafmt {
76struct imx074 { 77struct imx074 {
77 struct v4l2_subdev subdev; 78 struct v4l2_subdev subdev;
78 const struct imx074_datafmt *fmt; 79 const struct imx074_datafmt *fmt;
80 struct v4l2_clk *clk;
79}; 81};
80 82
81static const struct imx074_datafmt imx074_colour_fmts[] = { 83static const struct imx074_datafmt imx074_colour_fmts[] = {
@@ -254,8 +256,9 @@ static int imx074_s_power(struct v4l2_subdev *sd, int on)
254{ 256{
255 struct i2c_client *client = v4l2_get_subdevdata(sd); 257 struct i2c_client *client = v4l2_get_subdevdata(sd);
256 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 258 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
259 struct imx074 *priv = to_imx074(client);
257 260
258 return soc_camera_set_power(&client->dev, ssdd, on); 261 return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
259} 262}
260 263
261static int imx074_g_mbus_config(struct v4l2_subdev *sd, 264static int imx074_g_mbus_config(struct v4l2_subdev *sd,
@@ -412,6 +415,7 @@ static int imx074_probe(struct i2c_client *client,
412 struct imx074 *priv; 415 struct imx074 *priv;
413 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 416 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
414 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 417 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
418 int ret;
415 419
416 if (!ssdd) { 420 if (!ssdd) {
417 dev_err(&client->dev, "IMX074: missing platform data!\n"); 421 dev_err(&client->dev, "IMX074: missing platform data!\n");
@@ -432,13 +436,23 @@ static int imx074_probe(struct i2c_client *client,
432 436
433 priv->fmt = &imx074_colour_fmts[0]; 437 priv->fmt = &imx074_colour_fmts[0];
434 438
435 return imx074_video_probe(client); 439 priv->clk = v4l2_clk_get(&client->dev, "mclk");
440 if (IS_ERR(priv->clk))
441 return PTR_ERR(priv->clk);
442
443 ret = imx074_video_probe(client);
444 if (ret < 0)
445 v4l2_clk_put(priv->clk);
446
447 return ret;
436} 448}
437 449
438static int imx074_remove(struct i2c_client *client) 450static int imx074_remove(struct i2c_client *client)
439{ 451{
440 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 452 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
453 struct imx074 *priv = to_imx074(client);
441 454
455 v4l2_clk_put(priv->clk);
442 if (ssdd->free_bus) 456 if (ssdd->free_bus)
443 ssdd->free_bus(ssdd); 457 ssdd->free_bus(ssdd);
444 458
diff --git a/drivers/media/i2c/soc_camera/mt9m001.c b/drivers/media/i2c/soc_camera/mt9m001.c
index 3f1f437ee1c6..df97033fa6ef 100644
--- a/drivers/media/i2c/soc_camera/mt9m001.c
+++ b/drivers/media/i2c/soc_camera/mt9m001.c
@@ -16,6 +16,7 @@
16 16
17#include <media/soc_camera.h> 17#include <media/soc_camera.h>
18#include <media/soc_mediabus.h> 18#include <media/soc_mediabus.h>
19#include <media/v4l2-clk.h>
19#include <media/v4l2-subdev.h> 20#include <media/v4l2-subdev.h>
20#include <media/v4l2-ctrls.h> 21#include <media/v4l2-ctrls.h>
21 22
@@ -93,6 +94,7 @@ struct mt9m001 {
93 struct v4l2_ctrl *exposure; 94 struct v4l2_ctrl *exposure;
94 }; 95 };
95 struct v4l2_rect rect; /* Sensor window */ 96 struct v4l2_rect rect; /* Sensor window */
97 struct v4l2_clk *clk;
96 const struct mt9m001_datafmt *fmt; 98 const struct mt9m001_datafmt *fmt;
97 const struct mt9m001_datafmt *fmts; 99 const struct mt9m001_datafmt *fmts;
98 int num_fmts; 100 int num_fmts;
@@ -355,8 +357,9 @@ static int mt9m001_s_power(struct v4l2_subdev *sd, int on)
355{ 357{
356 struct i2c_client *client = v4l2_get_subdevdata(sd); 358 struct i2c_client *client = v4l2_get_subdevdata(sd);
357 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 359 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
360 struct mt9m001 *mt9m001 = to_mt9m001(client);
358 361
359 return soc_camera_set_power(&client->dev, ssdd, on); 362 return soc_camera_set_power(&client->dev, ssdd, mt9m001->clk, on);
360} 363}
361 364
362static int mt9m001_g_volatile_ctrl(struct v4l2_ctrl *ctrl) 365static int mt9m001_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
@@ -681,9 +684,18 @@ static int mt9m001_probe(struct i2c_client *client,
681 mt9m001->rect.width = MT9M001_MAX_WIDTH; 684 mt9m001->rect.width = MT9M001_MAX_WIDTH;
682 mt9m001->rect.height = MT9M001_MAX_HEIGHT; 685 mt9m001->rect.height = MT9M001_MAX_HEIGHT;
683 686
687 mt9m001->clk = v4l2_clk_get(&client->dev, "mclk");
688 if (IS_ERR(mt9m001->clk)) {
689 ret = PTR_ERR(mt9m001->clk);
690 goto eclkget;
691 }
692
684 ret = mt9m001_video_probe(ssdd, client); 693 ret = mt9m001_video_probe(ssdd, client);
685 if (ret) 694 if (ret) {
695 v4l2_clk_put(mt9m001->clk);
696eclkget:
686 v4l2_ctrl_handler_free(&mt9m001->hdl); 697 v4l2_ctrl_handler_free(&mt9m001->hdl);
698 }
687 699
688 return ret; 700 return ret;
689} 701}
@@ -693,6 +705,7 @@ static int mt9m001_remove(struct i2c_client *client)
693 struct mt9m001 *mt9m001 = to_mt9m001(client); 705 struct mt9m001 *mt9m001 = to_mt9m001(client);
694 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 706 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
695 707
708 v4l2_clk_put(mt9m001->clk);
696 v4l2_device_unregister_subdev(&mt9m001->subdev); 709 v4l2_device_unregister_subdev(&mt9m001->subdev);
697 v4l2_ctrl_handler_free(&mt9m001->hdl); 710 v4l2_ctrl_handler_free(&mt9m001->hdl);
698 mt9m001_video_remove(ssdd); 711 mt9m001_video_remove(ssdd);
diff --git a/drivers/media/i2c/soc_camera/mt9m111.c b/drivers/media/i2c/soc_camera/mt9m111.c
index 1aaca0423df7..de3605df47c5 100644
--- a/drivers/media/i2c/soc_camera/mt9m111.c
+++ b/drivers/media/i2c/soc_camera/mt9m111.c
@@ -17,6 +17,7 @@
17#include <linux/module.h> 17#include <linux/module.h>
18 18
19#include <media/soc_camera.h> 19#include <media/soc_camera.h>
20#include <media/v4l2-clk.h>
20#include <media/v4l2-common.h> 21#include <media/v4l2-common.h>
21#include <media/v4l2-ctrls.h> 22#include <media/v4l2-ctrls.h>
22 23
@@ -206,6 +207,7 @@ struct mt9m111 {
206 struct v4l2_ctrl *gain; 207 struct v4l2_ctrl *gain;
207 struct mt9m111_context *ctx; 208 struct mt9m111_context *ctx;
208 struct v4l2_rect rect; /* cropping rectangle */ 209 struct v4l2_rect rect; /* cropping rectangle */
210 struct v4l2_clk *clk;
209 int width; /* output */ 211 int width; /* output */
210 int height; /* sizes */ 212 int height; /* sizes */
211 struct mutex power_lock; /* lock to protect power_count */ 213 struct mutex power_lock; /* lock to protect power_count */
@@ -775,14 +777,14 @@ static int mt9m111_power_on(struct mt9m111 *mt9m111)
775 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 777 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
776 int ret; 778 int ret;
777 779
778 ret = soc_camera_power_on(&client->dev, ssdd); 780 ret = soc_camera_power_on(&client->dev, ssdd, mt9m111->clk);
779 if (ret < 0) 781 if (ret < 0)
780 return ret; 782 return ret;
781 783
782 ret = mt9m111_resume(mt9m111); 784 ret = mt9m111_resume(mt9m111);
783 if (ret < 0) { 785 if (ret < 0) {
784 dev_err(&client->dev, "Failed to resume the sensor: %d\n", ret); 786 dev_err(&client->dev, "Failed to resume the sensor: %d\n", ret);
785 soc_camera_power_off(&client->dev, ssdd); 787 soc_camera_power_off(&client->dev, ssdd, mt9m111->clk);
786 } 788 }
787 789
788 return ret; 790 return ret;
@@ -794,7 +796,7 @@ static void mt9m111_power_off(struct mt9m111 *mt9m111)
794 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 796 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
795 797
796 mt9m111_suspend(mt9m111); 798 mt9m111_suspend(mt9m111);
797 soc_camera_power_off(&client->dev, ssdd); 799 soc_camera_power_off(&client->dev, ssdd, mt9m111->clk);
798} 800}
799 801
800static int mt9m111_s_power(struct v4l2_subdev *sd, int on) 802static int mt9m111_s_power(struct v4l2_subdev *sd, int on)
@@ -973,9 +975,18 @@ static int mt9m111_probe(struct i2c_client *client,
973 mt9m111->lastpage = -1; 975 mt9m111->lastpage = -1;
974 mutex_init(&mt9m111->power_lock); 976 mutex_init(&mt9m111->power_lock);
975 977
978 mt9m111->clk = v4l2_clk_get(&client->dev, "mclk");
979 if (IS_ERR(mt9m111->clk)) {
980 ret = PTR_ERR(mt9m111->clk);
981 goto eclkget;
982 }
983
976 ret = mt9m111_video_probe(client); 984 ret = mt9m111_video_probe(client);
977 if (ret) 985 if (ret) {
986 v4l2_clk_put(mt9m111->clk);
987eclkget:
978 v4l2_ctrl_handler_free(&mt9m111->hdl); 988 v4l2_ctrl_handler_free(&mt9m111->hdl);
989 }
979 990
980 return ret; 991 return ret;
981} 992}
@@ -984,6 +995,7 @@ static int mt9m111_remove(struct i2c_client *client)
984{ 995{
985 struct mt9m111 *mt9m111 = to_mt9m111(client); 996 struct mt9m111 *mt9m111 = to_mt9m111(client);
986 997
998 v4l2_clk_put(mt9m111->clk);
987 v4l2_device_unregister_subdev(&mt9m111->subdev); 999 v4l2_device_unregister_subdev(&mt9m111->subdev);
988 v4l2_ctrl_handler_free(&mt9m111->hdl); 1000 v4l2_ctrl_handler_free(&mt9m111->hdl);
989 1001
diff --git a/drivers/media/i2c/soc_camera/mt9t031.c b/drivers/media/i2c/soc_camera/mt9t031.c
index b3dfeb6d1037..47d18d0bafe7 100644
--- a/drivers/media/i2c/soc_camera/mt9t031.c
+++ b/drivers/media/i2c/soc_camera/mt9t031.c
@@ -18,6 +18,7 @@
18#include <linux/module.h> 18#include <linux/module.h>
19 19
20#include <media/soc_camera.h> 20#include <media/soc_camera.h>
21#include <media/v4l2-clk.h>
21#include <media/v4l2-subdev.h> 22#include <media/v4l2-subdev.h>
22#include <media/v4l2-ctrls.h> 23#include <media/v4l2-ctrls.h>
23 24
@@ -75,6 +76,7 @@ struct mt9t031 {
75 struct v4l2_ctrl *exposure; 76 struct v4l2_ctrl *exposure;
76 }; 77 };
77 struct v4l2_rect rect; /* Sensor window */ 78 struct v4l2_rect rect; /* Sensor window */
79 struct v4l2_clk *clk;
78 u16 xskip; 80 u16 xskip;
79 u16 yskip; 81 u16 yskip;
80 unsigned int total_h; 82 unsigned int total_h;
@@ -585,16 +587,17 @@ static int mt9t031_s_power(struct v4l2_subdev *sd, int on)
585 struct i2c_client *client = v4l2_get_subdevdata(sd); 587 struct i2c_client *client = v4l2_get_subdevdata(sd);
586 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 588 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
587 struct video_device *vdev = soc_camera_i2c_to_vdev(client); 589 struct video_device *vdev = soc_camera_i2c_to_vdev(client);
590 struct mt9t031 *mt9t031 = to_mt9t031(client);
588 int ret; 591 int ret;
589 592
590 if (on) { 593 if (on) {
591 ret = soc_camera_power_on(&client->dev, ssdd); 594 ret = soc_camera_power_on(&client->dev, ssdd, mt9t031->clk);
592 if (ret < 0) 595 if (ret < 0)
593 return ret; 596 return ret;
594 vdev->dev.type = &mt9t031_dev_type; 597 vdev->dev.type = &mt9t031_dev_type;
595 } else { 598 } else {
596 vdev->dev.type = NULL; 599 vdev->dev.type = NULL;
597 soc_camera_power_off(&client->dev, ssdd); 600 soc_camera_power_off(&client->dev, ssdd, mt9t031->clk);
598 } 601 }
599 602
600 return 0; 603 return 0;
@@ -785,9 +788,18 @@ static int mt9t031_probe(struct i2c_client *client,
785 mt9t031->xskip = 1; 788 mt9t031->xskip = 1;
786 mt9t031->yskip = 1; 789 mt9t031->yskip = 1;
787 790
791 mt9t031->clk = v4l2_clk_get(&client->dev, "mclk");
792 if (IS_ERR(mt9t031->clk)) {
793 ret = PTR_ERR(mt9t031->clk);
794 goto eclkget;
795 }
796
788 ret = mt9t031_video_probe(client); 797 ret = mt9t031_video_probe(client);
789 if (ret) 798 if (ret) {
799 v4l2_clk_put(mt9t031->clk);
800eclkget:
790 v4l2_ctrl_handler_free(&mt9t031->hdl); 801 v4l2_ctrl_handler_free(&mt9t031->hdl);
802 }
791 803
792 return ret; 804 return ret;
793} 805}
@@ -796,6 +808,7 @@ static int mt9t031_remove(struct i2c_client *client)
796{ 808{
797 struct mt9t031 *mt9t031 = to_mt9t031(client); 809 struct mt9t031 *mt9t031 = to_mt9t031(client);
798 810
811 v4l2_clk_put(mt9t031->clk);
799 v4l2_device_unregister_subdev(&mt9t031->subdev); 812 v4l2_device_unregister_subdev(&mt9t031->subdev);
800 v4l2_ctrl_handler_free(&mt9t031->hdl); 813 v4l2_ctrl_handler_free(&mt9t031->hdl);
801 814
diff --git a/drivers/media/i2c/soc_camera/mt9t112.c b/drivers/media/i2c/soc_camera/mt9t112.c
index 9b276dde5ac8..46f431a13782 100644
--- a/drivers/media/i2c/soc_camera/mt9t112.c
+++ b/drivers/media/i2c/soc_camera/mt9t112.c
@@ -27,6 +27,7 @@
27 27
28#include <media/mt9t112.h> 28#include <media/mt9t112.h>
29#include <media/soc_camera.h> 29#include <media/soc_camera.h>
30#include <media/v4l2-clk.h>
30#include <media/v4l2-common.h> 31#include <media/v4l2-common.h>
31 32
32/* you can check PLL/clock info */ 33/* you can check PLL/clock info */
@@ -89,6 +90,7 @@ struct mt9t112_priv {
89 struct mt9t112_camera_info *info; 90 struct mt9t112_camera_info *info;
90 struct i2c_client *client; 91 struct i2c_client *client;
91 struct v4l2_rect frame; 92 struct v4l2_rect frame;
93 struct v4l2_clk *clk;
92 const struct mt9t112_format *format; 94 const struct mt9t112_format *format;
93 int num_formats; 95 int num_formats;
94 u32 flags; 96 u32 flags;
@@ -768,8 +770,9 @@ static int mt9t112_s_power(struct v4l2_subdev *sd, int on)
768{ 770{
769 struct i2c_client *client = v4l2_get_subdevdata(sd); 771 struct i2c_client *client = v4l2_get_subdevdata(sd);
770 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 772 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
773 struct mt9t112_priv *priv = to_mt9t112(client);
771 774
772 return soc_camera_set_power(&client->dev, ssdd, on); 775 return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
773} 776}
774 777
775static struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = { 778static struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = {
@@ -1092,16 +1095,29 @@ static int mt9t112_probe(struct i2c_client *client,
1092 1095
1093 v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops); 1096 v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops);
1094 1097
1098 priv->clk = v4l2_clk_get(&client->dev, "mclk");
1099 if (IS_ERR(priv->clk))
1100 return PTR_ERR(priv->clk);
1101
1095 ret = mt9t112_camera_probe(client); 1102 ret = mt9t112_camera_probe(client);
1096 if (ret)
1097 return ret;
1098 1103
1099 /* Cannot fail: using the default supported pixel code */ 1104 /* Cannot fail: using the default supported pixel code */
1100 mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8); 1105 if (!ret)
1106 mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8);
1107 else
1108 v4l2_clk_put(priv->clk);
1101 1109
1102 return ret; 1110 return ret;
1103} 1111}
1104 1112
1113static int mt9t112_remove(struct i2c_client *client)
1114{
1115 struct mt9t112_priv *priv = to_mt9t112(client);
1116
1117 v4l2_clk_put(priv->clk);
1118 return 0;
1119}
1120
1105static const struct i2c_device_id mt9t112_id[] = { 1121static const struct i2c_device_id mt9t112_id[] = {
1106 { "mt9t112", 0 }, 1122 { "mt9t112", 0 },
1107 { } 1123 { }
@@ -1113,6 +1129,7 @@ static struct i2c_driver mt9t112_i2c_driver = {
1113 .name = "mt9t112", 1129 .name = "mt9t112",
1114 }, 1130 },
1115 .probe = mt9t112_probe, 1131 .probe = mt9t112_probe,
1132 .remove = mt9t112_remove,
1116 .id_table = mt9t112_id, 1133 .id_table = mt9t112_id,
1117}; 1134};
1118 1135
diff --git a/drivers/media/i2c/soc_camera/mt9v022.c b/drivers/media/i2c/soc_camera/mt9v022.c
index 41ff4535eb0d..f9f95f815b1a 100644
--- a/drivers/media/i2c/soc_camera/mt9v022.c
+++ b/drivers/media/i2c/soc_camera/mt9v022.c
@@ -19,6 +19,7 @@
19#include <media/soc_camera.h> 19#include <media/soc_camera.h>
20#include <media/soc_mediabus.h> 20#include <media/soc_mediabus.h>
21#include <media/v4l2-subdev.h> 21#include <media/v4l2-subdev.h>
22#include <media/v4l2-clk.h>
22#include <media/v4l2-ctrls.h> 23#include <media/v4l2-ctrls.h>
23 24
24/* 25/*
@@ -153,6 +154,7 @@ struct mt9v022 {
153 struct v4l2_ctrl *hblank; 154 struct v4l2_ctrl *hblank;
154 struct v4l2_ctrl *vblank; 155 struct v4l2_ctrl *vblank;
155 struct v4l2_rect rect; /* Sensor window */ 156 struct v4l2_rect rect; /* Sensor window */
157 struct v4l2_clk *clk;
156 const struct mt9v022_datafmt *fmt; 158 const struct mt9v022_datafmt *fmt;
157 const struct mt9v022_datafmt *fmts; 159 const struct mt9v022_datafmt *fmts;
158 const struct mt9v02x_register *reg; 160 const struct mt9v02x_register *reg;
@@ -498,8 +500,9 @@ static int mt9v022_s_power(struct v4l2_subdev *sd, int on)
498{ 500{
499 struct i2c_client *client = v4l2_get_subdevdata(sd); 501 struct i2c_client *client = v4l2_get_subdevdata(sd);
500 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 502 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
503 struct mt9v022 *mt9v022 = to_mt9v022(client);
501 504
502 return soc_camera_set_power(&client->dev, ssdd, on); 505 return soc_camera_set_power(&client->dev, ssdd, mt9v022->clk, on);
503} 506}
504 507
505static int mt9v022_g_volatile_ctrl(struct v4l2_ctrl *ctrl) 508static int mt9v022_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
@@ -936,9 +939,18 @@ static int mt9v022_probe(struct i2c_client *client,
936 mt9v022->rect.width = MT9V022_MAX_WIDTH; 939 mt9v022->rect.width = MT9V022_MAX_WIDTH;
937 mt9v022->rect.height = MT9V022_MAX_HEIGHT; 940 mt9v022->rect.height = MT9V022_MAX_HEIGHT;
938 941
942 mt9v022->clk = v4l2_clk_get(&client->dev, "mclk");
943 if (IS_ERR(mt9v022->clk)) {
944 ret = PTR_ERR(mt9v022->clk);
945 goto eclkget;
946 }
947
939 ret = mt9v022_video_probe(client); 948 ret = mt9v022_video_probe(client);
940 if (ret) 949 if (ret) {
950 v4l2_clk_put(mt9v022->clk);
951eclkget:
941 v4l2_ctrl_handler_free(&mt9v022->hdl); 952 v4l2_ctrl_handler_free(&mt9v022->hdl);
953 }
942 954
943 return ret; 955 return ret;
944} 956}
@@ -948,6 +960,7 @@ static int mt9v022_remove(struct i2c_client *client)
948 struct mt9v022 *mt9v022 = to_mt9v022(client); 960 struct mt9v022 *mt9v022 = to_mt9v022(client);
949 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 961 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
950 962
963 v4l2_clk_put(mt9v022->clk);
951 v4l2_device_unregister_subdev(&mt9v022->subdev); 964 v4l2_device_unregister_subdev(&mt9v022->subdev);
952 if (ssdd->free_bus) 965 if (ssdd->free_bus)
953 ssdd->free_bus(ssdd); 966 ssdd->free_bus(ssdd);
diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/soc_camera/ov2640.c
index 7961cba6880a..6c6b1c3b45e3 100644
--- a/drivers/media/i2c/soc_camera/ov2640.c
+++ b/drivers/media/i2c/soc_camera/ov2640.c
@@ -22,6 +22,7 @@
22#include <linux/videodev2.h> 22#include <linux/videodev2.h>
23 23
24#include <media/soc_camera.h> 24#include <media/soc_camera.h>
25#include <media/v4l2-clk.h>
25#include <media/v4l2-subdev.h> 26#include <media/v4l2-subdev.h>
26#include <media/v4l2-ctrls.h> 27#include <media/v4l2-ctrls.h>
27 28
@@ -302,6 +303,7 @@ struct ov2640_priv {
302 struct v4l2_subdev subdev; 303 struct v4l2_subdev subdev;
303 struct v4l2_ctrl_handler hdl; 304 struct v4l2_ctrl_handler hdl;
304 enum v4l2_mbus_pixelcode cfmt_code; 305 enum v4l2_mbus_pixelcode cfmt_code;
306 struct v4l2_clk *clk;
305 const struct ov2640_win_size *win; 307 const struct ov2640_win_size *win;
306}; 308};
307 309
@@ -758,8 +760,9 @@ static int ov2640_s_power(struct v4l2_subdev *sd, int on)
758{ 760{
759 struct i2c_client *client = v4l2_get_subdevdata(sd); 761 struct i2c_client *client = v4l2_get_subdevdata(sd);
760 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 762 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
763 struct ov2640_priv *priv = to_ov2640(client);
761 764
762 return soc_camera_set_power(&client->dev, ssdd, on); 765 return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
763} 766}
764 767
765/* Select the nearest higher resolution for capture */ 768/* Select the nearest higher resolution for capture */
@@ -1097,11 +1100,20 @@ static int ov2640_probe(struct i2c_client *client,
1097 if (priv->hdl.error) 1100 if (priv->hdl.error)
1098 return priv->hdl.error; 1101 return priv->hdl.error;
1099 1102
1103 priv->clk = v4l2_clk_get(&client->dev, "mclk");
1104 if (IS_ERR(priv->clk)) {
1105 ret = PTR_ERR(priv->clk);
1106 goto eclkget;
1107 }
1108
1100 ret = ov2640_video_probe(client); 1109 ret = ov2640_video_probe(client);
1101 if (ret) 1110 if (ret) {
1111 v4l2_clk_put(priv->clk);
1112eclkget:
1102 v4l2_ctrl_handler_free(&priv->hdl); 1113 v4l2_ctrl_handler_free(&priv->hdl);
1103 else 1114 } else {
1104 dev_info(&adapter->dev, "OV2640 Probed\n"); 1115 dev_info(&adapter->dev, "OV2640 Probed\n");
1116 }
1105 1117
1106 return ret; 1118 return ret;
1107} 1119}
@@ -1110,6 +1122,7 @@ static int ov2640_remove(struct i2c_client *client)
1110{ 1122{
1111 struct ov2640_priv *priv = to_ov2640(client); 1123 struct ov2640_priv *priv = to_ov2640(client);
1112 1124
1125 v4l2_clk_put(priv->clk);
1113 v4l2_device_unregister_subdev(&priv->subdev); 1126 v4l2_device_unregister_subdev(&priv->subdev);
1114 v4l2_ctrl_handler_free(&priv->hdl); 1127 v4l2_ctrl_handler_free(&priv->hdl);
1115 return 0; 1128 return 0;
diff --git a/drivers/media/i2c/soc_camera/ov5642.c b/drivers/media/i2c/soc_camera/ov5642.c
index c93a157d1d93..0a5c5d4fedd6 100644
--- a/drivers/media/i2c/soc_camera/ov5642.c
+++ b/drivers/media/i2c/soc_camera/ov5642.c
@@ -24,6 +24,7 @@
24#include <linux/v4l2-mediabus.h> 24#include <linux/v4l2-mediabus.h>
25 25
26#include <media/soc_camera.h> 26#include <media/soc_camera.h>
27#include <media/v4l2-clk.h>
27#include <media/v4l2-subdev.h> 28#include <media/v4l2-subdev.h>
28 29
29/* OV5642 registers */ 30/* OV5642 registers */
@@ -609,6 +610,7 @@ struct ov5642 {
609 struct v4l2_subdev subdev; 610 struct v4l2_subdev subdev;
610 const struct ov5642_datafmt *fmt; 611 const struct ov5642_datafmt *fmt;
611 struct v4l2_rect crop_rect; 612 struct v4l2_rect crop_rect;
613 struct v4l2_clk *clk;
612 614
613 /* blanking information */ 615 /* blanking information */
614 int total_width; 616 int total_width;
@@ -917,12 +919,13 @@ static int ov5642_s_power(struct v4l2_subdev *sd, int on)
917{ 919{
918 struct i2c_client *client = v4l2_get_subdevdata(sd); 920 struct i2c_client *client = v4l2_get_subdevdata(sd);
919 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 921 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
922 struct ov5642 *priv = to_ov5642(client);
920 int ret; 923 int ret;
921 924
922 if (!on) 925 if (!on)
923 return soc_camera_power_off(&client->dev, ssdd); 926 return soc_camera_power_off(&client->dev, ssdd, priv->clk);
924 927
925 ret = soc_camera_power_on(&client->dev, ssdd); 928 ret = soc_camera_power_on(&client->dev, ssdd, priv->clk);
926 if (ret < 0) 929 if (ret < 0)
927 return ret; 930 return ret;
928 931
@@ -1002,6 +1005,7 @@ static int ov5642_probe(struct i2c_client *client,
1002{ 1005{
1003 struct ov5642 *priv; 1006 struct ov5642 *priv;
1004 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 1007 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
1008 int ret;
1005 1009
1006 if (!ssdd) { 1010 if (!ssdd) {
1007 dev_err(&client->dev, "OV5642: missing platform data!\n"); 1011 dev_err(&client->dev, "OV5642: missing platform data!\n");
@@ -1023,13 +1027,23 @@ static int ov5642_probe(struct i2c_client *client,
1023 priv->total_width = OV5642_DEFAULT_WIDTH + BLANKING_EXTRA_WIDTH; 1027 priv->total_width = OV5642_DEFAULT_WIDTH + BLANKING_EXTRA_WIDTH;
1024 priv->total_height = BLANKING_MIN_HEIGHT; 1028 priv->total_height = BLANKING_MIN_HEIGHT;
1025 1029
1026 return ov5642_video_probe(client); 1030 priv->clk = v4l2_clk_get(&client->dev, "mclk");
1031 if (IS_ERR(priv->clk))
1032 return PTR_ERR(priv->clk);
1033
1034 ret = ov5642_video_probe(client);
1035 if (ret < 0)
1036 v4l2_clk_put(priv->clk);
1037
1038 return ret;
1027} 1039}
1028 1040
1029static int ov5642_remove(struct i2c_client *client) 1041static int ov5642_remove(struct i2c_client *client)
1030{ 1042{
1031 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 1043 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
1044 struct ov5642 *priv = to_ov5642(client);
1032 1045
1046 v4l2_clk_put(priv->clk);
1033 if (ssdd->free_bus) 1047 if (ssdd->free_bus)
1034 ssdd->free_bus(ssdd); 1048 ssdd->free_bus(ssdd);
1035 1049
diff --git a/drivers/media/i2c/soc_camera/ov6650.c b/drivers/media/i2c/soc_camera/ov6650.c
index d2869d87d3b1..ab01598ec83f 100644
--- a/drivers/media/i2c/soc_camera/ov6650.c
+++ b/drivers/media/i2c/soc_camera/ov6650.c
@@ -32,6 +32,7 @@
32#include <linux/module.h> 32#include <linux/module.h>
33 33
34#include <media/soc_camera.h> 34#include <media/soc_camera.h>
35#include <media/v4l2-clk.h>
35#include <media/v4l2-ctrls.h> 36#include <media/v4l2-ctrls.h>
36 37
37/* Register definitions */ 38/* Register definitions */
@@ -195,6 +196,7 @@ struct ov6650 {
195 struct v4l2_ctrl *blue; 196 struct v4l2_ctrl *blue;
196 struct v4l2_ctrl *red; 197 struct v4l2_ctrl *red;
197 }; 198 };
199 struct v4l2_clk *clk;
198 bool half_scale; /* scale down output by 2 */ 200 bool half_scale; /* scale down output by 2 */
199 struct v4l2_rect rect; /* sensor cropping window */ 201 struct v4l2_rect rect; /* sensor cropping window */
200 unsigned long pclk_limit; /* from host */ 202 unsigned long pclk_limit; /* from host */
@@ -425,8 +427,9 @@ static int ov6650_s_power(struct v4l2_subdev *sd, int on)
425{ 427{
426 struct i2c_client *client = v4l2_get_subdevdata(sd); 428 struct i2c_client *client = v4l2_get_subdevdata(sd);
427 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 429 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
430 struct ov6650 *priv = to_ov6650(client);
428 431
429 return soc_camera_set_power(&client->dev, ssdd, on); 432 return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
430} 433}
431 434
432static int ov6650_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 435static int ov6650_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
@@ -1013,9 +1016,18 @@ static int ov6650_probe(struct i2c_client *client,
1013 priv->code = V4L2_MBUS_FMT_YUYV8_2X8; 1016 priv->code = V4L2_MBUS_FMT_YUYV8_2X8;
1014 priv->colorspace = V4L2_COLORSPACE_JPEG; 1017 priv->colorspace = V4L2_COLORSPACE_JPEG;
1015 1018
1019 priv->clk = v4l2_clk_get(&client->dev, "mclk");
1020 if (IS_ERR(priv->clk)) {
1021 ret = PTR_ERR(priv->clk);
1022 goto eclkget;
1023 }
1024
1016 ret = ov6650_video_probe(client); 1025 ret = ov6650_video_probe(client);
1017 if (ret) 1026 if (ret) {
1027 v4l2_clk_put(priv->clk);
1028eclkget:
1018 v4l2_ctrl_handler_free(&priv->hdl); 1029 v4l2_ctrl_handler_free(&priv->hdl);
1030 }
1019 1031
1020 return ret; 1032 return ret;
1021} 1033}
@@ -1024,6 +1036,7 @@ static int ov6650_remove(struct i2c_client *client)
1024{ 1036{
1025 struct ov6650 *priv = to_ov6650(client); 1037 struct ov6650 *priv = to_ov6650(client);
1026 1038
1039 v4l2_clk_put(priv->clk);
1027 v4l2_device_unregister_subdev(&priv->subdev); 1040 v4l2_device_unregister_subdev(&priv->subdev);
1028 v4l2_ctrl_handler_free(&priv->hdl); 1041 v4l2_ctrl_handler_free(&priv->hdl);
1029 return 0; 1042 return 0;
diff --git a/drivers/media/i2c/soc_camera/ov772x.c b/drivers/media/i2c/soc_camera/ov772x.c
index b2f623603986..7f2b3c8926af 100644
--- a/drivers/media/i2c/soc_camera/ov772x.c
+++ b/drivers/media/i2c/soc_camera/ov772x.c
@@ -26,6 +26,7 @@
26 26
27#include <media/ov772x.h> 27#include <media/ov772x.h>
28#include <media/soc_camera.h> 28#include <media/soc_camera.h>
29#include <media/v4l2-clk.h>
29#include <media/v4l2-ctrls.h> 30#include <media/v4l2-ctrls.h>
30#include <media/v4l2-subdev.h> 31#include <media/v4l2-subdev.h>
31 32
@@ -395,6 +396,7 @@ struct ov772x_win_size {
395struct ov772x_priv { 396struct ov772x_priv {
396 struct v4l2_subdev subdev; 397 struct v4l2_subdev subdev;
397 struct v4l2_ctrl_handler hdl; 398 struct v4l2_ctrl_handler hdl;
399 struct v4l2_clk *clk;
398 struct ov772x_camera_info *info; 400 struct ov772x_camera_info *info;
399 const struct ov772x_color_format *cfmt; 401 const struct ov772x_color_format *cfmt;
400 const struct ov772x_win_size *win; 402 const struct ov772x_win_size *win;
@@ -655,8 +657,9 @@ static int ov772x_s_power(struct v4l2_subdev *sd, int on)
655{ 657{
656 struct i2c_client *client = v4l2_get_subdevdata(sd); 658 struct i2c_client *client = v4l2_get_subdevdata(sd);
657 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 659 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
660 struct ov772x_priv *priv = to_ov772x(sd);
658 661
659 return soc_camera_set_power(&client->dev, ssdd, on); 662 return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
660} 663}
661 664
662static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height) 665static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height)
@@ -1072,13 +1075,22 @@ static int ov772x_probe(struct i2c_client *client,
1072 if (priv->hdl.error) 1075 if (priv->hdl.error)
1073 return priv->hdl.error; 1076 return priv->hdl.error;
1074 1077
1078 priv->clk = v4l2_clk_get(&client->dev, "mclk");
1079 if (IS_ERR(priv->clk)) {
1080 ret = PTR_ERR(priv->clk);
1081 goto eclkget;
1082 }
1083
1075 ret = ov772x_video_probe(priv); 1084 ret = ov772x_video_probe(priv);
1076 if (ret < 0) { 1085 if (ret < 0) {
1086 v4l2_clk_put(priv->clk);
1087eclkget:
1077 v4l2_ctrl_handler_free(&priv->hdl); 1088 v4l2_ctrl_handler_free(&priv->hdl);
1078 } else { 1089 } else {
1079 priv->cfmt = &ov772x_cfmts[0]; 1090 priv->cfmt = &ov772x_cfmts[0];
1080 priv->win = &ov772x_win_sizes[0]; 1091 priv->win = &ov772x_win_sizes[0];
1081 } 1092 }
1093
1082 return ret; 1094 return ret;
1083} 1095}
1084 1096
@@ -1086,6 +1098,7 @@ static int ov772x_remove(struct i2c_client *client)
1086{ 1098{
1087 struct ov772x_priv *priv = to_ov772x(i2c_get_clientdata(client)); 1099 struct ov772x_priv *priv = to_ov772x(i2c_get_clientdata(client));
1088 1100
1101 v4l2_clk_put(priv->clk);
1089 v4l2_device_unregister_subdev(&priv->subdev); 1102 v4l2_device_unregister_subdev(&priv->subdev);
1090 v4l2_ctrl_handler_free(&priv->hdl); 1103 v4l2_ctrl_handler_free(&priv->hdl);
1091 return 0; 1104 return 0;
diff --git a/drivers/media/i2c/soc_camera/ov9640.c b/drivers/media/i2c/soc_camera/ov9640.c
index 7d1f10f301d3..e968c3fdbd9e 100644
--- a/drivers/media/i2c/soc_camera/ov9640.c
+++ b/drivers/media/i2c/soc_camera/ov9640.c
@@ -28,6 +28,7 @@
28#include <linux/videodev2.h> 28#include <linux/videodev2.h>
29 29
30#include <media/soc_camera.h> 30#include <media/soc_camera.h>
31#include <media/v4l2-clk.h>
31#include <media/v4l2-common.h> 32#include <media/v4l2-common.h>
32#include <media/v4l2-ctrls.h> 33#include <media/v4l2-ctrls.h>
33 34
@@ -324,8 +325,9 @@ static int ov9640_s_power(struct v4l2_subdev *sd, int on)
324{ 325{
325 struct i2c_client *client = v4l2_get_subdevdata(sd); 326 struct i2c_client *client = v4l2_get_subdevdata(sd);
326 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 327 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
328 struct ov9640_priv *priv = to_ov9640_sensor(sd);
327 329
328 return soc_camera_set_power(&client->dev, ssdd, on); 330 return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
329} 331}
330 332
331/* select nearest higher resolution for capture */ 333/* select nearest higher resolution for capture */
@@ -700,10 +702,18 @@ static int ov9640_probe(struct i2c_client *client,
700 if (priv->hdl.error) 702 if (priv->hdl.error)
701 return priv->hdl.error; 703 return priv->hdl.error;
702 704
703 ret = ov9640_video_probe(client); 705 priv->clk = v4l2_clk_get(&client->dev, "mclk");
706 if (IS_ERR(priv->clk)) {
707 ret = PTR_ERR(priv->clk);
708 goto eclkget;
709 }
704 710
705 if (ret) 711 ret = ov9640_video_probe(client);
712 if (ret) {
713 v4l2_clk_put(priv->clk);
714eclkget:
706 v4l2_ctrl_handler_free(&priv->hdl); 715 v4l2_ctrl_handler_free(&priv->hdl);
716 }
707 717
708 return ret; 718 return ret;
709} 719}
@@ -713,6 +723,7 @@ static int ov9640_remove(struct i2c_client *client)
713 struct v4l2_subdev *sd = i2c_get_clientdata(client); 723 struct v4l2_subdev *sd = i2c_get_clientdata(client);
714 struct ov9640_priv *priv = to_ov9640_sensor(sd); 724 struct ov9640_priv *priv = to_ov9640_sensor(sd);
715 725
726 v4l2_clk_put(priv->clk);
716 v4l2_device_unregister_subdev(&priv->subdev); 727 v4l2_device_unregister_subdev(&priv->subdev);
717 v4l2_ctrl_handler_free(&priv->hdl); 728 v4l2_ctrl_handler_free(&priv->hdl);
718 return 0; 729 return 0;
diff --git a/drivers/media/i2c/soc_camera/ov9640.h b/drivers/media/i2c/soc_camera/ov9640.h
index 6b33a972c83c..65d13ff17536 100644
--- a/drivers/media/i2c/soc_camera/ov9640.h
+++ b/drivers/media/i2c/soc_camera/ov9640.h
@@ -199,6 +199,7 @@ struct ov9640_reg {
199struct ov9640_priv { 199struct ov9640_priv {
200 struct v4l2_subdev subdev; 200 struct v4l2_subdev subdev;
201 struct v4l2_ctrl_handler hdl; 201 struct v4l2_ctrl_handler hdl;
202 struct v4l2_clk *clk;
202 203
203 int model; 204 int model;
204 int revision; 205 int revision;
diff --git a/drivers/media/i2c/soc_camera/ov9740.c b/drivers/media/i2c/soc_camera/ov9740.c
index 0bc21a643c08..ea76863dfdb4 100644
--- a/drivers/media/i2c/soc_camera/ov9740.c
+++ b/drivers/media/i2c/soc_camera/ov9740.c
@@ -17,6 +17,7 @@
17#include <linux/v4l2-mediabus.h> 17#include <linux/v4l2-mediabus.h>
18 18
19#include <media/soc_camera.h> 19#include <media/soc_camera.h>
20#include <media/v4l2-clk.h>
20#include <media/v4l2-ctrls.h> 21#include <media/v4l2-ctrls.h>
21 22
22#define to_ov9740(sd) container_of(sd, struct ov9740_priv, subdev) 23#define to_ov9740(sd) container_of(sd, struct ov9740_priv, subdev)
@@ -195,6 +196,7 @@ struct ov9740_reg {
195struct ov9740_priv { 196struct ov9740_priv {
196 struct v4l2_subdev subdev; 197 struct v4l2_subdev subdev;
197 struct v4l2_ctrl_handler hdl; 198 struct v4l2_ctrl_handler hdl;
199 struct v4l2_clk *clk;
198 200
199 u16 model; 201 u16 model;
200 u8 revision; 202 u8 revision;
@@ -778,7 +780,7 @@ static int ov9740_s_power(struct v4l2_subdev *sd, int on)
778 int ret; 780 int ret;
779 781
780 if (on) { 782 if (on) {
781 ret = soc_camera_power_on(&client->dev, ssdd); 783 ret = soc_camera_power_on(&client->dev, ssdd, priv->clk);
782 if (ret < 0) 784 if (ret < 0)
783 return ret; 785 return ret;
784 786
@@ -792,7 +794,7 @@ static int ov9740_s_power(struct v4l2_subdev *sd, int on)
792 priv->current_enable = true; 794 priv->current_enable = true;
793 } 795 }
794 796
795 soc_camera_power_off(&client->dev, ssdd); 797 soc_camera_power_off(&client->dev, ssdd, priv->clk);
796 } 798 }
797 799
798 return 0; 800 return 0;
@@ -958,9 +960,18 @@ static int ov9740_probe(struct i2c_client *client,
958 if (priv->hdl.error) 960 if (priv->hdl.error)
959 return priv->hdl.error; 961 return priv->hdl.error;
960 962
963 priv->clk = v4l2_clk_get(&client->dev, "mclk");
964 if (IS_ERR(priv->clk)) {
965 ret = PTR_ERR(priv->clk);
966 goto eclkget;
967 }
968
961 ret = ov9740_video_probe(client); 969 ret = ov9740_video_probe(client);
962 if (ret < 0) 970 if (ret < 0) {
971 v4l2_clk_put(priv->clk);
972eclkget:
963 v4l2_ctrl_handler_free(&priv->hdl); 973 v4l2_ctrl_handler_free(&priv->hdl);
974 }
964 975
965 return ret; 976 return ret;
966} 977}
@@ -969,6 +980,7 @@ static int ov9740_remove(struct i2c_client *client)
969{ 980{
970 struct ov9740_priv *priv = i2c_get_clientdata(client); 981 struct ov9740_priv *priv = i2c_get_clientdata(client);
971 982
983 v4l2_clk_put(priv->clk);
972 v4l2_device_unregister_subdev(&priv->subdev); 984 v4l2_device_unregister_subdev(&priv->subdev);
973 v4l2_ctrl_handler_free(&priv->hdl); 985 v4l2_ctrl_handler_free(&priv->hdl);
974 return 0; 986 return 0;
diff --git a/drivers/media/i2c/soc_camera/rj54n1cb0c.c b/drivers/media/i2c/soc_camera/rj54n1cb0c.c
index 81b515c2fb36..7e6d97847874 100644
--- a/drivers/media/i2c/soc_camera/rj54n1cb0c.c
+++ b/drivers/media/i2c/soc_camera/rj54n1cb0c.c
@@ -17,6 +17,7 @@
17 17
18#include <media/rj54n1cb0c.h> 18#include <media/rj54n1cb0c.h>
19#include <media/soc_camera.h> 19#include <media/soc_camera.h>
20#include <media/v4l2-clk.h>
20#include <media/v4l2-subdev.h> 21#include <media/v4l2-subdev.h>
21#include <media/v4l2-ctrls.h> 22#include <media/v4l2-ctrls.h>
22 23
@@ -150,6 +151,7 @@ struct rj54n1_clock_div {
150struct rj54n1 { 151struct rj54n1 {
151 struct v4l2_subdev subdev; 152 struct v4l2_subdev subdev;
152 struct v4l2_ctrl_handler hdl; 153 struct v4l2_ctrl_handler hdl;
154 struct v4l2_clk *clk;
153 struct rj54n1_clock_div clk_div; 155 struct rj54n1_clock_div clk_div;
154 const struct rj54n1_datafmt *fmt; 156 const struct rj54n1_datafmt *fmt;
155 struct v4l2_rect rect; /* Sensor window */ 157 struct v4l2_rect rect; /* Sensor window */
@@ -1158,8 +1160,9 @@ static int rj54n1_s_power(struct v4l2_subdev *sd, int on)
1158{ 1160{
1159 struct i2c_client *client = v4l2_get_subdevdata(sd); 1161 struct i2c_client *client = v4l2_get_subdevdata(sd);
1160 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 1162 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
1163 struct rj54n1 *rj54n1 = to_rj54n1(client);
1161 1164
1162 return soc_camera_set_power(&client->dev, ssdd, on); 1165 return soc_camera_set_power(&client->dev, ssdd, rj54n1->clk, on);
1163} 1166}
1164 1167
1165static int rj54n1_s_ctrl(struct v4l2_ctrl *ctrl) 1168static int rj54n1_s_ctrl(struct v4l2_ctrl *ctrl)
@@ -1355,9 +1358,18 @@ static int rj54n1_probe(struct i2c_client *client,
1355 rj54n1->tgclk_mhz = (rj54n1_priv->mclk_freq / PLL_L * PLL_N) / 1358 rj54n1->tgclk_mhz = (rj54n1_priv->mclk_freq / PLL_L * PLL_N) /
1356 (clk_div.ratio_tg + 1) / (clk_div.ratio_t + 1); 1359 (clk_div.ratio_tg + 1) / (clk_div.ratio_t + 1);
1357 1360
1361 rj54n1->clk = v4l2_clk_get(&client->dev, "mclk");
1362 if (IS_ERR(rj54n1->clk)) {
1363 ret = PTR_ERR(rj54n1->clk);
1364 goto eclkget;
1365 }
1366
1358 ret = rj54n1_video_probe(client, rj54n1_priv); 1367 ret = rj54n1_video_probe(client, rj54n1_priv);
1359 if (ret < 0) 1368 if (ret < 0) {
1369 v4l2_clk_put(rj54n1->clk);
1370eclkget:
1360 v4l2_ctrl_handler_free(&rj54n1->hdl); 1371 v4l2_ctrl_handler_free(&rj54n1->hdl);
1372 }
1361 1373
1362 return ret; 1374 return ret;
1363} 1375}
@@ -1367,6 +1379,7 @@ static int rj54n1_remove(struct i2c_client *client)
1367 struct rj54n1 *rj54n1 = to_rj54n1(client); 1379 struct rj54n1 *rj54n1 = to_rj54n1(client);
1368 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 1380 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
1369 1381
1382 v4l2_clk_put(rj54n1->clk);
1370 v4l2_device_unregister_subdev(&rj54n1->subdev); 1383 v4l2_device_unregister_subdev(&rj54n1->subdev);
1371 if (ssdd->free_bus) 1384 if (ssdd->free_bus)
1372 ssdd->free_bus(ssdd); 1385 ssdd->free_bus(ssdd);
diff --git a/drivers/media/i2c/soc_camera/tw9910.c b/drivers/media/i2c/soc_camera/tw9910.c
index b15e1d8194da..ab54628d9411 100644
--- a/drivers/media/i2c/soc_camera/tw9910.c
+++ b/drivers/media/i2c/soc_camera/tw9910.c
@@ -27,6 +27,7 @@
27 27
28#include <media/soc_camera.h> 28#include <media/soc_camera.h>
29#include <media/tw9910.h> 29#include <media/tw9910.h>
30#include <media/v4l2-clk.h>
30#include <media/v4l2-subdev.h> 31#include <media/v4l2-subdev.h>
31 32
32#define GET_ID(val) ((val & 0xF8) >> 3) 33#define GET_ID(val) ((val & 0xF8) >> 3)
@@ -227,6 +228,7 @@ struct tw9910_scale_ctrl {
227 228
228struct tw9910_priv { 229struct tw9910_priv {
229 struct v4l2_subdev subdev; 230 struct v4l2_subdev subdev;
231 struct v4l2_clk *clk;
230 struct tw9910_video_info *info; 232 struct tw9910_video_info *info;
231 const struct tw9910_scale_ctrl *scale; 233 const struct tw9910_scale_ctrl *scale;
232 v4l2_std_id norm; 234 v4l2_std_id norm;
@@ -558,8 +560,9 @@ static int tw9910_s_power(struct v4l2_subdev *sd, int on)
558{ 560{
559 struct i2c_client *client = v4l2_get_subdevdata(sd); 561 struct i2c_client *client = v4l2_get_subdevdata(sd);
560 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 562 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
563 struct tw9910_priv *priv = to_tw9910(client);
561 564
562 return soc_camera_set_power(&client->dev, ssdd, on); 565 return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
563} 566}
564 567
565static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height) 568static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height)
@@ -899,6 +902,7 @@ static int tw9910_probe(struct i2c_client *client,
899 struct i2c_adapter *adapter = 902 struct i2c_adapter *adapter =
900 to_i2c_adapter(client->dev.parent); 903 to_i2c_adapter(client->dev.parent);
901 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); 904 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
905 int ret;
902 906
903 if (!ssdd || !ssdd->drv_priv) { 907 if (!ssdd || !ssdd->drv_priv) {
904 dev_err(&client->dev, "TW9910: missing platform data!\n"); 908 dev_err(&client->dev, "TW9910: missing platform data!\n");
@@ -922,7 +926,22 @@ static int tw9910_probe(struct i2c_client *client,
922 926
923 v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops); 927 v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
924 928
925 return tw9910_video_probe(client); 929 priv->clk = v4l2_clk_get(&client->dev, "mclk");
930 if (IS_ERR(priv->clk))
931 return PTR_ERR(priv->clk);
932
933 ret = tw9910_video_probe(client);
934 if (ret < 0)
935 v4l2_clk_put(priv->clk);
936
937 return ret;
938}
939
940static int tw9910_remove(struct i2c_client *client)
941{
942 struct tw9910_priv *priv = to_tw9910(client);
943 v4l2_clk_put(priv->clk);
944 return 0;
926} 945}
927 946
928static const struct i2c_device_id tw9910_id[] = { 947static const struct i2c_device_id tw9910_id[] = {
@@ -936,6 +955,7 @@ static struct i2c_driver tw9910_i2c_driver = {
936 .name = "tw9910", 955 .name = "tw9910",
937 }, 956 },
938 .probe = tw9910_probe, 957 .probe = tw9910_probe,
958 .remove = tw9910_remove,
939 .id_table = tw9910_id, 959 .id_table = tw9910_id,
940}; 960};
941 961