linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] mt9t001 and mt9p031 sensors drivers patches
@ 2014-02-10 21:54 Laurent Pinchart
  2014-02-10 21:54 ` [PATCH 1/5] ARM: omap2: cm-t35: Add regulators and clock for camera sensor Laurent Pinchart
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Laurent Pinchart @ 2014-02-10 21:54 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

This is a set of miscellaneous patches for the mt9t001 and mt9p031 sensors
drivers. Please see individual commit messages for details.

The mt9t001 driver receives support for regulators and clocks. As a
prerequisite, patch 1/5 registers a fixed rate clock and two fixed voltage
regulators for the CM-T35 board camera sensor.

Laurent Pinchart (5):
  ARM: omap2: cm-t35: Add regulators and clock for camera sensor
  mt9t001: Add regulator support
  mt9t001: Add clock support
  mt9p031: Fix typo in comment
  mt9p031: Add support for PLL bypass

 arch/arm/mach-omap2/board-cm-t35.c |  16 +++
 drivers/media/i2c/mt9p031.c        |  34 +++++-
 drivers/media/i2c/mt9t001.c        | 229 +++++++++++++++++++++++++++++--------
 3 files changed, 228 insertions(+), 51 deletions(-)

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/5] ARM: omap2: cm-t35: Add regulators and clock for camera sensor
  2014-02-10 21:54 [PATCH 0/5] mt9t001 and mt9p031 sensors drivers patches Laurent Pinchart
@ 2014-02-10 21:54 ` Laurent Pinchart
  2014-02-18 12:47   ` Laurent Pinchart
  2014-02-10 21:54 ` [PATCH 2/5] mt9t001: Add regulator support Laurent Pinchart
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Laurent Pinchart @ 2014-02-10 21:54 UTC (permalink / raw)
  To: linux-arm-kernel

The camera sensor will soon require regulators and clocks. Register
fixed regulators for its VAA and VDD power supplies and a fixed rate
clock for its master clock.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 arch/arm/mach-omap2/board-cm-t35.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 8dd0ec8..018353d 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -16,6 +16,8 @@
  *
  */
 
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -542,8 +544,22 @@ static struct isp_platform_data cm_t35_isp_pdata = {
 	.subdevs = cm_t35_isp_subdevs,
 };
 
