drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c- Extension
.c- Size
- 10830 bytes
- Lines
- 405
- 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.
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitfield.hlinux/clk.hlinux/delay.hlinux/device.hlinux/err.hlinux/i2c.hlinux/kernel.hlinux/mfd/syscon.hlinux/module.hlinux/mutex.hlinux/of_platform.hlinux/platform_device.hlinux/pm_runtime.hlinux/regmap.hlinux/types.hdrm/drm_edid.hmtk_hdmi_common.hmtk_hdmi_regs_v2.h
Detected Declarations
struct mtk_hdmi_ddcfunction mtk_ddc_check_and_rise_low_busfunction mtk_ddcm_write_hdmifunction mtk_ddcm_read_hdmifunction mtk_hdmi_fg_ddc_data_readfunction mtk_hdmi_ddc_fg_data_writefunction mtk_hdmi_ddc_v2_xferfunction mtk_hdmi_ddc_v2_funcfunction mtk_hdmi_ddc_v2_probe
Annotated Snippet
struct mtk_hdmi_ddc {
struct device *dev;
struct regmap *regs;
struct clk *clk;
struct i2c_adapter adap;
};
static int mtk_ddc_check_and_rise_low_bus(struct mtk_hdmi_ddc *ddc)
{
u32 val;
regmap_read(ddc->regs, HDCP2X_DDCM_STATUS, &val);
if (val & DDC_I2C_BUS_LOW) {
regmap_update_bits(ddc->regs, DDC_CTRL, DDC_CTRL_CMD,
FIELD_PREP(DDC_CTRL_CMD, DDC_CMD_CLOCK_SCL));
usleep_range(250, 300);
}
if (val & DDC_I2C_NO_ACK) {
u32 ddc_ctrl, hpd_ddc_ctrl, hpd_ddc_status;
regmap_read(ddc->regs, DDC_CTRL, &ddc_ctrl);
regmap_read(ddc->regs, HPD_DDC_CTRL, &hpd_ddc_ctrl);
regmap_read(ddc->regs, HPD_DDC_STATUS, &hpd_ddc_status);
}
if (val & DDC_I2C_NO_ACK)
return -EIO;
return 0;
}
static int mtk_ddcm_write_hdmi(struct mtk_hdmi_ddc *ddc, u16 addr_id,
u16 offset_id, u16 data_cnt, u8 *wr_data)
{
u32 val;
int ret, i;
/* Don't allow transfer with a size over than the transfer fifo size
* (16 byte)
*/
if (data_cnt > 16) {
dev_err(ddc->dev, "Invalid DDCM write request\n");
return -EINVAL;
}
/* If down, rise bus for write operation */
mtk_ddc_check_and_rise_low_bus(ddc);
regmap_update_bits(ddc->regs, HPD_DDC_CTRL, HPD_DDC_DELAY_CNT,
FIELD_PREP(HPD_DDC_DELAY_CNT, DDC2_DLY_CNT));
/* In case there is no payload data, just do a single write for the
* address only
*/
if (wr_data) {
/* Fill transfer fifo with payload data */
for (i = 0; i < data_cnt; i++) {
regmap_write(ddc->regs, SI2C_CTRL,
FIELD_PREP(SI2C_ADDR, SI2C_ADDR_READ) |
FIELD_PREP(SI2C_WDATA, wr_data[i]) |
SI2C_WR);
}
}
regmap_write(ddc->regs, DDC_CTRL,
FIELD_PREP(DDC_CTRL_CMD, DDC_CMD_SEQ_WRITE) |
FIELD_PREP(DDC_CTRL_DIN_CNT, wr_data == NULL ? 0 : data_cnt) |
FIELD_PREP(DDC_CTRL_OFFSET, offset_id) |
FIELD_PREP(DDC_CTRL_ADDR, addr_id));
usleep_range(1000, 1250);
ret = regmap_read_poll_timeout(ddc->regs, HPD_DDC_STATUS, val,
!(val & DDC_I2C_IN_PROG), 500, 1000);
if (ret) {
dev_err(ddc->dev, "DDC I2C write timeout\n");
/* Abort transfer if it is still in progress */
regmap_update_bits(ddc->regs, DDC_CTRL, DDC_CTRL_CMD,
FIELD_PREP(DDC_CTRL_CMD, DDC_CMD_ABORT_XFER));
return ret;
}
/* The I2C bus might be down after WR operation: rise it again */
ret = mtk_ddc_check_and_rise_low_bus(ddc);
if (ret) {
dev_err(ddc->dev, "Error during write operation: No ACK\n");
return ret;
}
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/clk.h`, `linux/delay.h`, `linux/device.h`, `linux/err.h`, `linux/i2c.h`, `linux/kernel.h`, `linux/mfd/syscon.h`.
- Detected declarations: `struct mtk_hdmi_ddc`, `function mtk_ddc_check_and_rise_low_bus`, `function mtk_ddcm_write_hdmi`, `function mtk_ddcm_read_hdmi`, `function mtk_hdmi_fg_ddc_data_read`, `function mtk_hdmi_ddc_fg_data_write`, `function mtk_hdmi_ddc_v2_xfer`, `function mtk_hdmi_ddc_v2_func`, `function mtk_hdmi_ddc_v2_probe`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.