linux/drivers/mfd/sec-irq.c
<<
>>
Prefs
   1/*
   2 * sec-irq.c
   3 *
   4 * Copyright (c) 2011 Samsung Electronics Co., Ltd
   5 *              http://www.samsung.com
   6 *
   7 *  This program is free software; you can redistribute  it and/or modify it
   8 *  under  the terms of  the GNU General  Public License as published by the
   9 *  Free Software Foundation;  either version 2 of the  License, or (at your
  10 *  option) any later version.
  11 *
  12 */
  13
  14#include <linux/device.h>
  15#include <linux/interrupt.h>
  16#include <linux/irq.h>
  17#include <linux/regmap.h>
  18
  19#include <linux/mfd/samsung/core.h>
  20#include <linux/mfd/samsung/irq.h>
  21#include <linux/mfd/samsung/s2mps11.h>
  22#include <linux/mfd/samsung/s5m8763.h>
  23#include <linux/mfd/samsung/s5m8767.h>
  24
  25static struct regmap_irq s2mps11_irqs[] = {
  26        [S2MPS11_IRQ_PWRONF] = {
  27                .reg_offset = 1,
  28                .mask = S2MPS11_IRQ_PWRONF_MASK,
  29        },
  30        [S2MPS11_IRQ_PWRONR] = {
  31                .reg_offset = 1,
  32                .mask = S2MPS11_IRQ_PWRONR_MASK,
  33        },
  34        [S2MPS11_IRQ_JIGONBF] = {
  35                .reg_offset = 1,
  36                .mask = S2MPS11_IRQ_JIGONBF_MASK,
  37        },
  38        [S2MPS11_IRQ_JIGONBR] = {
  39                .reg_offset = 1,
  40                .mask = S2MPS11_IRQ_JIGONBR_MASK,
  41        },
  42        [S2MPS11_IRQ_ACOKBF] = {
  43                .reg_offset = 1,
  44                .mask = S2MPS11_IRQ_ACOKBF_MASK,
  45        },
  46        [S2MPS11_IRQ_ACOKBR] = {
  47                .reg_offset = 1,
  48                .mask = S2MPS11_IRQ_ACOKBR_MASK,
  49        },
  50        [S2MPS11_IRQ_PWRON1S] = {
  51                .reg_offset = 1,
  52                .mask = S2MPS11_IRQ_PWRON1S_MASK,
  53        },
  54        [S2MPS11_IRQ_MRB] = {
  55                .reg_offset = 1,
  56                .mask = S2MPS11_IRQ_MRB_MASK,
  57        },
  58        [S2MPS11_IRQ_RTC60S] = {
  59                .reg_offset = 2,
  60                .mask = S2MPS11_IRQ_RTC60S_MASK,
  61        },
  62        [S2MPS11_IRQ_RTCA1] = {
  63                .reg_offset = 2,
  64                .mask = S2MPS11_IRQ_RTCA1_MASK,
  65        },
  66        [S2MPS11_IRQ_RTCA2] = {
  67                .reg_offset = 2,
  68                .mask = S2MPS11_IRQ_RTCA2_MASK,
  69        },
  70        [S2MPS11_IRQ_SMPL] = {
  71                .reg_offset = 2,
  72                .mask = S2MPS11_IRQ_SMPL_MASK,
  73        },
  74        [S2MPS11_IRQ_RTC1S] = {
  75                .reg_offset = 2,
  76                .mask = S2MPS11_IRQ_RTC1S_MASK,
  77        },
  78        [S2MPS11_IRQ_WTSR] = {
  79                .reg_offset = 2,
  80                .mask = S2MPS11_IRQ_WTSR_MASK,
  81        },
  82        [S2MPS11_IRQ_INT120C] = {
  83                .reg_offset = 3,
  84                .mask = S2MPS11_IRQ_INT120C_MASK,
  85        },
  86        [S2MPS11_IRQ_INT140C] = {
  87                .reg_offset = 3,
  88                .mask = S2MPS11_IRQ_INT140C_MASK,
  89        },
  90};
  91
  92
  93static struct regmap_irq s5m8767_irqs[] = {
  94        [S5M8767_IRQ_PWRR] = {
  95                .reg_offset = 1,
  96                .mask = S5M8767_IRQ_PWRR_MASK,
  97        },
  98        [S5M8767_IRQ_PWRF] = {
  99                .reg_offset = 1,
 100                .mask = S5M8767_IRQ_PWRF_MASK,
 101        },
 102        [S5M8767_IRQ_PWR1S] = {
 103                .reg_offset = 1,
 104                .mask = S5M8767_IRQ_PWR1S_MASK,
 105        },
 106        [S5M8767_IRQ_JIGR] = {
 107                .reg_offset = 1,
 108                .mask = S5M8767_IRQ_JIGR_MASK,
 109        },
 110        [S5M8767_IRQ_JIGF] = {
 111                .reg_offset = 1,
 112                .mask = S5M8767_IRQ_JIGF_MASK,
 113        },
 114        [S5M8767_IRQ_LOWBAT2] = {
 115                .reg_offset = 1,
 116                .mask = S5M8767_IRQ_LOWBAT2_MASK,
 117        },
 118        [S5M8767_IRQ_LOWBAT1] = {
 119                .reg_offset = 1,
 120                .mask = S5M8767_IRQ_LOWBAT1_MASK,
 121        },
 122        [S5M8767_IRQ_MRB] = {
 123                .reg_offset = 2,
 124                .mask = S5M8767_IRQ_MRB_MASK,
 125        },
 126        [S5M8767_IRQ_DVSOK2] = {
 127                .reg_offset = 2,
 128                .mask = S5M8767_IRQ_DVSOK2_MASK,
 129        },
 130        [S5M8767_IRQ_DVSOK3] = {
 131                .reg_offset = 2,
 132                .mask = S5M8767_IRQ_DVSOK3_MASK,
 133        },
 134        [S5M8767_IRQ_DVSOK4] = {
 135                .reg_offset = 2,
 136                .mask = S5M8767_IRQ_DVSOK4_MASK,
 137        },
 138        [S5M8767_IRQ_RTC60S] = {
 139                .reg_offset = 3,
 140                .mask = S5M8767_IRQ_RTC60S_MASK,
 141        },
 142        [S5M8767_IRQ_RTCA1] = {
 143                .reg_offset = 3,
 144                .mask = S5M8767_IRQ_RTCA1_MASK,
 145        },
 146        [S5M8767_IRQ_RTCA2] = {
 147                .reg_offset = 3,
 148                .mask = S5M8767_IRQ_RTCA2_MASK,
 149        },
 150        [S5M8767_IRQ_SMPL] = {
 151                .reg_offset = 3,
 152                .mask = S5M8767_IRQ_SMPL_MASK,
 153        },
 154        [S5M8767_IRQ_RTC1S] = {
 155                .reg_offset = 3,
 156                .mask = S5M8767_IRQ_RTC1S_MASK,
 157        },
 158        [S5M8767_IRQ_WTSR] = {
 159                .reg_offset = 3,
 160                .mask = S5M8767_IRQ_WTSR_MASK,
 161        },
 162};
 163
 164static struct regmap_irq s5m8763_irqs[] = {
 165        [S5M8763_IRQ_DCINF] = {
 166                .reg_offset = 1,
 167                .mask = S5M8763_IRQ_DCINF_MASK,
 168        },
 169        [S5M8763_IRQ_DCINR] = {
 170                .reg_offset = 1,
 171                .mask = S5M8763_IRQ_DCINR_MASK,
 172        },
 173        [S5M8763_IRQ_JIGF] = {
 174                .reg_offset = 1,
 175                .mask = S5M8763_IRQ_JIGF_MASK,
 176        },
 177        [S5M8763_IRQ_JIGR] = {
 178                .reg_offset = 1,
 179                .mask = S5M8763_IRQ_JIGR_MASK,
 180        },
 181        [S5M8763_IRQ_PWRONF] = {
 182                .reg_offset = 1,
 183                .mask = S5M8763_IRQ_PWRONF_MASK,
 184        },
 185        [S5M8763_IRQ_PWRONR] = {
 186                .reg_offset = 1,
 187                .mask = S5M8763_IRQ_PWRONR_MASK,
 188        },
 189        [S5M8763_IRQ_WTSREVNT] = {
 190                .reg_offset = 2,
 191                .mask = S5M8763_IRQ_WTSREVNT_MASK,
 192        },
 193        [S5M8763_IRQ_SMPLEVNT] = {
 194                .reg_offset = 2,
 195                .mask = S5M8763_IRQ_SMPLEVNT_MASK,
 196        },
 197        [S5M8763_IRQ_ALARM1] = {
 198                .reg_offset = 2,
 199                .mask = S5M8763_IRQ_ALARM1_MASK,
 200        },
 201        [S5M8763_IRQ_ALARM0] = {
 202                .reg_offset = 2,
 203                .mask = S5M8763_IRQ_ALARM0_MASK,
 204        },
 205        [S5M8763_IRQ_ONKEY1S] = {
 206                .reg_offset = 3,
 207                .mask = S5M8763_IRQ_ONKEY1S_MASK,
 208        },
 209        [S5M8763_IRQ_TOPOFFR] = {
 210                .reg_offset = 3,
 211                .mask = S5M8763_IRQ_TOPOFFR_MASK,
 212        },
 213        [S5M8763_IRQ_DCINOVPR] = {
 214                .reg_offset = 3,
 215                .mask = S5M8763_IRQ_DCINOVPR_MASK,
 216        },
 217        [S5M8763_IRQ_CHGRSTF] = {
 218                .reg_offset = 3,
 219                .mask = S5M8763_IRQ_CHGRSTF_MASK,
 220        },
 221        [S5M8763_IRQ_DONER] = {
 222                .reg_offset = 3,
 223                .mask = S5M8763_IRQ_DONER_MASK,
 224        },
 225        [S5M8763_IRQ_CHGFAULT] = {
 226                .reg_offset = 3,
 227                .mask = S5M8763_IRQ_CHGFAULT_MASK,
 228        },
 229        [S5M8763_IRQ_LOBAT1] = {
 230                .reg_offset = 4,
 231                .mask = S5M8763_IRQ_LOBAT1_MASK,
 232        },
 233        [S5M8763_IRQ_LOBAT2] = {
 234                .reg_offset = 4,
 235                .mask = S5M8763_IRQ_LOBAT2_MASK,
 236        },
 237};
 238
 239static struct regmap_irq_chip s2mps11_irq_chip = {
 240        .name = "s2mps11",
 241        .irqs = s2mps11_irqs,
 242        .num_irqs = ARRAY_SIZE(s2mps11_irqs),
 243        .num_regs = 3,
 244        .status_base = S2MPS11_REG_INT1,
 245        .mask_base = S2MPS11_REG_INT1M,
 246        .ack_base = S2MPS11_REG_INT1,
 247};
 248
 249static struct regmap_irq_chip s5m8767_irq_chip = {
 250        .name = "s5m8767",
 251        .irqs = s5m8767_irqs,
 252        .num_irqs = ARRAY_SIZE(s5m8767_irqs),
 253        .num_regs = 3,
 254        .status_base = S5M8767_REG_INT1,
 255        .mask_base = S5M8767_REG_INT1M,
 256        .ack_base = S5M8767_REG_INT1,
 257};
 258
 259static struct regmap_irq_chip s5m8763_irq_chip = {
 260        .name = "s5m8763",
 261        .irqs = s5m8763_irqs,
 262        .num_irqs = ARRAY_SIZE(s5m8763_irqs),
 263        .num_regs = 4,
 264        .status_base = S5M8763_REG_IRQ1,
 265        .mask_base = S5M8763_REG_IRQM1,
 266        .ack_base = S5M8763_REG_IRQ1,
 267};
 268
 269int sec_irq_init(struct sec_pmic_dev *sec_pmic)
 270{
 271        int ret = 0;
 272        int type = sec_pmic->device_type;
 273
 274        if (!sec_pmic->irq) {
 275                dev_warn(sec_pmic->dev,
 276                         "No interrupt specified, no interrupts\n");
 277                sec_pmic->irq_base = 0;
 278                return 0;
 279        }
 280
 281        switch (type) {
 282        case S5M8763X:
 283                ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
 284                                  IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 285                                  sec_pmic->irq_base, &s5m8763_irq_chip,
 286                                  &sec_pmic->irq_data);
 287                break;
 288        case S5M8767X:
 289                ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
 290                                  IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 291                                  sec_pmic->irq_base, &s5m8767_irq_chip,
 292                                  &sec_pmic->irq_data);
 293                break;
 294        case S2MPS11X:
 295                ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
 296                                  IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 297                                  sec_pmic->irq_base, &s2mps11_irq_chip,
 298                                  &sec_pmic->irq_data);
 299                break;
 300        default:
 301                dev_err(sec_pmic->dev, "Unknown device type %d\n",
 302                        sec_pmic->device_type);
 303                return -EINVAL;
 304        }
 305
 306        if (ret != 0) {
 307                dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret);
 308                return ret;
 309        }
 310
 311        return 0;
 312}
 313
 314void sec_irq_exit(struct sec_pmic_dev *sec_pmic)
 315{
 316        regmap_del_irq_chip(sec_pmic->irq, sec_pmic->irq_data);
 317}
 318
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.