+static struct regulator_consumer_supply cm_t35_camera_supplies[] = {
+	REGULATOR_SUPPLY("vaa", "3-005d"),
+	REGULATOR_SUPPLY("vdd", "3-005d"),
+};
+
 static void __init cm_t35_init_camera(void)
 {
+	struct clk *clk;
+
+	clk = clk_register_fixed_rate(NULL, "mt9t001-clkin", NULL, CLK_IS_ROOT,
+				      48000000);
+	clk_register_clkdev(clk, NULL, "3-005d");
+
+	regulator_register_fixed(2, cm_t35_camera_supplies,
+				 ARRAY_SIZE(cm_t35_camera_supplies));
+
 	if (omap3_init_camera(&cm_t35_isp_pdata) < 0)
 		pr_warn("CM-T3x: Failed registering camera device!\n");
 }
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/5] mt9t001: Add regulator support
  2014-02-10 21:54 [PATCH 0/5] mt9t001 and mt9p031 sensors drivers patches Laurent Pinchart
  2014-02-10 21:54 ` [PATCH 1/5] ARM: omap2: cm-t35: Add regulators and clock for camera sensor Laurent Pinchart
@ 2014-02-10 21:54 ` Laurent Pinchart
  2014-02-10 21:54 ` [PATCH 3/5] mt9t001: Add clock support Laurent Pinchart
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Laurent Pinchart @ 2014-02-10 21:54 UTC (permalink / raw)
  To: linux-arm-kernel

The sensor needs two power supplies, VAA and VDD. Require a regulator
for each of them.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/media/i2c/mt9t001.c | 206 +++++++++++++++++++++++++++++++++-----------
 1 file changed, 156 insertions(+), 50 deletions(-)

diff --git a/drivers/media/i2c/mt9t001.c b/drivers/media/i2c/mt9t001.c
index d41c70e..9a0bb06 100644
--- a/drivers/media/i2c/mt9t001.c
+++ b/drivers/media/i2c/mt9t001.c
@@ -13,8 +13,9 @@
  */
 
 #include <linux/i2c.h>
-#include <linux/module.h>
 #include <linux/log2.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <linux/v4l2-mediabus.h>
@@ -55,6 +56,7 @@
 #define		MT9T001_OUTPUT_CONTROL_SYNC		(1 << 0)
 #define		MT9T001_OUTPUT_CONTROL_CHIP_ENABLE	(1 << 1)
 #define		MT9T001_OUTPUT_CONTROL_TEST_DATA	(1 << 6)
+#define		MT9T001_OUTPUT_CONTROL_DEF		0x0002
 #define MT9T001_SHUTTER_WIDTH_HIGH			0x08
 #define MT9T001_SHUTTER_WIDTH_LOW			0x09
 #define		MT9T001_SHUTTER_WIDTH_MIN		1
@@ -116,6 +118,11 @@ struct mt9t001 {
 	struct v4l2_subdev subdev;
 	struct media_pad pad;
 
+	struct regulator_bulk_data regulators[2];
+
+	struct mutex power_lock; /* lock to protect power_count */
+	int power_count;
+
 	struct v4l2_mbus_framefmt format;
 	struct v4l2_rect crop;
 
@@ -159,6 +166,62 @@ static int mt9t001_set_output_control(struct mt9t001 *mt9t001, u16 clear,
 	return 0;
 }
 
+static int mt9t001_reset(struct mt9t001 *mt9t001)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev);
+	int ret;
+
+	/* Reset the chip and stop data read out */
+	ret = mt9t001_write(client, MT9T001_RESET, 1);
+	if (ret < 0)
+		return ret;
+
+	ret = mt9t001_write(client, MT9T001_RESET, 0);
+	if (ret < 0)
+		return ret;
+
+	mt9t001->output_control = MT9T001_OUTPUT_CONTROL_DEF;
+
+	return mt9t001_set_output_control(mt9t001,
+					  MT9T001_OUTPUT_CONTROL_CHIP_ENABLE,
+					  0);
+}
+
+static int mt9t001_power_on(struct mt9t001 *mt9t001)
+{
+	/* Bring up the supplies */
+	return regulator_bulk_enable(ARRAY_SIZE(mt9t001->regulators),
+				     mt9t001->regulators);
+}
+
+static void mt9t001_power_off(struct mt9t001 *mt9t001)
+{
+	regulator_bulk_disable(ARRAY_SIZE(mt9t001->regulators),
+			       mt9t001->regulators);
+
+static int __mt9t001_set_power(struct mt9t001 *mt9t001, bool on)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev);
+	int ret;
+
+	if (!on) {
+		mt9t001_power_off(mt9t001);
+		return 0;
+	}
+
+	ret = mt9t001_power_on(mt9t001);
+	if (ret < 0)
+		return ret;
+
+	ret = mt9t001_reset(mt9t001);
+	if (ret < 0) {
+		dev_err(&client->dev, "Failed to reset the camera\n");
+		return ret;
+	}
+
+	return v4l2_ctrl_handler_setup(&mt9t001->ctrls);
+}
+
 /* -----------------------------------------------------------------------------
  * V4L2 subdev video operations
  */
@@ -195,6 +258,7 @@ static int mt9t001_s_stream(struct v4l2_subdev *subdev, int enable)
 {
 	const u16 mode = MT9T001_OUTPUT_CONTROL_CHIP_ENABLE;
 	struct i2c_client *client = v4l2_get_subdevdata(subdev);
+	struct mt9t001_platform_data *pdata = client->dev.platform_data;
 	struct mt9t001 *mt9t001 = to_mt9t001(subdev);
 	struct v4l2_mbus_framefmt *format = &mt9t001->format;
 	struct v4l2_rect *crop = &mt9t001->crop;
@@ -205,6 +269,14 @@ static int mt9t001_s_stream(struct v4l2_subdev *subdev, int enable)
 	if (!enable)
 		return mt9t001_set_output_control(mt9t001, mode, 0);
 
+	/* Configure the pixel clock polarity */
+	if (pdata->clk_pol) {
+		ret  = mt9t001_write(client, MT9T001_PIXEL_CLOCK,
+				     MT9T001_PIXEL_CLOCK_INVERT);
+		if (ret < 0)
+			return ret;
+	}
+
 	/* Configure the window size and row/column bin */
 	hratio = DIV_ROUND_CLOSEST(crop->width, format->width);
 	vratio = DIV_ROUND_CLOSEST(crop->height, format->height);
@@ -630,9 +702,67 @@ static const struct v4l2_ctrl_config mt9t001_gains[] = {
 };
 
 /* -----------------------------------------------------------------------------
+ * V4L2 subdev core operations
+ */
+
+static int mt9t001_set_power(struct v4l2_subdev *subdev, int on)
+{
+	struct mt9t001 *mt9t001 = to_mt9t001(subdev);
+	int ret = 0;
+
+	mutex_lock(&mt9t001->power_lock);
+
+	/* If the power count is modified from 0 to != 0 or from != 0 to 0,
+	 * update the power state.
+	 */
+	if (mt9t001->power_count == !on) {
+		ret = __mt9t001_set_power(mt9t001, !!on);
+		if (ret < 0)
+			goto out;
+	}
+
+	/* Update the power count. */
+	mt9t001->power_count += on ? 1 : -1;
+	WARN_ON(mt9t001->power_count < 0);
+
+out:
+	mutex_unlock(&mt9t001->power_lock);
+	return ret;
+}
+
+/* -----------------------------------------------------------------------------
  * V4L2 subdev internal operations
  */
 
+static int mt9t001_registered(struct v4l2_subdev *subdev)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(subdev);
+	struct mt9t001 *mt9t001 = to_mt9t001(subdev);
+	s32 data;
+	int ret;
+
+	ret = mt9t001_power_on(mt9t001);
+	if (ret < 0) {
+		dev_err(&client->dev, "MT9T001 power up failed\n");
+		return ret;
+	}
+
+	/* Read out the chip version register */
+	data = mt9t001_read(client, MT9T001_CHIP_VERSION);
+	mt9t001_power_off(mt9t001);
+
+	if (data != MT9T001_CHIP_ID) {
+		dev_err(&client->dev,
+			"MT9T001 not detected, wrong version 0x%04x\n", data);
+		return -ENODEV;
+	}
+
+	dev_info(&client->dev, "MT9T001 detected at address 0x%02x\n",
+		 client->addr);
+
+	return 0;
+}
+
 static int mt9t001_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
 {
 	struct v4l2_mbus_framefmt *format;
@@ -651,9 +781,18 @@ static int mt9t001_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
 	format->field = V4L2_FIELD_NONE;
 	format->colorspace = V4L2_COLORSPACE_SRGB;
 
-	return 0;
+	return mt9t001_set_power(subdev, 1);
 }
 
+static int mt9t001_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
+{
+	return mt9t001_set_power(subdev, 0);
+}
+
+static struct v4l2_subdev_core_ops mt9t001_subdev_core_ops = {
+	.s_power = mt9t001_set_power,
+};
+
 static struct v4l2_subdev_video_ops mt9t001_subdev_video_ops = {
 	.s_stream = mt9t001_s_stream,
 };
@@ -668,58 +807,17 @@ static struct v4l2_subdev_pad_ops mt9t001_subdev_pad_ops = {
 };
 
 static struct v4l2_subdev_ops mt9t001_subdev_ops = {
+	.core = &mt9t001_subdev_core_ops,
 	.video = &mt9t001_subdev_video_ops,
 	.pad = &mt9t001_subdev_pad_ops,
 };
 
 static struct v4l2_subdev_internal_ops mt9t001_subdev_internal_ops = {
+	.registered = mt9t001_registered,
 	.open = mt9t001_open,
+	.close = mt9t001_close,
 };
 
-static int mt9t001_video_probe(struct i2c_client *client)
-{
-	struct mt9t001_platform_data *pdata = client->dev.platform_data;
-	s32 data;
-	int ret;
-
-	dev_info(&client->dev, "Probing MT9T001 at address 0x%02x\n",
-		 client->addr);
-
-	/* Reset the chip and stop data read out */
-	ret = mt9t001_write(client, MT9T001_RESET, 1);
-	if (ret < 0)
-		return ret;
-
-	ret = mt9t001_write(client, MT9T001_RESET, 0);
-	if (ret < 0)
-		return ret;
-
-	ret  = mt9t001_write(client, MT9T001_OUTPUT_CONTROL, 0);
-	if (ret < 0)
-		return ret;
-
-	/* Configure the pixel clock polarity */
-	if (pdata->clk_pol) {
-		ret  = mt9t001_write(client, MT9T001_PIXEL_CLOCK,
-				     MT9T001_PIXEL_CLOCK_INVERT);
-		if (ret < 0)
-			return ret;
-	}
-
-	/* Read and check the sensor version */
-	data = mt9t001_read(client, MT9T001_CHIP_VERSION);
-	if (data != MT9T001_CHIP_ID) {
-		dev_err(&client->dev, "MT9T001 not detected, wrong version "
-			"0x%04x\n", data);
-		return -ENODEV;
-	}
-
-	dev_info(&client->dev, "MT9T001 detected at address 0x%02x\n",
-		 client->addr);
-
-	return ret;
-}
-
 static int mt9t001_probe(struct i2c_client *client,
 			 const struct i2c_device_id *did)
 {
@@ -740,14 +838,22 @@ static int mt9t001_probe(struct i2c_client *client,
 		return -EIO;
 	}
 
-	ret = mt9t001_video_probe(client);
-	if (ret < 0)
-		return ret;
-
 	mt9t001 = devm_kzalloc(&client->dev, sizeof(*mt9t001), GFP_KERNEL);
 	if (!mt9t001)
 		return -ENOMEM;
 
+	mutex_init(&mt9t001->power_lock);
+	mt9t001->output_control = MT9T001_OUTPUT_CONTROL_DEF;
+
+	mt9t001->regulators[0].supply = "vdd";
+	mt9t001->regulators[1].supply = "vaa";
+
+	ret = devm_regulator_bulk_get(&client->dev, 2, mt9t001->regulators);
+	if (ret < 0) {
+		dev_err(&client->dev, "Unable to get regulators\n");
+		return ret;
+	}
+
 	v4l2_ctrl_handler_init(&mt9t001->ctrls, ARRAY_SIZE(mt9t001_ctrls) +
 						ARRAY_SIZE(mt9t001_gains) + 4);
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/5] mt9t001: Add clock support
  2014-02-10 21:54 [PATCH 0/5] mt9t001 and mt9p031 sensors drivers patches Laurent Pinchart
  2014-02-10 21:54 ` [PATCH 1/5] ARM: omap2: cm-t35: Add regulators and clock for camera sensor Laurent Pinchart
  2014-02-10 21:54 ` [PATCH 2/5] mt9t001: Add regulator support Laurent Pinchart
@ 2014-02-10 21:54 ` Laurent Pinchart
  2014-02-10 21:54 ` [PATCH 4/5] mt9p031: Fix typo in comment Laurent Pinchart
  2014-02-10 21:54 ` [PATCH 5/5] mt9p031: Add support for PLL bypass Laurent Pinchart
  4 siblings, 0 replies; 10+ messages in thread
