linux/drivers/mfd/sec-irq.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2//
   3// Copyright (c) 2011-2014 Samsung Electronics Co., Ltd
   4//              http://www.samsung.com
   5
   6#include <linux/device.h>
   7#include <linux/interrupt.h>
   8#include <linux/irq.h>
   9#include <linux/module.h>
  10#include <linux/regmap.h>
  11
  12#include <linux/mfd/samsung/core.h>
  13#include <linux/mfd/samsung/irq.h>
  14#include <linux/mfd/samsung/s2mps11.h>
  15#include <linux/mfd/samsung/s2mps14.h>
  16#include <linux/mfd/samsung/s2mpu02.h>
  17#include <linux/mfd/samsung/s5m8763.h>
  18#include <linux/mfd/samsung/s5m8767.h>
  19
  20static const struct regmap_irq s2mps11_irqs[] = {
  21        [S2MPS11_IRQ_PWRONF] = {
  22                .reg_offset = 0,
  23                .mask = S2MPS11_IRQ_PWRONF_MASK,
  24        },
  25        [S2MPS11_IRQ_PWRONR] = {
  26                .reg_offset = 0,
  27                .mask = S2MPS11_IRQ_PWRONR_MASK,
  28        },
  29        [S2MPS11_IRQ_JIGONBF] = {
  30                .reg_offset = 0,
  31                .mask = S2MPS11_IRQ_JIGONBF_MASK,
  32        },
  33        [S2MPS11_IRQ_JIGONBR] = {
  34                .reg_offset = 0,
  35                .mask = S2MPS11_IRQ_JIGONBR_MASK,
  36        },
  37        [S2MPS11_IRQ_ACOKBF] = {
  38                .reg_offset = 0,
  39                .mask = S2MPS11_IRQ_ACOKBF_MASK,
  40        },
  41        [S2MPS11_IRQ_ACOKBR] = {
  42                .reg_offset = 0,
  43                .mask = S2MPS11_IRQ_ACOKBR_MASK,
  44        },
  45        [S2MPS11_IRQ_PWRON1S] = {
  46                .reg_offset = 0,
  47                .mask = S2MPS11_IRQ_PWRON1S_MASK,
  48        },
  49        [S2MPS11_IRQ_MRB] = {
  50                .reg_offset = 0,
  51                .mask = S2MPS11_IRQ_MRB_MASK,
  52        },
  53        [S2MPS11_IRQ_RTC60S] = {
  54                .reg_offset = 1,
  55                .mask = S2MPS11_IRQ_RTC60S_MASK,
  56        },
  57        [S2MPS11_IRQ_RTCA1] = {
  58                .reg_offset = 1,
  59                .mask = S2MPS11_IRQ_RTCA1_MASK,
  60        },
  61        [S2MPS11_IRQ_RTCA0] = {
  62                .reg_offset = 1,
  63                .mask = S2MPS11_IRQ_RTCA0_MASK,
  64        },
  65        [S2MPS11_IRQ_SMPL] = {
  66                .reg_offset = 1,
  67                .mask = S2MPS11_IRQ_SMPL_MASK,
  68        },
  69        [S2MPS11_IRQ_RTC1S] = {
  70                .reg_offset = 1,
  71                .mask = S2MPS11_IRQ_RTC1S_MASK,
  72        },
  73        [S2MPS11_IRQ_WTSR] = {
  74                .reg_offset = 1,
  75                .mask = S2MPS11_IRQ_WTSR_MASK,
  76        },
  77        [S2MPS11_IRQ_INT120C] = {
  78                .reg_offset = 2,
  79                .mask = S2MPS11_IRQ_INT120C_MASK,
  80        },
  81        [S2MPS11_IRQ_INT140C] = {
  82                .reg_offset = 2,
  83                .mask = S2MPS11_IRQ_INT140C_MASK,
  84        },
  85};
  86
  87static const struct regmap_irq s2mps14_irqs[] = {
  88        [S2MPS14_IRQ_PWRONF] = {
  89                .reg_offset = 0,
  90                .mask = S2MPS11_IRQ_PWRONF_MASK,
  91        },
  92        [S2MPS14_IRQ_PWRONR] = {
  93                .reg_offset = 0,
  94                .mask = S2MPS11_IRQ_PWRONR_MASK,
  95        },
  96        [S2MPS14_IRQ_JIGONBF] = {
  97                .reg_offset = 0,
  98                .mask = S2MPS11_IRQ_JIGONBF_MASK,
  99        },
 100        [S2MPS14_IRQ_JIGONBR] = {
 101                .reg_offset = 0,
 102                .mask = S2MPS11_IRQ_JIGONBR_MASK,
 103        },
 104        [S2MPS14_IRQ_ACOKBF] = {
 105                .reg_offset = 0,
 106                .mask = S2MPS11_IRQ_ACOKBF_MASK,
 107        },
 108        [S2MPS14_IRQ_ACOKBR] = {
 109                .reg_offset = 0,
 110                .mask = S2MPS11_IRQ_ACOKBR_MASK,
 111        },
 112        [S2MPS14_IRQ_PWRON1S] = {
 113                .reg_offset = 0,
 114                .mask = S2MPS11_IRQ_PWRON1S_MASK,
 115        },
 116        [S2MPS14_IRQ_MRB] = {
 117                .reg_offset = 0,
 118                .mask = S2MPS11_IRQ_MRB_MASK,
 119        },
 120        [S2MPS14_IRQ_RTC60S] = {
 121                .reg_offset = 1,
 122                .mask = S2MPS11_IRQ_RTC60S_MASK,
 123        },
 124        [S2MPS14_IRQ_RTCA1] = {
 125                .reg_offset = 1,
 126                .mask = S2MPS11_IRQ_RTCA1_MASK,
 127        },
 128        [S2MPS14_IRQ_RTCA0] = {
 129                .reg_offset = 1,
 130                .mask = S2MPS11_IRQ_RTCA0_MASK,
 131        },
 132        [S2MPS14_IRQ_SMPL] = {
 133                .reg_offset = 1,
 134                .mask = S2MPS11_IRQ_SMPL_MASK,
 135        },
 136        [S2MPS14_IRQ_RTC1S] = {
 137                .reg_offset = 1,
 138                .mask = S2MPS11_IRQ_RTC1S_MASK,
 139        },
 140        [S2MPS14_IRQ_WTSR] = {
 141                .reg_offset = 1,
 142                .mask = S2MPS11_IRQ_WTSR_MASK,
 143        },
 144        [S2MPS14_IRQ_INT120C] = {
 145                .reg_offset = 2,
 146                .mask = S2MPS11_IRQ_INT120C_MASK,
 147        },
 148        [S2MPS14_IRQ_INT140C] = {
 149                .reg_offset = 2,
 150                .mask = S2MPS11_IRQ_INT140C_MASK,
 151        },
 152        [S2MPS14_IRQ_TSD] = {
 153                .reg_offset = 2,
 154                .mask = S2MPS14_IRQ_TSD_MASK,
 155        },
 156};
 157
 158static const struct regmap_irq s2mpu02_irqs[] = {
 159        [S2MPU02_IRQ_PWRONF] = {
 160                .reg_offset = 0,
 161                .mask = S2MPS11_IRQ_PWRONF_MASK,
 162        },
 163        [S2MPU02_IRQ_PWRONR] = {
 164                .reg_offset = 0,
 165                .mask = S2MPS11_IRQ_PWRONR_MASK,
 166        },
 167        [S2MPU02_IRQ_JIGONBF] = {
 168                .reg_offset = 0,
 169                .mask = S2MPS11_IRQ_JIGONBF_MASK,
 170        },
 171        [S2MPU02_IRQ_JIGONBR] = {
 172                .reg_offset = 0,
 173                .mask = S2MPS11_IRQ_JIGONBR_MASK,
 174        },
 175        [S2MPU02_IRQ_ACOKBF] = {
 176                .reg_offset = 0,
 177                .mask = S2MPS11_IRQ_ACOKBF_MASK,
 178        },
 179        [S2MPU02_IRQ_ACOKBR] = {
 180                .reg_offset = 0,
 181                .mask = S2MPS11_IRQ_ACOKBR_MASK,
 182        },
 183        [S2MPU02_IRQ_PWRON1S] = {
 184                .reg_offset = 0,
 185                .mask = S2MPS11_IRQ_PWRON1S_MASK,
 186        },
 187        [S2MPU02_IRQ_MRB] = {
 188                .reg_offset = 0,
 189                .mask = S2MPS11_IRQ_MRB_MASK,
 190        },
 191        [S2MPU02_IRQ_RTC60S] = {
 192                .reg_offset = 1,
 193                .mask = S2MPS11_IRQ_RTC60S_MASK,
 194        },
 195        [S2MPU02_IRQ_RTCA1] = {
 196                .reg_offset = 1,
 197                .mask = S2MPS11_IRQ_RTCA1_MASK,
 198        },
 199        [S2MPU02_IRQ_RTCA0] = {
 200                .reg_offset = 1,
 201                .mask = S2MPS11_IRQ_RTCA0_MASK,
 202        },
 203        [S2MPU02_IRQ_SMPL] = {
 204                .reg_offset = 1,
 205                .mask = S2MPS11_IRQ_SMPL_MASK,
 206        },
 207        [S2MPU02_IRQ_RTC1S] = {
 208                .reg_offset = 1,
 209                .mask = S2MPS11_IRQ_RTC1S_MASK,
 210        },
 211        [S2MPU02_IRQ_WTSR] = {
 212                .reg_offset = 1,
 213                .mask = S2MPS11_IRQ_WTSR_MASK,
 214        },
 215        [S2MPU02_IRQ_INT120C] = {
 216                .reg_offset = 2,
 217                .mask = S2MPS11_IRQ_INT120C_MASK,
 218        },
 219        [S2MPU02_IRQ_INT140C] = {
 220                .reg_offset = 2,
 221                .mask = S2MPS11_IRQ_INT140C_MASK,
 222        },
 223        [S2MPU02_IRQ_TSD] = {
 224                .reg_offset = 2,
 225                .mask = S2MPS14_IRQ_TSD_MASK,
 226        },
 227};
 228
 229static const struct regmap_irq s5m8767_irqs[] = {
 230        [S5M8767_IRQ_PWRR] = {
 231                .reg_offset = 0,
 232                .mask = S5M8767_IRQ_PWRR_MASK,
 233        },
 234        [S5M8767_IRQ_PWRF] = {
 235                .reg_offset = 0,
 236                .mask = S5M8767_IRQ_PWRF_MASK,
 237        },
 238        [S5M8767_IRQ_PWR1S] = {
 239                .reg_offset = 0,
 240                .mask = S5M8767_IRQ_PWR1S_MASK,
 241        },
 242        [S5M8767_IRQ_JIGR] = {
 243                .reg_offset = 0,
 244                .mask = S5M8767_IRQ_JIGR_MASK,
 245        },
 246        [S5M8767_IRQ_JIGF] = {
 247                .reg_offset = 0,
 248                .mask = S5M8767_IRQ_JIGF_MASK,
 249        },
 250        [S5M8767_IRQ_LOWBAT2] = {
 251                .reg_offset = 0,
 252                .mask = S5M8767_IRQ_LOWBAT2_MASK,
 253        },
 254        [S5M8767_IRQ_LOWBAT1] = {
 255                .reg_offset = 0,
 256                .mask = S5M8767_IRQ_LOWBAT1_MASK,
 257        },
 258        [S5M8767_IRQ_MRB] = {
 259                .reg_offset = 1,
 260                .mask = S5M8767_IRQ_MRB_MASK,
 261        },
 262        [S5M8767_IRQ_DVSOK2] = {
 263                .reg_offset = 1,
 264                .mask = S5M8767_IRQ_DVSOK2_MASK,
 265        },
 266        [S5M8767_IRQ_DVSOK3] = {
 267                .reg_offset = 1,
 268                .mask = S5M8767_IRQ_DVSOK3_MASK,
 269        },
 270        [S5M8767_IRQ_DVSOK4] = {
 271                .reg_offset = 1,
 272                .mask = S5M8767_IRQ_DVSOK4_MASK,
 273        },
 274        [S5M8767_IRQ_RTC60S] = {
 275                .reg_offset = 2,
 276                .mask = S5M8767_IRQ_RTC60S_MASK,
 277        },
 278        [S5M8767_IRQ_RTCA1] = {
 279                .reg_offset = 2,
 280                .mask = S5M8767_IRQ_RTCA1_MASK,
 281        },
 282        [S5M8767_IRQ_RTCA2] = {
 283                .reg_offset = 2,
 284                .mask = S5M8767_IRQ_RTCA2_MASK,
 285        },
 286        [S5M8767_IRQ_SMPL] = {
 287                .reg_offset = 2,
 288                .mask = S5M8767_IRQ_SMPL_MASK,
 289        },
 290        [S5M8767_IRQ_RTC1S] = {
 291                .reg_offset = 2,
 292                .mask = S5M8767_IRQ_RTC1S_MASK,
 293        },
 294        [S5M8767_IRQ_WTSR] = {
 295                .reg_offset = 2,
 296                .mask = S5M8767_IRQ_WTSR_MASK,
 297        },
 298};
 299
 300static const struct regmap_irq s5m8763_irqs[] = {
 301        [S5M8763_IRQ_DCINF] = {
 302                .reg_offset = 0,
 303                .mask = S5M8763_IRQ_DCINF_MASK,
 304        },
 305        [S5M8763_IRQ_DCINR] = {
 306                .reg_offset = 0,
 307                .mask = S5M8763_IRQ_DCINR_MASK,
 308        },
 309        [S5M8763_IRQ_JIGF] = {
 310                .reg_offset = 0,
 311                .mask = S5M8763_IRQ_JIGF_MASK,
 312        },
 313        [S5M8763_IRQ_JIGR] = {
 314                .reg_offset = 0,
 315                .mask = S5M8763_IRQ_JIGR_MASK,
 316        },
 317        [S5M8763_IRQ_PWRONF] = {
 318                .reg_offset = 0,
 319                .mask = S5M8763_IRQ_PWRONF_MASK,
 320        },
 321        [S5M8763_IRQ_PWRONR] = {
 322                .reg_offset = 0,
 323                .mask = S5M8763_IRQ_PWRONR_MASK,
 324        },
 325        [S5M8763_IRQ_WTSREVNT] = {
 326                .reg_offset = 1,
 327                .mask = S5M8763_IRQ_WTSREVNT_MASK,
 328        },
 329        [S5M8763_IRQ_SMPLEVNT] = {
 330                .reg_offset = 1,
 331                .mask = S5M8763_IRQ_SMPLEVNT_MASK,
 332        },
 333        [S5M8763_IRQ_ALARM1] = {
 334                .reg_offset = 1,
 335                .mask = S5M8763_IRQ_ALARM1_MASK,
 336        },
 337        [S5M8763_IRQ_ALARM0] = {
 338                .reg_offset = 1,
 339                .mask = S5M8763_IRQ_ALARM0_MASK,
 340        },
 341        [S5M8763_IRQ_ONKEY1S] = {
 342                .reg_offset = 2,
 343                .mask = S5M8763_IRQ_ONKEY1S_MASK,
 344        },
 345        [S5M8763_IRQ_TOPOFFR] = {
 346                .reg_offset = 2,
 347                .mask = S5M8763_IRQ_TOPOFFR_MASK,
 348        },
 349        [S5M8763_IRQ_DCINOVPR] = {
 350                .reg_offset = 2,
 351                .mask = S5M8763_IRQ_DCINOVPR_MASK,
 352        },
 353        [S5M8763_IRQ_CHGRSTF] = {
 354                .reg_offset = 2,
 355                .mask = S5M8763_IRQ_CHGRSTF_MASK,
 356        },
 357        [S5M8763_IRQ_DONER] = {
 358                .reg_offset = 2,
 359                .mask = S5M8763_IRQ_DONER_MASK,
 360        },
 361        [S5M8763_IRQ_CHGFAULT] = {
 362                .reg_offset = 2,
 363                .mask = S5M8763_IRQ_CHGFAULT_MASK,
 364        },
 365        [S5M8763_IRQ_LOBAT1] = {
 366                .reg_offset = 3,
 367                .mask = S5M8763_IRQ_LOBAT1_MASK,
 368        },
 369        [S5M8763_IRQ_LOBAT2] = {
 370                .reg_offset = 3,
 371                .mask = S5M8763_IRQ_LOBAT2_MASK,
 372        },
 373};
 374
 375static const struct regmap_irq_chip s2mps11_irq_chip = {
 376        .name = "s2mps11",
 377        .irqs = s2mps11_irqs,
 378        .num_irqs = ARRAY_SIZE(s2mps11_irqs),
 379        .num_regs = 3,
 380        .status_base = S2MPS11_REG_INT1,
 381        .mask_base = S2MPS11_REG_INT1M,
 382        .ack_base = S2MPS11_REG_INT1,
 383};
 384
 385#define S2MPS1X_IRQ_CHIP_COMMON_DATA            \
 386        .irqs = s2mps14_irqs,                   \
 387        .num_irqs = ARRAY_SIZE(s2mps14_irqs),   \
 388        .num_regs = 3,                          \
 389        .status_base = S2MPS14_REG_INT1,        \
 390        .mask_base = S2MPS14_REG_INT1M,         \
 391        .ack_base = S2MPS14_REG_INT1            \
 392
 393static const struct regmap_irq_chip s2mps13_irq_chip = {
 394        .name = "s2mps13",
 395        S2MPS1X_IRQ_CHIP_COMMON_DATA,
 396};
 397
 398static const struct regmap_irq_chip s2mps14_irq_chip = {
 399        .name = "s2mps14",
 400        S2MPS1X_IRQ_CHIP_COMMON_DATA,
 401};
 402
 403static const struct regmap_irq_chip s2mps15_irq_chip = {
 404        .name = "s2mps15",
 405        S2MPS1X_IRQ_CHIP_COMMON_DATA,
 406};
 407
 408static const struct regmap_irq_chip s2mpu02_irq_chip = {
 409        .name = "s2mpu02",
 410        .irqs = s2mpu02_irqs,
 411        .num_irqs = ARRAY_SIZE(s2mpu02_irqs),
 412        .num_regs = 3,
 413        .status_base = S2MPU02_REG_INT1,
 414        .mask_base = S2MPU02_REG_INT1M,
 415        .ack_base = S2MPU02_REG_INT1,
 416};
 417
 418static const struct regmap_irq_chip s5m8767_irq_chip = {
 419        .name = "s5m8767",
 420        .irqs = s5m8767_irqs,
 421        .num_irqs = ARRAY_SIZE(s5m8767_irqs),
 422        .num_regs = 3,
 423        .status_base = S5M8767_REG_INT1,
 424        .mask_base = S5M8767_REG_INT1M,
 425        .ack_base = S5M8767_REG_INT1,
 426};
 427
 428static const struct regmap_irq_chip s5m8763_irq_chip = {
 429        .name = "s5m8763",
 430        .irqs = s5m8763_irqs,
 431        .num_irqs = ARRAY_SIZE(s5m8763_irqs),
 432        .num_regs = 4,
 433        .status_base = S5M8763_REG_IRQ1,
 434        .mask_base = S5M8763_REG_IRQM1,
 435        .ack_base = S5M8763_REG_IRQ1,
 436};
 437
 438int sec_irq_init(struct sec_pmic_dev *sec_pmic)
 439{
 440        int ret = 0;
 441        int type = sec_pmic->device_type;
 442        const struct regmap_irq_chip *sec_irq_chip;
 443
 444        if (!sec_pmic->irq) {
 445                dev_warn(sec_pmic->dev,
 446                         "No interrupt specified, no interrupts\n");
 447                sec_pmic->irq_base = 0;
 448                return 0;
 449        }
 450
 451        switch (type) {
 452        case S5M8763X:
 453                sec_irq_chip = &s5m8763_irq_chip;
 454                break;
 455        case S5M8767X:
 456                sec_irq_chip = &s5m8767_irq_chip;
 457                break;
 458        case S2MPA01:
 459                sec_irq_chip = &s2mps14_irq_chip;
 460                break;
 461        case S2MPS11X:
 462                sec_irq_chip = &s2mps11_irq_chip;
 463                break;
 464        case S2MPS13X:
 465                sec_irq_chip = &s2mps13_irq_chip;
 466                break;
 467        case S2MPS14X:
 468                sec_irq_chip = &s2mps14_irq_chip;
 469                break;
 470        case S2MPS15X:
 471                sec_irq_chip = &s2mps15_irq_chip;
 472                break;
 473        case S2MPU02:
 474                sec_irq_chip = &s2mpu02_irq_chip;
 475                break;
 476        default:
 477                dev_err(sec_pmic->dev, "Unknown device type %lu\n",
 478                        sec_pmic->device_type);
 479                return -EINVAL;
 480        }
 481
 482        ret = devm_regmap_add_irq_chip(sec_pmic->dev, sec_pmic->regmap_pmic,
 483                                       sec_pmic->irq,
 484                                       IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 485                                       sec_pmic->irq_base, sec_irq_chip,
 486                                       &sec_pmic->irq_data);
 487        if (ret != 0) {
 488                dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret);
 489                return ret;
 490        }
 491
 492        /*
 493         * The rtc-s5m driver requests S2MPS14_IRQ_RTCA0 also for S2MPS11
 494         * so the interrupt number must be consistent.
 495         */
 496        BUILD_BUG_ON(((enum s2mps14_irq)S2MPS11_IRQ_RTCA0) != S2MPS14_IRQ_RTCA0);
 497
 498        return 0;
 499}
 500EXPORT_SYMBOL_GPL(sec_irq_init);
 501
 502MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
 503MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
 504MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>");
 505MODULE_DESCRIPTION("Interrupt support for the S5M MFD");
 506MODULE_LICENSE("GPL");
 507