drivers/media/platform/amlogic/c3/mipi-csi2/c3-mipi-csi2.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/amlogic/c3/mipi-csi2/c3-mipi-csi2.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/amlogic/c3/mipi-csi2/c3-mipi-csi2.c
Extension
.c
Size
24737 bytes
Lines
828
Domain
Driver Families
Bucket
drivers/media
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 c3_csi_info {
	char *clocks[MIPI_CSI2_CLOCK_NUM_MAX];
	u32 clock_num;
};

/*
 * struct c3_csi_device - MIPI CSI2 platform device
 *
 * @dev: pointer to the struct device
 * @aphy: MIPI CSI2 aphy register address
 * @dphy: MIPI CSI2 dphy register address
 * @host: MIPI CSI2 host register address
 * @clks: array of MIPI CSI2 clocks
 * @sd: MIPI CSI2 sub-device
 * @pads: MIPI CSI2 sub-device pads
 * @notifier: notifier to register on the v4l2-async API
 * @src_pad: source sub-device pad
 * @bus: MIPI CSI2 bus information
 * @info: version-specific MIPI CSI2 information
 */
struct c3_csi_device {
	struct device *dev;
	void __iomem *aphy;
	void __iomem *dphy;
	void __iomem *host;
	struct clk_bulk_data clks[MIPI_CSI2_CLOCK_NUM_MAX];

	struct v4l2_subdev sd;
	struct media_pad pads[C3_MIPI_CSI2_PAD_MAX];
	struct v4l2_async_notifier notifier;
	struct media_pad *src_pad;
	struct v4l2_mbus_config_mipi_csi2 bus;

	const struct c3_csi_info *info;
};

static const u32 c3_mipi_csi_formats[] = {
	MEDIA_BUS_FMT_SBGGR10_1X10,
	MEDIA_BUS_FMT_SGBRG10_1X10,
	MEDIA_BUS_FMT_SGRBG10_1X10,
	MEDIA_BUS_FMT_SRGGB10_1X10,
	MEDIA_BUS_FMT_SBGGR12_1X12,
	MEDIA_BUS_FMT_SGBRG12_1X12,
	MEDIA_BUS_FMT_SGRBG12_1X12,
	MEDIA_BUS_FMT_SRGGB12_1X12,
};

/* Hardware configuration */

static void c3_mipi_csi_write(struct c3_csi_device *csi, u32 reg, u32 val)
{
	void __iomem *addr;

	switch (CSI2_SUBMD(reg)) {
	case SUBMD_APHY:
		addr = csi->aphy + CSI2_REG_ADDR(reg);
		break;
	case SUBMD_DPHY:
		addr = csi->dphy + CSI2_REG_ADDR(reg);
		break;
	case SUBMD_HOST:
		addr = csi->host + CSI2_REG_ADDR(reg);
		break;
	default:
		dev_err(csi->dev, "Invalid sub-module: %lu\n", CSI2_SUBMD(reg));
		return;
	}

	writel(val, addr);
}

static void c3_mipi_csi_cfg_aphy(struct c3_csi_device *csi)
{
	c3_mipi_csi_write(csi, CSI_PHY_CNTL0,
			  CSI_PHY_CNTL0_HS_LP_BIAS_EN |
			  CSI_PHY_CNTL0_HS_RX_TRIM_11 |
			  CSI_PHY_CNTL0_LP_LOW_VTH_2 |
			  CSI_PHY_CNTL0_LP_HIGH_VTH_4 |
			  CSI_PHY_CNTL0_DATA_LANE0_HS_DIG_EN |
			  CSI_PHY_CNTL0_DATA_LANE1_HS_DIG_EN |
			  CSI_PHY_CNTL0_CLK0_LANE_HS_DIG_EN |
			  CSI_PHY_CNTL0_DATA_LANE2_HS_DIG_EN |
			  CSI_PHY_CNTL0_DATA_LANE3_HS_DIG_EN);

	c3_mipi_csi_write(csi, CSI_PHY_CNTL1,
			  CSI_PHY_CNTL1_HS_EQ_CAP_SMALL |
			  CSI_PHY_CNTL1_HS_EQ_RES_MED |
			  CSI_PHY_CNTL1_CLK_CHN_EQ_MAX_GAIN |
			  CSI_PHY_CNTL1_DATA_CHN_EQ_MAX_GAIN |
			  CSI_PHY_CNTL1_COM_BG_EN |

Annotation

Implementation Notes