Commit 5d7cc01b authored by Robert Jarzmik's avatar Robert Jarzmik Committed by Mauro Carvalho Chehab

[media] media: mt9m111: make a standalone v4l2 subdevice

Remove the soc_camera adherence. Mostly the change removes the power
manipulation provided by soc_camera, and instead :
 - powers on the sensor when the s_power control is activated
 - powers on the sensor in initial probe
 - enables and disables the MCLK provided to it in power on/off

This patch also drops support for inverters on synchronisation and clock
lines. It is assumed, if any board ever needs such inverters, support
for them can be added in the future
Acked-by: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: default avatarRobert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent fe713d60
...@@ -16,10 +16,11 @@ ...@@ -16,10 +16,11 @@
#include <linux/v4l2-mediabus.h> #include <linux/v4l2-mediabus.h>
#include <linux/module.h> #include <linux/module.h>
#include <media/soc_camera.h> #include <media/v4l2-async.h>
#include <media/v4l2-clk.h> #include <media/v4l2-clk.h>
#include <media/v4l2-common.h> #include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h> #include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
/* /*
* MT9M111, MT9M112 and MT9M131: * MT9M111, MT9M112 and MT9M131:
...@@ -391,7 +392,7 @@ static int mt9m111_set_selection(struct v4l2_subdev *sd, ...@@ -391,7 +392,7 @@ static int mt9m111_set_selection(struct v4l2_subdev *sd,
struct mt9m111 *mt9m111 = to_mt9m111(client); struct mt9m111 *mt9m111 = to_mt9m111(client);
struct v4l2_rect rect = sel->r; struct v4l2_rect rect = sel->r;
int width, height; int width, height;
int ret; int ret, align = 0;
if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
sel->target != V4L2_SEL_TGT_CROP) sel->target != V4L2_SEL_TGT_CROP)
...@@ -400,17 +401,19 @@ static int mt9m111_set_selection(struct v4l2_subdev *sd, ...@@ -400,17 +401,19 @@ static int mt9m111_set_selection(struct v4l2_subdev *sd,
if (mt9m111->fmt->code == MEDIA_BUS_FMT_SBGGR8_1X8 || if (mt9m111->fmt->code == MEDIA_BUS_FMT_SBGGR8_1X8 ||
mt9m111->fmt->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) { mt9m111->fmt->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) {
/* Bayer format - even size lengths */ /* Bayer format - even size lengths */
rect.width = ALIGN(rect.width, 2); align = 1;
rect.height = ALIGN(rect.height, 2);
/* Let the user play with the starting pixel */ /* Let the user play with the starting pixel */
} }
/* FIXME: the datasheet doesn't specify minimum sizes */ /* FIXME: the datasheet doesn't specify minimum sizes */
soc_camera_limit_side(&rect.left, &rect.width, v4l_bound_align_image(&rect.width, 2, MT9M111_MAX_WIDTH, align,
MT9M111_MIN_DARK_COLS, 2, MT9M111_MAX_WIDTH); &rect.height, 2, MT9M111_MAX_HEIGHT, align, 0);
rect.left = clamp(rect.left, MT9M111_MIN_DARK_COLS,
soc_camera_limit_side(&rect.top, &rect.height, MT9M111_MIN_DARK_COLS + MT9M111_MAX_WIDTH -
MT9M111_MIN_DARK_ROWS, 2, MT9M111_MAX_HEIGHT); (__s32)rect.width);
rect.top = clamp(rect.top, MT9M111_MIN_DARK_ROWS,
MT9M111_MIN_DARK_ROWS + MT9M111_MAX_HEIGHT -
(__s32)rect.height);
width = min(mt9m111->width, rect.width); width = min(mt9m111->width, rect.width);
height = min(mt9m111->height, rect.height); height = min(mt9m111->height, rect.height);
...@@ -779,17 +782,16 @@ static int mt9m111_init(struct mt9m111 *mt9m111) ...@@ -779,17 +782,16 @@ static int mt9m111_init(struct mt9m111 *mt9m111)
static int mt9m111_power_on(struct mt9m111 *mt9m111) static int mt9m111_power_on(struct mt9m111 *mt9m111)
{ {
struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
int ret; int ret;
ret = soc_camera_power_on(&client->dev, ssdd, mt9m111->clk); ret = v4l2_clk_enable(mt9m111->clk);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = mt9m111_resume(mt9m111); ret = mt9m111_resume(mt9m111);
if (ret < 0) { if (ret < 0) {
dev_err(&client->dev, "Failed to resume the sensor: %d\n", ret); dev_err(&client->dev, "Failed to resume the sensor: %d\n", ret);
soc_camera_power_off(&client->dev, ssdd, mt9m111->clk); v4l2_clk_disable(mt9m111->clk);
} }
return ret; return ret;
...@@ -797,11 +799,8 @@ static int mt9m111_power_on(struct mt9m111 *mt9m111) ...@@ -797,11 +799,8 @@ static int mt9m111_power_on(struct mt9m111 *mt9m111)
static void mt9m111_power_off(struct mt9m111 *mt9m111) static void mt9m111_power_off(struct mt9m111 *mt9m111)
{ {
struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
mt9m111_suspend(mt9m111); mt9m111_suspend(mt9m111);
soc_camera_power_off(&client->dev, ssdd, mt9m111->clk); v4l2_clk_disable(mt9m111->clk);
} }
static int mt9m111_s_power(struct v4l2_subdev *sd, int on) static int mt9m111_s_power(struct v4l2_subdev *sd, int on)
...@@ -858,14 +857,10 @@ static int mt9m111_enum_mbus_code(struct v4l2_subdev *sd, ...@@ -858,14 +857,10 @@ static int mt9m111_enum_mbus_code(struct v4l2_subdev *sd,
static int mt9m111_g_mbus_config(struct v4l2_subdev *sd, static int mt9m111_g_mbus_config(struct v4l2_subdev *sd,
struct v4l2_mbus_config *cfg) struct v4l2_mbus_config *cfg)
{ {
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING | cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
V4L2_MBUS_DATA_ACTIVE_HIGH; V4L2_MBUS_DATA_ACTIVE_HIGH;
cfg->type = V4L2_MBUS_PARALLEL; cfg->type = V4L2_MBUS_PARALLEL;
cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
return 0; return 0;
} }
...@@ -936,20 +931,8 @@ static int mt9m111_probe(struct i2c_client *client, ...@@ -936,20 +931,8 @@ static int mt9m111_probe(struct i2c_client *client,
{ {
struct mt9m111 *mt9m111; struct mt9m111 *mt9m111;
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
int ret; int ret;
if (client->dev.of_node) {
ssdd = devm_kzalloc(&client->dev, sizeof(*ssdd), GFP_KERNEL);
if (!ssdd)
return -ENOMEM;
client->dev.platform_data = ssdd;
}
if (!ssdd) {
dev_err(&client->dev, "mt9m111: driver needs platform data\n");
return -EINVAL;
}
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
dev_warn(&adapter->dev, dev_warn(&adapter->dev,
"I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
...@@ -995,10 +978,6 @@ static int mt9m111_probe(struct i2c_client *client, ...@@ -995,10 +978,6 @@ static int mt9m111_probe(struct i2c_client *client,
mt9m111->lastpage = -1; mt9m111->lastpage = -1;
mutex_init(&mt9m111->power_lock); mutex_init(&mt9m111->power_lock);
ret = soc_camera_power_init(&client->dev, ssdd);
if (ret < 0)
goto out_hdlfree;
ret = mt9m111_video_probe(client); ret = mt9m111_video_probe(client);
if (ret < 0) if (ret < 0)
goto out_hdlfree; goto out_hdlfree;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment