From 3a959dcd11a4b1f55bbb4a37d3bac685c4e106b1 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Wed, 29 May 2019 15:25:18 -0400 Subject: media: mt9m111: add regulator support In the soc_camera removal, the board specific power callback was dropped. This at least will remove the power optimization from ezx and em-x270 pxa based boards. As to recreate the same level of functionality, make the mt9m111 have a regulator providing it its power, so that board designers can plug in a gpio based or ldo regulator, mimicking their former soc_camera power hook. [sakari.ailus@linux.intel.com: fix a build warning] Fixes: 5c10113cc668 ("media: mt9m111: make a standalone v4l2 subdevice") Signed-off-by: Robert Jarzmik Signed-off-by: Mauro Carvalho Chehab Tested-by: Akinobu Mita Tested-by: Robert Jarzmik Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/mt9m111.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers/media/i2c/mt9m111.c') diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c index 5168bb5880c4..746d1345b505 100644 --- a/drivers/media/i2c/mt9m111.c +++ b/drivers/media/i2c/mt9m111.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -243,6 +244,7 @@ struct mt9m111 { int power_count; const struct mt9m111_datafmt *fmt; int lastpage; /* PageMap cache value */ + struct regulator *regulator; bool is_streaming; /* user point of view - 0: falling 1: rising edge */ unsigned int pclk_sample:1; @@ -982,6 +984,12 @@ static int mt9m111_power_on(struct mt9m111 *mt9m111) if (ret < 0) return ret; + if (mt9m111->regulator) { + ret = regulator_enable(mt9m111->regulator); + if (ret < 0) + return ret; + } + ret = mt9m111_resume(mt9m111); if (ret < 0) { dev_err(&client->dev, "Failed to resume the sensor: %d\n", ret); @@ -994,6 +1002,8 @@ static int mt9m111_power_on(struct mt9m111 *mt9m111) static void mt9m111_power_off(struct mt9m111 *mt9m111) { mt9m111_suspend(mt9m111); + if (mt9m111->regulator) + regulator_disable(mt9m111->regulator); v4l2_clk_disable(mt9m111->clk); } @@ -1256,6 +1266,13 @@ static int mt9m111_probe(struct i2c_client *client, if (IS_ERR(mt9m111->clk)) return PTR_ERR(mt9m111->clk); + mt9m111->regulator = devm_regulator_get(&client->dev, "vdd"); + if (IS_ERR(mt9m111->regulator)) { + dev_err(&client->dev, "regulator not found: %ld\n", + PTR_ERR(mt9m111->regulator)); + return PTR_ERR(mt9m111->regulator); + } + /* Default HIGHPOWER context */ mt9m111->ctx = &context_b; -- cgit v1.2.3 From 9a57d72b94869ceb29f932e95cb39f0cc156ea1f Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 31 May 2019 16:11:35 -0400 Subject: media: mt9m111: No need to check for the regulator The regulator_get() function returns a regulator when it succeeds. There's no need to check whether the regulator is NULL later on. Signed-off-by: Sakari Ailus Reviewed-by: Marco Felsch Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/mt9m111.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers/media/i2c/mt9m111.c') diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c index 746d1345b505..bb19f8c346cb 100644 --- a/drivers/media/i2c/mt9m111.c +++ b/drivers/media/i2c/mt9m111.c @@ -984,11 +984,9 @@ static int mt9m111_power_on(struct mt9m111 *mt9m111) if (ret < 0) return ret; - if (mt9m111->regulator) { - ret = regulator_enable(mt9m111->regulator); - if (ret < 0) - return ret; - } + ret = regulator_enable(mt9m111->regulator); + if (ret < 0) + return ret; ret = mt9m111_resume(mt9m111); if (ret < 0) { @@ -1002,8 +1000,7 @@ static int mt9m111_power_on(struct mt9m111 *mt9m111) static void mt9m111_power_off(struct mt9m111 *mt9m111) { mt9m111_suspend(mt9m111); - if (mt9m111->regulator) - regulator_disable(mt9m111->regulator); + regulator_disable(mt9m111->regulator); v4l2_clk_disable(mt9m111->clk); } -- cgit v1.2.3 From 04bc4f6631f7e47a9fe47ea6c0794ed56d9b3cf8 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 31 May 2019 16:12:49 -0400 Subject: media: mt9m111: Fix error handling in mt9m111_power_on The mt9m111_power_on function did not properly clean up whenever it encountered an error. Do that now. Signed-off-by: Sakari Ailus Reviewed-by: Marco Felsch Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/mt9m111.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers/media/i2c/mt9m111.c') diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c index bb19f8c346cb..593ebe5e2cb6 100644 --- a/drivers/media/i2c/mt9m111.c +++ b/drivers/media/i2c/mt9m111.c @@ -986,13 +986,21 @@ static int mt9m111_power_on(struct mt9m111 *mt9m111) ret = regulator_enable(mt9m111->regulator); if (ret < 0) - return ret; + goto out_clk_disable; ret = mt9m111_resume(mt9m111); - if (ret < 0) { - dev_err(&client->dev, "Failed to resume the sensor: %d\n", ret); - v4l2_clk_disable(mt9m111->clk); - } + if (ret < 0) + goto out_regulator_disable; + + return 0; + +out_regulator_disable: + regulator_disable(mt9m111->regulator); + +out_clk_disable: + v4l2_clk_disable(mt9m111->clk); + + dev_err(&client->dev, "Failed to resume the sensor: %d\n", ret); return ret; } -- cgit v1.2.3 From 54ed1c182ed28b09683240fe7ebff3000107d956 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 8 Jun 2019 06:55:47 -0400 Subject: media: i2c: mt9m111: simplify getting the adapter of a client We have a dedicated pointer for that, so use it. Much easier to read and less computation involved. Signed-off-by: Wolfram Sang Reviewed-by: Simon Horman Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/mt9m111.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/i2c/mt9m111.c') diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c index 593ebe5e2cb6..bd3a51c3b081 100644 --- a/drivers/media/i2c/mt9m111.c +++ b/drivers/media/i2c/mt9m111.c @@ -1250,7 +1250,7 @@ static int mt9m111_probe(struct i2c_client *client, const struct i2c_device_id *did) { struct mt9m111 *mt9m111; - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct i2c_adapter *adapter = client->adapter; int ret; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { -- cgit v1.2.3 From 8d4e29a51a954b43e06d916772fa4f50b7e5bbd6 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Mon, 3 Jun 2019 16:01:55 -0400 Subject: media: mt9m111: fix fw-node refactoring In the patch refactoring the fw-node, the mt9m111 was broken for all platform_data based platforms, which were the first aim of this driver. Only the devicetree platform are still functional, probably because the testing was done on these. The result is that -EINVAL is systematically return for such platforms, what this patch fixes. [Sakari Ailus: Rework this to resolve a merge conflict and use dev_fwnode] Fixes: 98480d65c48c ("media: mt9m111: allow to setup pixclk polarity") Signed-off-by: Robert Jarzmik Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/mt9m111.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/media/i2c/mt9m111.c') diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c index bd3a51c3b081..d10fe3712036 100644 --- a/drivers/media/i2c/mt9m111.c +++ b/drivers/media/i2c/mt9m111.c @@ -1263,9 +1263,11 @@ static int mt9m111_probe(struct i2c_client *client, if (!mt9m111) return -ENOMEM; - ret = mt9m111_probe_fw(client, mt9m111); - if (ret) - return ret; + if (dev_fwnode(&client->dev)) { + ret = mt9m111_probe_fw(client, mt9m111); + if (ret) + return ret; + } mt9m111->clk = v4l2_clk_get(&client->dev, "mclk"); if (IS_ERR(mt9m111->clk)) -- cgit v1.2.3