diff options
Diffstat (limited to 'drivers/media/i2c/ov13858.c')
| -rw-r--r-- | drivers/media/i2c/ov13858.c | 129 |
1 files changed, 45 insertions, 84 deletions
diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c index 3db3e64fa3ff..162b49046990 100644 --- a/drivers/media/i2c/ov13858.c +++ b/drivers/media/i2c/ov13858.c @@ -2,6 +2,7 @@ // Copyright (c) 2017 Intel Corporation. #include <linux/acpi.h> +#include <linux/clk.h> #include <linux/i2c.h> #include <linux/module.h> #include <linux/pm_runtime.h> @@ -1028,6 +1029,9 @@ static const struct ov13858_mode supported_modes[] = { }; struct ov13858 { + struct device *dev; + struct clk *clk; + struct v4l2_subdev sd; struct media_pad pad; @@ -1044,9 +1048,6 @@ struct ov13858 { /* Mutex for serialized access */ struct mutex mutex; - - /* Streaming on/off */ - bool streaming; }; #define to_ov13858(_sd) container_of(_sd, struct ov13858, sd) @@ -1120,7 +1121,6 @@ static int ov13858_write_reg(struct ov13858 *ov13858, u16 reg, u32 len, static int ov13858_write_regs(struct ov13858 *ov13858, const struct ov13858_reg *regs, u32 len) { - struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd); int ret; u32 i; @@ -1129,7 +1129,7 @@ static int ov13858_write_regs(struct ov13858 *ov13858, regs[i].val); if (ret) { dev_err_ratelimited( - &client->dev, + ov13858->dev, "Failed to write reg 0x%4.4x. error = %d\n", regs[i].address, ret); @@ -1150,9 +1150,8 @@ static int ov13858_write_reg_list(struct ov13858 *ov13858, static int ov13858_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct ov13858 *ov13858 = to_ov13858(sd); - struct v4l2_mbus_framefmt *try_fmt = v4l2_subdev_get_try_format(sd, - fh->state, - 0); + struct v4l2_mbus_framefmt *try_fmt = v4l2_subdev_state_get_format(fh->state, + 0); mutex_lock(&ov13858->mutex); @@ -1213,7 +1212,6 @@ static int ov13858_set_ctrl(struct v4l2_ctrl *ctrl) { struct ov13858 *ov13858 = container_of(ctrl->handler, struct ov13858, ctrl_handler); - struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd); s64 max; int ret; @@ -1232,7 +1230,7 @@ static int ov13858_set_ctrl(struct v4l2_ctrl *ctrl) * Applying V4L2 control value only happens * when power is up for streaming */ - if (!pm_runtime_get_if_in_use(&client->dev)) + if (!pm_runtime_get_if_in_use(ov13858->dev)) return 0; ret = 0; @@ -1260,13 +1258,13 @@ static int ov13858_set_ctrl(struct v4l2_ctrl *ctrl) ret = ov13858_enable_test_pattern(ov13858, ctrl->val); break; default: - dev_info(&client->dev, + dev_info(ov13858->dev, "ctrl(id:0x%x,val:0x%x) is not handled\n", ctrl->id, ctrl->val); break; } - pm_runtime_put(&client->dev); + pm_runtime_put(ov13858->dev); return ret; } @@ -1320,10 +1318,9 @@ static int ov13858_do_get_pad_format(struct ov13858 *ov13858, struct v4l2_subdev_format *fmt) { struct v4l2_mbus_framefmt *framefmt; - struct v4l2_subdev *sd = &ov13858->sd; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); + framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad); fmt->format = *framefmt; } else { ov13858_update_pad_format(ov13858->cur_mode, fmt); @@ -1372,7 +1369,7 @@ ov13858_set_pad_format(struct v4l2_subdev *sd, fmt->format.width, fmt->format.height); ov13858_update_pad_format(mode, fmt); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); + framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad); *framefmt = fmt->format; } else { ov13858->cur_mode = mode; @@ -1413,7 +1410,6 @@ static int ov13858_get_skip_frames(struct v4l2_subdev *sd, u32 *frames) /* Start streaming */ static int ov13858_start_streaming(struct ov13858 *ov13858) { - struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd); const struct ov13858_reg_list *reg_list; int ret, link_freq_index; @@ -1421,7 +1417,7 @@ static int ov13858_start_streaming(struct ov13858 *ov13858) ret = ov13858_write_reg(ov13858, OV13858_REG_SOFTWARE_RST, OV13858_REG_VALUE_08BIT, OV13858_SOFTWARE_RST); if (ret) { - dev_err(&client->dev, "%s failed to set powerup registers\n", + dev_err(ov13858->dev, "%s failed to set powerup registers\n", __func__); return ret; } @@ -1431,7 +1427,7 @@ static int ov13858_start_streaming(struct ov13858 *ov13858) reg_list = &link_freq_configs[link_freq_index].reg_list; ret = ov13858_write_reg_list(ov13858, reg_list); if (ret) { - dev_err(&client->dev, "%s failed to set plls\n", __func__); + dev_err(ov13858->dev, "%s failed to set plls\n", __func__); return ret; } @@ -1439,7 +1435,7 @@ static int ov13858_start_streaming(struct ov13858 *ov13858) reg_list = &ov13858->cur_mode->reg_list; ret = ov13858_write_reg_list(ov13858, reg_list); if (ret) { - dev_err(&client->dev, "%s failed to set mode\n", __func__); + dev_err(ov13858->dev, "%s failed to set mode\n", __func__); return ret; } @@ -1463,17 +1459,12 @@ static int ov13858_stop_streaming(struct ov13858 *ov13858) static int ov13858_set_stream(struct v4l2_subdev *sd, int enable) { struct ov13858 *ov13858 = to_ov13858(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); int ret = 0; mutex_lock(&ov13858->mutex); - if (ov13858->streaming == enable) { - mutex_unlock(&ov13858->mutex); - return 0; - } if (enable) { - ret = pm_runtime_resume_and_get(&client->dev); + ret = pm_runtime_resume_and_get(ov13858->dev); if (ret < 0) goto err_unlock; @@ -1486,57 +1477,24 @@ static int ov13858_set_stream(struct v4l2_subdev *sd, int enable) goto err_rpm_put; } else { ov13858_stop_streaming(ov13858); - pm_runtime_put(&client->dev); + pm_runtime_put(ov13858->dev); } - ov13858->streaming = enable; mutex_unlock(&ov13858->mutex); return ret; err_rpm_put: - pm_runtime_put(&client->dev); + pm_runtime_put(ov13858->dev); err_unlock: mutex_unlock(&ov13858->mutex); return ret; } -static int __maybe_unused ov13858_suspend(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ov13858 *ov13858 = to_ov13858(sd); - - if (ov13858->streaming) - ov13858_stop_streaming(ov13858); - - return 0; -} - -static int __maybe_unused ov13858_resume(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ov13858 *ov13858 = to_ov13858(sd); - int ret; - - if (ov13858->streaming) { - ret = ov13858_start_streaming(ov13858); - if (ret) - goto error; - } - - return 0; - -error: - ov13858_stop_streaming(ov13858); - ov13858->streaming = false; - return ret; -} - /* Verify chip ID */ static int ov13858_identify_module(struct ov13858 *ov13858) { - struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd); int ret; u32 val; @@ -1546,7 +1504,7 @@ static int ov13858_identify_module(struct ov13858 *ov13858) return ret; if (val != OV13858_CHIP_ID) { - dev_err(&client->dev, "chip id mismatch: %x!=%x\n", + dev_err(ov13858->dev, "chip id mismatch: %x!=%x\n", OV13858_CHIP_ID, val); return -EIO; } @@ -1593,7 +1551,6 @@ static const struct v4l2_subdev_internal_ops ov13858_internal_ops = { /* Initialize control handlers */ static int ov13858_init_controls(struct ov13858 *ov13858) { - struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd); struct v4l2_fwnode_device_properties props; struct v4l2_ctrl_handler *ctrl_hdlr; s64 exposure_max; @@ -1667,12 +1624,12 @@ static int ov13858_init_controls(struct ov13858 *ov13858) 0, 0, ov13858_test_pattern_menu); if (ctrl_hdlr->error) { ret = ctrl_hdlr->error; - dev_err(&client->dev, "%s control init failed (%d)\n", + dev_err(ov13858->dev, "%s control init failed (%d)\n", __func__, ret); goto error; } - ret = v4l2_fwnode_device_parse(&client->dev, &props); + ret = v4l2_fwnode_device_parse(ov13858->dev, &props); if (ret) goto error; @@ -1701,24 +1658,33 @@ static void ov13858_free_controls(struct ov13858 *ov13858) static int ov13858_probe(struct i2c_client *client) { struct ov13858 *ov13858; + unsigned long freq; int ret; - u32 val = 0; - - device_property_read_u32(&client->dev, "clock-frequency", &val); - if (val != 19200000) - return -EINVAL; ov13858 = devm_kzalloc(&client->dev, sizeof(*ov13858), GFP_KERNEL); if (!ov13858) return -ENOMEM; + ov13858->dev = &client->dev; + + ov13858->clk = devm_v4l2_sensor_clk_get(ov13858->dev, NULL); + if (IS_ERR(ov13858->clk)) + return dev_err_probe(ov13858->dev, PTR_ERR(ov13858->clk), + "failed to get clock\n"); + + freq = clk_get_rate(ov13858->clk); + if (freq != 19200000) + return dev_err_probe(ov13858->dev, -EINVAL, + "external clock %lu is not supported\n", + freq); + /* Initialize subdev */ v4l2_i2c_subdev_init(&ov13858->sd, client, &ov13858_subdev_ops); /* Check module identity */ ret = ov13858_identify_module(ov13858); if (ret) { - dev_err(&client->dev, "failed to find sensor: %d\n", ret); + dev_err(ov13858->dev, "failed to find sensor: %d\n", ret); return ret; } @@ -1740,7 +1706,7 @@ static int ov13858_probe(struct i2c_client *client) ov13858->pad.flags = MEDIA_PAD_FL_SOURCE; ret = media_entity_pads_init(&ov13858->sd.entity, 1, &ov13858->pad); if (ret) { - dev_err(&client->dev, "%s failed:%d\n", __func__, ret); + dev_err(ov13858->dev, "%s failed:%d\n", __func__, ret); goto error_handler_free; } @@ -1752,9 +1718,9 @@ static int ov13858_probe(struct i2c_client *client) * Device is already turned on by i2c-core with ACPI domain PM. * Enable runtime PM and turn off the device. */ - pm_runtime_set_active(&client->dev); - pm_runtime_enable(&client->dev); - pm_runtime_idle(&client->dev); + pm_runtime_set_active(ov13858->dev); + pm_runtime_enable(ov13858->dev); + pm_runtime_idle(ov13858->dev); return 0; @@ -1763,7 +1729,7 @@ error_media_entity: error_handler_free: ov13858_free_controls(ov13858); - dev_err(&client->dev, "%s failed:%d\n", __func__, ret); + dev_err(ov13858->dev, "%s failed:%d\n", __func__, ret); return ret; } @@ -1777,20 +1743,16 @@ static void ov13858_remove(struct i2c_client *client) media_entity_cleanup(&sd->entity); ov13858_free_controls(ov13858); - pm_runtime_disable(&client->dev); + pm_runtime_disable(ov13858->dev); } static const struct i2c_device_id ov13858_id_table[] = { - {"ov13858", 0}, - {}, + { "ov13858" }, + {} }; MODULE_DEVICE_TABLE(i2c, ov13858_id_table); -static const struct dev_pm_ops ov13858_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(ov13858_suspend, ov13858_resume) -}; - #ifdef CONFIG_ACPI static const struct acpi_device_id ov13858_acpi_ids[] = { {"OVTID858"}, @@ -1803,7 +1765,6 @@ MODULE_DEVICE_TABLE(acpi, ov13858_acpi_ids); static struct i2c_driver ov13858_i2c_driver = { .driver = { .name = "ov13858", - .pm = &ov13858_pm_ops, .acpi_match_table = ACPI_PTR(ov13858_acpi_ids), }, .probe = ov13858_probe, @@ -1814,7 +1775,7 @@ static struct i2c_driver ov13858_i2c_driver = { module_i2c_driver(ov13858_i2c_driver); MODULE_AUTHOR("Kan, Chris <chris.kan@intel.com>"); -MODULE_AUTHOR("Rapolu, Chiranjeevi <chiranjeevi.rapolu@intel.com>"); +MODULE_AUTHOR("Rapolu, Chiranjeevi"); MODULE_AUTHOR("Yang, Hyungwoo"); MODULE_DESCRIPTION("Omnivision ov13858 sensor driver"); MODULE_LICENSE("GPL v2"); |
