summaryrefslogtreecommitdiff
path: root/drivers/media/i2c/mt9m111.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/i2c/mt9m111.c')
-rw-r--r--drivers/media/i2c/mt9m111.c91
1 files changed, 50 insertions, 41 deletions
diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c
index 91a44359bcd3..3532c7c38bec 100644
--- a/drivers/media/i2c/mt9m111.c
+++ b/drivers/media/i2c/mt9m111.c
@@ -9,7 +9,6 @@
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/log2.h>
-#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/regulator/consumer.h>
#include <linux/v4l2-mediabus.h>
@@ -245,9 +244,7 @@ struct mt9m111 {
bool is_streaming;
/* user point of view - 0: falling 1: rising edge */
unsigned int pclk_sample:1;
-#ifdef CONFIG_MEDIA_CONTROLLER
struct media_pad pad;
-#endif
};
static const struct mt9m111_mode_info mt9m111_mode_data[MT9M111_NUM_MODES] = {
@@ -528,13 +525,9 @@ static int mt9m111_get_fmt(struct v4l2_subdev *sd,
return -EINVAL;
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
-#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
- mf = v4l2_subdev_get_try_format(sd, sd_state, format->pad);
+ mf = v4l2_subdev_state_get_format(sd_state, format->pad);
format->format = *mf;
return 0;
-#else
- return -EINVAL;
-#endif
}
mf->width = mt9m111->width;
@@ -678,7 +671,7 @@ static int mt9m111_set_fmt(struct v4l2_subdev *sd,
mf->xfer_func = V4L2_XFER_FUNC_DEFAULT;
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
- sd_state->pads->try_fmt = *mf;
+ *v4l2_subdev_state_get_format(sd_state, 0) = *mf;
return 0;
}
@@ -1052,18 +1045,27 @@ static const struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
#endif
};
-static int mt9m111_g_frame_interval(struct v4l2_subdev *sd,
- struct v4l2_subdev_frame_interval *fi)
+static int mt9m111_get_frame_interval(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_frame_interval *fi)
{
struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
+ /*
+ * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
+ * subdev active state API.
+ */
+ if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
+
fi->interval = mt9m111->frame_interval;
return 0;
}
-static int mt9m111_s_frame_interval(struct v4l2_subdev *sd,
- struct v4l2_subdev_frame_interval *fi)
+static int mt9m111_set_frame_interval(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_frame_interval *fi)
{
struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
const struct mt9m111_mode_info *mode;
@@ -1073,6 +1075,13 @@ static int mt9m111_s_frame_interval(struct v4l2_subdev *sd,
if (mt9m111->is_streaming)
return -EBUSY;
+ /*
+ * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
+ * subdev active state API.
+ */
+ if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
+
if (fi->pad != 0)
return -EINVAL;
@@ -1118,12 +1127,11 @@ static int mt9m111_s_stream(struct v4l2_subdev *sd, int enable)
return 0;
}
-static int mt9m111_init_cfg(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state)
+static int mt9m111_init_state(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state)
{
-#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
struct v4l2_mbus_framefmt *format =
- v4l2_subdev_get_try_format(sd, sd_state, 0);
+ v4l2_subdev_state_get_format(sd_state, 0);
format->width = MT9M111_MAX_WIDTH;
format->height = MT9M111_MAX_HEIGHT;
@@ -1133,7 +1141,7 @@ static int mt9m111_init_cfg(struct v4l2_subdev *sd,
format->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
format->quantization = V4L2_QUANTIZATION_DEFAULT;
format->xfer_func = V4L2_XFER_FUNC_DEFAULT;
-#endif
+
return 0;
}
@@ -1143,31 +1151,32 @@ static int mt9m111_get_mbus_config(struct v4l2_subdev *sd,
{
struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
- cfg->flags = V4L2_MBUS_MASTER |
- V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
- V4L2_MBUS_DATA_ACTIVE_HIGH;
+ cfg->type = V4L2_MBUS_PARALLEL;
- cfg->flags |= mt9m111->pclk_sample ? V4L2_MBUS_PCLK_SAMPLE_RISING :
- V4L2_MBUS_PCLK_SAMPLE_FALLING;
+ cfg->bus.parallel.flags = V4L2_MBUS_MASTER |
+ V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+ V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+ V4L2_MBUS_DATA_ACTIVE_HIGH;
- cfg->type = V4L2_MBUS_PARALLEL;
+ cfg->bus.parallel.flags |= mt9m111->pclk_sample ?
+ V4L2_MBUS_PCLK_SAMPLE_RISING :
+ V4L2_MBUS_PCLK_SAMPLE_FALLING;
return 0;
}
static const struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
.s_stream = mt9m111_s_stream,
- .g_frame_interval = mt9m111_g_frame_interval,
- .s_frame_interval = mt9m111_s_frame_interval,
};
static const struct v4l2_subdev_pad_ops mt9m111_subdev_pad_ops = {
- .init_cfg = mt9m111_init_cfg,
.enum_mbus_code = mt9m111_enum_mbus_code,
.get_selection = mt9m111_get_selection,
.set_selection = mt9m111_set_selection,
.get_fmt = mt9m111_get_fmt,
.set_fmt = mt9m111_set_fmt,
+ .get_frame_interval = mt9m111_get_frame_interval,
+ .set_frame_interval = mt9m111_set_frame_interval,
.get_mbus_config = mt9m111_get_mbus_config,
};
@@ -1177,6 +1186,10 @@ static const struct v4l2_subdev_ops mt9m111_subdev_ops = {
.pad = &mt9m111_subdev_pad_ops,
};
+static const struct v4l2_subdev_internal_ops mt9m111_internal_ops = {
+ .init_state = mt9m111_init_state,
+};
+
/*
* Interface active, can use i2c. If it fails, it can indeed mean, that
* this wasn't our capture interface, so, we wait for the right one
@@ -1266,14 +1279,15 @@ static int mt9m111_probe(struct i2c_client *client)
return ret;
}
- mt9m111->clk = devm_clk_get(&client->dev, "mclk");
+ mt9m111->clk = devm_v4l2_sensor_clk_get(&client->dev, "mclk");
if (IS_ERR(mt9m111->clk))
- return PTR_ERR(mt9m111->clk);
+ return dev_err_probe(&client->dev, PTR_ERR(mt9m111->clk),
+ "failed to get mclk\n");
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));
+ dev_err(&client->dev, "regulator not found: %pe\n",
+ mt9m111->regulator);
return PTR_ERR(mt9m111->regulator);
}
@@ -1281,6 +1295,7 @@ static int mt9m111_probe(struct i2c_client *client)
mt9m111->ctx = &context_b;
v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops);
+ mt9m111->subdev.internal_ops = &mt9m111_internal_ops;
mt9m111->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
V4L2_SUBDEV_FL_HAS_EVENTS;
@@ -1314,13 +1329,11 @@ static int mt9m111_probe(struct i2c_client *client)
return ret;
}
-#ifdef CONFIG_MEDIA_CONTROLLER
mt9m111->pad.flags = MEDIA_PAD_FL_SOURCE;
mt9m111->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR;
ret = media_entity_pads_init(&mt9m111->subdev.entity, 1, &mt9m111->pad);
if (ret < 0)
goto out_hdlfree;
-#endif
mt9m111->current_mode = &mt9m111_mode_data[MT9M111_MODE_SXGA_15FPS];
mt9m111->frame_interval.numerator = 1;
@@ -1349,24 +1362,20 @@ static int mt9m111_probe(struct i2c_client *client)
return 0;
out_entityclean:
-#ifdef CONFIG_MEDIA_CONTROLLER
media_entity_cleanup(&mt9m111->subdev.entity);
out_hdlfree:
-#endif
v4l2_ctrl_handler_free(&mt9m111->hdl);
return ret;
}
-static int mt9m111_remove(struct i2c_client *client)
+static void mt9m111_remove(struct i2c_client *client)
{
struct mt9m111 *mt9m111 = to_mt9m111(client);
v4l2_async_unregister_subdev(&mt9m111->subdev);
media_entity_cleanup(&mt9m111->subdev.entity);
v4l2_ctrl_handler_free(&mt9m111->hdl);
-
- return 0;
}
static const struct of_device_id mt9m111_of_match[] = {
{ .compatible = "micron,mt9m111", },
@@ -1375,7 +1384,7 @@ static const struct of_device_id mt9m111_of_match[] = {
MODULE_DEVICE_TABLE(of, mt9m111_of_match);
static const struct i2c_device_id mt9m111_id[] = {
- { "mt9m111", 0 },
+ { "mt9m111" },
{ }
};
MODULE_DEVICE_TABLE(i2c, mt9m111_id);
@@ -1383,9 +1392,9 @@ MODULE_DEVICE_TABLE(i2c, mt9m111_id);
static struct i2c_driver mt9m111_i2c_driver = {
.driver = {
.name = "mt9m111",
- .of_match_table = of_match_ptr(mt9m111_of_match),
+ .of_match_table = mt9m111_of_match,
},
- .probe_new = mt9m111_probe,
+ .probe = mt9m111_probe,
.remove = mt9m111_remove,
.id_table = mt9m111_id,
};