drivers/media/i2c/max96717.c

Source file repositories/reference/linux-study-clean/drivers/media/i2c/max96717.c

File Facts

System
Linux kernel
Corpus path
drivers/media/i2c/max96717.c
Extension
.c
Size
29935 bytes
Lines
1105
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 max96717_priv {
	struct i2c_client		  *client;
	struct regmap			  *regmap;
	struct i2c_mux_core		  *mux;
	struct v4l2_mbus_config_mipi_csi2 mipi_csi2;
	struct v4l2_subdev                sd;
	struct media_pad                  pads[MAX96717_PORTS];
	struct v4l2_ctrl_handler          ctrl_handler;
	struct v4l2_async_notifier        notifier;
	struct v4l2_subdev                *source_sd;
	u16                               source_sd_pad;
	u64			          enabled_source_streams;
	u8                                pll_predef_index;
	struct clk_hw                     clk_hw;
	struct gpio_chip                  gpio_chip;
	enum max96717_vpg_mode            pattern;
};

static inline struct max96717_priv *sd_to_max96717(struct v4l2_subdev *sd)
{
	return container_of(sd, struct max96717_priv, sd);
}

static inline struct max96717_priv *clk_hw_to_max96717(struct clk_hw *hw)
{
	return container_of(hw, struct max96717_priv, clk_hw);
}

static int max96717_i2c_mux_select(struct i2c_mux_core *mux, u32 chan)
{
	return 0;
}

static int max96717_i2c_mux_init(struct max96717_priv *priv)
{
	priv->mux = i2c_mux_alloc(priv->client->adapter, &priv->client->dev,
				  1, 0, I2C_MUX_LOCKED | I2C_MUX_GATE,
				  max96717_i2c_mux_select, NULL);
	if (!priv->mux)
		return -ENOMEM;

	return i2c_mux_add_adapter(priv->mux, 0, 0);
}

static inline int max96717_start_csi(struct max96717_priv *priv, bool start)
{
	return cci_update_bits(priv->regmap, MAX96717_FRONTOP0,
			       MAX96717_START_PORT_B,
			       start ? MAX96717_START_PORT_B : 0, NULL);
}

static int max96717_apply_patgen_timing(struct max96717_priv *priv,
					struct v4l2_subdev_state *state)
{
	struct v4l2_mbus_framefmt *fmt =
		v4l2_subdev_state_get_format(state, MAX96717_PAD_SOURCE);
	const u32 h_active = fmt->width;
	const u32 h_fp = 88;
	const u32 h_sw = 44;
	const u32 h_bp = 148;
	u32 h_tot;
	const u32 v_active = fmt->height;
	const u32 v_fp = 4;
	const u32 v_sw = 5;
	const u32 v_bp = 36;
	u32 v_tot;
	int ret = 0;

	h_tot = h_active + h_fp + h_sw + h_bp;
	v_tot = v_active + v_fp + v_sw + v_bp;

	/* 75 Mhz pixel clock */
	cci_update_bits(priv->regmap, MAX96717_VTX1,
			MAX96717_PATTERN_CLK_FREQ, 0xa, &ret);

	dev_info(&priv->client->dev, "height: %d width: %d\n", fmt->height,
		 fmt->width);

	cci_write(priv->regmap, MAX96717_VTX_VS_DLY, 0, &ret);
	cci_write(priv->regmap, MAX96717_VTX_VS_HIGH, v_sw * h_tot, &ret);
	cci_write(priv->regmap, MAX96717_VTX_VS_LOW,
		  (v_active + v_fp + v_bp) * h_tot, &ret);
	cci_write(priv->regmap, MAX96717_VTX_HS_HIGH, h_sw, &ret);
	cci_write(priv->regmap, MAX96717_VTX_HS_LOW, h_active + h_fp + h_bp,
		  &ret);
	cci_write(priv->regmap, MAX96717_VTX_V2D,
		  h_tot * (v_sw + v_bp) + (h_sw + h_bp), &ret);
	cci_write(priv->regmap, MAX96717_VTX_HS_CNT, v_tot, &ret);
	cci_write(priv->regmap, MAX96717_VTX_DE_HIGH, h_active, &ret);
	cci_write(priv->regmap, MAX96717_VTX_DE_LOW, h_fp + h_sw + h_bp,

Annotation

Implementation Notes