drivers/mfd/motorola-cpcap.c

Source file repositories/reference/linux-study-clean/drivers/mfd/motorola-cpcap.c

File Facts

System
Linux kernel
Corpus path
drivers/mfd/motorola-cpcap.c
Extension
.c
Size
8273 bytes
Lines
353
Domain
Driver Families
Bucket
drivers/mfd
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 cpcap_ddata {
	struct spi_device *spi;
	struct regmap_irq *irqs;
	struct regmap_irq_chip_data *irqdata[CPCAP_NR_IRQ_CHIPS];
	const struct regmap_config *regmap_conf;
	struct regmap *regmap;
};

static int cpcap_sense_irq(struct regmap *regmap, int irq)
{
	int regnum = irq / CPCAP_REGISTER_BITS;
	int mask = BIT(irq % CPCAP_REGISTER_BITS);
	int reg = CPCAP_REG_INTS1 + (regnum * CPCAP_REGISTER_SIZE);
	int err, val;

	if (reg < CPCAP_REG_INTS1 || reg > CPCAP_REG_INTS4)
		return -EINVAL;

	err = regmap_read(regmap, reg, &val);
	if (err)
		return err;

	return !!(val & mask);
}

int cpcap_sense_virq(struct regmap *regmap, int virq)
{
	struct regmap_irq_chip_data *d = irq_get_chip_data(virq);
	int irq_base = regmap_irq_chip_get_base(d);

	return cpcap_sense_irq(regmap, virq - irq_base);
}
EXPORT_SYMBOL_GPL(cpcap_sense_virq);

static int cpcap_check_revision(struct cpcap_ddata *cpcap)
{
	u16 vendor, rev;
	int ret;

	ret = cpcap_get_vendor(&cpcap->spi->dev, cpcap->regmap, &vendor);
	if (ret)
		return ret;

	ret = cpcap_get_revision(&cpcap->spi->dev, cpcap->regmap, &rev);
	if (ret)
		return ret;

	dev_info(&cpcap->spi->dev, "CPCAP vendor: %s rev: %i.%i (%x)\n",
		 vendor == CPCAP_VENDOR_ST ? "ST" : "TI",
		 CPCAP_REVISION_MAJOR(rev), CPCAP_REVISION_MINOR(rev),
		 rev);

	if (rev < CPCAP_REVISION_2_1) {
		dev_info(&cpcap->spi->dev,
			 "Please add old CPCAP revision support as needed\n");
		return -ENODEV;
	}

	return 0;
}

/*
 * First two irq chips are the two private macro interrupt chips, the third
 * irq chip is for register banks 1 - 4 and is available for drivers to use.
 */
static struct regmap_irq_chip cpcap_irq_chip[CPCAP_NR_IRQ_CHIPS] = {
	{
		.name = "cpcap-m2",
		.num_regs = 1,
		.status_base = CPCAP_REG_MI1,
		.ack_base = CPCAP_REG_MI1,
		.mask_base = CPCAP_REG_MIM1,
		.use_ack = true,
		.clear_ack = true,
	},
	{
		.name = "cpcap-m2",
		.num_regs = 1,
		.status_base = CPCAP_REG_MI2,
		.ack_base = CPCAP_REG_MI2,
		.mask_base = CPCAP_REG_MIM2,
		.use_ack = true,
		.clear_ack = true,
	},
	{
		.name = "cpcap1-4",
		.num_regs = 4,
		.status_base = CPCAP_REG_INT1,
		.ack_base = CPCAP_REG_INT1,
		.mask_base = CPCAP_REG_INTM1,

Annotation

Implementation Notes