From: Laurent Pinchart @ 2014-02-10 21:54 UTC (permalink / raw)
  To: linux-arm-kernel

The sensor needs a master clock, handle it explictly in the driver.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/media/i2c/mt9t001.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/drivers/media/i2c/mt9t001.c b/drivers/media/i2c/mt9t001.c
index 9a0bb06..422e068 100644
--- a/drivers/media/i2c/mt9t001.c
+++ b/drivers/media/i2c/mt9t001.c
@@ -12,6 +12,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/clk.h>
 #include <linux/i2c.h>
 #include <linux/log2.h>
 #include <linux/module.h>
@@ -118,6 +119,7 @@ struct mt9t001 {
 	struct v4l2_subdev subdev;
 	struct media_pad pad;
 
+	struct clk *clk;
 	struct regulator_bulk_data regulators[2];
 
 	struct mutex power_lock; /* lock to protect power_count */
@@ -189,9 +191,21 @@ static int mt9t001_reset(struct mt9t001 *mt9t001)
 
 static int mt9t001_power_on(struct mt9t001 *mt9t001)
 {
+	int ret;
+
 	/* Bring up the supplies */
-	return regulator_bulk_enable(ARRAY_SIZE(mt9t001->regulators),
-				     mt9t001->regulators);
+	ret = regulator_bulk_enable(ARRAY_SIZE(mt9t001->regulators),
+				   mt9t001->regulators);
+	if (ret < 0)
+		return ret;
+
+	/* Enable clock */
+	ret = clk_prepare_enable(mt9t001->clk);
+	if (ret < 0)
+		regulator_bulk_disable(ARRAY_SIZE(mt9t001->regulators),
+				       mt9t001->regulators);
+
+	return ret;
 }
 
 static void mt9t001_power_off(struct mt9t001 *mt9t001)
@@ -199,6 +213,9 @@ static void mt9t001_power_off(struct mt9t001 *mt9t001)
 	regulator_bulk_disable(ARRAY_SIZE(mt9t001->regulators),
 			       mt9t001->regulators);
 
+	clk_disable_unprepare(mt9t001->clk);
+}
+
 static int __mt9t001_set_power(struct mt9t001 *mt9t001, bool on)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev);
