ov2685
#define to_ov2685(sd) container_of(sd, struct ov2685, subdev)
struct ov2685 *ov2685 = to_ov2685(sd);
ov2685_fill_fmt(ov2685->cur_mode, mbus_fmt);
struct ov2685 *ov2685 = to_ov2685(sd);
ov2685_fill_fmt(ov2685->cur_mode, mbus_fmt);
__ov2685_get_pad_crop(struct ov2685 *ov2685,
const struct ov2685_mode *mode = ov2685->cur_mode;
struct ov2685 *ov2685 = to_ov2685(sd);
mutex_lock(&ov2685->mutex);
sel->r = *__ov2685_get_pad_crop(ov2685, sd_state, sel->pad,
mutex_unlock(&ov2685->mutex);
static int __ov2685_power_on(struct ov2685 *ov2685)
struct device *dev = &ov2685->client->dev;
ret = clk_prepare_enable(ov2685->xvclk);
gpiod_set_value_cansleep(ov2685->reset_gpio, 1);
ret = regulator_bulk_enable(OV2685_NUM_SUPPLIES, ov2685->supplies);
gpiod_set_value_cansleep(ov2685->reset_gpio, 0);
ret = ov2685_write_array(ov2685->client, ov2685->cur_mode->reg_list);
regulator_bulk_disable(OV2685_NUM_SUPPLIES, ov2685->supplies);
clk_disable_unprepare(ov2685->xvclk);
static void __ov2685_power_off(struct ov2685 *ov2685)
clk_disable_unprepare(ov2685->xvclk);
gpiod_set_value_cansleep(ov2685->reset_gpio, 1);
regulator_bulk_disable(OV2685_NUM_SUPPLIES, ov2685->supplies);
struct ov2685 *ov2685 = to_ov2685(sd);
struct i2c_client *client = ov2685->client;
mutex_lock(&ov2685->mutex);
ret = pm_runtime_resume_and_get(&ov2685->client->dev);
ret = __v4l2_ctrl_handler_setup(&ov2685->ctrl_handler);
pm_runtime_put(&ov2685->client->dev);
mutex_unlock(&ov2685->mutex);
struct ov2685 *ov2685 = to_ov2685(sd);
mutex_lock(&ov2685->mutex);
mutex_unlock(&ov2685->mutex);
struct ov2685 *ov2685 = to_ov2685(sd);
return __ov2685_power_on(ov2685);
struct ov2685 *ov2685 = to_ov2685(sd);
__ov2685_power_off(ov2685);
struct ov2685 *ov2685 = container_of(ctrl->handler,
struct ov2685, ctrl_handler);
struct i2c_client *client = ov2685->client;
max_expo = ov2685->cur_mode->height + ctrl->val - 4;
__v4l2_ctrl_modify_range(ov2685->exposure,
ov2685->exposure->minimum, max_expo,
ov2685->exposure->step,
ov2685->exposure->default_value);
ret = ov2685_write_reg(ov2685->client, OV2685_REG_EXPOSURE,
ret = ov2685_write_reg(ov2685->client, OV2685_REG_GAIN,
ret = ov2685_write_reg(ov2685->client, OV2685_REG_VTS,
ctrl->val + ov2685->cur_mode->height);
ret = ov2685_write_reg(ov2685->client, OV2685_REG_TEST_PATTERN,
static int ov2685_initialize_controls(struct ov2685 *ov2685)
handler = &ov2685->ctrl_handler;
mode = ov2685->cur_mode;
handler->lock = &ov2685->mutex;
ov2685->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
if (ov2685->hblank)
ov2685->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
ov2685->vblank = v4l2_ctrl_new_std(handler, &ov2685_ctrl_ops,
ov2685->exposure = v4l2_ctrl_new_std(handler, &ov2685_ctrl_ops,
ov2685->anal_gain = v4l2_ctrl_new_std(handler, &ov2685_ctrl_ops,
ov2685->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
ret = v4l2_fwnode_device_parse(&ov2685->client->dev, &props);
dev_err(&ov2685->client->dev,
ov2685->subdev.ctrl_handler = handler;
static int ov2685_check_sensor_id(struct ov2685 *ov2685,
struct device *dev = &ov2685->client->dev;
static int ov2685_configure_regulators(struct ov2685 *ov2685)
ov2685->supplies[i].supply = ov2685_supply_names[i];
return devm_regulator_bulk_get(&ov2685->client->dev,
ov2685->supplies);
struct ov2685 *ov2685;
ov2685 = devm_kzalloc(dev, sizeof(*ov2685), GFP_KERNEL);
if (!ov2685)
ov2685->client = client;
ov2685->cur_mode = &supported_modes[0];
ov2685->xvclk = devm_v4l2_sensor_clk_get_legacy(dev, "xvclk", true,
if (IS_ERR(ov2685->xvclk))
return dev_err_probe(dev, PTR_ERR(ov2685->xvclk),
if (clk_get_rate(ov2685->xvclk) != OV2685_XVCLK_FREQ)
ov2685->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(ov2685->reset_gpio)) {
ret = ov2685_configure_regulators(ov2685);
mutex_init(&ov2685->mutex);
v4l2_i2c_subdev_init(&ov2685->subdev, client, &ov2685_subdev_ops);
ret = ov2685_initialize_controls(ov2685);
ret = __ov2685_power_on(ov2685);
ret = ov2685_check_sensor_id(ov2685, client);
ov2685->subdev.internal_ops = &ov2685_internal_ops;
ov2685->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
ov2685->pad.flags = MEDIA_PAD_FL_SOURCE;
ov2685->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR;
ret = media_entity_pads_init(&ov2685->subdev.entity, 1, &ov2685->pad);
ret = v4l2_async_register_subdev(&ov2685->subdev);
media_entity_cleanup(&ov2685->subdev.entity);
__ov2685_power_off(ov2685);
v4l2_ctrl_handler_free(&ov2685->ctrl_handler);
mutex_destroy(&ov2685->mutex);
struct ov2685 *ov2685 = to_ov2685(sd);
v4l2_ctrl_handler_free(&ov2685->ctrl_handler);
mutex_destroy(&ov2685->mutex);
__ov2685_power_off(ov2685);