linux/drivers/media/i2c/adv7842.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * adv7842 - Analog Devices ADV7842 video decoder driver
 *
 * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
 */

/*
 * References (c = chapter, p = page):
 * REF_01 - Analog devices, ADV7842,
 *		Register Settings Recommendations, Rev. 1.9, April 2011
 * REF_02 - Analog devices, Software User Guide, UG-206,
 *		ADV7842 I2C Register Maps, Rev. 0, November 2010
 * REF_03 - Analog devices, Hardware User Guide, UG-214,
 *		ADV7842 Fast Switching 2:1 HDMI 1.4 Receiver with 3D-Comb
 *		Decoder and Digitizer , Rev. 0, January 2011
 */


#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/videodev2.h>
#include <linux/workqueue.h>
#include <linux/v4l2-dv-timings.h>
#include <linux/hdmi.h>
#include <media/cec.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-dv-timings.h>
#include <media/i2c/adv7842.h>

static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC();

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

/* ADV7842 system clock frequency */
#define ADV7842_fsc

#define ADV7842_RGB_OUT

#define ADV7842_OP_FORMAT_SEL_8BIT
#define ADV7842_OP_FORMAT_SEL_10BIT
#define ADV7842_OP_FORMAT_SEL_12BIT

#define ADV7842_OP_MODE_SEL_SDR_422
#define ADV7842_OP_MODE_SEL_DDR_422
#define ADV7842_OP_MODE_SEL_SDR_444
#define ADV7842_OP_MODE_SEL_DDR_444
#define ADV7842_OP_MODE_SEL_SDR_422_2X
#define ADV7842_OP_MODE_SEL_ADI_CM

#define ADV7842_OP_CH_SEL_GBR
#define ADV7842_OP_CH_SEL_GRB
#define ADV7842_OP_CH_SEL_BGR
#define ADV7842_OP_CH_SEL_RGB
#define ADV7842_OP_CH_SEL_BRG
#define ADV7842_OP_CH_SEL_RBG

#define ADV7842_OP_SWAP_CB_CR

#define ADV7842_MAX_ADDRS

/*
**********************************************************************
*
*  Arrays with configuration parameters for the ADV7842
*
**********************************************************************
*/

struct adv7842_format_info {};

struct adv7842_state {};

/* Unsupported timings. This device cannot support 720p30. */
static const struct v4l2_dv_timings adv7842_timings_exceptions[] =;

static bool adv7842_check_dv_timings(const struct v4l2_dv_timings *t, void *hdl)
{}

struct adv7842_video_standards {};

/* sorted by number of lines */
static const struct adv7842_video_standards adv7842_prim_mode_comp[] =;

/* sorted by number of lines */
static const struct adv7842_video_standards adv7842_prim_mode_gr[] =;

/* sorted by number of lines */
static const struct adv7842_video_standards adv7842_prim_mode_hdmi_comp[] =;

/* sorted by number of lines */
static const struct adv7842_video_standards adv7842_prim_mode_hdmi_gr[] =;

static const struct v4l2_event adv7842_ev_fmt =;

/* ----------------------------------------------------------------------- */

static inline struct adv7842_state *to_state(struct v4l2_subdev *sd)
{}

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

static inline unsigned htotal(const struct v4l2_bt_timings *t)
{}

static inline unsigned vtotal(const struct v4l2_bt_timings *t)
{}


/* ----------------------------------------------------------------------- */

static s32 adv_smbus_read_byte_data_check(struct i2c_client *client,
					  u8 command, bool check)
{}

static s32 adv_smbus_read_byte_data(struct i2c_client *client, u8 command)
{}

static s32 adv_smbus_write_byte_data(struct i2c_client *client,
				     u8 command, u8 value)
{}

static void adv_smbus_write_byte_no_check(struct i2c_client *client,
					  u8 command, u8 value)
{}

/* ----------------------------------------------------------------------- */

static inline int io_read(struct v4l2_subdev *sd, u8 reg)
{}

static inline int io_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{}

static inline int io_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
{}

static inline int io_write_clr_set(struct v4l2_subdev *sd,
				   u8 reg, u8 mask, u8 val)
{}

