#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/hdmi.h>
#include <linux/v4l2-dv-timings.h>
#include <media/v4l2-device.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-dv-timings.h>
#include <media/i2c/adv7511.h>
#include <media/cec.h>
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_AUTHOR(…) …;
MODULE_LICENSE(…) …;
#define MASK_ADV7511_EDID_RDY_INT …
#define MASK_ADV7511_MSEN_INT …
#define MASK_ADV7511_HPD_INT …
#define MASK_ADV7511_HPD_DETECT …
#define MASK_ADV7511_MSEN_DETECT …
#define MASK_ADV7511_EDID_RDY …
#define EDID_MAX_RETRIES …
#define EDID_DELAY …
#define EDID_MAX_SEGM …
#define ADV7511_MAX_WIDTH …
#define ADV7511_MAX_HEIGHT …
#define ADV7511_MIN_PIXELCLOCK …
#define ADV7511_MAX_PIXELCLOCK …
#define ADV7511_MAX_ADDRS …
struct adv7511_state_edid { … };
struct adv7511_state { … };
static void adv7511_check_monitor_present_status(struct v4l2_subdev *sd);
static bool adv7511_check_edid_status(struct v4l2_subdev *sd);
static void adv7511_setup(struct v4l2_subdev *sd);
static int adv7511_s_i2s_clock_freq(struct v4l2_subdev *sd, u32 freq);
static int adv7511_s_clock_freq(struct v4l2_subdev *sd, u32 freq);
static const struct v4l2_dv_timings_cap adv7511_timings_cap = …;
static inline struct adv7511_state *get_adv7511_state(struct v4l2_subdev *sd)
{ … }
static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
{ … }
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 int adv7511_rd(struct v4l2_subdev *sd, u8 reg)
{ … }
static int adv7511_wr(struct v4l2_subdev *sd, u8 reg, u8 val)
{ … }
static inline void adv7511_wr_and_or(struct v4l2_subdev *sd, u8 reg, u8 clr_mask, u8 val_mask)
{ … }
static int adv7511_edid_rd(struct v4l2_subdev *sd, uint16_t len, uint8_t *buf)
{ … }
static inline int adv7511_cec_read(struct v4l2_subdev *sd, u8 reg)
{ … }
static int adv7511_cec_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{ … }
static inline int adv7511_cec_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask,
u8 val)
{ … }
static int adv7511_pktmem_rd(struct v4l2_subdev *sd, u8 reg)
{ … }
static inline bool adv7511_have_hotplug(struct v4l2_subdev *sd)
{ … }
static inline bool adv7511_have_rx_sense(struct v4l2_subdev *sd)
{ … }
static void adv7511_csc_conversion_mode(struct v4l2_subdev *sd, u8 mode)
{ … }
static void adv7511_csc_coeff(struct v4l2_subdev *sd,
u16 A1, u16 A2, u16 A3, u16 A4,
u16 B1, u16 B2, u16 B3, u16 B4,
u16 C1, u16 C2, u16 C3, u16 C4)
{ … }
static void adv7511_csc_rgb_full2limit(struct v4l2_subdev *sd, bool enable)
{ … }
static void adv7511_set_rgb_quantization_mode(struct v4l2_subdev *sd, struct v4l2_ctrl *ctrl)
{ … }
static int adv7511_s_ctrl(struct v4l2_ctrl *ctrl)
{ … }
static const struct v4l2_ctrl_ops adv7511_ctrl_ops = …;
#ifdef CONFIG_VIDEO_ADV_DEBUG
static void adv7511_inv_register(struct v4l2_subdev *sd)
{ … }
static int adv7511_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{ … }
static int adv7511_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
{ … }
#endif
struct adv7511_cfg_read_infoframe { … };
static u8 hdmi_infoframe_checksum(u8 *ptr, size_t size)
{ … }
static void log_infoframe(struct v4l2_subdev *sd, const struct adv7511_cfg_read_infoframe *cri)
{ … }
static void adv7511_log_infoframes(struct v4l2_subdev *sd)
{ … }
static int adv7511_log_status(struct v4l2_subdev *sd)
{ … }
static int adv7511_s_power(struct v4l2_subdev *sd, int on)
{ … }
#if IS_ENABLED(CONFIG_VIDEO_ADV7511_CEC)
static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable)
{ … }
static int adv7511_cec_adap_log_addr(struct cec_adapter *adap, u8 addr)
{ … }
static int adv7511_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
u32 signal_free_time, struct cec_msg *msg)
{ … }
static void adv_cec_tx_raw_status(struct v4l2_subdev *sd, u8 tx_raw_status)
{ … }
static const struct cec_adap_ops adv7511_cec_adap_ops = …;
#endif
static void adv7511_set_isr(struct v4l2_subdev *sd, bool enable)
{ … }
static int adv7511_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
{ … }
static const struct v4l2_subdev_core_ops adv7511_core_ops = …;
static int adv7511_s_stream(struct v4l2_subdev *sd, int enable)
{ … }
static int adv7511_s_dv_timings(struct v4l2_subdev *sd, unsigned int pad,
struct v4l2_dv_timings *timings)
{ … }
static int adv7511_g_dv_timings(struct v4l2_subdev *sd, unsigned int pad,
struct v4l2_dv_timings *timings)
{ … }
static int adv7511_enum_dv_timings(struct v4l2_subdev *sd,
struct v4l2_enum_dv_timings *timings)
{ … }
static int adv7511_dv_timings_cap(struct v4l2_subdev *sd,
struct v4l2_dv_timings_cap *cap)
{ … }
static const struct v4l2_subdev_video_ops adv7511_video_ops = …;
static int adv7511_s_audio_stream(struct v4l2_subdev *sd, int enable)
{ … }
static int adv7511_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
{ … }
static int adv7511_s_i2s_clock_freq(struct v4l2_subdev *sd, u32 freq)
{ … }
static int adv7511_s_routing(struct v4l2_subdev *sd, u32 input, u32 output, u32 config)
{ … }
static const struct v4l2_subdev_audio_ops adv7511_audio_ops = …;
static int adv7511_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
{ … }
static int adv7511_enum_mbus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_mbus_code_enum *code)
{ … }
static void adv7511_fill_format(struct adv7511_state *state,
struct v4l2_mbus_framefmt *format)
{ … }
static int adv7511_get_fmt(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *format)
{ … }
static int adv7511_set_fmt(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *format)
{ … }
static const struct v4l2_subdev_pad_ops adv7511_pad_ops = …;
static const struct v4l2_subdev_ops adv7511_ops = …;
static void adv7511_dbg_dump_edid(int lvl, int debug, struct v4l2_subdev *sd, int segment, u8 *buf)
{ … }
static void adv7511_notify_no_edid(struct v4l2_subdev *sd)
{ … }
static void adv7511_edid_handler(struct work_struct *work)
{ … }
static void adv7511_audio_setup(struct v4l2_subdev *sd)
{ … }
static void adv7511_setup(struct v4l2_subdev *sd)
{ … }
static void adv7511_notify_monitor_detect(struct v4l2_subdev *sd)
{ … }
static void adv7511_check_monitor_present_status(struct v4l2_subdev *sd)
{ … }
static bool edid_block_verify_crc(u8 *edid_block)
{ … }
static bool edid_verify_crc(struct v4l2_subdev *sd, u32 segment)
{ … }
static bool edid_verify_header(struct v4l2_subdev *sd, u32 segment)
{ … }
static bool adv7511_check_edid_status(struct v4l2_subdev *sd)
{ … }
static int adv7511_registered(struct v4l2_subdev *sd)
{ … }
static void adv7511_unregistered(struct v4l2_subdev *sd)
{ … }
static const struct v4l2_subdev_internal_ops adv7511_int_ops = …;
static void adv7511_init_setup(struct v4l2_subdev *sd)
{ … }
static int adv7511_probe(struct i2c_client *client)
{ … }
static void adv7511_remove(struct i2c_client *client)
{ … }
static const struct i2c_device_id adv7511_id[] = …;
MODULE_DEVICE_TABLE(i2c, adv7511_id);
static struct i2c_driver adv7511_driver = …;
module_i2c_driver(…) …;