/* * The PMIC EIC controller only has one bank, and each bank now can contain * 16 EICs.
*/ #define SPRD_PMIC_EIC_PER_BANK_NR 16 #define SPRD_PMIC_EIC_NR SPRD_PMIC_EIC_PER_BANK_NR #define SPRD_PMIC_EIC_DATA_MASK GENMASK(15, 0) #define SPRD_PMIC_EIC_BIT(x) ((x) & (SPRD_PMIC_EIC_PER_BANK_NR - 1)) #define SPRD_PMIC_EIC_DBNC_MASK GENMASK(11, 0)
/* * These registers are modified under the irq bus lock and cached to avoid * unnecessary writes in bus_sync_unlock.
*/ enum {
REG_IEV,
REG_IE,
REG_TRIG,
CACHE_NR_REGS
};
/** * struct sprd_pmic_eic - PMIC EIC controller * @chip: the gpio_chip structure. * @map: the regmap from the parent device. * @offset: the EIC controller's offset address of the PMIC. * @reg: the array to cache the EIC registers. * @buslock: for bus lock/sync and unlock. * @irq: the interrupt number of the PMIC EIC conteroller.
*/ struct sprd_pmic_eic { struct gpio_chip chip; struct regmap *map;
u32 offset;
u8 reg[CACHE_NR_REGS]; struct mutex buslock; int irq;
};
switch (flow_type) { case IRQ_TYPE_LEVEL_HIGH:
pmic_eic->reg[REG_IEV] |= BIT(offset); break; case IRQ_TYPE_LEVEL_LOW:
pmic_eic->reg[REG_IEV] &= ~BIT(offset); break; case IRQ_TYPE_EDGE_RISING: case IRQ_TYPE_EDGE_FALLING: case IRQ_TYPE_EDGE_BOTH: /* * Will set the trigger level according to current EIC level * in irq_bus_sync_unlock() interface, so here nothing to do.
*/ break; default: return -ENOTSUPP;
}
/* * The PMIC EIC can only support level trigger, so we can * toggle the level trigger to emulate the edge trigger.
*/
sprd_pmic_eic_toggle_trigger(chip, girq, n);
}
pmic_eic = devm_kzalloc(&pdev->dev, sizeof(*pmic_eic), GFP_KERNEL); if (!pmic_eic) return -ENOMEM;
mutex_init(&pmic_eic->buslock);
pmic_eic->irq = platform_get_irq(pdev, 0); if (pmic_eic->irq < 0) return pmic_eic->irq;
pmic_eic->map = dev_get_regmap(pdev->dev.parent, NULL); if (!pmic_eic->map) return -ENODEV;
ret = of_property_read_u32(pdev->dev.of_node, "reg", &pmic_eic->offset); if (ret) {
dev_err(&pdev->dev, "Failed to get PMIC EIC base address.\n"); return ret;
}
ret = devm_request_threaded_irq(&pdev->dev, pmic_eic->irq, NULL,
sprd_pmic_eic_irq_handler,
IRQF_ONESHOT | IRQF_NO_SUSPEND,
dev_name(&pdev->dev), pmic_eic); if (ret) {
dev_err(&pdev->dev, "Failed to request PMIC EIC IRQ.\n"); return ret;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.