@@ -854,6 +871,12 @@ static int mt9t001_probe(struct i2c_client *client,
 		return ret;
 	}
 
+	mt9t001->clk = devm_clk_get(&client->dev, NULL);
+	if (IS_ERR(mt9t001->clk)) {
+		dev_err(&client->dev, "Unable to get clock\n");
+		return PTR_ERR(mt9t001->clk);
+	}
+
 	v4l2_ctrl_handler_init(&mt9t001->ctrls, ARRAY_SIZE(mt9t001_ctrls) +
 						ARRAY_SIZE(mt9t001_gains) + 4);
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/5] mt9p031: Fix typo in comment
  2014-02-10 21:54 [PATCH 0/5] mt9t001 and mt9p031 sensors drivers patches Laurent Pinchart
                   ` (2 preceding siblings ...)
  2014-02-10 21:54 ` [PATCH 3/5] mt9t001: Add clock support Laurent Pinchart
@ 2014-02-10 21:54 ` Laurent Pinchart
  2014-02-10 21:54 ` [PATCH 5/5] mt9p031: Add support for PLL bypass Laurent Pinchart
  4 siblings, 0 replies; 10+ messages in thread
From: Laurent Pinchart @ 2014-02-10 21:54 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/media/i2c/mt9p031.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
index 05278f5..14a616e 100644
--- a/drivers/media/i2c/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -288,7 +288,7 @@ static int mt9p031_power_on(struct mt9p031 *mt9p031)
 	if (ret < 0)
 		return ret;
 
