drivers/gpio/gpio-idio-16.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-idio-16.c
Extension
.c
Size
5292 bytes
Lines
179
Domain
Driver Families
Bucket
drivers/gpio
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 idio_16_data {
	struct regmap *map;
	unsigned int irq_mask;
};

static int idio_16_handle_mask_sync(const int index, const unsigned int mask_buf_def,
				    const unsigned int mask_buf, void *const irq_drv_data)
{
	struct idio_16_data *const data = irq_drv_data;
	const unsigned int prev_mask = data->irq_mask;
	int err;
	unsigned int val;

	/* exit early if no change since the previous mask */
	if (mask_buf == prev_mask)
		return 0;

	/* remember the current mask for the next mask sync */
	data->irq_mask = mask_buf;

	/* if all previously masked, enable interrupts when unmasking */
	if (prev_mask == mask_buf_def) {
		err = regmap_write(data->map, IDIO_16_CLEAR_INTERRUPT, 0x00);
		if (err)
			return err;
		return regmap_read(data->map, IDIO_16_ENABLE_IRQ, &val);
	}

	/* if all are currently masked, disable interrupts */
	if (mask_buf == mask_buf_def)
		return regmap_write(data->map, IDIO_16_DISABLE_IRQ, 0x00);

	return 0;
}

static int idio_16_reg_mask_xlate(struct gpio_regmap *const gpio, const unsigned int base,
				  const unsigned int offset, unsigned int *const reg,
				  unsigned int *const mask)
{
	unsigned int stride;

	/* Input lines start at GPIO 16 */
	if (offset < 16) {
		stride = offset / IDIO_16_NGPIO_PER_REG;
		*reg = IDIO_16_OUT_BASE + stride * IDIO_16_REG_STRIDE;
	} else {
		stride = (offset - 16) / IDIO_16_NGPIO_PER_REG;
		*reg = IDIO_16_IN_BASE + stride * IDIO_16_REG_STRIDE;
	}

	*mask = BIT(offset % IDIO_16_NGPIO_PER_REG);

	return 0;
}

static const char *idio_16_names[IDIO_16_NGPIO] = {
	"OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
	"OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
	"IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
	"IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15",
};

/**
 * devm_idio_16_regmap_register - Register an IDIO-16 GPIO device
 * @dev:	device that is registering this IDIO-16 GPIO device
 * @config:	configuration for idio_16_regmap_config
 *
 * Registers an IDIO-16 GPIO device. Returns 0 on success and negative error number on failure.
 */
int devm_idio_16_regmap_register(struct device *const dev,
				 const struct idio_16_regmap_config *const config)
{
	struct gpio_regmap_config gpio_config = {};
	int err;
	struct idio_16_data *data;
	struct regmap_irq_chip *chip;
	struct regmap_irq_chip_data *chip_data;
	DECLARE_BITMAP(fixed_direction_output, IDIO_16_NGPIO);

	if (!config->parent)
		return -EINVAL;

	if (!config->map)
		return -EINVAL;

	if (!config->regmap_irqs)
		return -EINVAL;

	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
	if (!data)

Annotation

Implementation Notes