drivers/pinctrl/freescale/pinctrl-imx-scmi.c

Source file repositories/reference/linux-study-clean/drivers/pinctrl/freescale/pinctrl-imx-scmi.c

File Facts

System
Linux kernel
Corpus path
drivers/pinctrl/freescale/pinctrl-imx-scmi.c
Extension
.c
Size
9948 bytes
Lines
373
Domain
Driver Families
Bucket
drivers/pinctrl
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 scmi_pinctrl_imx {
	struct device *dev;
	struct scmi_protocol_handle *ph;
	struct pinctrl_dev *pctldev;
	struct pinctrl_desc pctl_desc;
	const struct scmi_pinctrl_proto_ops *ops;
};

/* SCMI pin control types, aligned with SCMI firmware */
#define IMX_SCMI_NUM_CFG	5
#define IMX_SCMI_PIN_MUX	192
#define IMX_SCMI_PIN_CONFIG	193
#define IMX_SCMI_PIN_DAISY_ID	194
#define IMX_SCMI_PIN_DAISY_CFG	195
#define IMX_SCMI_PIN_EXT	196

#define IMX_SCMI_NO_PAD_CTL		BIT(31)
#define IMX_SCMI_PAD_SION		BIT(30)
#define IMX_SCMI_IOMUXC_CONFIG_SION	BIT(4)

#define IMX_SCMI_PIN_SIZE	24

#define IMX94_DAISY_OFF		0x608
#define IMX95_DAISY_OFF		0x408
#define IMX952_DAISY_OFF	0x460

static int pinctrl_scmi_imx_dt_node_to_map(struct pinctrl_dev *pctldev,
					   struct device_node *np,
					   struct pinctrl_map **map,
					   unsigned int *num_maps)
{
	struct pinctrl_map *new_map;
	const __be32 *list;
	unsigned long *configs = NULL;
	unsigned long cfg[IMX_SCMI_NUM_CFG];
	int map_num, size, pin_size, pin_id, num_pins;
	int mux_reg, conf_reg, input_reg, mux_val, conf_val, input_val;
	int i, j;
	uint32_t ncfg;
	static uint32_t daisy_off;

	if (!daisy_off) {
		if (of_machine_is_compatible("fsl,imx95")) {
			daisy_off = IMX95_DAISY_OFF;
		} else if (of_machine_is_compatible("fsl,imx94")) {
			daisy_off = IMX94_DAISY_OFF;
		} else if (of_machine_is_compatible("fsl,imx952")) {
			daisy_off = IMX952_DAISY_OFF;
		} else {
			dev_err(pctldev->dev, "platform not support scmi pinctrl\n");
			return -EINVAL;
		}
	}

	list = of_get_property(np, "fsl,pins", &size);
	if (!list) {
		dev_err(pctldev->dev, "no fsl,pins property in node %pOF\n", np);
		return -EINVAL;
	}

	pin_size = IMX_SCMI_PIN_SIZE;

	if (!size || size % pin_size) {
		dev_err(pctldev->dev, "Invalid fsl,pins or pins property in node %pOF\n", np);
		return -EINVAL;
	}

	num_pins = size / pin_size;
	map_num = num_pins;

	new_map = kmalloc_objs(struct pinctrl_map, map_num);
	if (!new_map)
		return -ENOMEM;

	*map = new_map;
	*num_maps = map_num;

	/* create config map */
	for (i = 0; i < num_pins; i++) {
		j = 0;
		ncfg = IMX_SCMI_NUM_CFG;
		mux_reg = be32_to_cpu(*list++);
		conf_reg = be32_to_cpu(*list++);
		input_reg = be32_to_cpu(*list++);
		mux_val = be32_to_cpu(*list++);
		input_val = be32_to_cpu(*list++);
		conf_val = be32_to_cpu(*list++);
		if (conf_val & IMX_SCMI_PAD_SION)
			mux_val |= IMX_SCMI_IOMUXC_CONFIG_SION;

Annotation

Implementation Notes