-	/* Emable clock */
+	/* Enable clock */
 	if (mt9p031->clk) {
 		ret = clk_prepare_enable(mt9p031->clk);
 		if (ret) {
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/5] mt9p031: Add support for PLL bypass
  2014-02-10 21:54 [PATCH 0/5] mt9t001 and mt9p031 sensors drivers patches Laurent Pinchart
                   ` (3 preceding siblings ...)
  2014-02-10 21:54 ` [PATCH 4/5] mt9p031: Fix typo in comment Laurent Pinchart
@ 2014-02-10 21:54 ` Laurent Pinchart
  4 siblings, 0 replies; 10+ messages in thread
From: Laurent Pinchart @ 2014-02-10 21:54 UTC (permalink / raw)
  To: linux-arm-kernel

When the input clock frequency is out of bounds for the PLL, bypass the
PLL and just divide the input clock to achieve the requested output
frequency.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/media/i2c/mt9p031.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
index 14a616e..5483ab2 100644
--- a/drivers/media/i2c/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -78,6 +78,9 @@
 #define	MT9P031_PLL_CONFIG_1				0x11
 #define	MT9P031_PLL_CONFIG_2				0x12
 #define MT9P031_PIXEL_CLOCK_CONTROL			0x0a
+#define		MT9P031_PIXEL_CLOCK_INVERT		(1 << 15)
+#define		MT9P031_PIXEL_CLOCK_SHIFT(n)		((n) << 8)
+#define		MT9P031_PIXEL_CLOCK_DIVIDE(n)		((n) << 0)
 #define MT9P031_FRAME_RESTART				0x0b
 #define MT9P031_SHUTTER_DELAY				0x0c
 #define MT9P031_RST					0x0d
@@ -130,6 +133,8 @@ struct mt9p031 {
 
 	enum mt9p031_model model;
 	struct aptina_pll pll;
+	unsigned int clk_div;
+	bool use_pll;
 	int reset;
 
 	struct v4l2_ctrl_handler ctrls;
@@ -198,6 +203,11 @@ static int mt9p031_reset(struct mt9p031 *mt9p031)
 	if (ret < 0)
 		return ret;
 
+	ret = mt9p031_write(client, MT9P031_PIXEL_CLOCK_CONTROL,
+			    MT9P031_PIXEL_CLOCK_DIVIDE(mt9p031->clk_div));
+	if (ret < 0)
+		return ret;
+
 	return mt9p031_set_output_control(mt9p031, MT9P031_OUTPUT_CONTROL_CEN,
 					  0);
 }
@@ -232,8 +242,24 @@ static int mt9p031_clk_setup(struct mt9p031 *mt9p031)
 	if (ret < 0)
 		return ret;
 
+	/* If the external clock frequency is out of bounds for the PLL use the
+	 * pixel clock divider only and disable the PLL.
+	 */
+	if (pdata->ext_freq > limits.ext_clock_max) {
+		unsigned int div;
+
+		div = DIV_ROUND_UP(pdata->ext_freq, pdata->target_freq);
+		div = roundup_pow_of_two(div) / 2;
+
+		mt9p031->clk_div = max_t(unsigned int, div, 64);
+		mt9p031->use_pll = false;
+
+		return 0;
+	}
+
 	mt9p031->pll.ext_clock = pdata->ext_freq;
 	mt9p031->pll.pix_clock = pdata->target_freq;
+	mt9p031->use_pll = true;
 
 	return aptina_pll_calculate(&client->dev, &limits, &mt9p031->pll);
 }
@@ -243,6 +269,9 @@ static int mt9p031_pll_enable(struct mt9p031 *mt9p031)
 	struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
 	int ret;
 
+	if (!mt9p031->use_pll)
+		return 0;
+
 	ret = mt9p031_write(client, MT9P031_PLL_CONTROL,
 			    MT9P031_PLL_CONTROL_PWRON);
 	if (ret < 0)
@@ -268,6 +297,9 @@ static inline int mt9p031_pll_disable(struct mt9p031 *mt9p031)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
 
+	if (!mt9p031->use_pll)
+		return 0;
+
 	return mt9p031_write(client, MT9P031_PLL_CONTROL,
 			     MT9P031_PLL_CONTROL_PWROFF);
 }
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 1/5] ARM: omap2: cm-t35: Add regulators and clock for camera sensor
  2014-02-10 21:54 ` [PATCH 1/5] ARM: omap2: cm-t35: Add regulators and clock for camera sensor Laurent Pinchart
@ 2014-02-18 12:47   ` Laurent Pinchart
  2014-02-18 14:03     ` Igor Grinberg
  0 siblings, 1 reply; 10+ messages in thread
From: Laurent Pinchart @ 2014-02-18 12:47 UTC (permalink / raw)
  To: linux-arm-kernel

Mauro, Tony,

On Monday 10 February 2014 22:54:40 Laurent Pinchart wrote:
> The camera sensor will soon require regulators and clocks. Register
> fixed regulators for its VAA and VDD power supplies and a fixed rate
> clock for its master clock.

This patch is a prerequisite for a set of 4 patches that need to go through 
the linux-media tree. It would simpler if it could go through the same tree as 
well. Given that arch/arm/mach-omap2/board-cm-t35.c has seen very little 
activity recently I believe the risk of conflict is pretty low. Tony, would 
that be fine with you ?

> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  arch/arm/mach-omap2/board-cm-t35.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/arch/arm/mach-omap2/board-cm-t35.c
> b/arch/arm/mach-omap2/board-cm-t35.c index 8dd0ec8..018353d 100644
> --- a/arch/arm/mach-omap2/board-cm-t35.c
> +++ b/arch/arm/mach-omap2/board-cm-t35.c
> @@ -16,6 +16,8 @@
>   *
>   */
> 
> +#include <linux/clk-provider.h>
> +#include <linux/clkdev.h>
>  #include <linux/kernel.h>
>  #include <linux/init.h>
>  #include <linux/platform_device.h>
> @@ -542,8 +544,22 @@ static struct isp_platform_data cm_t35_isp_pdata = {
>  	.subdevs = cm_t35_isp_subdevs,
>  };
> 
> +static struct regulator_consumer_supply cm_t35_camera_supplies[] = {
> +	REGULATOR_SUPPLY("vaa", "3-005d"),
> +	REGULATOR_SUPPLY("vdd", "3-005d"),
> +};
> +
>  static void __init cm_t35_init_camera(void)
>  {
> +	struct clk *clk;
> +
> +	clk = clk_register_fixed_rate(NULL, "mt9t001-clkin", NULL, CLK_IS_ROOT,
> +				      48000000);
> +	clk_register_clkdev(clk, NULL, "3-005d");
> +
> +	regulator_register_fixed(2, cm_t35_camera_supplies,
> +				 ARRAY_SIZE(cm_t35_camera_supplies));
> +
>  	if (omap3_init_camera(&cm_t35_isp_pdata) < 0)
>  		pr_warn("CM-T3x: Failed registering camera device!\n");
>  }

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/5] ARM: omap2: cm-t35: Add regulators and clock for camera sensor
  2014-02-18 12:47   ` Laurent Pinchart
@ 2014-02-18 14:03     ` Igor Grinberg
  2014-02-18 15:03       ` Laurent Pinchart
  0 siblings, 1 reply; 10+ messages in thread
From: Igor Grinberg @ 2014-02-18 14:03 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Laurent,

On 02/18/14 14:47, Laurent Pinchart wrote:
> Mauro, Tony,
> 
> On Monday 10 February 2014 22:54:40 Laurent Pinchart wrote:
>> The camera sensor will soon require regulators and clocks. Register
>> fixed regulators for its VAA and VDD power supplies and a fixed rate
>> clock for its master clock.
> 
> This patch is a prerequisite for a set of 4 patches that need to go through 
> the linux-media tree. It would simpler if it could go through the same tree as 
> well. Given that arch/arm/mach-omap2/board-cm-t35.c has seen very little 
> activity recently I believe the risk of conflict is pretty low.

Indeed, as we work on DT stuff of cm-t35/3730 and pretty much stopped
updating the board-cm-t35.c file.

> Tony, would 
> that be fine with you ?
> 
>> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Acked-by: Igor Grinberg <grinberg@compulab.co.il>

>> ---
>>  arch/arm/mach-omap2/board-cm-t35.c | 16 ++++++++++++++++
>>  1 file changed, 16 insertions(+)
>>
>> diff --git a/arch/arm/mach-omap2/board-cm-t35.c
>> b/arch/arm/mach-omap2/board-cm-t35.c index 8dd0ec8..018353d 100644
>> --- a/arch/arm/mach-omap2/board-cm-t35.c
>> +++ b/arch/arm/mach-omap2/board-cm-t35.c
>> @@ -16,6 +16,8 @@
>>   *
>>   */
>>
>> +#include <linux/clk-provider.h>
>> +#include <linux/clkdev.h>
>>  #include <linux/kernel.h>
>>  #include <linux/init.h>
>>  #include <linux/platform_device.h>
>> @@ -542,8 +544,22 @@ static struct isp_platform_data cm_t35_isp_pdata = {
>>  	.subdevs = cm_t35_isp_subdevs,
>>  };
>>
>> +static struct regulator_consumer_supply cm_t35_camera_supplies[] = {
>> +	REGULATOR_SUPPLY("vaa", "3-005d"),
>> +	REGULATOR_SUPPLY("vdd", "3-005d"),
>> +};
>> +
>>  static void __init cm_t35_init_camera(void)
>>  {
>> +	struct clk *clk;
>> +
>> +	clk = clk_register_fixed_rate(NULL, "mt9t001-clkin", NULL, CLK_IS_ROOT,
>> +				      48000000);
>> +	clk_register_clkdev(clk, NULL, "3-005d");
>> +
>> +	regulator_register_fixed(2, cm_t35_camera_supplies,
>> +				 ARRAY_SIZE(cm_t35_camera_supplies));
>> +
>>  	if (omap3_init_camera(&cm_t35_isp_pdata) < 0)
>>  		pr_warn("CM-T3x: Failed registering camera device!\n");
>>  }
> 

-- 
Regards,
Igor.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/5] ARM: omap2: cm-t35: Add regulators and clock for camera sensor
  2014-02-18 14:03     ` Igor Grinberg
