drivers/pinctrl/pinctrl-mcp23s08.c

Source file repositories/reference/linux-study-clean/drivers/pinctrl/pinctrl-mcp23s08.c

File Facts

System
Linux kernel
Corpus path
drivers/pinctrl/pinctrl-mcp23s08.c
Extension
.c
Size
18957 bytes
Lines
715
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

switch (param) {
		case PIN_CONFIG_BIAS_PULL_UP:
			mutex_lock(&mcp->lock);
			ret = mcp_set_bit(mcp, MCP_GPPU, pin, arg);
			mutex_unlock(&mcp->lock);
			break;
		default:
			dev_dbg(mcp->dev, "Invalid config param %04x\n", param);
			return -ENOTSUPP;
		}
	}

	return ret;
}

static const struct pinconf_ops mcp_pinconf_ops = {
	.pin_config_get = mcp_pinconf_get,
	.pin_config_set = mcp_pinconf_set,
	.is_generic = true,
};

/*----------------------------------------------------------------------*/

static int mcp23s08_direction_input(struct gpio_chip *chip, unsigned offset)
{
	struct mcp23s08	*mcp = gpiochip_get_data(chip);
	int status;

	mutex_lock(&mcp->lock);
	status = mcp_set_bit(mcp, MCP_IODIR, offset, true);
	mutex_unlock(&mcp->lock);

	return status;
}

static int mcp23s08_get(struct gpio_chip *chip, unsigned offset)
{
	struct mcp23s08	*mcp = gpiochip_get_data(chip);
	int status, ret;

	mutex_lock(&mcp->lock);

	/* REVISIT reading this clears any IRQ ... */
	ret = mcp_read(mcp, MCP_GPIO, &status);
	if (ret < 0)
		status = 0;
	else {
		mcp->cached_gpio = status;
		status = !!(status & (1 << offset));
	}

	mutex_unlock(&mcp->lock);
	return status;
}

static int mcp23s08_get_multiple(struct gpio_chip *chip,
				 unsigned long *mask, unsigned long *bits)
{
	struct mcp23s08 *mcp = gpiochip_get_data(chip);
	unsigned int status;
	int ret;

	mutex_lock(&mcp->lock);

	/* REVISIT reading this clears any IRQ ... */
	ret = mcp_read(mcp, MCP_GPIO, &status);
	if (ret < 0)
		status = 0;
	else {
		mcp->cached_gpio = status;
		*bits = status;
	}

	mutex_unlock(&mcp->lock);
	return ret;
}

static int __mcp23s08_set(struct mcp23s08 *mcp, unsigned mask, bool value)
{
	return mcp_update_bits(mcp, MCP_OLAT, mask, value ? mask : 0);
}

static int mcp23s08_set(struct gpio_chip *chip, unsigned int offset, int value)
{
	struct mcp23s08	*mcp = gpiochip_get_data(chip);
	unsigned mask = BIT(offset);
	int ret;

	mutex_lock(&mcp->lock);
	ret = __mcp23s08_set(mcp, mask, !!value);

Annotation

Implementation Notes