lt6911uxe
static inline struct lt6911uxe *to_lt6911uxe(struct v4l2_subdev *sd)
return container_of(sd, struct lt6911uxe, sd);
static s64 get_pixel_rate(struct lt6911uxe *lt6911uxe)
pixel_rate = (s64)lt6911uxe->cur_mode.width *
lt6911uxe->cur_mode.height *
lt6911uxe->cur_mode.fps * 16;
do_div(pixel_rate, lt6911uxe->cur_mode.lanes);
struct lt6911uxe *lt6911uxe = to_lt6911uxe(sd);
bt->width = lt6911uxe->cur_mode.width;
bt->height = lt6911uxe->cur_mode.height;
bt->vsync = lt6911uxe->cur_mode.vtotal - lt6911uxe->cur_mode.height;
bt->hsync = lt6911uxe->cur_mode.htotal - lt6911uxe->cur_mode.width;
bt->pixelclock = lt6911uxe->cur_mode.pixel_clk;
struct lt6911uxe *lt6911uxe = to_lt6911uxe(sd);
if (v4l2_match_dv_timings(<6911uxe->timings, timings, 0, false)) {
lt6911uxe->timings = *timings;
struct lt6911uxe *lt6911uxe = to_lt6911uxe(sd);
*timings = lt6911uxe->timings;
static int lt6911uxe_status_update(struct lt6911uxe *lt6911uxe)
struct i2c_client *client = v4l2_get_subdevdata(<6911uxe->sd);
cci_read(lt6911uxe->regmap, REG_INT_HDMI, &int_event, &ret);
cci_read(lt6911uxe->regmap, REG_BYTE_CLK, &byte_clk, &ret);
cci_read(lt6911uxe->regmap, REG_HALF_PIX_CLK,
cci_read(lt6911uxe->regmap, REG_HALF_H_TOTAL,
cci_read(lt6911uxe->regmap, REG_V_TOTAL, &vtotal, &ret);
cci_read(lt6911uxe->regmap, REG_HALF_H_ACTIVE,
cci_read(lt6911uxe->regmap, REG_V_ACTIVE, &height, &ret);
cci_read(lt6911uxe->regmap, REG_MIPI_FORMAT, &format, &ret);
lt6911uxe->cur_mode.height = height;
lt6911uxe->cur_mode.width = half_width * 2;
lt6911uxe->cur_mode.fps = fps;
lt6911uxe->cur_mode.link_freq = byte_clk * 4;
lt6911uxe->cur_mode.pixel_clk = half_pix_clk * 2;
lt6911uxe->cur_mode.vtotal = vtotal;
lt6911uxe->cur_mode.htotal = half_htotal * 2;
cci_write(lt6911uxe->regmap, REG_MIPI_TX_CTRL, 0x0, &ret);
lt6911uxe->cur_mode.height = 0;
lt6911uxe->cur_mode.width = 0;
lt6911uxe->cur_mode.fps = 0;
lt6911uxe->cur_mode.link_freq = 0;
v4l2_subdev_notify_event(<6911uxe->sd, <6911uxe_ev_source_change);
static int lt6911uxe_init_controls(struct lt6911uxe *lt6911uxe)
ctrl_hdlr = <6911uxe->ctrl_handler;
pixel_rate = get_pixel_rate(lt6911uxe);
lt6911uxe->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, NULL,
lt6911uxe->sd.ctrl_handler = ctrl_hdlr;
struct lt6911uxe *lt6911uxe = to_lt6911uxe(sd);
cci_write(lt6911uxe->regmap, REG_MIPI_TX_CTRL, 0x1, &ret);
struct lt6911uxe *lt6911uxe = to_lt6911uxe(sd);
struct i2c_client *client = v4l2_get_subdevdata(<6911uxe->sd);
ret = cci_write(lt6911uxe->regmap, REG_MIPI_TX_CTRL, 0x0, NULL);
struct lt6911uxe *lt6911uxe = to_lt6911uxe(sd);
lt6911uxe_update_pad_format(<6911uxe->cur_mode, &fmt->format);
pixel_rate = get_pixel_rate(lt6911uxe);
__v4l2_ctrl_modify_range(lt6911uxe->pixel_rate, pixel_rate,
struct lt6911uxe *lt6911uxe = to_lt6911uxe(sd);
code->code = lt6911uxe->cur_mode.code;
struct lt6911uxe *lt6911uxe = to_lt6911uxe(sd);
cfg->link_freq = lt6911uxe->cur_mode.link_freq;
static int lt6911uxe_fwnode_parse(struct lt6911uxe *lt6911uxe,
lt6911uxe->cur_mode.lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
lt6911uxe->cur_mode.code = MEDIA_BUS_FMT_UYVY8_1X16;
static int lt6911uxe_identify_module(struct lt6911uxe *lt6911uxe,
cci_write(lt6911uxe->regmap, REG_ENABLE_I2C, 0x1, &ret);
cci_read(lt6911uxe->regmap, REG_CHIP_ID, &val, &ret);
cci_write(lt6911uxe->regmap, REG_ENABLE_I2C, 0x0, &ret);
struct lt6911uxe *lt6911uxe = to_lt6911uxe(sd);
lt6911uxe_status_update(lt6911uxe);
struct lt6911uxe *lt6911uxe = to_lt6911uxe(sd);
free_irq(gpiod_to_irq(lt6911uxe->irq_gpio), lt6911uxe);
v4l2_ctrl_handler_free(<6911uxe->ctrl_handler);
struct lt6911uxe *lt6911uxe;
lt6911uxe = devm_kzalloc(dev, sizeof(*lt6911uxe), GFP_KERNEL);
if (!lt6911uxe)
lt6911uxe->regmap = devm_regmap_init_i2c(client,
if (IS_ERR(lt6911uxe->regmap))
return dev_err_probe(dev, PTR_ERR(lt6911uxe->regmap),
v4l2_i2c_subdev_init(<6911uxe->sd, client, <6911uxe_subdev_ops);
lt6911uxe->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(lt6911uxe->reset_gpio))
return dev_err_probe(dev, PTR_ERR(lt6911uxe->reset_gpio),
lt6911uxe->irq_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN);
if (IS_ERR(lt6911uxe->irq_gpio))
return dev_err_probe(dev, PTR_ERR(lt6911uxe->irq_gpio),
ret = lt6911uxe_fwnode_parse(lt6911uxe, dev);
ret = lt6911uxe_identify_module(lt6911uxe, dev);
ret = lt6911uxe_init_controls(lt6911uxe);
lt6911uxe->sd.dev = dev;
lt6911uxe->sd.internal_ops = <6911uxe_internal_ops;
lt6911uxe->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
lt6911uxe->sd.entity.ops = <6911uxe_subdev_entity_ops;
lt6911uxe->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
lt6911uxe->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(<6911uxe->sd.entity, 1, <6911uxe->pad);
ret = v4l2_subdev_init_finalize(<6911uxe->sd);
ret = request_threaded_irq(gpiod_to_irq(lt6911uxe->irq_gpio), NULL,
IRQF_ONESHOT, NULL, lt6911uxe);
ret = v4l2_async_register_subdev_sensor(<6911uxe->sd);
free_irq(gpiod_to_irq(lt6911uxe->irq_gpio), lt6911uxe);
v4l2_subdev_cleanup(<6911uxe->sd);
media_entity_cleanup(<6911uxe->sd.entity);
v4l2_ctrl_handler_free(lt6911uxe->sd.ctrl_handler);