drivers/pinctrl/pinctrl-da9062.c

Source file repositories/reference/linux-study-clean/drivers/pinctrl/pinctrl-da9062.c

File Facts

System
Linux kernel
Corpus path
drivers/pinctrl/pinctrl-da9062.c
Extension
.c
Size
8100 bytes
Lines
301
Domain
Driver Families
Bucket
drivers/pinctrl
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 da9062_pctl {
	struct da9062 *da9062;
	struct gpio_chip gc;
	unsigned int pin_config[DA9062_GPIO_NUM];
};

static int da9062_pctl_get_pin_mode(struct da9062_pctl *pctl,
				    unsigned int offset)
{
	struct regmap *regmap = pctl->da9062->regmap;
	int ret, val;

	ret = regmap_read(regmap, DA9062AA_GPIO_0_1 + (offset >> 1), &val);
	if (ret < 0)
		return ret;

	val >>= DA9062_PIN_SHIFT(offset);
	val &= DA9062AA_GPIO0_PIN_MASK;

	return val;
}

static int da9062_pctl_set_pin_mode(struct da9062_pctl *pctl,
				    unsigned int offset, unsigned int mode_req)
{
	struct regmap *regmap = pctl->da9062->regmap;
	unsigned int mode = mode_req;
	unsigned int mask;
	int ret;

	mode &= DA9062AA_GPIO0_PIN_MASK;
	mode <<= DA9062_PIN_SHIFT(offset);
	mask = DA9062AA_GPIO0_PIN_MASK << DA9062_PIN_SHIFT(offset);

	ret = regmap_update_bits(regmap, DA9062AA_GPIO_0_1 + (offset >> 1),
				 mask, mode);
	if (!ret)
		pctl->pin_config[offset] = mode_req;

	return ret;
}

static int da9062_gpio_get(struct gpio_chip *gc, unsigned int offset)
{
	struct da9062_pctl *pctl = gpiochip_get_data(gc);
	struct regmap *regmap = pctl->da9062->regmap;
	int gpio_mode, val;
	int ret;

	gpio_mode = da9062_pctl_get_pin_mode(pctl, offset);
	if (gpio_mode < 0)
		return gpio_mode;

	switch (gpio_mode) {
	case DA9062_PIN_ALTERNATE:
		return -ENOTSUPP;
	case DA9062_PIN_GPI:
		ret = regmap_read(regmap, DA9062AA_STATUS_B, &val);
		if (ret < 0)
			return ret;
		break;
	case DA9062_PIN_GPO_OD:
	case DA9062_PIN_GPO_PP:
		ret = regmap_read(regmap, DA9062AA_GPIO_MODE0_4, &val);
		if (ret < 0)
			return ret;
	}

	return !!(val & BIT(offset));
}

static int da9062_gpio_set(struct gpio_chip *gc, unsigned int offset,
			   int value)
{
	struct da9062_pctl *pctl = gpiochip_get_data(gc);
	struct regmap *regmap = pctl->da9062->regmap;

	return regmap_update_bits(regmap, DA9062AA_GPIO_MODE0_4, BIT(offset),
				  value << offset);
}

static int da9062_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
{
	struct da9062_pctl *pctl = gpiochip_get_data(gc);
	int gpio_mode;

	gpio_mode = da9062_pctl_get_pin_mode(pctl, offset);
	if (gpio_mode < 0)
		return gpio_mode;

Annotation

Implementation Notes