linux/drivers/media/i2c/tvp7002.c

// SPDX-License-Identifier: GPL-2.0-or-later
/* Texas Instruments Triple 8-/10-BIT 165-/110-MSPS Video and Graphics
 * Digitizer with Horizontal PLL registers
 *
 * Copyright (C) 2009 Texas Instruments Inc
 * Author: Santiago Nunez-Corrales <[email protected]>
 *
 * This code is partially based upon the TVP5150 driver
 * written by Mauro Carvalho Chehab <[email protected]>,
 * the TVP514x driver written by Vaibhav Hiremath <[email protected]>
 * and the TVP7002 driver in the TI LSP 2.10.00.14. Revisions by
 * Muralidharan Karicheri and Snehaprabha Narnakaje (TI).
 */
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/v4l2-dv-timings.h>
#include <media/i2c/tvp7002.h>
#include <media/v4l2-async.h>
#include <media/v4l2-device.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-fwnode.h>

#include "tvp7002_reg.h"

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();

/* I2C retry attempts */
#define I2C_RETRY_COUNT

/* End of registers */
#define TVP7002_EOR

/* Read write definition for registers */
#define TVP7002_READ
#define TVP7002_WRITE
#define TVP7002_RESERVED

/* Interlaced vs progressive mask and shift */
#define TVP7002_IP_SHIFT
#define TVP7002_INPR_MASK

/* Shift for CPL and LPF registers */
#define TVP7002_CL_SHIFT
#define TVP7002_CL_MASK

/* Debug functions */
static bool debug;
module_param(debug, bool, 0644);
MODULE_PARM_DESC();

/* Structure for register values */
struct i2c_reg_value {};

/*
 * Register default values (according to tvp7002 datasheet)
 * In the case of read-only registers, the value (0xff) is
 * never written. R/W functionality is controlled by the
 * writable bit in the register struct definition.
 */
static const struct i2c_reg_value tvp7002_init_default[] =;

/* Register parameters for 480P */
static const struct i2c_reg_value tvp7002_parms_480P[] =;

/* Register parameters for 576P */
static const struct i2c_reg_value tvp7002_parms_576P[] =;

/* Register parameters for 1080I60 */
static const struct i2c_reg_value tvp7002_parms_1080I60[] =;

/* Register parameters for 1080P60 */
static const struct i2c_reg_value tvp7002_parms_1080P60[] =;

/* Register parameters for 1080I50 */
static const struct i2c_reg_value tvp7002_parms_1080I50[] =;

/* Register parameters for 720P60 */
static const struct i2c_reg_value tvp7002_parms_720P60[] =;

/* Register parameters for 720P50 */
static const struct i2c_reg_value tvp7002_parms_720P50[] =;

/* Timings definition for handling device operation */
struct tvp7002_timings_definition {};

/* Struct list for digital video timings */
static const struct tvp7002_timings_definition tvp7002_timings[] =;

#define NUM_TIMINGS

/* Device definition */
struct tvp7002 {};

/*
 * to_tvp7002 - Obtain device handler TVP7002
 * @sd: ptr to v4l2_subdev struct
 *
 * Returns device handler tvp7002.
 */
static inline struct tvp7002 *to_tvp7002(struct v4l2_subdev *sd)
{}

static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
{}

/*
 * 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.
 */
static int tvp7002_read(struct v4l2_subdev *sd, u8 addr, u8 *dst)
{}

/*
 * 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
 */
static inline void tvp7002_read_err(struct v4l2_subdev *sd, u8 reg,
							u8 *dst, int *err)
{}

/*
 * 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.
 */
static int tvp7002_write(struct v4l2_subdev *sd, u8 addr, u8 value)
{}

/*
 * 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
 */
static inline void tvp7002_write_err(struct v4l2_subdev *sd, u8 reg,
							u8 val, int *err)
{}

/*
 * 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.
 */
static int tvp7002_write_inittab(struct v4l2_subdev *sd,
					const struct i2c_reg_value *regs)
{}

static int tvp7002_s_dv_timings(struct v4l2_subdev *sd, unsigned int pad,
				struct v4l2_dv_timings *dv_timings)
{}

static int tvp7002_g_dv_timings(struct v4l2_subdev *sd, unsigned int pad,
				struct v4l2_dv_timings *dv_timings)
{}

/*
 * 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.
 */
static int tvp7002_s_ctrl(struct v4l2_ctrl *ctrl)
{}

/*
 * 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
 */
static int tvp7002_query_dv(struct v4l2_subdev *sd, int *index)
{}

static int tvp7002_query_dv_timings(struct v4l2_subdev *sd, unsigned int pad,
				    struct v4l2_dv_timings *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.
 */
static int tvp7002_g_register(struct v4l2_subdev *sd,
						struct v4l2_dbg_register *reg)
{}

/*
 * 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.
 */
static int tvp7002_s_register(struct v4l2_subdev *sd,
						const struct v4l2_dbg_register *reg)
{}
#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.
 */
static int tvp7002_s_stream(struct v4l2_subdev *sd, int enable)
{}

/*
 * 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.
 */
static int tvp7002_log_status(struct v4l2_subdev *sd)
{}

static int tvp7002_enum_dv_timings(struct v4l2_subdev *sd,
		struct v4l2_enum_dv_timings *timings)
{}

static const struct v4l2_ctrl_ops tvp7002_ctrl_ops =;

/*
 * 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.
 */
static int
tvp7002_enum_mbus_code(struct v4l2_subdev *sd,
		       struct v4l2_subdev_state *sd_state,
		       struct v4l2_subdev_mbus_code_enum *code)
{}

/*
 * 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.
 */
static int
tvp7002_get_pad_format(struct v4l2_subdev *sd,
		       struct v4l2_subdev_state *sd_state,
		       struct v4l2_subdev_format *fmt)
{}

/*
 * 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.
 */
static int
tvp7002_set_pad_format(struct v4l2_subdev *sd,
		       struct v4l2_subdev_state *sd_state,
		       struct v4l2_subdev_format *fmt)
{}

/* V4L2 core operation handlers */
static const struct v4l2_subdev_core_ops tvp7002_core_ops =;

/* Specific video subsystem operation handlers */
static const struct v4l2_subdev_video_ops tvp7002_video_ops =;

/* media pad related operation handlers */
static const struct v4l2_subdev_pad_ops tvp7002_pad_ops =;

/* V4L2 top level operation handlers */
static const struct v4l2_subdev_ops tvp7002_ops =;

static struct tvp7002_config *
tvp7002_get_pdata(struct i2c_client *client)
{}

/*
 * 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.
 */
static int tvp7002_probe(struct i2c_client *c)
{}

/*
 * tvp7002_remove - Remove TVP7002 device support
 * @c: ptr to i2c_client struct
 *
 * Reset the TVP7002 device
 * Returns zero.
 */
static void tvp7002_remove(struct i2c_client *c)
{}

/* I2C Device ID table */
static const struct i2c_device_id tvp7002_id[] =;
MODULE_DEVICE_TABLE(i2c, tvp7002_id);

#if IS_ENABLED(CONFIG_OF)
static const struct of_device_id tvp7002_of_match[] =;
MODULE_DEVICE_TABLE(of, tvp7002_of_match);
#endif

/* I2C driver data */
static struct i2c_driver tvp7002_driver =;

module_i2c_driver();