root/drivers/mfd/da9052-irq.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. da9052_map_irq
  2. da9052_enable_irq
  3. da9052_disable_irq
  4. da9052_disable_irq_nosync
  5. da9052_request_irq
  6. da9052_free_irq
  7. da9052_auxadc_irq
  8. da9052_irq_init
  9. da9052_irq_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * DA9052 interrupt support
   4  *
   5  * Author: Fabio Estevam <fabio.estevam@freescale.com>
   6  * Based on arizona-irq.c, which is:
   7  *
   8  * Copyright 2012 Wolfson Microelectronics plc
   9  *
  10  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
  11  */
  12 
  13 #include <linux/device.h>
  14 #include <linux/delay.h>
  15 #include <linux/input.h>
  16 #include <linux/interrupt.h>
  17 #include <linux/irq.h>
  18 #include <linux/irqdomain.h>
  19 #include <linux/slab.h>
  20 #include <linux/module.h>
  21 
  22 #include <linux/mfd/da9052/da9052.h>
  23 #include <linux/mfd/da9052/reg.h>
  24 
  25 #define DA9052_NUM_IRQ_REGS             4
  26 #define DA9052_IRQ_MASK_POS_1           0x01
  27 #define DA9052_IRQ_MASK_POS_2           0x02
  28 #define DA9052_IRQ_MASK_POS_3           0x04
  29 #define DA9052_IRQ_MASK_POS_4           0x08
  30 #define DA9052_IRQ_MASK_POS_5           0x10
  31 #define DA9052_IRQ_MASK_POS_6           0x20
  32 #define DA9052_IRQ_MASK_POS_7           0x40
  33 #define DA9052_IRQ_MASK_POS_8           0x80
  34 
  35 static const struct regmap_irq da9052_irqs[] = {
  36         [DA9052_IRQ_DCIN] = {
  37                 .reg_offset = 0,
  38                 .mask = DA9052_IRQ_MASK_POS_1,
  39         },
  40         [DA9052_IRQ_VBUS] = {
  41                 .reg_offset = 0,
  42                 .mask = DA9052_IRQ_MASK_POS_2,
  43         },
  44         [DA9052_IRQ_DCINREM] = {
  45                 .reg_offset = 0,
  46                 .mask = DA9052_IRQ_MASK_POS_3,
  47         },
  48         [DA9052_IRQ_VBUSREM] = {
  49                 .reg_offset = 0,
  50                 .mask = DA9052_IRQ_MASK_POS_4,
  51         },
  52         [DA9052_IRQ_VDDLOW] = {
  53                 .reg_offset = 0,
  54                 .mask = DA9052_IRQ_MASK_POS_5,
  55         },
  56         [DA9052_IRQ_ALARM] = {
  57                 .reg_offset = 0,
  58                 .mask = DA9052_IRQ_MASK_POS_6,
  59         },
  60         [DA9052_IRQ_SEQRDY] = {
  61                 .reg_offset = 0,
  62                 .mask = DA9052_IRQ_MASK_POS_7,
  63         },
  64         [DA9052_IRQ_COMP1V2] = {
  65                 .reg_offset = 0,
  66                 .mask = DA9052_IRQ_MASK_POS_8,
  67         },
  68         [DA9052_IRQ_NONKEY] = {
  69                 .reg_offset = 1,
  70                 .mask = DA9052_IRQ_MASK_POS_1,
  71         },
  72         [DA9052_IRQ_IDFLOAT] = {
  73                 .reg_offset = 1,
  74                 .mask = DA9052_IRQ_MASK_POS_2,
  75         },
  76         [DA9052_IRQ_IDGND] = {
  77                 .reg_offset = 1,
  78                 .mask = DA9052_IRQ_MASK_POS_3,
  79         },
  80         [DA9052_IRQ_CHGEND] = {
  81                 .reg_offset = 1,
  82                 .mask = DA9052_IRQ_MASK_POS_4,
  83         },
  84         [DA9052_IRQ_TBAT] = {
  85                 .reg_offset = 1,
  86                 .mask = DA9052_IRQ_MASK_POS_5,
  87         },
  88         [DA9052_IRQ_ADC_EOM] = {
  89                 .reg_offset = 1,
  90                 .mask = DA9052_IRQ_MASK_POS_6,
  91         },
  92         [DA9052_IRQ_PENDOWN] = {
  93                 .reg_offset = 1,
  94                 .mask = DA9052_IRQ_MASK_POS_7,
  95         },
  96         [DA9052_IRQ_TSIREADY] = {
  97                 .reg_offset = 1,
  98                 .mask = DA9052_IRQ_MASK_POS_8,
  99         },
 100         [DA9052_IRQ_GPI0] = {
 101                 .reg_offset = 2,
 102                 .mask = DA9052_IRQ_MASK_POS_1,
 103         },
 104         [DA9052_IRQ_GPI1] = {
 105                 .reg_offset = 2,
 106                 .mask = DA9052_IRQ_MASK_POS_2,
 107         },
 108         [DA9052_IRQ_GPI2] = {
 109                 .reg_offset = 2,
 110                 .mask = DA9052_IRQ_MASK_POS_3,
 111         },
 112         [DA9052_IRQ_GPI3] = {
 113                 .reg_offset = 2,
 114                 .mask = DA9052_IRQ_MASK_POS_4,
 115         },
 116         [DA9052_IRQ_GPI4] = {
 117                 .reg_offset = 2,
 118                 .mask = DA9052_IRQ_MASK_POS_5,
 119         },
 120         [DA9052_IRQ_GPI5] = {
 121                 .reg_offset = 2,
 122                 .mask = DA9052_IRQ_MASK_POS_6,
 123         },
 124         [DA9052_IRQ_GPI6] = {
 125                 .reg_offset = 2,
 126                 .mask = DA9052_IRQ_MASK_POS_7,
 127         },
 128         [DA9052_IRQ_GPI7] = {
 129                 .reg_offset = 2,
 130                 .mask = DA9052_IRQ_MASK_POS_8,
 131         },
 132         [DA9052_IRQ_GPI8] = {
 133                 .reg_offset = 3,
 134                 .mask = DA9052_IRQ_MASK_POS_1,
 135         },
 136         [DA9052_IRQ_GPI9] = {
 137                 .reg_offset = 3,
 138                 .mask = DA9052_IRQ_MASK_POS_2,
 139         },
 140         [DA9052_IRQ_GPI10] = {
 141                 .reg_offset = 3,
 142                 .mask = DA9052_IRQ_MASK_POS_3,
 143         },
 144         [DA9052_IRQ_GPI11] = {
 145                 .reg_offset = 3,
 146                 .mask = DA9052_IRQ_MASK_POS_4,
 147         },
 148         [DA9052_IRQ_GPI12] = {
 149                 .reg_offset = 3,
 150                 .mask = DA9052_IRQ_MASK_POS_5,
 151         },
 152         [DA9052_IRQ_GPI13] = {
 153                 .reg_offset = 3,
 154                 .mask = DA9052_IRQ_MASK_POS_6,
 155         },
 156         [DA9052_IRQ_GPI14] = {
 157                 .reg_offset = 3,
 158                 .mask = DA9052_IRQ_MASK_POS_7,
 159         },
 160         [DA9052_IRQ_GPI15] = {
 161                 .reg_offset = 3,
 162                 .mask = DA9052_IRQ_MASK_POS_8,
 163         },
 164 };
 165 
 166 static const struct regmap_irq_chip da9052_regmap_irq_chip = {
 167         .name = "da9052_irq",
 168         .status_base = DA9052_EVENT_A_REG,
 169         .mask_base = DA9052_IRQ_MASK_A_REG,
 170         .ack_base = DA9052_EVENT_A_REG,
 171         .num_regs = DA9052_NUM_IRQ_REGS,
 172         .irqs = da9052_irqs,
 173         .num_irqs = ARRAY_SIZE(da9052_irqs),
 174 };
 175 
 176 static int da9052_map_irq(struct da9052 *da9052, int irq)
 177 {
 178         return regmap_irq_get_virq(da9052->irq_data, irq);
 179 }
 180 
 181 int da9052_enable_irq(struct da9052 *da9052, int irq)
 182 {
 183         irq = da9052_map_irq(da9052, irq);
 184         if (irq < 0)
 185                 return irq;
 186 
 187         enable_irq(irq);
 188 
 189         return 0;
 190 }
 191 EXPORT_SYMBOL_GPL(da9052_enable_irq);
 192 
 193 int da9052_disable_irq(struct da9052 *da9052, int irq)
 194 {
 195         irq = da9052_map_irq(da9052, irq);
 196         if (irq < 0)
 197                 return irq;
 198 
 199         disable_irq(irq);
 200 
 201         return 0;
 202 }
 203 EXPORT_SYMBOL_GPL(da9052_disable_irq);
 204 
 205 int da9052_disable_irq_nosync(struct da9052 *da9052, int irq)
 206 {
 207         irq = da9052_map_irq(da9052, irq);
 208         if (irq < 0)
 209                 return irq;
 210 
 211         disable_irq_nosync(irq);
 212 
 213         return 0;
 214 }
 215 EXPORT_SYMBOL_GPL(da9052_disable_irq_nosync);
 216 
 217 int da9052_request_irq(struct da9052 *da9052, int irq, char *name,
 218                            irq_handler_t handler, void *data)
 219 {
 220         irq = da9052_map_irq(da9052, irq);
 221         if (irq < 0)
 222                 return irq;
 223 
 224         return request_threaded_irq(irq, NULL, handler,
 225                                      IRQF_TRIGGER_LOW | IRQF_ONESHOT,
 226                                      name, data);
 227 }
 228 EXPORT_SYMBOL_GPL(da9052_request_irq);
 229 
 230 void da9052_free_irq(struct da9052 *da9052, int irq, void *data)
 231 {
 232         irq = da9052_map_irq(da9052, irq);
 233         if (irq < 0)
 234                 return;
 235 
 236         free_irq(irq, data);
 237 }
 238 EXPORT_SYMBOL_GPL(da9052_free_irq);
 239 
 240 static irqreturn_t da9052_auxadc_irq(int irq, void *irq_data)
 241 {
 242         struct da9052 *da9052 = irq_data;
 243 
 244         complete(&da9052->done);
 245 
 246         return IRQ_HANDLED;
 247 }
 248 
 249 int da9052_irq_init(struct da9052 *da9052)
 250 {
 251         int ret;
 252 
 253         ret = regmap_add_irq_chip(da9052->regmap, da9052->chip_irq,
 254                                   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
 255                                   -1, &da9052_regmap_irq_chip,
 256                                   &da9052->irq_data);
 257         if (ret < 0) {
 258                 dev_err(da9052->dev, "regmap_add_irq_chip failed: %d\n", ret);
 259                 goto regmap_err;
 260         }
 261 
 262         enable_irq_wake(da9052->chip_irq);
 263 
 264         ret = da9052_request_irq(da9052, DA9052_IRQ_ADC_EOM, "adc-irq",
 265                             da9052_auxadc_irq, da9052);
 266 
 267         if (ret != 0) {
 268                 dev_err(da9052->dev, "DA9052_IRQ_ADC_EOM failed: %d\n", ret);
 269                 goto request_irq_err;
 270         }
 271 
 272         return 0;
 273 
 274 request_irq_err:
 275         regmap_del_irq_chip(da9052->chip_irq, da9052->irq_data);
 276 regmap_err:
 277         return ret;
 278 
 279 }
 280 
 281 int da9052_irq_exit(struct da9052 *da9052)
 282 {
 283         da9052_free_irq(da9052, DA9052_IRQ_ADC_EOM, da9052);
 284         regmap_del_irq_chip(da9052->chip_irq, da9052->irq_data);
 285 
 286         return 0;
 287 }

/* [<][>][^][v][top][bottom][index][help] */