drivers/gpio/gpio-crystalcove.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-crystalcove.c
Extension
.c
Size
10105 bytes
Lines
399
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 crystalcove_gpio {
	struct mutex buslock; /* irq_bus_lock */
	struct gpio_chip chip;
	struct regmap *regmap;
	int update;
	int intcnt_value;
	bool set_irq_mask;
};

static inline int to_reg(int gpio, enum ctrl_register reg_type)
{
	int reg;

	if (gpio >= CRYSTALCOVE_GPIO_NUM) {
		/*
		 * Virtual GPIO called from ACPI, for now we only support
		 * the panel ctl.
		 */
		switch (gpio) {
		case 0x5e:
			return GPIOPANELCTL;
		default:
			return -ENOTSUPP;
		}
	}

	if (reg_type == CTRL_IN) {
		if (gpio < 8)
			reg = GPIO0P0CTLI;
		else
			reg = GPIO1P0CTLI;
	} else {
		if (gpio < 8)
			reg = GPIO0P0CTLO;
		else
			reg = GPIO1P0CTLO;
	}

	return reg + gpio % 8;
}

static void crystalcove_update_irq_mask(struct crystalcove_gpio *cg, int gpio)
{
	u8 mirqs0 = gpio < 8 ? MGPIO0IRQS0 : MGPIO1IRQS0;
	int mask = BIT(gpio % 8);

	if (cg->set_irq_mask)
		regmap_update_bits(cg->regmap, mirqs0, mask, mask);
	else
		regmap_update_bits(cg->regmap, mirqs0, mask, 0);
}

static void crystalcove_update_irq_ctrl(struct crystalcove_gpio *cg, int gpio)
{
	int reg = to_reg(gpio, CTRL_IN);

	regmap_update_bits(cg->regmap, reg, CTLI_INTCNT_BE, cg->intcnt_value);
}

static int crystalcove_gpio_dir_in(struct gpio_chip *chip, unsigned int gpio)
{
	struct crystalcove_gpio *cg = gpiochip_get_data(chip);
	int reg = to_reg(gpio, CTRL_OUT);

	if (reg < 0)
		return 0;

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

static int crystalcove_gpio_dir_out(struct gpio_chip *chip, unsigned int gpio, int value)
{
	struct crystalcove_gpio *cg = gpiochip_get_data(chip);
	int reg = to_reg(gpio, CTRL_OUT);

	if (reg < 0)
		return 0;

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

static int crystalcove_gpio_get(struct gpio_chip *chip, unsigned int gpio)
{
	struct crystalcove_gpio *cg = gpiochip_get_data(chip);
	unsigned int val;
	int ret, reg = to_reg(gpio, CTRL_IN);

	if (reg < 0)
		return 0;

Annotation

Implementation Notes