#include <linux/component.h>
#include <linux/gpio/consumer.h>
#include <linux/hdmi.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/platform_data/tda9950.h>
#include <linux/irq.h>
#include <sound/asoundef.h>
#include <sound/hdmi-codec.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_edid.h>
#include <drm/drm_of.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_simple_kms_helper.h>
#include <drm/i2c/tda998x.h>
#include <media/cec-notifier.h>
#define DBG(fmt, ...) …
enum { … };
struct tda998x_audio_route { … };
struct tda998x_audio_settings { … };
struct tda998x_priv { … };
#define conn_to_tda998x_priv(x) …
#define enc_to_tda998x_priv(x) …
#define bridge_to_tda998x_priv(x) …
#define REG(page, addr) …
#define REG2ADDR(reg) …
#define REG2PAGE(reg) …
#define REG_CURPAGE …
#define REG_VERSION_LSB …
#define REG_MAIN_CNTRL0 …
#define MAIN_CNTRL0_SR …
#define MAIN_CNTRL0_DECS …
#define MAIN_CNTRL0_DEHS …
#define MAIN_CNTRL0_CECS …
#define MAIN_CNTRL0_CEHS …
#define MAIN_CNTRL0_SCALER …
#define REG_VERSION_MSB …
#define REG_SOFTRESET …
#define SOFTRESET_AUDIO …
#define SOFTRESET_I2C_MASTER …
#define REG_DDC_DISABLE …
#define REG_CCLK_ON …
#define REG_I2C_MASTER …
#define I2C_MASTER_DIS_MM …
#define I2C_MASTER_DIS_FILT …
#define I2C_MASTER_APP_STRT_LAT …
#define REG_FEAT_POWERDOWN …
#define FEAT_POWERDOWN_PREFILT …
#define FEAT_POWERDOWN_CSC …
#define FEAT_POWERDOWN_SPDIF …
#define REG_INT_FLAGS_0 …
#define REG_INT_FLAGS_1 …
#define REG_INT_FLAGS_2 …
#define INT_FLAGS_2_EDID_BLK_RD …
#define REG_ENA_ACLK …
#define REG_ENA_VP_0 …
#define REG_ENA_VP_1 …
#define REG_ENA_VP_2 …
#define REG_ENA_AP …
#define REG_VIP_CNTRL_0 …
#define VIP_CNTRL_0_MIRR_A …
#define VIP_CNTRL_0_SWAP_A(x) …
#define VIP_CNTRL_0_MIRR_B …
#define VIP_CNTRL_0_SWAP_B(x) …
#define REG_VIP_CNTRL_1 …
#define VIP_CNTRL_1_MIRR_C …
#define VIP_CNTRL_1_SWAP_C(x) …
#define VIP_CNTRL_1_MIRR_D …
#define VIP_CNTRL_1_SWAP_D(x) …
#define REG_VIP_CNTRL_2 …
#define VIP_CNTRL_2_MIRR_E …
#define VIP_CNTRL_2_SWAP_E(x) …
#define VIP_CNTRL_2_MIRR_F …
#define VIP_CNTRL_2_SWAP_F(x) …
#define REG_VIP_CNTRL_3 …
#define VIP_CNTRL_3_X_TGL …
#define VIP_CNTRL_3_H_TGL …
#define VIP_CNTRL_3_V_TGL …
#define VIP_CNTRL_3_EMB …
#define VIP_CNTRL_3_SYNC_DE …
#define VIP_CNTRL_3_SYNC_HS …
#define VIP_CNTRL_3_DE_INT …
#define VIP_CNTRL_3_EDGE …
#define REG_VIP_CNTRL_4 …
#define VIP_CNTRL_4_BLC(x) …
#define VIP_CNTRL_4_BLANKIT(x) …
#define VIP_CNTRL_4_CCIR656 …
#define VIP_CNTRL_4_656_ALT …
#define VIP_CNTRL_4_TST_656 …
#define VIP_CNTRL_4_TST_PAT …
#define REG_VIP_CNTRL_5 …
#define VIP_CNTRL_5_CKCASE …
#define VIP_CNTRL_5_SP_CNT(x) …
#define REG_MUX_AP …
#define MUX_AP_SELECT_I2S …
#define MUX_AP_SELECT_SPDIF …
#define REG_MUX_VP_VIP_OUT …
#define REG_MAT_CONTRL …
#define MAT_CONTRL_MAT_SC(x) …
#define MAT_CONTRL_MAT_BP …
#define REG_VIDFORMAT …
#define REG_REFPIX_MSB …
#define REG_REFPIX_LSB …
#define REG_REFLINE_MSB …
#define REG_REFLINE_LSB …
#define REG_NPIX_MSB …
#define REG_NPIX_LSB …
#define REG_NLINE_MSB …
#define REG_NLINE_LSB …
#define REG_VS_LINE_STRT_1_MSB …
#define REG_VS_LINE_STRT_1_LSB …
#define REG_VS_PIX_STRT_1_MSB …
#define REG_VS_PIX_STRT_1_LSB …
#define REG_VS_LINE_END_1_MSB …
#define REG_VS_LINE_END_1_LSB …
#define REG_VS_PIX_END_1_MSB …
#define REG_VS_PIX_END_1_LSB …
#define REG_VS_LINE_STRT_2_MSB …
#define REG_VS_LINE_STRT_2_LSB …
#define REG_VS_PIX_STRT_2_MSB …
#define REG_VS_PIX_STRT_2_LSB …
#define REG_VS_LINE_END_2_MSB …
#define REG_VS_LINE_END_2_LSB …
#define REG_VS_PIX_END_2_MSB …
#define REG_VS_PIX_END_2_LSB …
#define REG_HS_PIX_START_MSB …
#define REG_HS_PIX_START_LSB …
#define REG_HS_PIX_STOP_MSB …
#define REG_HS_PIX_STOP_LSB …
#define REG_VWIN_START_1_MSB …
#define REG_VWIN_START_1_LSB …
#define REG_VWIN_END_1_MSB …
#define REG_VWIN_END_1_LSB …
#define REG_VWIN_START_2_MSB …
#define REG_VWIN_START_2_LSB …
#define REG_VWIN_END_2_MSB …
#define REG_VWIN_END_2_LSB …
#define REG_DE_START_MSB …
#define REG_DE_START_LSB …
#define REG_DE_STOP_MSB …
#define REG_DE_STOP_LSB …
#define REG_TBG_CNTRL_0 …
#define TBG_CNTRL_0_TOP_TGL …
#define TBG_CNTRL_0_TOP_SEL …
#define TBG_CNTRL_0_DE_EXT …
#define TBG_CNTRL_0_TOP_EXT …
#define TBG_CNTRL_0_FRAME_DIS …
#define TBG_CNTRL_0_SYNC_MTHD …
#define TBG_CNTRL_0_SYNC_ONCE …
#define REG_TBG_CNTRL_1 …
#define TBG_CNTRL_1_H_TGL …
#define TBG_CNTRL_1_V_TGL …
#define TBG_CNTRL_1_TGL_EN …
#define TBG_CNTRL_1_X_EXT …
#define TBG_CNTRL_1_H_EXT …
#define TBG_CNTRL_1_V_EXT …
#define TBG_CNTRL_1_DWIN_DIS …
#define REG_ENABLE_SPACE …
#define REG_HVF_CNTRL_0 …
#define HVF_CNTRL_0_SM …
#define HVF_CNTRL_0_RWB …
#define HVF_CNTRL_0_PREFIL(x) …
#define HVF_CNTRL_0_INTPOL(x) …
#define REG_HVF_CNTRL_1 …
#define HVF_CNTRL_1_FOR …
#define HVF_CNTRL_1_YUVBLK …
#define HVF_CNTRL_1_VQR(x) …
#define HVF_CNTRL_1_PAD(x) …
#define HVF_CNTRL_1_SEMI_PLANAR …
#define REG_RPT_CNTRL …
#define RPT_CNTRL_REPEAT(x) …
#define REG_I2S_FORMAT …
#define I2S_FORMAT_PHILIPS …
#define I2S_FORMAT_LEFT_J …
#define I2S_FORMAT_RIGHT_J …
#define REG_AIP_CLKSEL …
#define AIP_CLKSEL_AIP_SPDIF …
#define AIP_CLKSEL_AIP_I2S …
#define AIP_CLKSEL_FS_ACLK …
#define AIP_CLKSEL_FS_MCLK …
#define AIP_CLKSEL_FS_FS64SPDIF …
#define REG_PLL_SERIAL_1 …
#define PLL_SERIAL_1_SRL_FDN …
#define PLL_SERIAL_1_SRL_IZ(x) …
#define PLL_SERIAL_1_SRL_MAN_IZ …
#define REG_PLL_SERIAL_2 …
#define PLL_SERIAL_2_SRL_NOSC(x) …
#define PLL_SERIAL_2_SRL_PR(x) …
#define REG_PLL_SERIAL_3 …
#define PLL_SERIAL_3_SRL_CCIR …
#define PLL_SERIAL_3_SRL_DE …
#define PLL_SERIAL_3_SRL_PXIN_SEL …
#define REG_SERIALIZER …
#define REG_BUFFER_OUT …
#define REG_PLL_SCG1 …
#define REG_PLL_SCG2 …
#define REG_PLL_SCGN1 …
#define REG_PLL_SCGN2 …
#define REG_PLL_SCGR1 …
#define REG_PLL_SCGR2 …
#define REG_AUDIO_DIV …
#define AUDIO_DIV_SERCLK_1 …
#define AUDIO_DIV_SERCLK_2 …
#define AUDIO_DIV_SERCLK_4 …
#define AUDIO_DIV_SERCLK_8 …
#define AUDIO_DIV_SERCLK_16 …
#define AUDIO_DIV_SERCLK_32 …
#define REG_SEL_CLK …
#define SEL_CLK_SEL_CLK1 …
#define SEL_CLK_SEL_VRF_CLK(x) …
#define SEL_CLK_ENA_SC_CLK …
#define REG_ANA_GENERAL …
#define REG_EDID_DATA_0 …
#define REG_EDID_CTRL …
#define REG_DDC_ADDR …
#define REG_DDC_OFFS …
#define REG_DDC_SEGM_ADDR …
#define REG_DDC_SEGM …
#define REG_IF1_HB0 …
#define REG_IF2_HB0 …
#define REG_IF3_HB0 …
#define REG_IF4_HB0 …
#define REG_IF5_HB0 …
#define REG_AIP_CNTRL_0 …
#define AIP_CNTRL_0_RST_FIFO …
#define AIP_CNTRL_0_SWAP …
#define AIP_CNTRL_0_LAYOUT …
#define AIP_CNTRL_0_ACR_MAN …
#define AIP_CNTRL_0_RST_CTS …
#define REG_CA_I2S …
#define CA_I2S_CA_I2S(x) …
#define CA_I2S_HBR_CHSTAT …
#define REG_LATENCY_RD …
#define REG_ACR_CTS_0 …
#define REG_ACR_CTS_1 …
#define REG_ACR_CTS_2 …
#define REG_ACR_N_0 …
#define REG_ACR_N_1 …
#define REG_ACR_N_2 …
#define REG_CTS_N …
#define CTS_N_K(x) …
#define CTS_N_M(x) …
#define REG_ENC_CNTRL …
#define ENC_CNTRL_RST_ENC …
#define ENC_CNTRL_RST_SEL …
#define ENC_CNTRL_CTL_CODE(x) …
#define REG_DIP_FLAGS …
#define DIP_FLAGS_ACR …
#define DIP_FLAGS_GC …
#define REG_DIP_IF_FLAGS …
#define DIP_IF_FLAGS_IF1 …
#define DIP_IF_FLAGS_IF2 …
#define DIP_IF_FLAGS_IF3 …
#define DIP_IF_FLAGS_IF4 …
#define DIP_IF_FLAGS_IF5 …
#define REG_CH_STAT_B(x) …
#define REG_TX3 …
#define REG_TX4 …
#define TX4_PD_RAM …
#define REG_TX33 …
#define TX33_HDMI …
#define REG_CEC_INTSTATUS …
#define CEC_INTSTATUS_CEC …
#define CEC_INTSTATUS_HDMI …
#define REG_CEC_CAL_XOSC_CTRL1 …
#define CEC_CAL_XOSC_CTRL1_ENA_CAL …
#define REG_CEC_DES_FREQ2 …
#define CEC_DES_FREQ2_DIS_AUTOCAL …
#define REG_CEC_CLK …
#define CEC_CLK_FRO …
#define REG_CEC_FRO_IM_CLK_CTRL …
#define CEC_FRO_IM_CLK_CTRL_GHOST_DIS …
#define CEC_FRO_IM_CLK_CTRL_ENA_OTP …
#define CEC_FRO_IM_CLK_CTRL_IMCLK_SEL …
#define CEC_FRO_IM_CLK_CTRL_FRO_DIV …
#define REG_CEC_RXSHPDINTENA …
#define REG_CEC_RXSHPDINT …
#define CEC_RXSHPDINT_RXSENS …
#define CEC_RXSHPDINT_HPD …
#define REG_CEC_RXSHPDLEV …
#define CEC_RXSHPDLEV_RXSENS …
#define CEC_RXSHPDLEV_HPD …
#define REG_CEC_ENAMODS …
#define CEC_ENAMODS_EN_CEC_CLK …
#define CEC_ENAMODS_DIS_FRO …
#define CEC_ENAMODS_DIS_CCLK …
#define CEC_ENAMODS_EN_RXSENS …
#define CEC_ENAMODS_EN_HDMI …
#define CEC_ENAMODS_EN_CEC …
#define TDA9989N2 …
#define TDA19989 …
#define TDA19989N2 …
#define TDA19988 …
static void
cec_write(struct tda998x_priv *priv, u16 addr, u8 val)
{ … }
static u8
cec_read(struct tda998x_priv *priv, u8 addr)
{ … }
static void cec_enamods(struct tda998x_priv *priv, u8 mods, bool enable)
{ … }
static void tda998x_cec_set_calibration(struct tda998x_priv *priv, bool enable)
{ … }
static void tda998x_cec_calibration(struct tda998x_priv *priv)
{ … }
static int tda998x_cec_hook_init(void *data)
{ … }
static void tda998x_cec_hook_exit(void *data)
{ … }
static int tda998x_cec_hook_open(void *data)
{ … }
static void tda998x_cec_hook_release(void *data)
{ … }
static int
set_page(struct tda998x_priv *priv, u16 reg)
{ … }
static int
reg_read_range(struct tda998x_priv *priv, u16 reg, char *buf, int cnt)
{ … }
#define MAX_WRITE_RANGE_BUF …
static void
reg_write_range(struct tda998x_priv *priv, u16 reg, u8 *p, int cnt)
{ … }
static int
reg_read(struct tda998x_priv *priv, u16 reg)
{ … }
static void
reg_write(struct tda998x_priv *priv, u16 reg, u8 val)
{ … }
static void
reg_write16(struct tda998x_priv *priv, u16 reg, u16 val)
{ … }
static void
reg_set(struct tda998x_priv *priv, u16 reg, u8 val)
{ … }
static void
reg_clear(struct tda998x_priv *priv, u16 reg, u8 val)
{ … }
static void
tda998x_reset(struct tda998x_priv *priv)
{ … }
static void tda998x_edid_delay_done(struct timer_list *t)
{ … }
static void tda998x_edid_delay_start(struct tda998x_priv *priv)
{ … }
static int tda998x_edid_delay_wait(struct tda998x_priv *priv)
{ … }
static void tda998x_detect_work(struct work_struct *work)
{ … }
static irqreturn_t tda998x_irq_thread(int irq, void *data)
{ … }
static void
tda998x_write_if(struct tda998x_priv *priv, u8 bit, u16 addr,
union hdmi_infoframe *frame)
{ … }
static void tda998x_write_aif(struct tda998x_priv *priv,
const struct hdmi_audio_infoframe *cea)
{ … }
static void
tda998x_write_avi(struct tda998x_priv *priv, const struct drm_display_mode *mode)
{ … }
static void tda998x_write_vsi(struct tda998x_priv *priv,
const struct drm_display_mode *mode)
{ … }
static const struct tda998x_audio_route tda998x_audio_route[AUDIO_ROUTE_NUM] = …;
static int tda998x_derive_routing(struct tda998x_priv *priv,
struct tda998x_audio_settings *s,
unsigned int route)
{ … }
static u8 tda998x_get_adiv(struct tda998x_priv *priv, unsigned int fs)
{ … }
static int tda998x_derive_cts_n(struct tda998x_priv *priv,
struct tda998x_audio_settings *settings,
unsigned int ratio)
{ … }
static void tda998x_audio_mute(struct tda998x_priv *priv, bool on)
{ … }
static void tda998x_configure_audio(struct tda998x_priv *priv)
{ … }
static int tda998x_audio_hw_params(struct device *dev, void *data,
struct hdmi_codec_daifmt *daifmt,
struct hdmi_codec_params *params)
{ … }
static void tda998x_audio_shutdown(struct device *dev, void *data)
{ … }
static int tda998x_audio_mute_stream(struct device *dev, void *data,
bool enable, int direction)
{ … }
static int tda998x_audio_get_eld(struct device *dev, void *data,
uint8_t *buf, size_t len)
{ … }
static const struct hdmi_codec_ops audio_codec_ops = …;
static int tda998x_audio_codec_init(struct tda998x_priv *priv,
struct device *dev)
{ … }
static enum drm_connector_status
tda998x_connector_detect(struct drm_connector *connector, bool force)
{ … }
static void tda998x_connector_destroy(struct drm_connector *connector)
{ … }
static const struct drm_connector_funcs tda998x_connector_funcs = …;
static int read_edid_block(void *data, u8 *buf, unsigned int blk, size_t length)
{ … }
static int tda998x_connector_get_modes(struct drm_connector *connector)
{ … }
static struct drm_encoder *
tda998x_connector_best_encoder(struct drm_connector *connector)
{ … }
static
const struct drm_connector_helper_funcs tda998x_connector_helper_funcs = …;
static int tda998x_connector_init(struct tda998x_priv *priv,
struct drm_device *drm)
{ … }
static int tda998x_bridge_attach(struct drm_bridge *bridge,
enum drm_bridge_attach_flags flags)
{ … }
static void tda998x_bridge_detach(struct drm_bridge *bridge)
{ … }
static enum drm_mode_status tda998x_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode)
{ … }
static void tda998x_bridge_enable(struct drm_bridge *bridge)
{ … }
static void tda998x_bridge_disable(struct drm_bridge *bridge)
{ … }
static void tda998x_bridge_mode_set(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
const struct drm_display_mode *adjusted_mode)
{ … }
static const struct drm_bridge_funcs tda998x_bridge_funcs = …;
static int tda998x_get_audio_ports(struct tda998x_priv *priv,
struct device_node *np)
{ … }
static int tda998x_set_config(struct tda998x_priv *priv,
const struct tda998x_encoder_params *p)
{ … }
static void tda998x_destroy(struct device *dev)
{ … }
static int tda998x_create(struct device *dev)
{ … }
static int tda998x_encoder_init(struct device *dev, struct drm_device *drm)
{ … }
static int tda998x_bind(struct device *dev, struct device *master, void *data)
{ … }
static void tda998x_unbind(struct device *dev, struct device *master,
void *data)
{ … }
static const struct component_ops tda998x_ops = …;
static int
tda998x_probe(struct i2c_client *client)
{ … }
static void tda998x_remove(struct i2c_client *client)
{ … }
#ifdef CONFIG_OF
static const struct of_device_id tda998x_dt_ids[] = …;
MODULE_DEVICE_TABLE(of, tda998x_dt_ids);
#endif
static const struct i2c_device_id tda998x_ids[] = …;
MODULE_DEVICE_TABLE(i2c, tda998x_ids);
static struct i2c_driver tda998x_driver = …;
module_i2c_driver(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;