@ 2014-02-18 15:03       ` Laurent Pinchart
  2014-02-19 17:05         ` Tony Lindgren
  0 siblings, 1 reply; 10+ messages in thread
From: Laurent Pinchart @ 2014-02-18 15:03 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Igor,

On Tuesday 18 February 2014 16:03:44 Igor Grinberg wrote:
> On 02/18/14 14:47, Laurent Pinchart wrote:
> > On Monday 10 February 2014 22:54:40 Laurent Pinchart wrote:
> >> The camera sensor will soon require regulators and clocks. Register
> >> fixed regulators for its VAA and VDD power supplies and a fixed rate
> >> clock for its master clock.
> > 
> > This patch is a prerequisite for a set of 4 patches that need to go
> > through the linux-media tree. It would simpler if it could go through the
> > same tree as well. Given that arch/arm/mach-omap2/board-cm-t35.c has seen
> > very little activity recently I believe the risk of conflict is pretty
> > low.
> 
> Indeed, as we work on DT stuff of cm-t35/3730 and pretty much stopped
> updating the board-cm-t35.c file.

DT support for the OMAP3 ISP is coming. Too slowly, but it's coming :-)

> > Tony, would
> > that be fine with you ?
> > 
> >> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
> Acked-by: Igor Grinberg <grinberg@compulab.co.il>

