ov5695
static void __ov5695_power_off(struct ov5695 *ov5695)
struct device *dev = &ov5695->client->dev;
clk_disable_unprepare(ov5695->xvclk);
gpiod_set_value_cansleep(ov5695->reset_gpio, 1);
ret = regulator_disable(ov5695->supplies[i].consumer);
ov5695->supplies[i].supply, ret);
struct ov5695 *ov5695 = to_ov5695(sd);
return __ov5695_power_on(ov5695);
struct ov5695 *ov5695 = to_ov5695(sd);
__ov5695_power_off(ov5695);
struct ov5695 *ov5695 = to_ov5695(sd);
mutex_lock(&ov5695->mutex);
mutex_unlock(&ov5695->mutex);
struct ov5695 *ov5695 = container_of(ctrl->handler,
struct ov5695, ctrl_handler);
struct i2c_client *client = ov5695->client;
max = ov5695->cur_mode->height + ctrl->val - 4;
__v4l2_ctrl_modify_range(ov5695->exposure,
ov5695->exposure->minimum, max,
ov5695->exposure->step,
ov5695->exposure->default_value);
ret = ov5695_write_reg(ov5695->client, OV5695_REG_EXPOSURE,
ret = ov5695_write_reg(ov5695->client, OV5695_REG_ANALOG_GAIN,
ret = ov5695_write_reg(ov5695->client, OV5695_REG_DIGI_GAIN_L,
ret = ov5695_write_reg(ov5695->client, OV5695_REG_DIGI_GAIN_H,
ret = ov5695_write_reg(ov5695->client, OV5695_REG_VTS,
ctrl->val + ov5695->cur_mode->height);
ret = ov5695_enable_test_pattern(ov5695, ctrl->val);
#define to_ov5695(sd) container_of(sd, struct ov5695, subdev)
static int ov5695_initialize_controls(struct ov5695 *ov5695)
handler = &ov5695->ctrl_handler;
mode = ov5695->cur_mode;
handler->lock = &ov5695->mutex;
ov5695->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
if (ov5695->hblank)
ov5695->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
ov5695->vblank = v4l2_ctrl_new_std(handler, &ov5695_ctrl_ops,
ov5695->exposure = v4l2_ctrl_new_std(handler, &ov5695_ctrl_ops,
ov5695->anal_gain = v4l2_ctrl_new_std(handler, &ov5695_ctrl_ops,
ov5695->digi_gain = v4l2_ctrl_new_std(handler, &ov5695_ctrl_ops,
ov5695->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
dev_err(&ov5695->client->dev,
ov5695->subdev.ctrl_handler = handler;
static int ov5695_check_sensor_id(struct ov5695 *ov5695,
struct device *dev = &ov5695->client->dev;
static int ov5695_configure_regulators(struct ov5695 *ov5695)
ov5695->supplies[i].supply = ov5695_supply_names[i];
return devm_regulator_bulk_get(&ov5695->client->dev,
ov5695->supplies);
struct ov5695 *ov5695;
ov5695 = devm_kzalloc(dev, sizeof(*ov5695), GFP_KERNEL);
if (!ov5695)
ov5695->client = client;
ov5695->cur_mode = &supported_modes[0];
ov5695->xvclk = devm_v4l2_sensor_clk_get_legacy(dev, "xvclk", true,
if (IS_ERR(ov5695->xvclk))
return dev_err_probe(dev, PTR_ERR(ov5695->xvclk),
if (clk_get_rate(ov5695->xvclk) != OV5695_XVCLK_FREQ)
ov5695->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(ov5695->reset_gpio)) {
ret = ov5695_configure_regulators(ov5695);
mutex_init(&ov5695->mutex);
sd = &ov5695->subdev;
ret = ov5695_initialize_controls(ov5695);
ret = __ov5695_power_on(ov5695);
ret = ov5695_check_sensor_id(ov5695, client);
ov5695->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&sd->entity, 1, &ov5695->pad);
__ov5695_power_off(ov5695);
v4l2_ctrl_handler_free(&ov5695->ctrl_handler);
mutex_destroy(&ov5695->mutex);
struct ov5695 *ov5695 = to_ov5695(sd);
v4l2_ctrl_handler_free(&ov5695->ctrl_handler);
mutex_destroy(&ov5695->mutex);
__ov5695_power_off(ov5695);
struct ov5695 *ov5695 = to_ov5695(sd);
mutex_lock(&ov5695->mutex);
ov5695->cur_mode = mode;
__v4l2_ctrl_modify_range(ov5695->hblank, h_blank,
__v4l2_ctrl_modify_range(ov5695->vblank, vblank_def,
mutex_unlock(&ov5695->mutex);
struct ov5695 *ov5695 = to_ov5695(sd);
const struct ov5695_mode *mode = ov5695->cur_mode;
mutex_lock(&ov5695->mutex);
mutex_unlock(&ov5695->mutex);
static int ov5695_enable_test_pattern(struct ov5695 *ov5695, u32 pattern)
return ov5695_write_reg(ov5695->client, OV5695_REG_TEST_PATTERN,
static int __ov5695_start_stream(struct ov5695 *ov5695)
ret = ov5695_write_array(ov5695->client, ov5695_global_regs);
ret = ov5695_write_array(ov5695->client, ov5695->cur_mode->reg_list);
ret = __v4l2_ctrl_handler_setup(&ov5695->ctrl_handler);
return ov5695_write_reg(ov5695->client, OV5695_REG_CTRL_MODE,
static int __ov5695_stop_stream(struct ov5695 *ov5695)
return ov5695_write_reg(ov5695->client, OV5695_REG_CTRL_MODE,
struct ov5695 *ov5695 = to_ov5695(sd);
struct i2c_client *client = ov5695->client;
mutex_lock(&ov5695->mutex);
ret = __ov5695_start_stream(ov5695);
__ov5695_stop_stream(ov5695);
mutex_unlock(&ov5695->mutex);
static int __ov5695_power_on(struct ov5695 *ov5695)
struct device *dev = &ov5695->client->dev;
ret = clk_prepare_enable(ov5695->xvclk);
gpiod_set_value_cansleep(ov5695->reset_gpio, 1);
ret = regulator_enable(ov5695->supplies[i].consumer);
ov5695->supplies[i].supply, ret);
gpiod_set_value_cansleep(ov5695->reset_gpio, 0);
regulator_disable(ov5695->supplies[i].consumer);
clk_disable_unprepare(ov5695->xvclk);