198 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/* Interrupt support for Dialog DA90633 *4 * Copyright 2012 Dialog Semiconductor Ltd.5 * Copyright 2013 Philipp Zabel, Pengutronix6 *7 * Author: Michal Hajduk, Dialog Semiconductor8 */9 10#include <linux/kernel.h>11#include <linux/module.h>12#include <linux/irq.h>13#include <linux/mfd/core.h>14#include <linux/interrupt.h>15#include <linux/regmap.h>16#include <linux/mfd/da9063/core.h>17 18#define DA9063_REG_EVENT_A_OFFSET 019#define DA9063_REG_EVENT_B_OFFSET 120#define DA9063_REG_EVENT_C_OFFSET 221#define DA9063_REG_EVENT_D_OFFSET 322 23static const struct regmap_irq da9063_irqs[] = {24 /* DA9063 event A register */25 REGMAP_IRQ_REG(DA9063_IRQ_ONKEY,26 DA9063_REG_EVENT_A_OFFSET, DA9063_M_ONKEY),27 REGMAP_IRQ_REG(DA9063_IRQ_ALARM,28 DA9063_REG_EVENT_A_OFFSET, DA9063_M_ALARM),29 REGMAP_IRQ_REG(DA9063_IRQ_TICK,30 DA9063_REG_EVENT_A_OFFSET, DA9063_M_TICK),31 REGMAP_IRQ_REG(DA9063_IRQ_ADC_RDY,32 DA9063_REG_EVENT_A_OFFSET, DA9063_M_ADC_RDY),33 REGMAP_IRQ_REG(DA9063_IRQ_SEQ_RDY,34 DA9063_REG_EVENT_A_OFFSET, DA9063_M_SEQ_RDY),35 /* DA9063 event B register */36 REGMAP_IRQ_REG(DA9063_IRQ_WAKE,37 DA9063_REG_EVENT_B_OFFSET, DA9063_M_WAKE),38 REGMAP_IRQ_REG(DA9063_IRQ_TEMP,39 DA9063_REG_EVENT_B_OFFSET, DA9063_M_TEMP),40 REGMAP_IRQ_REG(DA9063_IRQ_COMP_1V2,41 DA9063_REG_EVENT_B_OFFSET, DA9063_M_COMP_1V2),42 REGMAP_IRQ_REG(DA9063_IRQ_LDO_LIM,43 DA9063_REG_EVENT_B_OFFSET, DA9063_M_LDO_LIM),44 REGMAP_IRQ_REG(DA9063_IRQ_REG_UVOV,45 DA9063_REG_EVENT_B_OFFSET, DA9063_M_UVOV),46 REGMAP_IRQ_REG(DA9063_IRQ_DVC_RDY,47 DA9063_REG_EVENT_B_OFFSET, DA9063_M_DVC_RDY),48 REGMAP_IRQ_REG(DA9063_IRQ_VDD_MON,49 DA9063_REG_EVENT_B_OFFSET, DA9063_M_VDD_MON),50 REGMAP_IRQ_REG(DA9063_IRQ_WARN,51 DA9063_REG_EVENT_B_OFFSET, DA9063_M_VDD_WARN),52 /* DA9063 event C register */53 REGMAP_IRQ_REG(DA9063_IRQ_GPI0,54 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI0),55 REGMAP_IRQ_REG(DA9063_IRQ_GPI1,56 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI1),57 REGMAP_IRQ_REG(DA9063_IRQ_GPI2,58 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI2),59 REGMAP_IRQ_REG(DA9063_IRQ_GPI3,60 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI3),61 REGMAP_IRQ_REG(DA9063_IRQ_GPI4,62 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI4),63 REGMAP_IRQ_REG(DA9063_IRQ_GPI5,64 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI5),65 REGMAP_IRQ_REG(DA9063_IRQ_GPI6,66 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI6),67 REGMAP_IRQ_REG(DA9063_IRQ_GPI7,68 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI7),69 /* DA9063 event D register */70 REGMAP_IRQ_REG(DA9063_IRQ_GPI8,71 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI8),72 REGMAP_IRQ_REG(DA9063_IRQ_GPI9,73 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI9),74 REGMAP_IRQ_REG(DA9063_IRQ_GPI10,75 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI10),76 REGMAP_IRQ_REG(DA9063_IRQ_GPI11,77 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI11),78 REGMAP_IRQ_REG(DA9063_IRQ_GPI12,79 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI12),80 REGMAP_IRQ_REG(DA9063_IRQ_GPI13,81 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI13),82 REGMAP_IRQ_REG(DA9063_IRQ_GPI14,83 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI14),84 REGMAP_IRQ_REG(DA9063_IRQ_GPI15,85 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI15),86};87 88static const struct regmap_irq_chip da9063_irq_chip = {89 .name = "da9063-irq",90 .irqs = da9063_irqs,91 .num_irqs = ARRAY_SIZE(da9063_irqs),92 .num_regs = 4,93 .status_base = DA9063_REG_EVENT_A,94 .mask_base = DA9063_REG_IRQ_MASK_A,95 .ack_base = DA9063_REG_EVENT_A,96 .init_ack_masked = true,97};98 99static const struct regmap_irq da9063l_irqs[] = {100 /* DA9063 event A register */101 REGMAP_IRQ_REG(DA9063_IRQ_ONKEY,102 DA9063_REG_EVENT_A_OFFSET, DA9063_M_ONKEY),103 REGMAP_IRQ_REG(DA9063_IRQ_ADC_RDY,104 DA9063_REG_EVENT_A_OFFSET, DA9063_M_ADC_RDY),105 REGMAP_IRQ_REG(DA9063_IRQ_SEQ_RDY,106 DA9063_REG_EVENT_A_OFFSET, DA9063_M_SEQ_RDY),107 /* DA9063 event B register */108 REGMAP_IRQ_REG(DA9063_IRQ_WAKE,109 DA9063_REG_EVENT_B_OFFSET, DA9063_M_WAKE),110 REGMAP_IRQ_REG(DA9063_IRQ_TEMP,111 DA9063_REG_EVENT_B_OFFSET, DA9063_M_TEMP),112 REGMAP_IRQ_REG(DA9063_IRQ_COMP_1V2,113 DA9063_REG_EVENT_B_OFFSET, DA9063_M_COMP_1V2),114 REGMAP_IRQ_REG(DA9063_IRQ_LDO_LIM,115 DA9063_REG_EVENT_B_OFFSET, DA9063_M_LDO_LIM),116 REGMAP_IRQ_REG(DA9063_IRQ_REG_UVOV,117 DA9063_REG_EVENT_B_OFFSET, DA9063_M_UVOV),118 REGMAP_IRQ_REG(DA9063_IRQ_DVC_RDY,119 DA9063_REG_EVENT_B_OFFSET, DA9063_M_DVC_RDY),120 REGMAP_IRQ_REG(DA9063_IRQ_VDD_MON,121 DA9063_REG_EVENT_B_OFFSET, DA9063_M_VDD_MON),122 REGMAP_IRQ_REG(DA9063_IRQ_WARN,123 DA9063_REG_EVENT_B_OFFSET, DA9063_M_VDD_WARN),124 /* DA9063 event C register */125 REGMAP_IRQ_REG(DA9063_IRQ_GPI0,126 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI0),127 REGMAP_IRQ_REG(DA9063_IRQ_GPI1,128 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI1),129 REGMAP_IRQ_REG(DA9063_IRQ_GPI2,130 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI2),131 REGMAP_IRQ_REG(DA9063_IRQ_GPI3,132 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI3),133 REGMAP_IRQ_REG(DA9063_IRQ_GPI4,134 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI4),135 REGMAP_IRQ_REG(DA9063_IRQ_GPI5,136 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI5),137 REGMAP_IRQ_REG(DA9063_IRQ_GPI6,138 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI6),139 REGMAP_IRQ_REG(DA9063_IRQ_GPI7,140 DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI7),141 /* DA9063 event D register */142 REGMAP_IRQ_REG(DA9063_IRQ_GPI8,143 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI8),144 REGMAP_IRQ_REG(DA9063_IRQ_GPI9,145 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI9),146 REGMAP_IRQ_REG(DA9063_IRQ_GPI10,147 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI10),148 REGMAP_IRQ_REG(DA9063_IRQ_GPI11,149 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI11),150 REGMAP_IRQ_REG(DA9063_IRQ_GPI12,151 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI12),152 REGMAP_IRQ_REG(DA9063_IRQ_GPI13,153 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI13),154 REGMAP_IRQ_REG(DA9063_IRQ_GPI14,155 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI14),156 REGMAP_IRQ_REG(DA9063_IRQ_GPI15,157 DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI15),158};159 160static const struct regmap_irq_chip da9063l_irq_chip = {161 .name = "da9063l-irq",162 .irqs = da9063l_irqs,163 .num_irqs = ARRAY_SIZE(da9063l_irqs),164 .num_regs = 4,165 .status_base = DA9063_REG_EVENT_A,166 .mask_base = DA9063_REG_IRQ_MASK_A,167 .ack_base = DA9063_REG_EVENT_A,168 .init_ack_masked = true,169};170 171int da9063_irq_init(struct da9063 *da9063)172{173 const struct regmap_irq_chip *irq_chip;174 int ret;175 176 if (!da9063->chip_irq) {177 dev_err(da9063->dev, "No IRQ configured\n");178 return -EINVAL;179 }180 181 if (da9063->type == PMIC_TYPE_DA9063)182 irq_chip = &da9063_irq_chip;183 else184 irq_chip = &da9063l_irq_chip;185 186 ret = devm_regmap_add_irq_chip(da9063->dev, da9063->regmap,187 da9063->chip_irq,188 IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,189 da9063->irq_base, irq_chip, &da9063->regmap_irq);190 if (ret) {191 dev_err(da9063->dev, "Failed to reguest IRQ %d: %d\n",192 da9063->chip_irq, ret);193 return ret;194 }195 196 return 0;197}198