Thank you. Tony, could I get your ack as well to push this through Mauro's 
tree ?

> >> ---
> >> 
> >>  arch/arm/mach-omap2/board-cm-t35.c | 16 ++++++++++++++++
> >>  1 file changed, 16 insertions(+)
> >> 
> >> diff --git a/arch/arm/mach-omap2/board-cm-t35.c
> >> b/arch/arm/mach-omap2/board-cm-t35.c index 8dd0ec8..018353d 100644
> >> --- a/arch/arm/mach-omap2/board-cm-t35.c
> >> +++ b/arch/arm/mach-omap2/board-cm-t35.c
> >> @@ -16,6 +16,8 @@
> >> 
> >>   *
> >>   */
> >> 
> >> +#include <linux/clk-provider.h>
> >> +#include <linux/clkdev.h>
> >> 
> >>  #include <linux/kernel.h>
> >>  #include <linux/init.h>
> >>  #include <linux/platform_device.h>
> >> 
> >> @@ -542,8 +544,22 @@ static struct isp_platform_data cm_t35_isp_pdata = {
> >> 
> >>  	.subdevs = cm_t35_isp_subdevs,
> >>  
> >>  };
> >> 
> >> +static struct regulator_consumer_supply cm_t35_camera_supplies[] = {
> >> +	REGULATOR_SUPPLY("vaa", "3-005d"),
> >> +	REGULATOR_SUPPLY("vdd", "3-005d"),
> >> +};
> >> +
> >> 
> >>  static void __init cm_t35_init_camera(void)
> >>  {
> >> 
> >> +	struct clk *clk;
> >> +
> >> +	clk = clk_register_fixed_rate(NULL, "mt9t001-clkin", NULL, 
CLK_IS_ROOT,
> >> +				      48000000);
> >> +	clk_register_clkdev(clk, NULL, "3-005d");
> >> +
> >> +	regulator_register_fixed(2, cm_t35_camera_supplies,
> >> +				 ARRAY_SIZE(cm_t35_camera_supplies));
> >> +
> >> 
> >>  	if (omap3_init_camera(&cm_t35_isp_pdata) < 0)
> >>  	
> >>  		pr_warn("CM-T3x: Failed registering camera device!\n");
> >>  
> >>  }

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/5] ARM: omap2: cm-t35: Add regulators and clock for camera sensor
  2014-02-18 15:03       ` Laurent Pinchart
@ 2014-02-19 17:05         ` Tony Lindgren
  0 siblings, 0 replies; 10+ messages in thread
