drivers/gpio/gpio-adnp.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-adnp.c
Extension
.c
Size
12210 bytes
Lines
528
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 adnp {
	struct i2c_client *client;
	struct gpio_chip gpio;
	unsigned int reg_shift;

	struct mutex i2c_lock;
	struct mutex irq_lock;

	u8 *irq_enable;
	u8 *irq_level;
	u8 *irq_rise;
	u8 *irq_fall;
	u8 *irq_high;
	u8 *irq_low;
};

static int adnp_read(struct adnp *adnp, unsigned offset, uint8_t *value)
{
	int err;

	err = i2c_smbus_read_byte_data(adnp->client, offset);
	if (err < 0) {
		dev_err(adnp->gpio.parent, "%s failed: %d\n",
			"i2c_smbus_read_byte_data()", err);
		return err;
	}

	*value = err;
	return 0;
}

static int adnp_write(struct adnp *adnp, unsigned offset, uint8_t value)
{
	int err;

	err = i2c_smbus_write_byte_data(adnp->client, offset, value);
	if (err < 0) {
		dev_err(adnp->gpio.parent, "%s failed: %d\n",
			"i2c_smbus_write_byte_data()", err);
		return err;
	}

	return 0;
}

static int adnp_gpio_get(struct gpio_chip *chip, unsigned offset)
{
	struct adnp *adnp = gpiochip_get_data(chip);
	unsigned int reg = offset >> adnp->reg_shift;
	unsigned int pos = offset & 7;
	u8 value;
	int err;

	err = adnp_read(adnp, GPIO_PLR(adnp) + reg, &value);
	if (err < 0)
		return err;

	return (value & BIT(pos)) ? 1 : 0;
}

static int __adnp_gpio_set(struct adnp *adnp, unsigned int offset, int value)
{
	unsigned int reg = offset >> adnp->reg_shift;
	unsigned int pos = offset & 7;
	int err;
	u8 val;

	err = adnp_read(adnp, GPIO_PLR(adnp) + reg, &val);
	if (err < 0)
		return err;

	if (value)
		val |= BIT(pos);
	else
		val &= ~BIT(pos);

	return adnp_write(adnp, GPIO_PLR(adnp) + reg, val);
}

static int adnp_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
{
	struct adnp *adnp = gpiochip_get_data(chip);

	guard(mutex)(&adnp->i2c_lock);

	return __adnp_gpio_set(adnp, offset, value);
}

static int adnp_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{

Annotation

Implementation Notes