ov6211
static int ov6211_set_test_pattern(struct ov6211 *ov6211, u32 pattern)
u64 val = ov6211->pre_isp;
return cci_write(ov6211->regmap, OV6211_REG_PRE_ISP, val, NULL);
struct ov6211 *ov6211 = container_of(ctrl->handler, struct ov6211,
ret = __v4l2_ctrl_modify_range(ov6211->exposure,
ov6211->exposure->minimum,
ov6211->exposure->step,
ov6211->exposure->default_value);
if (!pm_runtime_get_if_active(ov6211->dev))
ret = cci_write(ov6211->regmap, OV6211_REG_ANALOGUE_GAIN,
ret = cci_write(ov6211->regmap, OV6211_REG_EXPOSURE,
ret = cci_write(ov6211->regmap, OV6211_REG_VTS,
ret = ov6211_set_test_pattern(ov6211, ctrl->val);
pm_runtime_put(ov6211->dev);
static int ov6211_init_controls(struct ov6211 *ov6211)
struct v4l2_ctrl_handler *ctrl_hdlr = &ov6211->ctrl_handler;
ov6211->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov6211_ctrl_ops,
ov6211->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov6211_ctrl_ops,
ret = v4l2_fwnode_device_parse(ov6211->dev, &props);
ov6211->sd.ctrl_handler = ctrl_hdlr;
struct ov6211 *ov6211 = to_ov6211(sd);
ret = pm_runtime_resume_and_get(ov6211->dev);
ret = cci_write(ov6211->regmap, OV6211_REG_SOFTWARE_RST,
dev_err(ov6211->dev, "failed to software reset: %d\n", ret);
ret = cci_multi_reg_write(ov6211->regmap, reg_list->regs,
dev_err(ov6211->dev, "failed to set mode: %d\n", ret);
ret = __v4l2_ctrl_handler_setup(ov6211->sd.ctrl_handler);
ret = cci_write(ov6211->regmap, OV6211_REG_MODE_SELECT,
dev_err(ov6211->dev, "failed to start streaming: %d\n", ret);
pm_runtime_put_autosuspend(ov6211->dev);
struct ov6211 *ov6211 = to_ov6211(sd);
ret = cci_write(ov6211->regmap, OV6211_REG_MODE_SELECT,
dev_err(ov6211->dev, "failed to stop streaming: %d\n", ret);
pm_runtime_put_autosuspend(ov6211->dev);
#define to_ov6211(_sd) container_of(_sd, struct ov6211, sd)
static int ov6211_identify_sensor(struct ov6211 *ov6211)
ret = cci_read(ov6211->regmap, OV6211_REG_CHIP_ID, &val, NULL);
dev_err(ov6211->dev, "failed to read chip id: %d\n", ret);
dev_err(ov6211->dev, "chip id mismatch: %x!=%llx\n",
ret = cci_read(ov6211->regmap, OV6211_REG_PRE_ISP,
&ov6211->pre_isp, NULL);
dev_err(ov6211->dev, "failed to read pre_isp: %d\n", ret);
static int ov6211_check_hwcfg(struct ov6211 *ov6211)
struct fwnode_handle *fwnode = dev_fwnode(ov6211->dev), *ep;
ret = v4l2_link_freq_to_bitmap(ov6211->dev, bus_cfg.link_frequencies,
struct ov6211 *ov6211 = to_ov6211(sd);
ret = regulator_bulk_enable(OV6211_NUM_SUPPLIES, ov6211->supplies);
gpiod_set_value_cansleep(ov6211->reset_gpio, 0);
ret = clk_prepare_enable(ov6211->xvclk);
gpiod_set_value_cansleep(ov6211->reset_gpio, 1);
regulator_bulk_disable(OV6211_NUM_SUPPLIES, ov6211->supplies);
struct ov6211 *ov6211 = to_ov6211(sd);
clk_disable_unprepare(ov6211->xvclk);
gpiod_set_value_cansleep(ov6211->reset_gpio, 1);
regulator_bulk_disable(OV6211_NUM_SUPPLIES, ov6211->supplies);
struct ov6211 *ov6211;
ov6211 = devm_kzalloc(&client->dev, sizeof(*ov6211), GFP_KERNEL);
if (!ov6211)
ov6211->dev = &client->dev;
v4l2_i2c_subdev_init(&ov6211->sd, client, &ov6211_subdev_ops);
ov6211->regmap = devm_cci_regmap_init_i2c(client, 16);
if (IS_ERR(ov6211->regmap))
return dev_err_probe(ov6211->dev, PTR_ERR(ov6211->regmap),
ov6211->xvclk = devm_v4l2_sensor_clk_get(ov6211->dev, NULL);
if (IS_ERR(ov6211->xvclk))
return dev_err_probe(ov6211->dev, PTR_ERR(ov6211->xvclk),
freq = clk_get_rate(ov6211->xvclk);
return dev_err_probe(ov6211->dev, -EINVAL,
ret = ov6211_check_hwcfg(ov6211);
return dev_err_probe(ov6211->dev, ret,
ov6211->reset_gpio = devm_gpiod_get_optional(ov6211->dev, "reset",
if (IS_ERR(ov6211->reset_gpio))
return dev_err_probe(ov6211->dev, PTR_ERR(ov6211->reset_gpio),
ov6211->supplies[i].supply = ov6211_supply_names[i];
ret = devm_regulator_bulk_get(ov6211->dev, OV6211_NUM_SUPPLIES,
ov6211->supplies);
return dev_err_probe(ov6211->dev, ret,
ret = ov6211_power_on(ov6211->dev);
ret = ov6211_identify_sensor(ov6211);
dev_err_probe(ov6211->dev, ret, "failed to find sensor\n");
ret = ov6211_init_controls(ov6211);
dev_err_probe(ov6211->dev, ret, "failed to init controls\n");
ov6211->sd.state_lock = ov6211->ctrl_handler.lock;
ov6211->sd.internal_ops = &ov6211_internal_ops;
ov6211->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
ov6211->sd.entity.ops = &ov6211_subdev_entity_ops;
ov6211->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
ov6211->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&ov6211->sd.entity, 1, &ov6211->pad);
dev_err_probe(ov6211->dev, ret,
ret = v4l2_subdev_init_finalize(&ov6211->sd);
dev_err_probe(ov6211->dev, ret,
pm_runtime_set_active(ov6211->dev);
pm_runtime_enable(ov6211->dev);
ret = v4l2_async_register_subdev_sensor(&ov6211->sd);
dev_err_probe(ov6211->dev, ret,
pm_runtime_idle(ov6211->dev);
pm_runtime_set_autosuspend_delay(ov6211->dev, 1000);
pm_runtime_use_autosuspend(ov6211->dev);
v4l2_subdev_cleanup(&ov6211->sd);
pm_runtime_disable(ov6211->dev);
pm_runtime_set_suspended(ov6211->dev);
media_entity_cleanup(&ov6211->sd.entity);
v4l2_ctrl_handler_free(ov6211->sd.ctrl_handler);
ov6211_power_off(ov6211->dev);
struct ov6211 *ov6211 = to_ov6211(sd);
pm_runtime_disable(ov6211->dev);
if (!pm_runtime_status_suspended(ov6211->dev)) {
ov6211_power_off(ov6211->dev);
pm_runtime_set_suspended(ov6211->dev);