#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(…) …;
#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 …
struct adv7842_format_info { … };
struct adv7842_state { … };
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 { … };
static const struct adv7842_video_standards adv7842_prim_mode_comp[] = …;
static const struct adv7842_video_standards adv7842_prim_mode_gr[] = …;
static const struct adv7842_video_standards adv7842_prim_mode_hdmi_comp[] = …;
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)
{ … }
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)
{ … }
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)
{ … }
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)
{ … }
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
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 = …;
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(…) …;