diff options
Diffstat (limited to 'drivers/media/i2c/mt9v111.c')
| -rw-r--r-- | drivers/media/i2c/mt9v111.c | 113 |
1 files changed, 56 insertions, 57 deletions
diff --git a/drivers/media/i2c/mt9v111.c b/drivers/media/i2c/mt9v111.c index 61ae6a0d5679..64a758c95ab7 100644 --- a/drivers/media/i2c/mt9v111.c +++ b/drivers/media/i2c/mt9v111.c @@ -35,7 +35,7 @@ * The IFP can produce several output image formats from the sensor core * output. This driver currently supports only YUYV format permutations. * - * The driver allows manual frame rate control through s_frame_interval subdev + * The driver allows manual frame rate control through set_frame_interval subdev * operation or V4L2_CID_V/HBLANK controls, but it is known that the * auto-exposure algorithm might modify the programmed frame rate. While the * driver initially programs the sensor with auto-exposure and @@ -121,9 +121,7 @@ struct mt9v111_dev { u8 addr_space; struct v4l2_subdev sd; -#if IS_ENABLED(CONFIG_MEDIA_CONTROLLER) struct media_pad pad; -#endif struct v4l2_ctrl *auto_awb; struct v4l2_ctrl *auto_exp; @@ -367,8 +365,6 @@ static int __mt9v111_power_on(struct v4l2_subdev *sd) if (ret) return ret; - clk_set_rate(mt9v111->clk, mt9v111->sysclk); - gpiod_set_value(mt9v111->standby, 0); usleep_range(500, 1000); @@ -534,8 +530,8 @@ static int mt9v111_calc_frame_rate(struct mt9v111_dev *mt9v111, static int mt9v111_hw_config(struct mt9v111_dev *mt9v111) { struct i2c_client *c = mt9v111->client; - unsigned int ret; u16 outfmtctrl2; + int ret; /* Force device reset. */ ret = __mt9v111_hw_reset(mt9v111); @@ -633,7 +629,7 @@ static int mt9v111_hw_config(struct mt9v111_dev *mt9v111) /* * Set pixel integration time to the whole frame time. - * This value controls the the shutter delay when running with AE + * This value controls the shutter delay when running with AE * disabled. If longer than frame time, it affects the output * frame rate. */ @@ -721,8 +717,9 @@ error_unlock: return ret; } -static int mt9v111_s_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_frame_interval *ival) +static int mt9v111_set_frame_interval(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_frame_interval *ival) { struct mt9v111_dev *mt9v111 = sd_to_mt9v111(sd); struct v4l2_fract *tpf = &ival->interval; @@ -731,6 +728,13 @@ static int mt9v111_s_frame_interval(struct v4l2_subdev *sd, tpf->denominator; unsigned int max_fps; + /* + * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2 + * subdev active state API. + */ + if (ival->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; + if (!tpf->numerator) tpf->numerator = 1; @@ -773,12 +777,20 @@ static int mt9v111_s_frame_interval(struct v4l2_subdev *sd, return 0; } -static int mt9v111_g_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_frame_interval *ival) +static int mt9v111_get_frame_interval(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_frame_interval *ival) { struct mt9v111_dev *mt9v111 = sd_to_mt9v111(sd); struct v4l2_fract *tpf = &ival->interval; + /* + * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2 + * subdev active state API. + */ + if (ival->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; + mutex_lock(&mt9v111->stream_mutex); tpf->numerator = 1; @@ -791,17 +803,13 @@ static int mt9v111_g_frame_interval(struct v4l2_subdev *sd, static struct v4l2_mbus_framefmt *__mt9v111_get_pad_format( struct mt9v111_dev *mt9v111, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: -#if IS_ENABLED(CONFIG_VIDEO_V4L2_SUBDEV_API) - return v4l2_subdev_get_try_format(&mt9v111->sd, cfg, pad); -#else - return &cfg->try_fmt; -#endif + return v4l2_subdev_state_get_format(sd_state, pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &mt9v111->fmt; default: @@ -810,7 +818,7 @@ static struct v4l2_mbus_framefmt *__mt9v111_get_pad_format( } static int mt9v111_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index > ARRAY_SIZE(mt9v111_formats) - 1) @@ -822,7 +830,7 @@ static int mt9v111_enum_mbus_code(struct v4l2_subdev *subdev, } static int mt9v111_enum_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *fie) { unsigned int i; @@ -845,7 +853,7 @@ static int mt9v111_enum_frame_interval(struct v4l2_subdev *sd, } static int mt9v111_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->pad || fse->index >= ARRAY_SIZE(mt9v111_frame_sizes)) @@ -860,7 +868,7 @@ static int mt9v111_enum_frame_size(struct v4l2_subdev *subdev, } static int mt9v111_get_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct mt9v111_dev *mt9v111 = sd_to_mt9v111(subdev); @@ -869,7 +877,8 @@ static int mt9v111_get_format(struct v4l2_subdev *subdev, return -EINVAL; mutex_lock(&mt9v111->stream_mutex); - format->format = *__mt9v111_get_pad_format(mt9v111, cfg, format->pad, + format->format = *__mt9v111_get_pad_format(mt9v111, sd_state, + format->pad, format->which); mutex_unlock(&mt9v111->stream_mutex); @@ -877,7 +886,7 @@ static int mt9v111_get_format(struct v4l2_subdev *subdev, } static int mt9v111_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct mt9v111_dev *mt9v111 = sd_to_mt9v111(subdev); @@ -925,7 +934,7 @@ static int mt9v111_set_format(struct v4l2_subdev *subdev, new_fmt.height = mt9v111_frame_sizes[idx].height; /* Update the device (or pad) format if it has changed. */ - __fmt = __mt9v111_get_pad_format(mt9v111, cfg, format->pad, + __fmt = __mt9v111_get_pad_format(mt9v111, sd_state, format->pad, format->which); /* Format hasn't changed, stop here. */ @@ -953,10 +962,10 @@ done: return 0; } -static int mt9v111_init_cfg(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg) +static int mt9v111_init_state(struct v4l2_subdev *subdev, + struct v4l2_subdev_state *sd_state) { - cfg->try_fmt = mt9v111_def_fmt; + *v4l2_subdev_state_get_format(sd_state, 0) = mt9v111_def_fmt; return 0; } @@ -967,17 +976,16 @@ static const struct v4l2_subdev_core_ops mt9v111_core_ops = { static const struct v4l2_subdev_video_ops mt9v111_video_ops = { .s_stream = mt9v111_s_stream, - .s_frame_interval = mt9v111_s_frame_interval, - .g_frame_interval = mt9v111_g_frame_interval, }; static const struct v4l2_subdev_pad_ops mt9v111_pad_ops = { - .init_cfg = mt9v111_init_cfg, .enum_mbus_code = mt9v111_enum_mbus_code, .enum_frame_size = mt9v111_enum_frame_size, .enum_frame_interval = mt9v111_enum_frame_interval, .get_fmt = mt9v111_get_format, .set_fmt = mt9v111_set_format, + .get_frame_interval = mt9v111_get_frame_interval, + .set_frame_interval = mt9v111_set_frame_interval, }; static const struct v4l2_subdev_ops mt9v111_ops = { @@ -986,11 +994,13 @@ static const struct v4l2_subdev_ops mt9v111_ops = { .pad = &mt9v111_pad_ops, }; -#if IS_ENABLED(CONFIG_MEDIA_CONTROLLER) +static const struct v4l2_subdev_internal_ops mt9v111_internal_ops = { + .init_state = mt9v111_init_state, +}; + static const struct media_entity_operations mt9v111_subdev_entity_ops = { .link_validate = v4l2_subdev_link_validate, }; -#endif /* --- V4L2 ctrl --- */ static int mt9v111_s_ctrl(struct v4l2_ctrl *ctrl) @@ -1117,9 +1127,10 @@ static int mt9v111_probe(struct i2c_client *client) mt9v111->dev = &client->dev; mt9v111->client = client; - mt9v111->clk = devm_clk_get(&client->dev, NULL); + mt9v111->clk = devm_v4l2_sensor_clk_get(&client->dev, NULL); if (IS_ERR(mt9v111->clk)) - return PTR_ERR(mt9v111->clk); + return dev_err_probe(&client->dev, PTR_ERR(mt9v111->clk), + "failed to get the clock\n"); mt9v111->sysclk = clk_get_rate(mt9v111->clk); if (mt9v111->sysclk > MT9V111_MAX_CLKIN) @@ -1128,24 +1139,24 @@ static int mt9v111_probe(struct i2c_client *client) mt9v111->oe = devm_gpiod_get_optional(&client->dev, "enable", GPIOD_OUT_LOW); if (IS_ERR(mt9v111->oe)) { - dev_err(&client->dev, "Unable to get GPIO \"enable\": %ld\n", - PTR_ERR(mt9v111->oe)); + dev_err(&client->dev, "Unable to get GPIO \"enable\": %pe\n", + mt9v111->oe); return PTR_ERR(mt9v111->oe); } mt9v111->standby = devm_gpiod_get_optional(&client->dev, "standby", GPIOD_OUT_HIGH); if (IS_ERR(mt9v111->standby)) { - dev_err(&client->dev, "Unable to get GPIO \"standby\": %ld\n", - PTR_ERR(mt9v111->standby)); + dev_err(&client->dev, "Unable to get GPIO \"standby\": %pe\n", + mt9v111->standby); return PTR_ERR(mt9v111->standby); } mt9v111->reset = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(mt9v111->reset)) { - dev_err(&client->dev, "Unable to get GPIO \"reset\": %ld\n", - PTR_ERR(mt9v111->reset)); + dev_err(&client->dev, "Unable to get GPIO \"reset\": %pe\n", + mt9v111->reset); return PTR_ERR(mt9v111->reset); } @@ -1201,8 +1212,8 @@ static int mt9v111_probe(struct i2c_client *client) mt9v111->pending = true; v4l2_i2c_subdev_init(&mt9v111->sd, client, &mt9v111_ops); + mt9v111->sd.internal_ops = &mt9v111_internal_ops; -#if IS_ENABLED(CONFIG_MEDIA_CONTROLLER) mt9v111->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; mt9v111->sd.entity.ops = &mt9v111_subdev_entity_ops; mt9v111->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; @@ -1211,7 +1222,6 @@ static int mt9v111_probe(struct i2c_client *client) ret = media_entity_pads_init(&mt9v111->sd.entity, 1, &mt9v111->pad); if (ret) goto error_free_entity; -#endif ret = mt9v111_chip_probe(mt9v111); if (ret) @@ -1224,9 +1234,7 @@ static int mt9v111_probe(struct i2c_client *client) return 0; error_free_entity: -#if IS_ENABLED(CONFIG_MEDIA_CONTROLLER) media_entity_cleanup(&mt9v111->sd.entity); -#endif error_free_ctrls: v4l2_ctrl_handler_free(&mt9v111->ctrls); @@ -1237,42 +1245,33 @@ error_free_ctrls: return ret; } -static int mt9v111_remove(struct i2c_client *client) +static void mt9v111_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); struct mt9v111_dev *mt9v111 = sd_to_mt9v111(sd); v4l2_async_unregister_subdev(sd); -#if IS_ENABLED(CONFIG_MEDIA_CONTROLLER) media_entity_cleanup(&sd->entity); -#endif v4l2_ctrl_handler_free(&mt9v111->ctrls); mutex_destroy(&mt9v111->pwr_mutex); mutex_destroy(&mt9v111->stream_mutex); - - devm_gpiod_put(mt9v111->dev, mt9v111->oe); - devm_gpiod_put(mt9v111->dev, mt9v111->standby); - devm_gpiod_put(mt9v111->dev, mt9v111->reset); - - devm_clk_put(mt9v111->dev, mt9v111->clk); - - return 0; } static const struct of_device_id mt9v111_of_match[] = { { .compatible = "aptina,mt9v111", }, - { /* sentinel */ }, + { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, mt9v111_of_match); static struct i2c_driver mt9v111_driver = { .driver = { .name = "mt9v111", .of_match_table = mt9v111_of_match, }, - .probe_new = mt9v111_probe, + .probe = mt9v111_probe, .remove = mt9v111_remove, }; |
