415 lines · c
1// SPDX-License-Identifier: GPL-2.0+2//3// Copyright (c) 2011-2014 Samsung Electronics Co., Ltd4// http://www.samsung.com5 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/s5m8767.h>18 19static const struct regmap_irq s2mps11_irqs[] = {20 [S2MPS11_IRQ_PWRONF] = {21 .reg_offset = 0,22 .mask = S2MPS11_IRQ_PWRONF_MASK,23 },24 [S2MPS11_IRQ_PWRONR] = {25 .reg_offset = 0,26 .mask = S2MPS11_IRQ_PWRONR_MASK,27 },28 [S2MPS11_IRQ_JIGONBF] = {29 .reg_offset = 0,30 .mask = S2MPS11_IRQ_JIGONBF_MASK,31 },32 [S2MPS11_IRQ_JIGONBR] = {33 .reg_offset = 0,34 .mask = S2MPS11_IRQ_JIGONBR_MASK,35 },36 [S2MPS11_IRQ_ACOKBF] = {37 .reg_offset = 0,38 .mask = S2MPS11_IRQ_ACOKBF_MASK,39 },40 [S2MPS11_IRQ_ACOKBR] = {41 .reg_offset = 0,42 .mask = S2MPS11_IRQ_ACOKBR_MASK,43 },44 [S2MPS11_IRQ_PWRON1S] = {45 .reg_offset = 0,46 .mask = S2MPS11_IRQ_PWRON1S_MASK,47 },48 [S2MPS11_IRQ_MRB] = {49 .reg_offset = 0,50 .mask = S2MPS11_IRQ_MRB_MASK,51 },52 [S2MPS11_IRQ_RTC60S] = {53 .reg_offset = 1,54 .mask = S2MPS11_IRQ_RTC60S_MASK,55 },56 [S2MPS11_IRQ_RTCA1] = {57 .reg_offset = 1,58 .mask = S2MPS11_IRQ_RTCA1_MASK,59 },60 [S2MPS11_IRQ_RTCA0] = {61 .reg_offset = 1,62 .mask = S2MPS11_IRQ_RTCA0_MASK,63 },64 [S2MPS11_IRQ_SMPL] = {65 .reg_offset = 1,66 .mask = S2MPS11_IRQ_SMPL_MASK,67 },68 [S2MPS11_IRQ_RTC1S] = {69 .reg_offset = 1,70 .mask = S2MPS11_IRQ_RTC1S_MASK,71 },72 [S2MPS11_IRQ_WTSR] = {73 .reg_offset = 1,74 .mask = S2MPS11_IRQ_WTSR_MASK,75 },76 [S2MPS11_IRQ_INT120C] = {77 .reg_offset = 2,78 .mask = S2MPS11_IRQ_INT120C_MASK,79 },80 [S2MPS11_IRQ_INT140C] = {81 .reg_offset = 2,82 .mask = S2MPS11_IRQ_INT140C_MASK,83 },84};85 86static const struct regmap_irq s2mps14_irqs[] = {87 [S2MPS14_IRQ_PWRONF] = {88 .reg_offset = 0,89 .mask = S2MPS11_IRQ_PWRONF_MASK,90 },91 [S2MPS14_IRQ_PWRONR] = {92 .reg_offset = 0,93 .mask = S2MPS11_IRQ_PWRONR_MASK,94 },95 [S2MPS14_IRQ_JIGONBF] = {96 .reg_offset = 0,97 .mask = S2MPS11_IRQ_JIGONBF_MASK,98 },99 [S2MPS14_IRQ_JIGONBR] = {100 .reg_offset = 0,101 .mask = S2MPS11_IRQ_JIGONBR_MASK,102 },103 [S2MPS14_IRQ_ACOKBF] = {104 .reg_offset = 0,105 .mask = S2MPS11_IRQ_ACOKBF_MASK,106 },107 [S2MPS14_IRQ_ACOKBR] = {108 .reg_offset = 0,109 .mask = S2MPS11_IRQ_ACOKBR_MASK,110 },111 [S2MPS14_IRQ_PWRON1S] = {112 .reg_offset = 0,113 .mask = S2MPS11_IRQ_PWRON1S_MASK,114 },115 [S2MPS14_IRQ_MRB] = {116 .reg_offset = 0,117 .mask = S2MPS11_IRQ_MRB_MASK,118 },119 [S2MPS14_IRQ_RTC60S] = {120 .reg_offset = 1,121 .mask = S2MPS11_IRQ_RTC60S_MASK,122 },123 [S2MPS14_IRQ_RTCA1] = {124 .reg_offset = 1,125 .mask = S2MPS11_IRQ_RTCA1_MASK,126 },127 [S2MPS14_IRQ_RTCA0] = {128 .reg_offset = 1,129 .mask = S2MPS11_IRQ_RTCA0_MASK,130 },131 [S2MPS14_IRQ_SMPL] = {132 .reg_offset = 1,133 .mask = S2MPS11_IRQ_SMPL_MASK,134 },135 [S2MPS14_IRQ_RTC1S] = {136 .reg_offset = 1,137 .mask = S2MPS11_IRQ_RTC1S_MASK,138 },139 [S2MPS14_IRQ_WTSR] = {140 .reg_offset = 1,141 .mask = S2MPS11_IRQ_WTSR_MASK,142 },143 [S2MPS14_IRQ_INT120C] = {144 .reg_offset = 2,145 .mask = S2MPS11_IRQ_INT120C_MASK,146 },147 [S2MPS14_IRQ_INT140C] = {148 .reg_offset = 2,149 .mask = S2MPS11_IRQ_INT140C_MASK,150 },151 [S2MPS14_IRQ_TSD] = {152 .reg_offset = 2,153 .mask = S2MPS14_IRQ_TSD_MASK,154 },155};156 157static const struct regmap_irq s2mpu02_irqs[] = {158 [S2MPU02_IRQ_PWRONF] = {159 .reg_offset = 0,160 .mask = S2MPS11_IRQ_PWRONF_MASK,161 },162 [S2MPU02_IRQ_PWRONR] = {163 .reg_offset = 0,164 .mask = S2MPS11_IRQ_PWRONR_MASK,165 },166 [S2MPU02_IRQ_JIGONBF] = {167 .reg_offset = 0,168 .mask = S2MPS11_IRQ_JIGONBF_MASK,169 },170 [S2MPU02_IRQ_JIGONBR] = {171 .reg_offset = 0,172 .mask = S2MPS11_IRQ_JIGONBR_MASK,173 },174 [S2MPU02_IRQ_ACOKBF] = {175 .reg_offset = 0,176 .mask = S2MPS11_IRQ_ACOKBF_MASK,177 },178 [S2MPU02_IRQ_ACOKBR] = {179 .reg_offset = 0,180 .mask = S2MPS11_IRQ_ACOKBR_MASK,181 },182 [S2MPU02_IRQ_PWRON1S] = {183 .reg_offset = 0,184 .mask = S2MPS11_IRQ_PWRON1S_MASK,185 },186 [S2MPU02_IRQ_MRB] = {187 .reg_offset = 0,188 .mask = S2MPS11_IRQ_MRB_MASK,189 },190 [S2MPU02_IRQ_RTC60S] = {191 .reg_offset = 1,192 .mask = S2MPS11_IRQ_RTC60S_MASK,193 },194 [S2MPU02_IRQ_RTCA1] = {195 .reg_offset = 1,196 .mask = S2MPS11_IRQ_RTCA1_MASK,197 },198 [S2MPU02_IRQ_RTCA0] = {199 .reg_offset = 1,200 .mask = S2MPS11_IRQ_RTCA0_MASK,201 },202 [S2MPU02_IRQ_SMPL] = {203 .reg_offset = 1,204 .mask = S2MPS11_IRQ_SMPL_MASK,205 },206 [S2MPU02_IRQ_RTC1S] = {207 .reg_offset = 1,208 .mask = S2MPS11_IRQ_RTC1S_MASK,209 },210 [S2MPU02_IRQ_WTSR] = {211 .reg_offset = 1,212 .mask = S2MPS11_IRQ_WTSR_MASK,213 },214 [S2MPU02_IRQ_INT120C] = {215 .reg_offset = 2,216 .mask = S2MPS11_IRQ_INT120C_MASK,217 },218 [S2MPU02_IRQ_INT140C] = {219 .reg_offset = 2,220 .mask = S2MPS11_IRQ_INT140C_MASK,221 },222 [S2MPU02_IRQ_TSD] = {223 .reg_offset = 2,224 .mask = S2MPS14_IRQ_TSD_MASK,225 },226};227 228static const struct regmap_irq s5m8767_irqs[] = {229 [S5M8767_IRQ_PWRR] = {230 .reg_offset = 0,231 .mask = S5M8767_IRQ_PWRR_MASK,232 },233 [S5M8767_IRQ_PWRF] = {234 .reg_offset = 0,235 .mask = S5M8767_IRQ_PWRF_MASK,236 },237 [S5M8767_IRQ_PWR1S] = {238 .reg_offset = 0,239 .mask = S5M8767_IRQ_PWR1S_MASK,240 },241 [S5M8767_IRQ_JIGR] = {242 .reg_offset = 0,243 .mask = S5M8767_IRQ_JIGR_MASK,244 },245 [S5M8767_IRQ_JIGF] = {246 .reg_offset = 0,247 .mask = S5M8767_IRQ_JIGF_MASK,248 },249 [S5M8767_IRQ_LOWBAT2] = {250 .reg_offset = 0,251 .mask = S5M8767_IRQ_LOWBAT2_MASK,252 },253 [S5M8767_IRQ_LOWBAT1] = {254 .reg_offset = 0,255 .mask = S5M8767_IRQ_LOWBAT1_MASK,256 },257 [S5M8767_IRQ_MRB] = {258 .reg_offset = 1,259 .mask = S5M8767_IRQ_MRB_MASK,260 },261 [S5M8767_IRQ_DVSOK2] = {262 .reg_offset = 1,263 .mask = S5M8767_IRQ_DVSOK2_MASK,264 },265 [S5M8767_IRQ_DVSOK3] = {266 .reg_offset = 1,267 .mask = S5M8767_IRQ_DVSOK3_MASK,268 },269 [S5M8767_IRQ_DVSOK4] = {270 .reg_offset = 1,271 .mask = S5M8767_IRQ_DVSOK4_MASK,272 },273 [S5M8767_IRQ_RTC60S] = {274 .reg_offset = 2,275 .mask = S5M8767_IRQ_RTC60S_MASK,276 },277 [S5M8767_IRQ_RTCA1] = {278 .reg_offset = 2,279 .mask = S5M8767_IRQ_RTCA1_MASK,280 },281 [S5M8767_IRQ_RTCA2] = {282 .reg_offset = 2,283 .mask = S5M8767_IRQ_RTCA2_MASK,284 },285 [S5M8767_IRQ_SMPL] = {286 .reg_offset = 2,287 .mask = S5M8767_IRQ_SMPL_MASK,288 },289 [S5M8767_IRQ_RTC1S] = {290 .reg_offset = 2,291 .mask = S5M8767_IRQ_RTC1S_MASK,292 },293 [S5M8767_IRQ_WTSR] = {294 .reg_offset = 2,295 .mask = S5M8767_IRQ_WTSR_MASK,296 },297};298 299static const struct regmap_irq_chip s2mps11_irq_chip = {300 .name = "s2mps11",301 .irqs = s2mps11_irqs,302 .num_irqs = ARRAY_SIZE(s2mps11_irqs),303 .num_regs = 3,304 .status_base = S2MPS11_REG_INT1,305 .mask_base = S2MPS11_REG_INT1M,306 .ack_base = S2MPS11_REG_INT1,307};308 309#define S2MPS1X_IRQ_CHIP_COMMON_DATA \310 .irqs = s2mps14_irqs, \311 .num_irqs = ARRAY_SIZE(s2mps14_irqs), \312 .num_regs = 3, \313 .status_base = S2MPS14_REG_INT1, \314 .mask_base = S2MPS14_REG_INT1M, \315 .ack_base = S2MPS14_REG_INT1 \316 317static const struct regmap_irq_chip s2mps13_irq_chip = {318 .name = "s2mps13",319 S2MPS1X_IRQ_CHIP_COMMON_DATA,320};321 322static const struct regmap_irq_chip s2mps14_irq_chip = {323 .name = "s2mps14",324 S2MPS1X_IRQ_CHIP_COMMON_DATA,325};326 327static const struct regmap_irq_chip s2mps15_irq_chip = {328 .name = "s2mps15",329 S2MPS1X_IRQ_CHIP_COMMON_DATA,330};331 332static const struct regmap_irq_chip s2mpu02_irq_chip = {333 .name = "s2mpu02",334 .irqs = s2mpu02_irqs,335 .num_irqs = ARRAY_SIZE(s2mpu02_irqs),336 .num_regs = 3,337 .status_base = S2MPU02_REG_INT1,338 .mask_base = S2MPU02_REG_INT1M,339 .ack_base = S2MPU02_REG_INT1,340};341 342static const struct regmap_irq_chip s5m8767_irq_chip = {343 .name = "s5m8767",344 .irqs = s5m8767_irqs,345 .num_irqs = ARRAY_SIZE(s5m8767_irqs),346 .num_regs = 3,347 .status_base = S5M8767_REG_INT1,348 .mask_base = S5M8767_REG_INT1M,349 .ack_base = S5M8767_REG_INT1,350};351 352int sec_irq_init(struct sec_pmic_dev *sec_pmic)353{354 int ret = 0;355 int type = sec_pmic->device_type;356 const struct regmap_irq_chip *sec_irq_chip;357 358 if (!sec_pmic->irq) {359 dev_warn(sec_pmic->dev,360 "No interrupt specified, no interrupts\n");361 return 0;362 }363 364 switch (type) {365 case S5M8767X:366 sec_irq_chip = &s5m8767_irq_chip;367 break;368 case S2MPA01:369 sec_irq_chip = &s2mps14_irq_chip;370 break;371 case S2MPS11X:372 sec_irq_chip = &s2mps11_irq_chip;373 break;374 case S2MPS13X:375 sec_irq_chip = &s2mps13_irq_chip;376 break;377 case S2MPS14X:378 sec_irq_chip = &s2mps14_irq_chip;379 break;380 case S2MPS15X:381 sec_irq_chip = &s2mps15_irq_chip;382 break;383 case S2MPU02:384 sec_irq_chip = &s2mpu02_irq_chip;385 break;386 default:387 dev_err(sec_pmic->dev, "Unknown device type %lu\n",388 sec_pmic->device_type);389 return -EINVAL;390 }391 392 ret = devm_regmap_add_irq_chip(sec_pmic->dev, sec_pmic->regmap_pmic,393 sec_pmic->irq, IRQF_ONESHOT,394 0, sec_irq_chip, &sec_pmic->irq_data);395 if (ret != 0) {396 dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret);397 return ret;398 }399 400 /*401 * The rtc-s5m driver requests S2MPS14_IRQ_RTCA0 also for S2MPS11402 * so the interrupt number must be consistent.403 */404 BUILD_BUG_ON(((enum s2mps14_irq)S2MPS11_IRQ_RTCA0) != S2MPS14_IRQ_RTCA0);405 406 return 0;407}408EXPORT_SYMBOL_GPL(sec_irq_init);409 410MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");411MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");412MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>");413MODULE_DESCRIPTION("Interrupt support for the S5M MFD");414MODULE_LICENSE("GPL");415