os05b10
os05b10->supplies[i].supply = os05b10_supply_name[i];
ret = devm_regulator_bulk_get(os05b10->dev,
os05b10->supplies);
return dev_err_probe(os05b10->dev, ret,
ret = os05b10_parse_endpoint(os05b10);
return dev_err_probe(os05b10->dev, ret,
os05b10->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
if (IS_ERR(os05b10->reset_gpio))
return dev_err_probe(os05b10->dev, PTR_ERR(os05b10->reset_gpio),
ret = os05b10_power_on(os05b10->dev);
ret = os05b10_identify_module(os05b10);
ret = os05b10_init_controls(os05b10);
os05b10->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
os05b10->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
os05b10->sd.internal_ops = &os05b10_internal_ops;
os05b10->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&os05b10->sd.entity, 1, &os05b10->pad);
dev_err_probe(os05b10->dev, ret,
os05b10->sd.state_lock = os05b10->handler.lock;
ret = v4l2_subdev_init_finalize(&os05b10->sd);
dev_err_probe(os05b10->dev, ret, "subdev init error\n");
pm_runtime_set_active(os05b10->dev);
pm_runtime_enable(os05b10->dev);
ret = v4l2_async_register_subdev_sensor(&os05b10->sd);
dev_err_probe(os05b10->dev, ret,
pm_runtime_idle(os05b10->dev);
v4l2_subdev_cleanup(&os05b10->sd);
pm_runtime_disable(os05b10->dev);
pm_runtime_set_suspended(os05b10->dev);
media_entity_cleanup(&os05b10->sd.entity);
v4l2_ctrl_handler_free(os05b10->sd.ctrl_handler);
os05b10_power_off(os05b10->dev);
struct os05b10 *os05b10 = to_os05b10(sd);
v4l2_subdev_cleanup(&os05b10->sd);
v4l2_ctrl_handler_free(os05b10->sd.ctrl_handler);
static inline struct os05b10 *to_os05b10(struct v4l2_subdev *sd)
return container_of_const(sd, struct os05b10, sd);
struct os05b10 *os05b10 = container_of_const(ctrl->handler,
struct os05b10, handler);
state = v4l2_subdev_get_locked_active_state(&os05b10->sd);
ret = __v4l2_ctrl_modify_range(os05b10->exposure,
os05b10->exposure->minimum, max,
os05b10->exposure->step,
os05b10->exposure->default_value);
if (pm_runtime_get_if_in_use(os05b10->dev) == 0)
ret = cci_write(os05b10->cci, OS05B10_REG_VTS, vmax, NULL);
ret = cci_write(os05b10->cci, OS05B10_REG_ANALOG_GAIN,
ret = cci_write(os05b10->cci, OS05B10_REG_EXPOSURE,
pm_runtime_put(os05b10->dev);
static int os05b10_set_framing_limits(struct os05b10 *os05b10,
ret = __v4l2_ctrl_modify_range(os05b10->hblank, hblank, hblank, 1,
ret = __v4l2_ctrl_modify_range(os05b10->vblank, 0, vblank_max, 1,
return __v4l2_ctrl_modify_range(os05b10->exposure,
struct os05b10 *os05b10 = to_os05b10(sd);
ret = os05b10_set_framing_limits(os05b10, mode);
struct os05b10 *os05b10 = to_os05b10(sd);
ret = pm_runtime_resume_and_get(os05b10->dev);
ret = cci_multi_reg_write(os05b10->cci, os05b10_common_regs,
dev_err(os05b10->dev, "failed to write common registers\n");
ret = __v4l2_ctrl_handler_setup(os05b10->sd.ctrl_handler);
ret = cci_write(os05b10->cci, OS05B10_REG_CTRL_MODE,
pm_runtime_put(os05b10->dev);
struct os05b10 *os05b10 = to_os05b10(sd);
ret = cci_write(os05b10->cci, OS05B10_REG_CTRL_MODE,
dev_err(os05b10->dev, "failed to set stream off\n");
pm_runtime_put(os05b10->dev);
static int os05b10_identify_module(struct os05b10 *os05b10)
ret = cci_read(os05b10->cci, OS05B10_REG_CHIP_ID, &val, NULL);
return dev_err_probe(os05b10->dev, ret,
return dev_err_probe(os05b10->dev, -ENODEV,
struct os05b10 *os05b10 = to_os05b10(sd);
os05b10->supplies);
dev_err(os05b10->dev, "failed to enable regulators\n");
ret = clk_prepare_enable(os05b10->xclk);
dev_err(os05b10->dev, "failed to enable clock\n");
gpiod_set_value_cansleep(os05b10->reset_gpio, 0);
os05b10->supplies);
struct os05b10 *os05b10 = to_os05b10(sd);
gpiod_set_value_cansleep(os05b10->reset_gpio, 1);
os05b10->supplies);
clk_disable_unprepare(os05b10->xclk);
static int os05b10_parse_endpoint(struct os05b10 *os05b10)
ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(os05b10->dev), 0, 0, 0);
dev_err(os05b10->dev, "Failed to get next endpoint\n");
ret = dev_err_probe(os05b10->dev, -EINVAL,
os05b10->data_lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
ret = v4l2_link_freq_to_bitmap(os05b10->dev, bus_cfg.link_frequencies,
dev_err(os05b10->dev, "only 600MHz frequency is available\n");
os05b10->link_freq_index = __ffs(link_freq_bitmap);
static u64 os05b10_pixel_rate(struct os05b10 *os05b10,
u64 link_freq = link_frequencies[os05b10->link_freq_index];
u64 pixel_rate = div_u64(link_freq * 2 * os05b10->data_lanes, mode->bpp);
dev_dbg(os05b10->dev,
link_freq, mode->bpp, os05b10->data_lanes, pixel_rate);
static int os05b10_init_controls(struct os05b10 *os05b10)
ctrl_hdlr = &os05b10->handler;
pixel_rate = os05b10_pixel_rate(os05b10, mode);
os05b10->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &os05b10_ctrl_ops,
os05b10->link_freq_index,
if (os05b10->link_freq)
os05b10->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
os05b10->hblank = v4l2_ctrl_new_std(ctrl_hdlr, NULL, V4L2_CID_HBLANK,
if (os05b10->hblank)
os05b10->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
os05b10->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &os05b10_ctrl_ops,
os05b10->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &os05b10_ctrl_ops,
os05b10->gain = v4l2_ctrl_new_std(ctrl_hdlr, &os05b10_ctrl_ops,
dev_err(os05b10->dev, "control init failed (%d)\n", ret);
ret = v4l2_fwnode_device_parse(os05b10->dev, &props);
os05b10->sd.ctrl_handler = ctrl_hdlr;
struct os05b10 *os05b10;
os05b10 = devm_kzalloc(&client->dev, sizeof(*os05b10), GFP_KERNEL);
if (!os05b10)
os05b10->client = client;
os05b10->dev = &client->dev;
v4l2_i2c_subdev_init(&os05b10->sd, client, &os05b10_subdev_ops);
os05b10->cci = devm_cci_regmap_init_i2c(client, 16);
if (IS_ERR(os05b10->cci))
return dev_err_probe(os05b10->dev, PTR_ERR(os05b10->cci),
os05b10->xclk = devm_v4l2_sensor_clk_get(os05b10->dev, NULL);
if (IS_ERR(os05b10->xclk))
return dev_err_probe(os05b10->dev, PTR_ERR(os05b10->xclk),
xclk_freq = clk_get_rate(os05b10->xclk);
return dev_err_probe(os05b10->dev, -EINVAL,