static inline int avlink_read(struct v4l2_subdev *sd, u8 reg)
{}

static inline int avlink_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{}

static inline int cec_read(struct v4l2_subdev *sd, u8 reg)
{}

static inline int cec_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{}

static inline int cec_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
{}

static inline int infoframe_read(struct v4l2_subdev *sd, u8 reg)
{}

static inline int infoframe_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{}

static inline int sdp_io_read(struct v4l2_subdev *sd, u8 reg)
{}

static inline int sdp_io_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{}

static inline int sdp_io_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
{}

static inline int sdp_read(struct v4l2_subdev *sd, u8 reg)
{}

static inline int sdp_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{}

static inline int sdp_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
{}

static inline int afe_read(struct v4l2_subdev *sd, u8 reg)
{}

static inline int afe_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{}

static inline int afe_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
{}

static inline int rep_read(struct v4l2_subdev *sd, u8 reg)
{}

static inline int rep_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{}

static inline int rep_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
{}

static inline int edid_read(struct v4l2_subdev *sd, u8 reg)
{}

static inline int edid_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{}

static inline int hdmi_read(struct v4l2_subdev *sd, u8 reg)
{}

static inline int hdmi_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{}

static inline int hdmi_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
{}

static inline int cp_read(struct v4l2_subdev *sd, u8 reg)
{}

static inline int cp_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{}

static inline int cp_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
{}

static inline int vdp_read(struct v4l2_subdev *sd, u8 reg)
{}

static inline int vdp_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{}

static void main_reset(struct v4l2_subdev *sd)
{}

/* -----------------------------------------------------------------------------
 * Format helpers
 */

static const struct adv7842_format_info adv7842_formats[] =;

static const struct adv7842_format_info *
adv7842_format_info(struct adv7842_state *state, u32 code)
{}

/* ----------------------------------------------------------------------- */

static inline bool is_analog_input(struct v4l2_subdev *sd)
{}

static inline bool is_digital_input(struct v4l2_subdev *sd)
{}

static const struct v4l2_dv_timings_cap adv7842_timings_cap_analog =;

static const struct v4l2_dv_timings_cap adv7842_timings_cap_digital =;

static inline const struct v4l2_dv_timings_cap *
adv7842_get_dv_timings_cap(struct v4l2_subdev *sd)
{}

/* ----------------------------------------------------------------------- */

static u16 adv7842_read_cable_det(struct v4l2_subdev *sd)
{}

static void adv7842_delayed_work_enable_hotplug(struct work_struct *work)
{}

static int edid_write_vga_segment(struct v4l2_subdev *sd)
{}

static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port)
{}

/* ----------------------------------------------------------------------- */

#ifdef CONFIG_VIDEO_ADV_DEBUG
static void adv7842_inv_register(struct v4l2_subdev *sd)
{}

static int adv7842_g_register(struct v4l2_subdev *sd,
			      struct v4l2_dbg_register *reg)
{}

static int adv7842_s_register(struct v4l2_subdev *sd,
		const struct v4l2_dbg_register *reg)
{}
#endif

static int adv7842_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd)
{}

static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd,
		u8 prim_mode,
		const struct adv7842_video_standards *predef_vid_timings,
		const struct v4l2_dv_timings *timings)
{}

static int configure_predefined_video_timings(struct v4l2_subdev *sd,
		struct v4l2_dv_timings *timings)
{}

static void configure_custom_video_timings(struct v4l2_subdev *sd,
		const struct v4l2_bt_timings *bt)
{}

static void adv7842_set_offset(struct v4l2_subdev *sd, bool auto_offset, u16 offset_a, u16 offset_b, u16 offset_c)
{}

static void adv7842_set_gain(struct v4l2_subdev *sd, bool auto_gain, u16 gain_a, u16 gain_b, u16 gain_c)
{}

static void set_rgb_quantization_range(struct v4l2_subdev *sd)
{}

static int adv7842_s_ctrl(struct v4l2_ctrl *ctrl)
{}

static int adv7842_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
{}

static inline bool no_power(struct v4l2_subdev *sd)
{}

static inline bool no_cp_signal(struct v4l2_subdev *sd)
{}

static inline bool is_hdmi(struct v4l2_subdev *sd)
{}

