drivers/pinctrl/sophgo/pinctrl-sg2042-ops.c

Source file repositories/reference/linux-study-clean/drivers/pinctrl/sophgo/pinctrl-sg2042-ops.c

File Facts

System
Linux kernel
Corpus path
drivers/pinctrl/sophgo/pinctrl-sg2042-ops.c
Extension
.c
Size
7677 bytes
Lines
297
Domain
Driver Families
Bucket
drivers/pinctrl
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 sg2042_priv {
	void __iomem				*regs;
};

static u8 sg2042_dt_get_pin_mux(u32 value)
{
	return value >> 16;
}

static inline u32 sg2042_get_pin_reg(struct sophgo_pinctrl *pctrl,
				     const struct sophgo_pin *sp)
{
	struct sg2042_priv *priv = pctrl->priv_ctrl;
	const struct sg2042_pin *pin = sophgo_to_sg2042_pin(sp);
	void __iomem *reg = priv->regs + pin->offset;

	if (sp->flags & PIN_FLAG_WRITE_HIGH)
		return readl(reg) >> 16;
	else
		return readl(reg) & 0xffff;
}

static int sg2042_set_pin_reg(struct sophgo_pinctrl *pctrl,
			      const struct sophgo_pin *sp,
			      u32 value, u32 mask)
{
	struct sg2042_priv *priv = pctrl->priv_ctrl;
	const struct sg2042_pin *pin = sophgo_to_sg2042_pin(sp);
	void __iomem *reg = priv->regs + pin->offset;
	u32 v = readl(reg);

	if (sp->flags & PIN_FLAG_WRITE_HIGH) {
		v &= ~(mask << 16);
		v |= value << 16;
	} else {
		v &= ~mask;
		v |= value;
	}

	writel(v, reg);

	return 0;
}

static void sg2042_pctrl_dbg_show(struct pinctrl_dev *pctldev,
				  struct seq_file *seq, unsigned int pin_id)
{
	struct sophgo_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
	const struct sophgo_pin *sp = sophgo_get_pin(pctrl, pin_id);
	u32 value, mux;

	value = sg2042_get_pin_reg(pctrl, sp);
	mux = FIELD_GET(PIN_IO_MUX, value);
	seq_printf(seq, "mux:%u reg:0x%04x ", mux, value);
}

const struct pinctrl_ops sg2042_pctrl_ops = {
	.get_groups_count	= pinctrl_generic_get_group_count,
	.get_group_name		= pinctrl_generic_get_group_name,
	.get_group_pins		= pinctrl_generic_get_group_pins,
	.pin_dbg_show		= sg2042_pctrl_dbg_show,
	.dt_node_to_map		= sophgo_pctrl_dt_node_to_map,
	.dt_free_map		= pinctrl_utils_free_map,
};
EXPORT_SYMBOL_GPL(sg2042_pctrl_ops);

static void sg2042_set_pinmux_config(struct sophgo_pinctrl *pctrl,
				     const struct sophgo_pin *sp, u32 config)
{
	u32 mux = sg2042_dt_get_pin_mux(config);

	if (!(sp->flags & PIN_FLAG_NO_PINMUX))
		sg2042_set_pin_reg(pctrl, sp, mux, PIN_IO_MUX);
}

const struct pinmux_ops sg2042_pmx_ops = {
	.get_functions_count	= pinmux_generic_get_function_count,
	.get_function_name	= pinmux_generic_get_function_name,
	.get_function_groups	= pinmux_generic_get_function_groups,
	.set_mux		= sophgo_pmx_set_mux,
	.strict			= true,
};
EXPORT_SYMBOL_GPL(sg2042_pmx_ops);

static int sg2042_pconf_get(struct pinctrl_dev *pctldev,
			    unsigned int pin_id, unsigned long *config)
{
	struct sophgo_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
	int param = pinconf_to_config_param(*config);
	const struct sophgo_pin *sp = sophgo_get_pin(pctrl, pin_id);

Annotation

Implementation Notes