linux/drivers/mfd/da9063-irq.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/* Interrupt support for Dialog DA9063
   3 *
   4 * Copyright 2012 Dialog Semiconductor Ltd.
   5 * Copyright 2013 Philipp Zabel, Pengutronix
   6 *
   7 * Author: Michal Hajduk, Dialog Semiconductor
   8 */
   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       0
  19#define DA9063_REG_EVENT_B_OFFSET       1
  20#define DA9063_REG_EVENT_C_OFFSET       2
  21#define DA9063_REG_EVENT_D_OFFSET       3
  22
  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        else
 184                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