gc2145
ret = clk_prepare_enable(gc2145->xclk);
gpiod_set_value_cansleep(gc2145->powerdown_gpio, 0);
gpiod_set_value_cansleep(gc2145->reset_gpio, 0);
regulator_bulk_disable(GC2145_NUM_SUPPLIES, gc2145->supplies);
struct gc2145 *gc2145 = to_gc2145(sd);
gpiod_set_value_cansleep(gc2145->powerdown_gpio, 1);
gpiod_set_value_cansleep(gc2145->reset_gpio, 1);
clk_disable_unprepare(gc2145->xclk);
regulator_bulk_disable(GC2145_NUM_SUPPLIES, gc2145->supplies);
static int gc2145_get_regulators(struct gc2145 *gc2145)
struct i2c_client *client = v4l2_get_subdevdata(&gc2145->sd);
gc2145->supplies[i].supply = gc2145_supply_name[i];
gc2145->supplies);
static int gc2145_identify_module(struct gc2145 *gc2145)
struct i2c_client *client = v4l2_get_subdevdata(&gc2145->sd);
ret = cci_read(gc2145->regmap, GC2145_REG_CHIP_ID, &chip_id, NULL);
static int gc2145_set_ctrl_test_pattern(struct gc2145 *gc2145, int value)
cci_write(gc2145->regmap, GC2145_REG_DEBUG_MODE2, 0, &ret);
return cci_write(gc2145->regmap, GC2145_REG_DEBUG_MODE3, 0,
cci_write(gc2145->regmap, GC2145_REG_DEBUG_MODE2,
return cci_write(gc2145->regmap, GC2145_REG_DEBUG_MODE3, 0,
return cci_write(gc2145->regmap, GC2145_REG_DEBUG_MODE3,
struct gc2145 *gc2145 = to_gc2145(sd);
ret = cci_write(gc2145->regmap, GC2145_REG_HBLANK, ctrl->val,
ret = cci_write(gc2145->regmap, GC2145_REG_VBLANK, ctrl->val,
ret = gc2145_set_ctrl_test_pattern(gc2145, ctrl->val);
ret = cci_update_bits(gc2145->regmap, GC2145_REG_ANALOG_MODE1,
ret = cci_update_bits(gc2145->regmap, GC2145_REG_ANALOG_MODE1,
static int gc2145_init_controls(struct gc2145 *gc2145)
struct i2c_client *client = v4l2_get_subdevdata(&gc2145->sd);
struct gc2145_ctrls *ctrls = &gc2145->ctrls;
gc2145->sd.ctrl_handler = hdl;
struct gc2145 *gc2145;
gc2145 = devm_kzalloc(&client->dev, sizeof(*gc2145), GFP_KERNEL);
if (!gc2145)
v4l2_i2c_subdev_init(&gc2145->sd, client, &gc2145_subdev_ops);
gc2145->sd.internal_ops = &gc2145_subdev_internal_ops;
gc2145->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
if (IS_ERR(gc2145->xclk))
return dev_err_probe(dev, PTR_ERR(gc2145->xclk),
xclk_freq = clk_get_rate(gc2145->xclk);
ret = gc2145_get_regulators(gc2145);
gc2145->reset_gpio = devm_gpiod_get_optional(dev, "reset",
if (IS_ERR(gc2145->reset_gpio))
return dev_err_probe(dev, PTR_ERR(gc2145->reset_gpio),
gc2145->powerdown_gpio = devm_gpiod_get_optional(dev, "powerdown",
if (IS_ERR(gc2145->powerdown_gpio))
return dev_err_probe(dev, PTR_ERR(gc2145->powerdown_gpio),
gc2145->regmap = devm_cci_regmap_init_i2c(client, 8);
if (IS_ERR(gc2145->regmap))
return dev_err_probe(dev, PTR_ERR(gc2145->regmap),
ret = gc2145_identify_module(gc2145);
gc2145->mode = &supported_modes[0];
ret = gc2145_init_controls(gc2145);
gc2145->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
gc2145->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
gc2145->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&gc2145->sd.entity, 1, &gc2145->pad);
gc2145->sd.state_lock = gc2145->ctrls.handler.lock;
ret = v4l2_subdev_init_finalize(&gc2145->sd);
ret = v4l2_async_register_subdev_sensor(&gc2145->sd);
v4l2_subdev_cleanup(&gc2145->sd);
media_entity_cleanup(&gc2145->sd.entity);
v4l2_ctrl_handler_free(&gc2145->ctrls.handler);
struct gc2145 *gc2145 = to_gc2145(sd);
v4l2_ctrl_handler_free(&gc2145->ctrls.handler);
static inline struct gc2145 *to_gc2145(struct v4l2_subdev *_sd)
return container_of(_sd, struct gc2145, sd);
return &container_of(ctrl->handler, struct gc2145,
gc2145_get_format_code(struct gc2145 *gc2145, u32 code)
static void gc2145_update_pad_format(struct gc2145 *gc2145,
struct gc2145 *gc2145 = to_gc2145(sd);
gc2145_update_pad_format(gc2145, &supported_modes[0], format,
struct gc2145 *gc2145 = to_gc2145(sd);
gc2145_format = gc2145_get_format_code(gc2145, fse->code);
struct gc2145 *gc2145 = to_gc2145(sd);
struct gc2145_ctrls *ctrls = &gc2145->ctrls;
gc2145_fmt = gc2145_get_format_code(gc2145, fmt->format.code);
gc2145_update_pad_format(gc2145, mode, &fmt->format, gc2145_fmt->code,
gc2145->mode = mode;
static int gc2145_config_mipi_mode(struct gc2145 *gc2145,
cci_multi_reg_write(gc2145->regmap, gc2145_common_mipi_regs,
lwc = gc2145->mode->width * 2;
lwc = gc2145->mode->width;
cci_write(gc2145->regmap, GC2145_REG_LWC, lwc, &ret);
if (gc2145->mode->width == 1280 || gc2145->mode->width == 1600)
cci_write(gc2145->regmap, GC2145_REG_FIFO_FULL_LVL,
cci_write(gc2145->regmap, GC2145_REG_FIFO_GATE_MODE,
cci_write(gc2145->regmap, GC2145_REG_MIPI_DT,
cci_write(gc2145->regmap, GC2145_REG_BUF_CSI2_MODE,
struct gc2145 *gc2145 = to_gc2145(sd);
struct i2c_client *client = v4l2_get_subdevdata(&gc2145->sd);
cci_multi_reg_write(gc2145->regmap, gc2145->mode->reg_seq,
gc2145->mode->reg_seq_size, &ret);
cci_multi_reg_write(gc2145->regmap, gc2145_common_regs,
gc2145_format = gc2145_get_format_code(gc2145, fmt->code);
cci_write(gc2145->regmap, GC2145_REG_PAGE_SELECT, 0x00, &ret);
cci_write(gc2145->regmap, GC2145_REG_OUTPUT_FMT,
cci_update_bits(gc2145->regmap, GC2145_REG_BYPASS_MODE,
cci_update_bits(gc2145->regmap, GC2145_REG_SYNC_MODE,
ret = __v4l2_ctrl_handler_setup(&gc2145->ctrls.handler);
ret = gc2145_config_mipi_mode(gc2145, gc2145_format);
cci_write(gc2145->regmap, GC2145_REG_PAGE_SELECT, 0x00, &ret);
struct gc2145 *gc2145 = to_gc2145(sd);
struct i2c_client *client = v4l2_get_subdevdata(&gc2145->sd);
cci_write(gc2145->regmap, GC2145_REG_PAGE_SELECT, 0x03, &ret);
cci_update_bits(gc2145->regmap, GC2145_REG_BUF_CSI2_MODE,
cci_write(gc2145->regmap, GC2145_REG_PAGE_SELECT, 0x00, &ret);
struct gc2145 *gc2145 = to_gc2145(sd);
ret = regulator_bulk_enable(GC2145_NUM_SUPPLIES, gc2145->supplies);