static int adv7842_g_input_status(struct v4l2_subdev *sd, u32 *status)
{}

struct stdi_readback {};

static int stdi2dv_timings(struct v4l2_subdev *sd,
		struct stdi_readback *stdi,
		struct v4l2_dv_timings *timings)
{}

static int read_stdi(struct v4l2_subdev *sd, struct stdi_readback *stdi)
{}

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

static int adv7842_dv_timings_cap(struct v4l2_subdev *sd,
				  struct v4l2_dv_timings_cap *cap)
{}

/* Fill the optional fields .standards and .flags in struct v4l2_dv_timings
   if the format is listed in adv7842_timings[] */
static void adv7842_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
		struct v4l2_dv_timings *timings)
{}

static int adv7842_query_dv_timings(struct v4l2_subdev *sd, unsigned int pad,
				    struct v4l2_dv_timings *timings)
{}

static int adv7842_s_dv_timings(struct v4l2_subdev *sd, unsigned int pad,
				struct v4l2_dv_timings *timings)
{}

static int adv7842_g_dv_timings(struct v4l2_subdev *sd, unsigned int pad,
				struct v4l2_dv_timings *timings)
{}

static void enable_input(struct v4l2_subdev *sd)
{}

static void disable_input(struct v4l2_subdev *sd)
{}

static void sdp_csc_coeff(struct v4l2_subdev *sd,
			  const struct adv7842_sdp_csc_coeff *c)
{}

static void select_input(struct v4l2_subdev *sd,
			 enum adv7842_vid_std_select vid_std_select)
{}

static int adv7842_s_routing(struct v4l2_subdev *sd,
		u32 input, u32 output, u32 config)
{}

static int adv7842_enum_mbus_code(struct v4l2_subdev *sd,
		struct v4l2_subdev_state *sd_state,
		struct v4l2_subdev_mbus_code_enum *code)
{}

static void adv7842_fill_format(struct adv7842_state *state,
				struct v4l2_mbus_framefmt *format)
{}

/*
 * Compute the op_ch_sel value required to obtain on the bus the component order
 * corresponding to the selected format taking into account bus reordering
 * applied by the board at the output of the device.
 *
 * The following table gives the op_ch_value from the format component order
 * (expressed as op_ch_sel value in column) and the bus reordering (expressed as
 * adv7842_bus_order value in row).
 *
 *           |	GBR(0)	GRB(1)	BGR(2)	RGB(3)	BRG(4)	RBG(5)
 * ----------+-------------------------------------------------
 * RGB (NOP) |	GBR	GRB	BGR	RGB	BRG	RBG
 * GRB (1-2) |	BGR	RGB	GBR	GRB	RBG	BRG
 * RBG (2-3) |	GRB	GBR	BRG	RBG	BGR	RGB
 * BGR (1-3) |	RBG	BRG	RGB	BGR	GRB	GBR
 * BRG (ROR) |	BRG	RBG	GRB	GBR	RGB	BGR
 * GBR (ROL) |	RGB	BGR	RBG	BRG	GBR	GRB
 */
static unsigned int adv7842_op_ch_sel(struct adv7842_state *state)
{}

static void adv7842_setup_format(struct adv7842_state *state)
{}

static int adv7842_get_format(struct v4l2_subdev *sd,
			      struct v4l2_subdev_state *sd_state,
			      struct v4l2_subdev_format *format)
{}

static int adv7842_set_format(struct v4l2_subdev *sd,
			      struct v4l2_subdev_state *sd_state,
			      struct v4l2_subdev_format *format)
{}

static void adv7842_irq_enable(struct v4l2_subdev *sd, bool enable)
{}

#if IS_ENABLED(CONFIG_VIDEO_ADV7842_CEC)
static void adv7842_cec_tx_raw_status(struct v4l2_subdev *sd, u8 tx_raw_status)
{}

static void adv7842_cec_isr(struct v4l2_subdev *sd, bool *handled)
{}

static int adv7842_cec_adap_enable(struct cec_adapter *adap, bool enable)
{}

static int adv7842_cec_adap_log_addr(struct cec_adapter *adap, u8 addr)
{}

