drivers/gpio/gpio-pmic-eic-sprd.c

Source file repositories/reference/linux-study-clean/drivers/gpio/gpio-pmic-eic-sprd.c

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-pmic-eic-sprd.c
Extension
.c
Size
10381 bytes
Lines
382
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 sprd_pmic_eic {
	struct gpio_chip chip;
	struct regmap *map;
	u32 offset;
	u8 reg[CACHE_NR_REGS];
	struct mutex buslock;
	int irq;
};

static void sprd_pmic_eic_update(struct gpio_chip *chip, unsigned int offset,
				 u16 reg, unsigned int val)
{
	struct sprd_pmic_eic *pmic_eic = gpiochip_get_data(chip);
	u32 shift = SPRD_PMIC_EIC_BIT(offset);

	regmap_update_bits(pmic_eic->map, pmic_eic->offset + reg,
			   BIT(shift), val << shift);
}

static int sprd_pmic_eic_read(struct gpio_chip *chip, unsigned int offset,
			      u16 reg)
{
	struct sprd_pmic_eic *pmic_eic = gpiochip_get_data(chip);
	u32 value;
	int ret;

	ret = regmap_read(pmic_eic->map, pmic_eic->offset + reg, &value);
	if (ret)
		return ret;

	return !!(value & BIT(SPRD_PMIC_EIC_BIT(offset)));
}

static int sprd_pmic_eic_request(struct gpio_chip *chip, unsigned int offset)
{
	sprd_pmic_eic_update(chip, offset, SPRD_PMIC_EIC_DMSK, 1);
	return 0;
}

static void sprd_pmic_eic_free(struct gpio_chip *chip, unsigned int offset)
{
	sprd_pmic_eic_update(chip, offset, SPRD_PMIC_EIC_DMSK, 0);
}

static int sprd_pmic_eic_get(struct gpio_chip *chip, unsigned int offset)
{
	return sprd_pmic_eic_read(chip, offset, SPRD_PMIC_EIC_DATA);
}

static int sprd_pmic_eic_direction_input(struct gpio_chip *chip,
					 unsigned int offset)
{
	/* EICs are always input, nothing need to do here. */
	return 0;
}

static int sprd_pmic_eic_set_debounce(struct gpio_chip *chip,
				      unsigned int offset,
				      unsigned int debounce)
{
	struct sprd_pmic_eic *pmic_eic = gpiochip_get_data(chip);
	u32 reg, value;
	int ret;

	reg = SPRD_PMIC_EIC_CTRL0 + SPRD_PMIC_EIC_BIT(offset) * 0x4;
	ret = regmap_read(pmic_eic->map, pmic_eic->offset + reg, &value);
	if (ret)
		return ret;

	value &= ~SPRD_PMIC_EIC_DBNC_MASK;
	value |= (debounce / 1000) & SPRD_PMIC_EIC_DBNC_MASK;
	return regmap_write(pmic_eic->map, pmic_eic->offset + reg, value);
}

static int sprd_pmic_eic_set_config(struct gpio_chip *chip, unsigned int offset,
				    unsigned long config)
{
	unsigned long param = pinconf_to_config_param(config);
	u32 arg = pinconf_to_config_argument(config);

	if (param == PIN_CONFIG_INPUT_DEBOUNCE)
		return sprd_pmic_eic_set_debounce(chip, offset, arg);

	return -ENOTSUPP;
}

static void sprd_pmic_eic_irq_mask(struct irq_data *data)
{
	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
	struct sprd_pmic_eic *pmic_eic = gpiochip_get_data(chip);

Annotation

Implementation Notes