drivers/gpio/gpio-104-idi-48.c

Source file repositories/reference/linux-study-clean/drivers/gpio/gpio-104-idi-48.c

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-104-idi-48.c
Extension
.c
Size
6524 bytes
Lines
190
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

// SPDX-License-Identifier: GPL-2.0-only
/*
 * GPIO driver for the ACCES 104-IDI-48 family
 * Copyright (C) 2015 William Breathitt Gray
 *
 * This driver supports the following ACCES devices: 104-IDI-48A,
 * 104-IDI-48AC, 104-IDI-48B, and 104-IDI-48BC.
 */
#include <linux/bits.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/gpio/regmap.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/irq.h>
#include <linux/isa.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/regmap.h>
#include <linux/types.h>

#define IDI_48_EXTENT 8
#define MAX_NUM_IDI_48 max_num_isa_dev(IDI_48_EXTENT)

static unsigned int base[MAX_NUM_IDI_48];
static unsigned int num_idi_48;
module_param_hw_array(base, uint, ioport, &num_idi_48, 0);
MODULE_PARM_DESC(base, "ACCES 104-IDI-48 base addresses");

static unsigned int irq[MAX_NUM_IDI_48];
static unsigned int num_irq;
module_param_hw_array(irq, uint, irq, &num_irq, 0);
MODULE_PARM_DESC(irq, "ACCES 104-IDI-48 interrupt line numbers");

#define IDI48_IRQ_STATUS 0x7
#define IDI48_IRQ_ENABLE IDI48_IRQ_STATUS

static int idi_48_reg_mask_xlate(struct gpio_regmap *gpio, unsigned int base,
				 unsigned int offset, unsigned int *reg,
				 unsigned int *mask)
{
	const unsigned int line = offset % 8;
	const unsigned int stride = offset / 8;
	const unsigned int port = (stride / 3) * 4;
	const unsigned int port_stride = stride % 3;

	*reg = base + port + port_stride;
	*mask = BIT(line);

	return 0;
}

static const struct regmap_range idi_48_wr_ranges[] = {
	regmap_reg_range(0x0, 0x6),
};
static const struct regmap_range idi_48_rd_ranges[] = {
	regmap_reg_range(0x0, 0x2), regmap_reg_range(0x4, 0x7),
};
static const struct regmap_range idi_48_precious_ranges[] = {
	regmap_reg_range(0x7, 0x7),
};
static const struct regmap_access_table idi_48_wr_table = {
	.no_ranges = idi_48_wr_ranges,
	.n_no_ranges = ARRAY_SIZE(idi_48_wr_ranges),
};
static const struct regmap_access_table idi_48_rd_table = {
	.yes_ranges = idi_48_rd_ranges,
	.n_yes_ranges = ARRAY_SIZE(idi_48_rd_ranges),
};
static const struct regmap_access_table idi_48_precious_table = {
	.yes_ranges = idi_48_precious_ranges,
	.n_yes_ranges = ARRAY_SIZE(idi_48_precious_ranges),
};
static const struct regmap_config idi48_regmap_config = {
	.reg_bits = 8,
	.reg_stride = 1,
	.val_bits = 8,
	.io_port = true,
	.max_register = 0x6,
	.wr_table = &idi_48_wr_table,
	.rd_table = &idi_48_rd_table,
	.precious_table = &idi_48_precious_table,
	.use_raw_spinlock = true,
};

#define IDI48_NGPIO 48

#define IDI48_REGMAP_IRQ(_id)						\
	[_id] = {							\

Annotation

Implementation Notes