/* * tvp7002_read - Read a value from a register in an TVP7002 * @sd: ptr to v4l2_subdev struct * @addr: TVP7002 register address * @dst: pointer to 8-bit destination * * Returns value read if successful, or non-zero (-1) otherwise.
*/ staticint tvp7002_read(struct v4l2_subdev *sd, u8 addr, u8 *dst)
{ struct i2c_client *c = v4l2_get_subdevdata(sd); int retry; int error;
/* * tvp7002_read_err() - Read a register value with error code * @sd: pointer to standard V4L2 sub-device structure * @reg: destination register * @val: value to be read * @err: pointer to error value * * Read a value in a register and save error value in pointer. * Also update the register table if successful
*/ staticinlinevoid tvp7002_read_err(struct v4l2_subdev *sd, u8 reg,
u8 *dst, int *err)
{ if (!*err)
*err = tvp7002_read(sd, reg, dst);
}
/* * tvp7002_write() - Write a value to a register in TVP7002 * @sd: ptr to v4l2_subdev struct * @addr: TVP7002 register address * @value: value to be written to the register * * Write a value to a register in an TVP7002 decoder device. * Returns zero if successful, or non-zero otherwise.
*/ staticint tvp7002_write(struct v4l2_subdev *sd, u8 addr, u8 value)
{ struct i2c_client *c; int retry; int error;
/* * tvp7002_write_err() - Write a register value with error code * @sd: pointer to standard V4L2 sub-device structure * @reg: destination register * @val: value to be written * @err: pointer to error value * * Write a value in a register and save error value in pointer. * Also update the register table if successful
*/ staticinlinevoid tvp7002_write_err(struct v4l2_subdev *sd, u8 reg,
u8 val, int *err)
{ if (!*err)
*err = tvp7002_write(sd, reg, val);
}
/* * tvp7002_write_inittab() - Write initialization values * @sd: ptr to v4l2_subdev struct * @regs: ptr to i2c_reg_value struct * * Write initialization values. * Returns zero or -EINVAL if read operation fails.
*/ staticint tvp7002_write_inittab(struct v4l2_subdev *sd, conststruct i2c_reg_value *regs)
{ int error = 0;
/* Initialize the first (defined) registers */ while (TVP7002_EOR != regs->reg) { if (TVP7002_WRITE == regs->type)
tvp7002_write_err(sd, regs->reg, regs->value, &error);
regs++;
}
if (dv_timings->type != V4L2_DV_BT_656_1120) return -EINVAL; for (i = 0; i < NUM_TIMINGS; i++) { conststruct v4l2_bt_timings *t = &tvp7002_timings[i].timings.bt;
/* * tvp7002_s_ctrl() - Set a control * @ctrl: ptr to v4l2_ctrl struct * * Set a control in TVP7002 decoder device. * Returns zero when successful or -EINVAL if register access fails.
*/ staticint tvp7002_s_ctrl(struct v4l2_ctrl *ctrl)
{ struct v4l2_subdev *sd = to_sd(ctrl); int error = 0;
/* * tvp7002_query_dv() - query DV timings * @sd: pointer to standard V4L2 sub-device structure * @index: index into the tvp7002_timings array * * Returns the current DV timings detected by TVP7002. If no active input is * detected, returns -EINVAL
*/ staticint tvp7002_query_dv(struct v4l2_subdev *sd, int *index)
{ conststruct tvp7002_timings_definition *timings = tvp7002_timings;
u8 progressive;
u32 lpfr;
u32 cpln; int error = 0;
u8 lpf_lsb;
u8 lpf_msb;
u8 cpl_lsb;
u8 cpl_msb;
/* Return invalid index if no active input is detected */
*index = NUM_TIMINGS;
#ifdef CONFIG_VIDEO_ADV_DEBUG /* * tvp7002_g_register() - Get the value of a register * @sd: ptr to v4l2_subdev struct * @reg: ptr to v4l2_dbg_register struct * * Get the value of a TVP7002 decoder device register. * Returns zero when successful, -EINVAL if register read fails or * access to I2C client fails.
*/ staticint tvp7002_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
u8 val; int ret;
/* * tvp7002_s_register() - set a control * @sd: ptr to v4l2_subdev struct * @reg: ptr to v4l2_dbg_register struct * * Get the value of a TVP7002 decoder device register. * Returns zero when successful, -EINVAL if register read fails.
*/ staticint tvp7002_s_register(struct v4l2_subdev *sd, conststruct v4l2_dbg_register *reg)
{ return tvp7002_write(sd, reg->reg & 0xff, reg->val & 0xff);
} #endif
/* * tvp7002_s_stream() - V4L2 decoder i/f handler for s_stream * @sd: pointer to standard V4L2 sub-device structure * @enable: streaming enable or disable * * Sets streaming to enable or disable, if possible.
*/ staticint tvp7002_s_stream(struct v4l2_subdev *sd, int enable)
{ struct tvp7002 *device = to_tvp7002(sd); int error;
if (device->streaming == enable) return 0;
/* low impedance: on, high impedance: off */
error = tvp7002_write(sd, TVP7002_MISC_CTL_2, enable ? 0x00 : 0x03); if (error) {
v4l2_dbg(1, debug, sd, "Fail to set streaming\n"); return error;
}
device->streaming = enable; return 0;
}
/* * tvp7002_log_status() - Print information about register settings * @sd: ptr to v4l2_subdev struct * * Log register values of a TVP7002 decoder device. * Returns zero or -EINVAL if read operation fails.
*/ staticint tvp7002_log_status(struct v4l2_subdev *sd)
{ struct tvp7002 *device = to_tvp7002(sd); conststruct v4l2_bt_timings *bt; int detected;
/* Find my current timings */
tvp7002_query_dv(sd, &detected);
/* * tvp7002_enum_mbus_code() - Enum supported digital video format on pad * @sd: pointer to standard V4L2 sub-device structure * @sd_state: V4L2 subdev state * @code: pointer to subdev enum mbus code struct * * Enumerate supported digital video formats for pad.
*/ staticint
tvp7002_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code)
{ /* Check requested format index is within range */ if (code->index != 0) return -EINVAL;
code->code = MEDIA_BUS_FMT_YUYV10_1X20;
return 0;
}
/* * tvp7002_get_pad_format() - get video format on pad * @sd: pointer to standard V4L2 sub-device structure * @sd_state: V4L2 subdev state * @fmt: pointer to subdev format struct * * get video format for pad.
*/ staticint
tvp7002_get_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt)
{ struct tvp7002 *tvp7002 = to_tvp7002(sd);
/* * tvp7002_set_pad_format() - set video format on pad * @sd: pointer to standard V4L2 sub-device structure * @sd_state: V4L2 subdev state * @fmt: pointer to subdev format struct * * set video format for pad.
*/ staticint
tvp7002_set_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt)
{ return tvp7002_get_pad_format(sd, sd_state, fmt);
}
if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) return client->dev.platform_data;
endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1); if (!endpoint) return NULL;
if (v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), &bus_cfg)) goto done;
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) goto done;
flags = bus_cfg.bus.parallel.flags;
if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
pdata->hs_polarity = 1;
if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
pdata->vs_polarity = 1;
if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
pdata->clk_polarity = 1;
if (flags & V4L2_MBUS_FIELD_EVEN_HIGH)
pdata->fid_polarity = 1;
if (flags & V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH)
pdata->sog_polarity = 1;
done:
of_node_put(endpoint); return pdata;
}
/* * tvp7002_probe - Probe a TVP7002 device * @c: ptr to i2c_client struct * @id: ptr to i2c_device_id struct * * Initialize the TVP7002 device * Returns zero when successful, -EINVAL if register read fails or * -EIO if i2c access is not available.
*/ staticint tvp7002_probe(struct i2c_client *c)
{ struct tvp7002_config *pdata = tvp7002_get_pdata(c); struct v4l2_subdev *sd; struct tvp7002 *device; struct v4l2_dv_timings timings; int polarity_a; int polarity_b;
u8 revision; int error;
if (pdata == NULL) {
dev_err(&c->dev, "No platform data\n"); return -EINVAL;
}
/* Check if the adapter supports the needed features */ if (!i2c_check_functionality(c->adapter,
I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) return -EIO;
/* Get revision number */
v4l2_info(sd, "Rev. %02x detected.\n", revision); if (revision != 0x02)
v4l2_info(sd, "Unknown revision detected.\n");
/* Initializes TVP7002 to its default values */
error = tvp7002_write_inittab(sd, tvp7002_init_default);
if (error < 0) return error;
/* Set polarity information after registers have been set */
polarity_a = 0x20 | device->pdata->hs_polarity << 5
| device->pdata->vs_polarity << 2;
error = tvp7002_write(sd, TVP7002_SYNC_CTL_1, polarity_a); if (error < 0) return error;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.