drivers/gpio/gpio-adp5520.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-adp5520.c
Extension
.c
Size
3967 bytes
Lines
170
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 adp5520_gpio {
	struct device *master;
	struct gpio_chip gpio_chip;
	unsigned char lut[ADP5520_MAXGPIOS];
	unsigned long output;
};

static int adp5520_gpio_get_value(struct gpio_chip *chip, unsigned off)
{
	struct adp5520_gpio *dev;
	uint8_t reg_val;

	dev = gpiochip_get_data(chip);

	/*
	 * There are dedicated registers for GPIO IN/OUT.
	 * Make sure we return the right value, even when configured as output
	 */

	if (test_bit(off, &dev->output))
		adp5520_read(dev->master, ADP5520_GPIO_OUT, &reg_val);
	else
		adp5520_read(dev->master, ADP5520_GPIO_IN, &reg_val);

	return !!(reg_val & dev->lut[off]);
}

static int adp5520_gpio_set_value(struct gpio_chip *chip,
				  unsigned int off, int val)
{
	struct adp5520_gpio *dev;
	dev = gpiochip_get_data(chip);

	if (val)
		return adp5520_set_bits(dev->master, ADP5520_GPIO_OUT,
					dev->lut[off]);
	else
		return adp5520_clr_bits(dev->master, ADP5520_GPIO_OUT,
					dev->lut[off]);
}

static int adp5520_gpio_direction_input(struct gpio_chip *chip, unsigned off)
{
	struct adp5520_gpio *dev;
	dev = gpiochip_get_data(chip);

	clear_bit(off, &dev->output);

	return adp5520_clr_bits(dev->master, ADP5520_GPIO_CFG_2,
				dev->lut[off]);
}

static int adp5520_gpio_direction_output(struct gpio_chip *chip,
		unsigned off, int val)
{
	struct adp5520_gpio *dev;
	int ret = 0;
	dev = gpiochip_get_data(chip);

	set_bit(off, &dev->output);

	if (val)
		ret |= adp5520_set_bits(dev->master, ADP5520_GPIO_OUT,
					dev->lut[off]);
	else
		ret |= adp5520_clr_bits(dev->master, ADP5520_GPIO_OUT,
					dev->lut[off]);

	ret |= adp5520_set_bits(dev->master, ADP5520_GPIO_CFG_2,
					dev->lut[off]);

	return ret;
}

static int adp5520_gpio_probe(struct platform_device *pdev)
{
	struct adp5520_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
	struct adp5520_gpio *dev;
	struct gpio_chip *gc;
	int ret, i, gpios;
	unsigned char ctl_mask = 0;

	if (pdata == NULL) {
		dev_err(&pdev->dev, "missing platform data\n");
		return -ENODEV;
	}

	if (pdev->id != ID_ADP5520) {
		dev_err(&pdev->dev, "only ADP5520 supports GPIO\n");
		return -ENODEV;

Annotation

Implementation Notes