ov2732
#define to_ov2732(_sd) container_of(_sd, struct ov2732, sd)
struct ov2732 *ov2732 = to_ov2732(sd);
ov2732->supplies);
ret = clk_prepare_enable(ov2732->xvclk);
gpiod_set_value_cansleep(ov2732->reset_gpio, 0);
gpiod_set_value_cansleep(ov2732->powerdown_gpio, 0);
ov2732->supplies);
struct ov2732 *ov2732 = to_ov2732(sd);
clk_disable_unprepare(ov2732->xvclk);
gpiod_set_value_cansleep(ov2732->powerdown_gpio, 1);
gpiod_set_value_cansleep(ov2732->reset_gpio, 1);
ov2732->supplies);
static int ov2732_identify_chip(struct ov2732 *ov2732)
struct i2c_client *client = v4l2_get_subdevdata(&ov2732->sd);
ret = cci_read(ov2732->regmap, OV2732_REG_CHIP_ID, &val, NULL);
struct ov2732 *ov2732 = to_ov2732(sd);
ret = __v4l2_ctrl_modify_range(ov2732->vblank, vblank_def,
struct ov2732 *ov2732 = to_ov2732(sd);
struct i2c_client *client = v4l2_get_subdevdata(&ov2732->sd);
ret = cci_write(ov2732->regmap, OV2732_REG_MODE_SELECT,
ret = cci_multi_reg_write(ov2732->regmap, ov2732_common_regs,
ret = __v4l2_ctrl_handler_setup(ov2732->sd.ctrl_handler);
ret = cci_write(ov2732->regmap, OV2732_REG_MODE_SELECT,
struct ov2732 *ov2732 = to_ov2732(sd);
struct i2c_client *client = v4l2_get_subdevdata(&ov2732->sd);
ret = cci_write(ov2732->regmap, OV2732_REG_MODE_SELECT,
struct ov2732 *ov2732 =
container_of(ctrl->handler, struct ov2732, ctrl_handler);
struct i2c_client *client = v4l2_get_subdevdata(&ov2732->sd);
state = v4l2_subdev_get_locked_active_state(&ov2732->sd);
ret = __v4l2_ctrl_modify_range(ov2732->exposure,
ov2732->exposure->step,
cci_write(ov2732->regmap, OV2732_REG_ANALOGUE_GAIN,
cci_write(ov2732->regmap, OV2732_REG_DIGITAL_GAIN,
cci_write(ov2732->regmap, OV2732_REG_EXPOSURE,
cci_write(ov2732->regmap, OV2732_REG_VTS,
cci_write(ov2732->regmap, OV2732_REG_TEST_PATTERN,
static int ov2732_init_controls(struct ov2732 *ov2732)
handler = &ov2732->ctrl_handler;
ov2732->hblank = v4l2_ctrl_new_std(handler, &ov2732_ctrl_ops,
if (ov2732->hblank)
ov2732->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
ov2732->vblank = v4l2_ctrl_new_std(handler, &ov2732_ctrl_ops,
ov2732->exposure = v4l2_ctrl_new_std(handler, &ov2732_ctrl_ops,
dev_err_probe(ov2732->dev, ret, "Control init failed\n");
ret = v4l2_fwnode_device_parse(ov2732->dev, &props);
ov2732->sd.ctrl_handler = handler;
static int ov2632_probe_dt(struct ov2732 *ov2732)
struct fwnode_handle *fwnode = dev_fwnode(ov2732->dev);
dev_err_probe(ov2732->dev, -EINVAL, "could not parse endpoint\n");
dev_err(ov2732->dev, "only a 2-lane CSI2 config is supported\n");
static int ov2732_get_regulators(struct ov2732 *ov2732)
ov2732->supplies[i].supply = ov2732_supply_names[i];
return devm_regulator_bulk_get(ov2732->dev,
ov2732->supplies);
struct ov2732 *ov2732;
ov2732 = devm_kzalloc(&client->dev, sizeof(*ov2732), GFP_KERNEL);
if (!ov2732)
ov2732->dev = &client->dev;
ret = ov2632_probe_dt(ov2732);
ov2732->xvclk = devm_v4l2_sensor_clk_get(ov2732->dev, NULL);
if (IS_ERR(ov2732->xvclk))
return dev_err_probe(ov2732->dev, PTR_ERR(ov2732->xvclk),
ov2732->xvclk_freq = clk_get_rate(ov2732->xvclk);
if (ov2732->xvclk_freq != OV2732_XVCLK_FREQ)
return dev_err_probe(ov2732->dev, -EINVAL,
ov2732->xvclk_freq);
ov2732->powerdown_gpio = devm_gpiod_get_optional(ov2732->dev,
ov2732->reset_gpio = devm_gpiod_get_optional(ov2732->dev, "reset",
ov2732->regmap = devm_cci_regmap_init_i2c(client, 16);
if (IS_ERR(ov2732->regmap))
return dev_err_probe(ov2732->dev, PTR_ERR(ov2732->regmap),
ret = ov2732_get_regulators(ov2732);
return dev_err_probe(ov2732->dev, ret,
v4l2_i2c_subdev_init(&ov2732->sd, client, &ov2732_subdev_ops);
ret = ov2732_power_on(ov2732->dev);
pm_runtime_set_active(ov2732->dev);
pm_runtime_enable(ov2732->dev);
ret = ov2732_identify_chip(ov2732);
ret = ov2732_init_controls(ov2732);
ov2732->sd.internal_ops = &ov2732_internal_ops;
ov2732->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
ov2732->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
ov2732->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&ov2732->sd.entity, 1, &ov2732->pad);
dev_err_probe(ov2732->dev, ret, "failed to init entity pads\n");
ov2732->sd.state_lock = ov2732->ctrl_handler.lock;
ret = v4l2_subdev_init_finalize(&ov2732->sd);
dev_err_probe(ov2732->dev, ret, "subdev init error\n");
ret = v4l2_async_register_subdev_sensor(&ov2732->sd);
dev_err_probe(ov2732->dev, ret,
pm_runtime_set_autosuspend_delay(ov2732->dev, 1000);
pm_runtime_use_autosuspend(ov2732->dev);
pm_runtime_idle(ov2732->dev);
v4l2_subdev_cleanup(&ov2732->sd);
media_entity_cleanup(&ov2732->sd.entity);
v4l2_ctrl_handler_free(&ov2732->ctrl_handler);
pm_runtime_disable(ov2732->dev);
pm_runtime_set_suspended(ov2732->dev);
ov2732_power_off(ov2732->dev);
struct ov2732 *ov2732 = to_ov2732(sd);
v4l2_ctrl_handler_free(&ov2732->ctrl_handler);
pm_runtime_disable(ov2732->dev);
if (!pm_runtime_status_suspended(ov2732->dev)) {
ov2732_power_off(ov2732->dev);
pm_runtime_set_suspended(ov2732->dev);