Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 //
0003 // Copyright (c) 2011-2014 Samsung Electronics Co., Ltd
0004 //              http://www.samsung.com
0005 
0006 #include <linux/device.h>
0007 #include <linux/interrupt.h>
0008 #include <linux/irq.h>
0009 #include <linux/module.h>
0010 #include <linux/regmap.h>
0011 
0012 #include <linux/mfd/samsung/core.h>
0013 #include <linux/mfd/samsung/irq.h>
0014 #include <linux/mfd/samsung/s2mps11.h>
0015 #include <linux/mfd/samsung/s2mps14.h>
0016 #include <linux/mfd/samsung/s2mpu02.h>
0017 #include <linux/mfd/samsung/s5m8763.h>
0018 #include <linux/mfd/samsung/s5m8767.h>
0019 
0020 static const struct regmap_irq s2mps11_irqs[] = {
0021     [S2MPS11_IRQ_PWRONF] = {
0022         .reg_offset = 0,
0023         .mask = S2MPS11_IRQ_PWRONF_MASK,
0024     },
0025     [S2MPS11_IRQ_PWRONR] = {
0026         .reg_offset = 0,
0027         .mask = S2MPS11_IRQ_PWRONR_MASK,
0028     },
0029     [S2MPS11_IRQ_JIGONBF] = {
0030         .reg_offset = 0,
0031         .mask = S2MPS11_IRQ_JIGONBF_MASK,
0032     },
0033     [S2MPS11_IRQ_JIGONBR] = {
0034         .reg_offset = 0,
0035         .mask = S2MPS11_IRQ_JIGONBR_MASK,
0036     },
0037     [S2MPS11_IRQ_ACOKBF] = {
0038         .reg_offset = 0,
0039         .mask = S2MPS11_IRQ_ACOKBF_MASK,
0040     },
0041     [S2MPS11_IRQ_ACOKBR] = {
0042         .reg_offset = 0,
0043         .mask = S2MPS11_IRQ_ACOKBR_MASK,
0044     },
0045     [S2MPS11_IRQ_PWRON1S] = {
0046         .reg_offset = 0,
0047         .mask = S2MPS11_IRQ_PWRON1S_MASK,
0048     },
0049     [S2MPS11_IRQ_MRB] = {
0050         .reg_offset = 0,
0051         .mask = S2MPS11_IRQ_MRB_MASK,
0052     },
0053     [S2MPS11_IRQ_RTC60S] = {
0054         .reg_offset = 1,
0055         .mask = S2MPS11_IRQ_RTC60S_MASK,
0056     },
0057     [S2MPS11_IRQ_RTCA1] = {
0058         .reg_offset = 1,
0059         .mask = S2MPS11_IRQ_RTCA1_MASK,
0060     },
0061     [S2MPS11_IRQ_RTCA0] = {
0062         .reg_offset = 1,
0063         .mask = S2MPS11_IRQ_RTCA0_MASK,
0064     },
0065     [S2MPS11_IRQ_SMPL] = {
0066         .reg_offset = 1,
0067         .mask = S2MPS11_IRQ_SMPL_MASK,
0068     },
0069     [S2MPS11_IRQ_RTC1S] = {
0070         .reg_offset = 1,
0071         .mask = S2MPS11_IRQ_RTC1S_MASK,
0072     },
0073     [S2MPS11_IRQ_WTSR] = {
0074         .reg_offset = 1,
0075         .mask = S2MPS11_IRQ_WTSR_MASK,
0076     },
0077     [S2MPS11_IRQ_INT120C] = {
0078         .reg_offset = 2,
0079         .mask = S2MPS11_IRQ_INT120C_MASK,
0080     },
0081     [S2MPS11_IRQ_INT140C] = {
0082         .reg_offset = 2,
0083         .mask = S2MPS11_IRQ_INT140C_MASK,
0084     },
0085 };
0086 
0087 static const struct regmap_irq s2mps14_irqs[] = {
0088     [S2MPS14_IRQ_PWRONF] = {
0089         .reg_offset = 0,
0090         .mask = S2MPS11_IRQ_PWRONF_MASK,
0091     },
0092     [S2MPS14_IRQ_PWRONR] = {
0093         .reg_offset = 0,
0094         .mask = S2MPS11_IRQ_PWRONR_MASK,
0095     },
0096     [S2MPS14_IRQ_JIGONBF] = {
0097         .reg_offset = 0,
0098         .mask = S2MPS11_IRQ_JIGONBF_MASK,
0099     },
0100     [S2MPS14_IRQ_JIGONBR] = {
0101         .reg_offset = 0,
0102         .mask = S2MPS11_IRQ_JIGONBR_MASK,
0103     },
0104     [S2MPS14_IRQ_ACOKBF] = {
0105         .reg_offset = 0,
0106         .mask = S2MPS11_IRQ_ACOKBF_MASK,
0107     },
0108     [S2MPS14_IRQ_ACOKBR] = {
0109         .reg_offset = 0,
0110         .mask = S2MPS11_IRQ_ACOKBR_MASK,
0111     },
0112     [S2MPS14_IRQ_PWRON1S] = {
0113         .reg_offset = 0,
0114         .mask = S2MPS11_IRQ_PWRON1S_MASK,
0115     },
0116     [S2MPS14_IRQ_MRB] = {
0117         .reg_offset = 0,
0118         .mask = S2MPS11_IRQ_MRB_MASK,
0119     },
0120     [S2MPS14_IRQ_RTC60S] = {
0121         .reg_offset = 1,
0122         .mask = S2MPS11_IRQ_RTC60S_MASK,
0123     },
0124     [S2MPS14_IRQ_RTCA1] = {
0125         .reg_offset = 1,
0126         .mask = S2MPS11_IRQ_RTCA1_MASK,
0127     },
0128     [S2MPS14_IRQ_RTCA0] = {
0129         .reg_offset = 1,
0130         .mask = S2MPS11_IRQ_RTCA0_MASK,
0131     },
0132     [S2MPS14_IRQ_SMPL] = {
0133         .reg_offset = 1,
0134         .mask = S2MPS11_IRQ_SMPL_MASK,
0135     },
0136     [S2MPS14_IRQ_RTC1S] = {
0137         .reg_offset = 1,
0138         .mask = S2MPS11_IRQ_RTC1S_MASK,
0139     },
0140     [S2MPS14_IRQ_WTSR] = {
0141         .reg_offset = 1,
0142         .mask = S2MPS11_IRQ_WTSR_MASK,
0143     },
0144     [S2MPS14_IRQ_INT120C] = {
0145         .reg_offset = 2,
0146         .mask = S2MPS11_IRQ_INT120C_MASK,
0147     },
0148     [S2MPS14_IRQ_INT140C] = {
0149         .reg_offset = 2,
0150         .mask = S2MPS11_IRQ_INT140C_MASK,
0151     },
0152     [S2MPS14_IRQ_TSD] = {
0153         .reg_offset = 2,
0154         .mask = S2MPS14_IRQ_TSD_MASK,
0155     },
0156 };
0157 
0158 static const struct regmap_irq s2mpu02_irqs[] = {
0159     [S2MPU02_IRQ_PWRONF] = {
0160         .reg_offset = 0,
0161         .mask = S2MPS11_IRQ_PWRONF_MASK,
0162     },
0163     [S2MPU02_IRQ_PWRONR] = {
0164         .reg_offset = 0,
0165         .mask = S2MPS11_IRQ_PWRONR_MASK,
0166     },
0167     [S2MPU02_IRQ_JIGONBF] = {
0168         .reg_offset = 0,
0169         .mask = S2MPS11_IRQ_JIGONBF_MASK,
0170     },
0171     [S2MPU02_IRQ_JIGONBR] = {
0172         .reg_offset = 0,
0173         .mask = S2MPS11_IRQ_JIGONBR_MASK,
0174     },
0175     [S2MPU02_IRQ_ACOKBF] = {
0176         .reg_offset = 0,
0177         .mask = S2MPS11_IRQ_ACOKBF_MASK,
0178     },
0179     [S2MPU02_IRQ_ACOKBR] = {
0180         .reg_offset = 0,
0181         .mask = S2MPS11_IRQ_ACOKBR_MASK,
0182     },
0183     [S2MPU02_IRQ_PWRON1S] = {
0184         .reg_offset = 0,
0185         .mask = S2MPS11_IRQ_PWRON1S_MASK,
0186     },
0187     [S2MPU02_IRQ_MRB] = {
0188         .reg_offset = 0,
0189         .mask = S2MPS11_IRQ_MRB_MASK,
0190     },
0191     [S2MPU02_IRQ_RTC60S] = {
0192         .reg_offset = 1,
0193         .mask = S2MPS11_IRQ_RTC60S_MASK,
0194     },
0195     [S2MPU02_IRQ_RTCA1] = {
0196         .reg_offset = 1,
0197         .mask = S2MPS11_IRQ_RTCA1_MASK,
0198     },
0199     [S2MPU02_IRQ_RTCA0] = {
0200         .reg_offset = 1,
0201         .mask = S2MPS11_IRQ_RTCA0_MASK,
0202     },
0203     [S2MPU02_IRQ_SMPL] = {
0204         .reg_offset = 1,
0205         .mask = S2MPS11_IRQ_SMPL_MASK,
0206     },
0207     [S2MPU02_IRQ_RTC1S] = {
0208         .reg_offset = 1,
0209         .mask = S2MPS11_IRQ_RTC1S_MASK,
0210     },
0211     [S2MPU02_IRQ_WTSR] = {
0212         .reg_offset = 1,
0213         .mask = S2MPS11_IRQ_WTSR_MASK,
0214     },
0215     [S2MPU02_IRQ_INT120C] = {
0216         .reg_offset = 2,
0217         .mask = S2MPS11_IRQ_INT120C_MASK,
0218     },
0219     [S2MPU02_IRQ_INT140C] = {
0220         .reg_offset = 2,
0221         .mask = S2MPS11_IRQ_INT140C_MASK,
0222     },
0223     [S2MPU02_IRQ_TSD] = {
0224         .reg_offset = 2,
0225         .mask = S2MPS14_IRQ_TSD_MASK,
0226     },
0227 };
0228 
0229 static const struct regmap_irq s5m8767_irqs[] = {
0230     [S5M8767_IRQ_PWRR] = {
0231         .reg_offset = 0,
0232         .mask = S5M8767_IRQ_PWRR_MASK,
0233     },
0234     [S5M8767_IRQ_PWRF] = {
0235         .reg_offset = 0,
0236         .mask = S5M8767_IRQ_PWRF_MASK,
0237     },
0238     [S5M8767_IRQ_PWR1S] = {
0239         .reg_offset = 0,
0240         .mask = S5M8767_IRQ_PWR1S_MASK,
0241     },
0242     [S5M8767_IRQ_JIGR] = {
0243         .reg_offset = 0,
0244         .mask = S5M8767_IRQ_JIGR_MASK,
0245     },
0246     [S5M8767_IRQ_JIGF] = {
0247         .reg_offset = 0,
0248         .mask = S5M8767_IRQ_JIGF_MASK,
0249     },
0250     [S5M8767_IRQ_LOWBAT2] = {
0251         .reg_offset = 0,
0252         .mask = S5M8767_IRQ_LOWBAT2_MASK,
0253     },
0254     [S5M8767_IRQ_LOWBAT1] = {
0255         .reg_offset = 0,
0256         .mask = S5M8767_IRQ_LOWBAT1_MASK,
0257     },
0258     [S5M8767_IRQ_MRB] = {
0259         .reg_offset = 1,
0260         .mask = S5M8767_IRQ_MRB_MASK,
0261     },
0262     [S5M8767_IRQ_DVSOK2] = {
0263         .reg_offset = 1,
0264         .mask = S5M8767_IRQ_DVSOK2_MASK,
0265     },
0266     [S5M8767_IRQ_DVSOK3] = {
0267         .reg_offset = 1,
0268         .mask = S5M8767_IRQ_DVSOK3_MASK,
0269     },
0270     [S5M8767_IRQ_DVSOK4] = {
0271         .reg_offset = 1,
0272         .mask = S5M8767_IRQ_DVSOK4_MASK,
0273     },
0274     [S5M8767_IRQ_RTC60S] = {
0275         .reg_offset = 2,
0276         .mask = S5M8767_IRQ_RTC60S_MASK,
0277     },
0278     [S5M8767_IRQ_RTCA1] = {
0279         .reg_offset = 2,
0280         .mask = S5M8767_IRQ_RTCA1_MASK,
0281     },
0282     [S5M8767_IRQ_RTCA2] = {
0283         .reg_offset = 2,
0284         .mask = S5M8767_IRQ_RTCA2_MASK,
0285     },
0286     [S5M8767_IRQ_SMPL] = {
0287         .reg_offset = 2,
0288         .mask = S5M8767_IRQ_SMPL_MASK,
0289     },
0290     [S5M8767_IRQ_RTC1S] = {
0291         .reg_offset = 2,
0292         .mask = S5M8767_IRQ_RTC1S_MASK,
0293     },
0294     [S5M8767_IRQ_WTSR] = {
0295         .reg_offset = 2,
0296         .mask = S5M8767_IRQ_WTSR_MASK,
0297     },
0298 };
0299 
0300 static const struct regmap_irq s5m8763_irqs[] = {
0301     [S5M8763_IRQ_DCINF] = {
0302         .reg_offset = 0,
0303         .mask = S5M8763_IRQ_DCINF_MASK,
0304     },
0305     [S5M8763_IRQ_DCINR] = {
0306         .reg_offset = 0,
0307         .mask = S5M8763_IRQ_DCINR_MASK,
0308     },
0309     [S5M8763_IRQ_JIGF] = {
0310         .reg_offset = 0,
0311         .mask = S5M8763_IRQ_JIGF_MASK,
0312     },
0313     [S5M8763_IRQ_JIGR] = {
0314         .reg_offset = 0,
0315         .mask = S5M8763_IRQ_JIGR_MASK,
0316     },
0317     [S5M8763_IRQ_PWRONF] = {
0318         .reg_offset = 0,
0319         .mask = S5M8763_IRQ_PWRONF_MASK,
0320     },
0321     [S5M8763_IRQ_PWRONR] = {
0322         .reg_offset = 0,
0323         .mask = S5M8763_IRQ_PWRONR_MASK,
0324     },
0325     [S5M8763_IRQ_WTSREVNT] = {
0326         .reg_offset = 1,
0327         .mask = S5M8763_IRQ_WTSREVNT_MASK,
0328     },
0329     [S5M8763_IRQ_SMPLEVNT] = {
0330         .reg_offset = 1,
0331         .mask = S5M8763_IRQ_SMPLEVNT_MASK,
0332     },
0333     [S5M8763_IRQ_ALARM1] = {
0334         .reg_offset = 1,
0335         .mask = S5M8763_IRQ_ALARM1_MASK,
0336     },
0337     [S5M8763_IRQ_ALARM0] = {
0338         .reg_offset = 1,
0339         .mask = S5M8763_IRQ_ALARM0_MASK,
0340     },
0341     [S5M8763_IRQ_ONKEY1S] = {
0342         .reg_offset = 2,
0343         .mask = S5M8763_IRQ_ONKEY1S_MASK,
0344     },
0345     [S5M8763_IRQ_TOPOFFR] = {
0346         .reg_offset = 2,
0347         .mask = S5M8763_IRQ_TOPOFFR_MASK,
0348     },
0349     [S5M8763_IRQ_DCINOVPR] = {
0350         .reg_offset = 2,
0351         .mask = S5M8763_IRQ_DCINOVPR_MASK,
0352     },
0353     [S5M8763_IRQ_CHGRSTF] = {
0354         .reg_offset = 2,
0355         .mask = S5M8763_IRQ_CHGRSTF_MASK,
0356     },
0357     [S5M8763_IRQ_DONER] = {
0358         .reg_offset = 2,
0359         .mask = S5M8763_IRQ_DONER_MASK,
0360     },
0361     [S5M8763_IRQ_CHGFAULT] = {
0362         .reg_offset = 2,
0363         .mask = S5M8763_IRQ_CHGFAULT_MASK,
0364     },
0365     [S5M8763_IRQ_LOBAT1] = {
0366         .reg_offset = 3,
0367         .mask = S5M8763_IRQ_LOBAT1_MASK,
0368     },
0369     [S5M8763_IRQ_LOBAT2] = {
0370         .reg_offset = 3,
0371         .mask = S5M8763_IRQ_LOBAT2_MASK,
0372     },
0373 };
0374 
0375 static const struct regmap_irq_chip s2mps11_irq_chip = {
0376     .name = "s2mps11",
0377     .irqs = s2mps11_irqs,
0378     .num_irqs = ARRAY_SIZE(s2mps11_irqs),
0379     .num_regs = 3,
0380     .status_base = S2MPS11_REG_INT1,
0381     .mask_base = S2MPS11_REG_INT1M,
0382     .ack_base = S2MPS11_REG_INT1,
0383 };
0384 
0385 #define S2MPS1X_IRQ_CHIP_COMMON_DATA        \
0386     .irqs = s2mps14_irqs,           \
0387     .num_irqs = ARRAY_SIZE(s2mps14_irqs),   \
0388     .num_regs = 3,              \
0389     .status_base = S2MPS14_REG_INT1,    \
0390     .mask_base = S2MPS14_REG_INT1M,     \
0391     .ack_base = S2MPS14_REG_INT1        \
0392 
0393 static const struct regmap_irq_chip s2mps13_irq_chip = {
0394     .name = "s2mps13",
0395     S2MPS1X_IRQ_CHIP_COMMON_DATA,
0396 };
0397 
0398 static const struct regmap_irq_chip s2mps14_irq_chip = {
0399     .name = "s2mps14",
0400     S2MPS1X_IRQ_CHIP_COMMON_DATA,
0401 };
0402 
0403 static const struct regmap_irq_chip s2mps15_irq_chip = {
0404     .name = "s2mps15",
0405     S2MPS1X_IRQ_CHIP_COMMON_DATA,
0406 };
0407 
0408 static const struct regmap_irq_chip s2mpu02_irq_chip = {
0409     .name = "s2mpu02",
0410     .irqs = s2mpu02_irqs,
0411     .num_irqs = ARRAY_SIZE(s2mpu02_irqs),
0412     .num_regs = 3,
0413     .status_base = S2MPU02_REG_INT1,
0414     .mask_base = S2MPU02_REG_INT1M,
0415     .ack_base = S2MPU02_REG_INT1,
0416 };
0417 
0418 static const struct regmap_irq_chip s5m8767_irq_chip = {
0419     .name = "s5m8767",
0420     .irqs = s5m8767_irqs,
0421     .num_irqs = ARRAY_SIZE(s5m8767_irqs),
0422     .num_regs = 3,
0423     .status_base = S5M8767_REG_INT1,
0424     .mask_base = S5M8767_REG_INT1M,
0425     .ack_base = S5M8767_REG_INT1,
0426 };
0427 
0428 static const struct regmap_irq_chip s5m8763_irq_chip = {
0429     .name = "s5m8763",
0430     .irqs = s5m8763_irqs,
0431     .num_irqs = ARRAY_SIZE(s5m8763_irqs),
0432     .num_regs = 4,
0433     .status_base = S5M8763_REG_IRQ1,
0434     .mask_base = S5M8763_REG_IRQM1,
0435     .ack_base = S5M8763_REG_IRQ1,
0436 };
0437 
0438 int sec_irq_init(struct sec_pmic_dev *sec_pmic)
0439 {
0440     int ret = 0;
0441     int type = sec_pmic->device_type;
0442     const struct regmap_irq_chip *sec_irq_chip;
0443 
0444     if (!sec_pmic->irq) {
0445         dev_warn(sec_pmic->dev,
0446              "No interrupt specified, no interrupts\n");
0447         return 0;
0448     }
0449 
0450     switch (type) {
0451     case S5M8763X:
0452         sec_irq_chip = &s5m8763_irq_chip;
0453         break;
0454     case S5M8767X:
0455         sec_irq_chip = &s5m8767_irq_chip;
0456         break;
0457     case S2MPA01:
0458         sec_irq_chip = &s2mps14_irq_chip;
0459         break;
0460     case S2MPS11X:
0461         sec_irq_chip = &s2mps11_irq_chip;
0462         break;
0463     case S2MPS13X:
0464         sec_irq_chip = &s2mps13_irq_chip;
0465         break;
0466     case S2MPS14X:
0467         sec_irq_chip = &s2mps14_irq_chip;
0468         break;
0469     case S2MPS15X:
0470         sec_irq_chip = &s2mps15_irq_chip;
0471         break;
0472     case S2MPU02:
0473         sec_irq_chip = &s2mpu02_irq_chip;
0474         break;
0475     default:
0476         dev_err(sec_pmic->dev, "Unknown device type %lu\n",
0477             sec_pmic->device_type);
0478         return -EINVAL;
0479     }
0480 
0481     ret = devm_regmap_add_irq_chip(sec_pmic->dev, sec_pmic->regmap_pmic,
0482                        sec_pmic->irq, IRQF_ONESHOT,
0483                        0, sec_irq_chip, &sec_pmic->irq_data);
0484     if (ret != 0) {
0485         dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret);
0486         return ret;
0487     }
0488 
0489     /*
0490      * The rtc-s5m driver requests S2MPS14_IRQ_RTCA0 also for S2MPS11
0491      * so the interrupt number must be consistent.
0492      */
0493     BUILD_BUG_ON(((enum s2mps14_irq)S2MPS11_IRQ_RTCA0) != S2MPS14_IRQ_RTCA0);
0494 
0495     return 0;
0496 }
0497 EXPORT_SYMBOL_GPL(sec_irq_init);
0498 
0499 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
0500 MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
0501 MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>");
0502 MODULE_DESCRIPTION("Interrupt support for the S5M MFD");
0503 MODULE_LICENSE("GPL");