drivers/gpu/drm/bridge/tda998x_drv.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/bridge/tda998x_drv.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/bridge/tda998x_drv.c
Extension
.c
Size
62800 bytes
Lines
2082
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct tda998x_audio_route {
	u8 ena_aclk;
	u8 mux_ap;
	u8 aip_clksel;
};

struct tda998x_audio_settings {
	const struct tda998x_audio_route *route;
	struct hdmi_audio_infoframe cea;
	unsigned int sample_rate;
	u8 status[5];
	u8 ena_ap;
	u8 i2s_format;
	u8 cts_n;
};

struct tda998x_priv {
	struct i2c_client *cec;
	struct i2c_client *hdmi;
	struct mutex mutex;
	u16 rev;
	u8 cec_addr;
	u8 current_page;
	bool is_on;
	bool supports_infoframes;
	bool sink_has_audio;
	enum hdmi_quantization_range rgb_quant_range;
	u8 vip_cntrl_0;
	u8 vip_cntrl_1;
	u8 vip_cntrl_2;
	unsigned long tmds_clock;
	struct tda998x_audio_settings audio;

	struct platform_device *audio_pdev;
	struct mutex audio_mutex;

	struct mutex edid_mutex;
	wait_queue_head_t wq_edid;
	volatile int wq_edid_wait;

	struct work_struct detect_work;
	struct timer_list edid_delay_timer;
	wait_queue_head_t edid_delay_waitq;
	bool edid_delay_active;

	struct drm_encoder encoder;
	struct drm_bridge bridge;
	struct drm_connector connector;

	u8 audio_port_enable[AUDIO_ROUTE_NUM];
	struct tda9950_glue cec_glue;
	struct gpio_desc *calib;
	struct cec_notifier *cec_notify;
};

#define conn_to_tda998x_priv(x) \
	container_of(x, struct tda998x_priv, connector)
#define enc_to_tda998x_priv(x) \
	container_of(x, struct tda998x_priv, encoder)
#define bridge_to_tda998x_priv(x) \
	container_of(x, struct tda998x_priv, bridge)

/* The TDA9988 series of devices use a paged register scheme.. to simplify
 * things we encode the page # in upper bits of the register #.  To read/
 * write a given register, we need to make sure CURPAGE register is set
 * appropriately.  Which implies reads/writes are not atomic.  Fun!
 */

#define REG(page, addr) (((page) << 8) | (addr))
#define REG2ADDR(reg)   ((reg) & 0xff)
#define REG2PAGE(reg)   (((reg) >> 8) & 0xff)

#define REG_CURPAGE               0xff                /* write */


/* Page 00h: General Control */
#define REG_VERSION_LSB           REG(0x00, 0x00)     /* read */
#define REG_MAIN_CNTRL0           REG(0x00, 0x01)     /* read/write */
# define MAIN_CNTRL0_SR           (1 << 0)
# define MAIN_CNTRL0_DECS         (1 << 1)
# define MAIN_CNTRL0_DEHS         (1 << 2)
# define MAIN_CNTRL0_CECS         (1 << 3)
# define MAIN_CNTRL0_CEHS         (1 << 4)
# define MAIN_CNTRL0_SCALER       (1 << 7)
#define REG_VERSION_MSB           REG(0x00, 0x02)     /* read */
#define REG_SOFTRESET             REG(0x00, 0x0a)     /* write */
# define SOFTRESET_AUDIO          (1 << 0)
# define SOFTRESET_I2C_MASTER     (1 << 1)
#define REG_DDC_DISABLE           REG(0x00, 0x0b)     /* read/write */
#define REG_CCLK_ON               REG(0x00, 0x0c)     /* read/write */

Annotation

Implementation Notes