static int adv7842_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
				     u32 signal_free_time, struct cec_msg *msg)
{}

static const struct cec_adap_ops adv7842_cec_adap_ops =;
#endif

static int adv7842_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
{}

static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
{}

/*
 * If the VGA_EDID_ENABLE bit is set (Repeater Map 0x7f, bit 7), then
 * the first two blocks of the EDID are for the HDMI, and the first block
 * of segment 1 (i.e. the third block of the EDID) is for VGA.
 * So if a VGA EDID is installed, then the maximum size of the HDMI EDID
 * is 2 blocks.
 */
static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *e)
{}

struct adv7842_cfg_read_infoframe {};

static void log_infoframe(struct v4l2_subdev *sd, const struct adv7842_cfg_read_infoframe *cri)
{}

static void adv7842_log_infoframes(struct v4l2_subdev *sd)
{}

#if 0
/* Let's keep it here for now, as it could be useful for debug */
static const char * const prim_mode_txt[] = {
	"SDP",
	"Component",
	"Graphics",
	"Reserved",
	"CVBS & HDMI AUDIO",
	"HDMI-Comp",
	"HDMI-GR",
	"Reserved",
	"Reserved",
	"Reserved",
	"Reserved",
	"Reserved",
	"Reserved",
	"Reserved",
	"Reserved",
	"Reserved",
};
#endif

static int adv7842_sdp_log_status(struct v4l2_subdev *sd)
{}

static int adv7842_cp_log_status(struct v4l2_subdev *sd)
{}

static int adv7842_log_status(struct v4l2_subdev *sd)
{}

static int adv7842_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
{}

static void adv7842_s_sdp_io(struct v4l2_subdev *sd, struct adv7842_sdp_io_sync_adjustment *s)
{}

static int adv7842_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
{}

static int adv7842_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
{}

/* ----------------------------------------------------------------------- */

static int adv7842_core_init(struct v4l2_subdev *sd)
{}

/* ----------------------------------------------------------------------- */

static int adv7842_ddr_ram_test(struct v4l2_subdev *sd)
{}

static void adv7842_rewrite_i2c_addresses(struct v4l2_subdev *sd,
		struct adv7842_platform_data *pdata)
{}

static int adv7842_command_ram_test(struct v4l2_subdev *sd)
{}

static long adv7842_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{}

static int adv7842_subscribe_event(struct v4l2_subdev *sd,
				   struct v4l2_fh *fh,
				   struct v4l2_event_subscription *sub)
{}

static int adv7842_registered(struct v4l2_subdev *sd)
{}

static void adv7842_unregistered(struct v4l2_subdev *sd)
{}

/* ----------------------------------------------------------------------- */

static const struct v4l2_ctrl_ops adv7842_ctrl_ops =;

static const struct v4l2_subdev_core_ops adv7842_core_ops =;

static const struct v4l2_subdev_video_ops adv7842_video_ops =;

static const struct v4l2_subdev_pad_ops adv7842_pad_ops =;

static const struct v4l2_subdev_ops adv7842_ops =;

static const struct v4l2_subdev_internal_ops adv7842_int_ops =;

/* -------------------------- custom ctrls ---------------------------------- */

static const struct v4l2_ctrl_config adv7842_ctrl_analog_sampling_phase =;

static const struct v4l2_ctrl_config adv7842_ctrl_free_run_color_manual =;

static const struct v4l2_ctrl_config adv7842_ctrl_free_run_color =;


static void adv7842_unregister_clients(struct v4l2_subdev *sd)
{}

static struct i2c_client *adv7842_dummy_client(struct v4l2_subdev *sd, const char *desc,
					       u8 addr, u8 io_reg)
{}

static int adv7842_register_clients(struct v4l2_subdev *sd)
{}

static int adv7842_probe(struct i2c_client *client)
{}

/* ----------------------------------------------------------------------- */

static void adv7842_remove(struct i2c_client *client)
{}

/* ----------------------------------------------------------------------- */

static const struct i2c_device_id adv7842_id[] =;
MODULE_DEVICE_TABLE(i2c, adv7842_id);

/* ----------------------------------------------------------------------- */

static struct i2c_driver adv7842_driver =;

module_i2c_driver();