drivers/gpio/gpio-wcove.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-wcove.c
Extension
.c
Size
13190 bytes
Lines
513
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 wcove_gpio {
	struct mutex buslock;
	struct gpio_chip chip;
	struct device *dev;
	struct regmap *regmap;
	struct regmap_irq_chip_data *regmap_irq_chip;
	int update;
	int intcnt;
	bool set_irq_mask;
};

static inline int to_reg(int gpio, enum ctrl_register type)
{
	unsigned int reg = type == CTRL_IN ? GPIO_IN_CTRL_BASE : GPIO_OUT_CTRL_BASE;

	if (gpio >= WCOVE_GPIO_NUM)
		return -ENOTSUPP;

	return reg + gpio;
}

static inline int to_ireg(int gpio, enum ctrl_register type, unsigned int *mask)
{
	unsigned int reg = type == IRQ_STATUS ? IRQ_STATUS_BASE : IRQ_MASK_BASE;

	if (gpio < GROUP0_NR_IRQS) {
		reg += 0;
		*mask = BIT(gpio);
	} else {
		reg += 1;
		*mask = BIT(gpio - GROUP0_NR_IRQS);
	}

	return reg;
}

static void wcove_update_irq_mask(struct wcove_gpio *wg, irq_hw_number_t gpio)
{
	unsigned int mask, reg = to_ireg(gpio, IRQ_MASK, &mask);

	if (wg->set_irq_mask)
		regmap_set_bits(wg->regmap, reg, mask);
	else
		regmap_clear_bits(wg->regmap, reg, mask);
}

static void wcove_update_irq_ctrl(struct wcove_gpio *wg, irq_hw_number_t gpio)
{
	int reg = to_reg(gpio, CTRL_IN);

	regmap_update_bits(wg->regmap, reg, CTLI_INTCNT_BE, wg->intcnt);
}

static int wcove_gpio_dir_in(struct gpio_chip *chip, unsigned int gpio)
{
	struct wcove_gpio *wg = gpiochip_get_data(chip);
	int reg = to_reg(gpio, CTRL_OUT);

	if (reg < 0)
		return 0;

	return regmap_write(wg->regmap, reg, CTLO_INPUT_SET);
}

static int wcove_gpio_dir_out(struct gpio_chip *chip, unsigned int gpio,
				    int value)
{
	struct wcove_gpio *wg = gpiochip_get_data(chip);
	int reg = to_reg(gpio, CTRL_OUT);

	if (reg < 0)
		return 0;

	return regmap_write(wg->regmap, reg, CTLO_OUTPUT_SET | value);
}

static int wcove_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
{
	struct wcove_gpio *wg = gpiochip_get_data(chip);
	unsigned int val;
	int ret, reg = to_reg(gpio, CTRL_OUT);

	if (reg < 0)
		return GPIO_LINE_DIRECTION_OUT;

	ret = regmap_read(wg->regmap, reg, &val);
	if (ret)
		return ret;

	if (val & CTLO_DIR_OUT)

Annotation

Implementation Notes