From: Tony Lindgren @ 2014-02-19 17:05 UTC (permalink / raw)
  To: linux-arm-kernel

* Laurent Pinchart <laurent.pinchart@ideasonboard.com> [140218 07:05]:
> Hi Igor,
> 
> On Tuesday 18 February 2014 16:03:44 Igor Grinberg wrote:
> > On 02/18/14 14:47, Laurent Pinchart wrote:
> > > On Monday 10 February 2014 22:54:40 Laurent Pinchart wrote:
> > >> The camera sensor will soon require regulators and clocks. Register
> > >> fixed regulators for its VAA and VDD power supplies and a fixed rate
> > >> clock for its master clock.
> > > 
> > > This patch is a prerequisite for a set of 4 patches that need to go
> > > through the linux-media tree. It would simpler if it could go through the
> > > same tree as well. Given that arch/arm/mach-omap2/board-cm-t35.c has seen
> > > very little activity recently I believe the risk of conflict is pretty
> > > low.
> > 
> > Indeed, as we work on DT stuff of cm-t35/3730 and pretty much stopped
> > updating the board-cm-t35.c file.
> 
> DT support for the OMAP3 ISP is coming. Too slowly, but it's coming :-)
> 
> > > Tony, would
> > > that be fine with you ?
> > > 
> > >> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > 
> > Acked-by: Igor Grinberg <grinberg@compulab.co.il>
> 
> Thank you. Tony, could I get your ack as well to push this through Mauro's 
> tree ?

Sure, the board-*.c files will get removed soonish, but meanwhile:

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2014-02-19 17:05 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-02-10 21:54 [PATCH 0/5] mt9t001 and mt9p031 sensors drivers patches Laurent Pinchart
2014-02-10 21:54 ` [PATCH 1/5] ARM: omap2: cm-t35: Add regulators and clock for camera sensor Laurent Pinchart
2014-02-18 12:47   ` Laurent Pinchart
2014-02-18 14:03     ` Igor Grinberg
2014-02-18 15:03       ` Laurent Pinchart
2014-02-19 17:05         ` Tony Lindgren
2014-02-10 21:54 ` [PATCH 2/5] mt9t001: Add regulator support Laurent Pinchart
2014-02-10 21:54 ` [PATCH 3/5] mt9t001: Add clock support Laurent Pinchart
2014-02-10 21:54 ` [PATCH 4/5] mt9p031: Fix typo in comment Laurent Pinchart
2014-02-10 21:54 ` [PATCH 5/5] mt9p031: Add support for PLL bypass Laurent Pinchart

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).