drivers/gpio/gpio-bd72720.c

Source file repositories/reference/linux-study-clean/drivers/gpio/gpio-bd72720.c

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-bd72720.c
Extension
.c
Size
7412 bytes
Lines
284
Domain
Driver Families
Bucket
drivers/gpio
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 bd72720_gpio {
	/* chip.parent points the MFD which provides DT node and regmap */
	struct gpio_chip chip;
	/* dev points to the platform device for devm and prints */
	struct device *dev;
	struct regmap *regmap;
	int gpio_is_input;
};

static int bd72720gpi_get(struct bd72720_gpio *bdgpio, unsigned int reg_offset)
{
	int ret, val, shift;

	ret = regmap_read(bdgpio->regmap, BD72720_REG_INT_ETC1_SRC, &val);
	if (ret)
		return ret;

	shift = BD72720_INT_GPIO1_IN_SRC + reg_offset;

	return (val >> shift) & 1;
}

static int bd72720gpo_get(struct bd72720_gpio *bdgpio,
			  unsigned int offset)
{
	const int regs[] = { BD72720_REG_GPIO1_CTRL, BD72720_REG_GPIO2_CTRL,
			     BD72720_REG_GPIO3_CTRL, BD72720_REG_GPIO4_CTRL,
			     BD72720_REG_GPIO5_CTRL, BD72720_REG_EPDEN_CTRL };
	int ret, val;

	ret = regmap_read(bdgpio->regmap, regs[offset], &val);
	if (ret)
		return ret;

	return val & BD72720_GPIO_HIGH;
}

static int bd72720gpio_get(struct gpio_chip *chip, unsigned int offset)
{
	struct bd72720_gpio *bdgpio = gpiochip_get_data(chip);

	if (BIT(offset) & bdgpio->gpio_is_input)
		return bd72720gpi_get(bdgpio, offset);

	return bd72720gpo_get(bdgpio, offset);
}

static int bd72720gpo_set(struct gpio_chip *chip, unsigned int offset,
			  int value)
{
	struct bd72720_gpio *bdgpio = gpiochip_get_data(chip);
	const int regs[] = { BD72720_REG_GPIO1_CTRL, BD72720_REG_GPIO2_CTRL,
			     BD72720_REG_GPIO3_CTRL, BD72720_REG_GPIO4_CTRL,
			     BD72720_REG_GPIO5_CTRL, BD72720_REG_EPDEN_CTRL };

	if (BIT(offset) & bdgpio->gpio_is_input) {
		dev_dbg(bdgpio->dev, "pin %d not output.\n", offset);
		return -EINVAL;
	}

	if (value)
		return regmap_set_bits(bdgpio->regmap, regs[offset],
				      BD72720_GPIO_HIGH);

	return regmap_clear_bits(bdgpio->regmap, regs[offset],
					BD72720_GPIO_HIGH);
}

static int bd72720_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
				   unsigned long config)
{
	struct bd72720_gpio *bdgpio = gpiochip_get_data(chip);
	const int regs[] = { BD72720_REG_GPIO1_CTRL, BD72720_REG_GPIO2_CTRL,
			     BD72720_REG_GPIO3_CTRL, BD72720_REG_GPIO4_CTRL,
			     BD72720_REG_GPIO5_CTRL, BD72720_REG_EPDEN_CTRL };

	/*
	 * We can only set the output mode, which makes sense only when output
	 * OTP configuration is used.
	 */
	if (BIT(offset) & bdgpio->gpio_is_input)
		return -ENOTSUPP;

	switch (pinconf_to_config_param(config)) {
	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
		return regmap_update_bits(bdgpio->regmap,
					  regs[offset],
					  BD72720_GPIO_DRIVE_MASK,
					  BD72720_GPIO_OPEN_DRAIN);
	case PIN_CONFIG_DRIVE_PUSH_PULL:

Annotation

Implementation Notes