1*ebaec90eSSamuel Kayode // SPDX-License-Identifier: GPL-2.0 2*ebaec90eSSamuel Kayode /* 3*ebaec90eSSamuel Kayode * Core driver for the PF1550 4*ebaec90eSSamuel Kayode * 5*ebaec90eSSamuel Kayode * Copyright (C) 2016 Freescale Semiconductor, Inc. 6*ebaec90eSSamuel Kayode * Robin Gong <yibin.gong@freescale.com> 7*ebaec90eSSamuel Kayode * 8*ebaec90eSSamuel Kayode * Portions Copyright (c) 2025 Savoir-faire Linux Inc. 9*ebaec90eSSamuel Kayode * Samuel Kayode <samuel.kayode@savoirfairelinux.com> 10*ebaec90eSSamuel Kayode */ 11*ebaec90eSSamuel Kayode 12*ebaec90eSSamuel Kayode #include <linux/err.h> 13*ebaec90eSSamuel Kayode #include <linux/i2c.h> 14*ebaec90eSSamuel Kayode #include <linux/interrupt.h> 15*ebaec90eSSamuel Kayode #include <linux/mfd/core.h> 16*ebaec90eSSamuel Kayode #include <linux/mfd/pf1550.h> 17*ebaec90eSSamuel Kayode #include <linux/module.h> 18*ebaec90eSSamuel Kayode #include <linux/of.h> 19*ebaec90eSSamuel Kayode #include <linux/regmap.h> 20*ebaec90eSSamuel Kayode 21*ebaec90eSSamuel Kayode static const struct regmap_config pf1550_regmap_config = { 22*ebaec90eSSamuel Kayode .reg_bits = 8, 23*ebaec90eSSamuel Kayode .val_bits = 8, 24*ebaec90eSSamuel Kayode .max_register = PF1550_PMIC_REG_END, 25*ebaec90eSSamuel Kayode }; 26*ebaec90eSSamuel Kayode 27*ebaec90eSSamuel Kayode static const struct regmap_irq pf1550_irqs[] = { 28*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_IRQ_CHG, 0, IRQ_CHG), 29*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_IRQ_REGULATOR, 0, IRQ_REGULATOR), 30*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_IRQ_ONKEY, 0, IRQ_ONKEY), 31*ebaec90eSSamuel Kayode }; 32*ebaec90eSSamuel Kayode 33*ebaec90eSSamuel Kayode static const struct regmap_irq_chip pf1550_irq_chip = { 34*ebaec90eSSamuel Kayode .name = "pf1550", 35*ebaec90eSSamuel Kayode .status_base = PF1550_PMIC_REG_INT_CATEGORY, 36*ebaec90eSSamuel Kayode .init_ack_masked = 1, 37*ebaec90eSSamuel Kayode .num_regs = 1, 38*ebaec90eSSamuel Kayode .irqs = pf1550_irqs, 39*ebaec90eSSamuel Kayode .num_irqs = ARRAY_SIZE(pf1550_irqs), 40*ebaec90eSSamuel Kayode }; 41*ebaec90eSSamuel Kayode 42*ebaec90eSSamuel Kayode static const struct regmap_irq pf1550_regulator_irqs[] = { 43*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_PMIC_IRQ_SW1_LS, 0, PMIC_IRQ_SW1_LS), 44*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_PMIC_IRQ_SW2_LS, 0, PMIC_IRQ_SW2_LS), 45*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_PMIC_IRQ_SW3_LS, 0, PMIC_IRQ_SW3_LS), 46*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_PMIC_IRQ_SW1_HS, 3, PMIC_IRQ_SW1_HS), 47*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_PMIC_IRQ_SW2_HS, 3, PMIC_IRQ_SW2_HS), 48*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_PMIC_IRQ_SW3_HS, 3, PMIC_IRQ_SW3_HS), 49*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_PMIC_IRQ_LDO1_FAULT, 16, PMIC_IRQ_LDO1_FAULT), 50*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_PMIC_IRQ_LDO2_FAULT, 16, PMIC_IRQ_LDO2_FAULT), 51*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_PMIC_IRQ_LDO3_FAULT, 16, PMIC_IRQ_LDO3_FAULT), 52*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_PMIC_IRQ_TEMP_110, 24, PMIC_IRQ_TEMP_110), 53*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_PMIC_IRQ_TEMP_125, 24, PMIC_IRQ_TEMP_125), 54*ebaec90eSSamuel Kayode }; 55*ebaec90eSSamuel Kayode 56*ebaec90eSSamuel Kayode static const struct regmap_irq_chip pf1550_regulator_irq_chip = { 57*ebaec90eSSamuel Kayode .name = "pf1550-regulator", 58*ebaec90eSSamuel Kayode .status_base = PF1550_PMIC_REG_SW_INT_STAT0, 59*ebaec90eSSamuel Kayode .ack_base = PF1550_PMIC_REG_SW_INT_STAT0, 60*ebaec90eSSamuel Kayode .mask_base = PF1550_PMIC_REG_SW_INT_MASK0, 61*ebaec90eSSamuel Kayode .use_ack = 1, 62*ebaec90eSSamuel Kayode .init_ack_masked = 1, 63*ebaec90eSSamuel Kayode .num_regs = 25, 64*ebaec90eSSamuel Kayode .irqs = pf1550_regulator_irqs, 65*ebaec90eSSamuel Kayode .num_irqs = ARRAY_SIZE(pf1550_regulator_irqs), 66*ebaec90eSSamuel Kayode }; 67*ebaec90eSSamuel Kayode 68*ebaec90eSSamuel Kayode static const struct resource regulator_resources[] = { 69*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_PMIC_IRQ_SW1_LS), 70*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_PMIC_IRQ_SW2_LS), 71*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_PMIC_IRQ_SW3_LS), 72*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_PMIC_IRQ_SW1_HS), 73*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_PMIC_IRQ_SW2_HS), 74*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_PMIC_IRQ_SW3_HS), 75*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_PMIC_IRQ_LDO1_FAULT), 76*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_PMIC_IRQ_LDO2_FAULT), 77*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_PMIC_IRQ_LDO3_FAULT), 78*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_PMIC_IRQ_TEMP_110), 79*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_PMIC_IRQ_TEMP_125), 80*ebaec90eSSamuel Kayode }; 81*ebaec90eSSamuel Kayode 82*ebaec90eSSamuel Kayode static const struct regmap_irq pf1550_onkey_irqs[] = { 83*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_ONKEY_IRQ_PUSHI, 0, ONKEY_IRQ_PUSHI), 84*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_ONKEY_IRQ_1SI, 0, ONKEY_IRQ_1SI), 85*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_ONKEY_IRQ_2SI, 0, ONKEY_IRQ_2SI), 86*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_ONKEY_IRQ_3SI, 0, ONKEY_IRQ_3SI), 87*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_ONKEY_IRQ_4SI, 0, ONKEY_IRQ_4SI), 88*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_ONKEY_IRQ_8SI, 0, ONKEY_IRQ_8SI), 89*ebaec90eSSamuel Kayode }; 90*ebaec90eSSamuel Kayode 91*ebaec90eSSamuel Kayode static const struct regmap_irq_chip pf1550_onkey_irq_chip = { 92*ebaec90eSSamuel Kayode .name = "pf1550-onkey", 93*ebaec90eSSamuel Kayode .status_base = PF1550_PMIC_REG_ONKEY_INT_STAT0, 94*ebaec90eSSamuel Kayode .ack_base = PF1550_PMIC_REG_ONKEY_INT_STAT0, 95*ebaec90eSSamuel Kayode .mask_base = PF1550_PMIC_REG_ONKEY_INT_MASK0, 96*ebaec90eSSamuel Kayode .use_ack = 1, 97*ebaec90eSSamuel Kayode .init_ack_masked = 1, 98*ebaec90eSSamuel Kayode .num_regs = 1, 99*ebaec90eSSamuel Kayode .irqs = pf1550_onkey_irqs, 100*ebaec90eSSamuel Kayode .num_irqs = ARRAY_SIZE(pf1550_onkey_irqs), 101*ebaec90eSSamuel Kayode }; 102*ebaec90eSSamuel Kayode 103*ebaec90eSSamuel Kayode static const struct resource onkey_resources[] = { 104*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_ONKEY_IRQ_PUSHI), 105*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_ONKEY_IRQ_1SI), 106*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_ONKEY_IRQ_2SI), 107*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_ONKEY_IRQ_3SI), 108*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_ONKEY_IRQ_4SI), 109*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_ONKEY_IRQ_8SI), 110*ebaec90eSSamuel Kayode }; 111*ebaec90eSSamuel Kayode 112*ebaec90eSSamuel Kayode static const struct regmap_irq pf1550_charger_irqs[] = { 113*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_CHARG_IRQ_BAT2SOCI, 0, CHARG_IRQ_BAT2SOCI), 114*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_CHARG_IRQ_BATI, 0, CHARG_IRQ_BATI), 115*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_CHARG_IRQ_CHGI, 0, CHARG_IRQ_CHGI), 116*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_CHARG_IRQ_VBUSI, 0, CHARG_IRQ_VBUSI), 117*ebaec90eSSamuel Kayode REGMAP_IRQ_REG(PF1550_CHARG_IRQ_THMI, 0, CHARG_IRQ_THMI), 118*ebaec90eSSamuel Kayode }; 119*ebaec90eSSamuel Kayode 120*ebaec90eSSamuel Kayode static const struct regmap_irq_chip pf1550_charger_irq_chip = { 121*ebaec90eSSamuel Kayode .name = "pf1550-charger", 122*ebaec90eSSamuel Kayode .status_base = PF1550_CHARG_REG_CHG_INT, 123*ebaec90eSSamuel Kayode .ack_base = PF1550_CHARG_REG_CHG_INT, 124*ebaec90eSSamuel Kayode .mask_base = PF1550_CHARG_REG_CHG_INT_MASK, 125*ebaec90eSSamuel Kayode .use_ack = 1, 126*ebaec90eSSamuel Kayode .init_ack_masked = 1, 127*ebaec90eSSamuel Kayode .num_regs = 1, 128*ebaec90eSSamuel Kayode .irqs = pf1550_charger_irqs, 129*ebaec90eSSamuel Kayode .num_irqs = ARRAY_SIZE(pf1550_charger_irqs), 130*ebaec90eSSamuel Kayode }; 131*ebaec90eSSamuel Kayode 132*ebaec90eSSamuel Kayode static const struct resource charger_resources[] = { 133*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_CHARG_IRQ_BAT2SOCI), 134*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_CHARG_IRQ_BATI), 135*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_CHARG_IRQ_CHGI), 136*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_CHARG_IRQ_VBUSI), 137*ebaec90eSSamuel Kayode DEFINE_RES_IRQ(PF1550_CHARG_IRQ_THMI), 138*ebaec90eSSamuel Kayode }; 139*ebaec90eSSamuel Kayode 140*ebaec90eSSamuel Kayode static const struct mfd_cell pf1550_regulator_cell = { 141*ebaec90eSSamuel Kayode .name = "pf1550-regulator", 142*ebaec90eSSamuel Kayode .num_resources = ARRAY_SIZE(regulator_resources), 143*ebaec90eSSamuel Kayode .resources = regulator_resources, 144*ebaec90eSSamuel Kayode }; 145*ebaec90eSSamuel Kayode 146*ebaec90eSSamuel Kayode static const struct mfd_cell pf1550_onkey_cell = { 147*ebaec90eSSamuel Kayode .name = "pf1550-onkey", 148*ebaec90eSSamuel Kayode .num_resources = ARRAY_SIZE(onkey_resources), 149*ebaec90eSSamuel Kayode .resources = onkey_resources, 150*ebaec90eSSamuel Kayode }; 151*ebaec90eSSamuel Kayode 152*ebaec90eSSamuel Kayode static const struct mfd_cell pf1550_charger_cell = { 153*ebaec90eSSamuel Kayode .name = "pf1550-charger", 154*ebaec90eSSamuel Kayode .num_resources = ARRAY_SIZE(charger_resources), 155*ebaec90eSSamuel Kayode .resources = charger_resources, 156*ebaec90eSSamuel Kayode }; 157*ebaec90eSSamuel Kayode 158*ebaec90eSSamuel Kayode /* 159*ebaec90eSSamuel Kayode * The PF1550 is shipped in variants of A0, A1,...A9. Each variant defines a 160*ebaec90eSSamuel Kayode * configuration of the PMIC in a One-Time Programmable (OTP) memory. 161*ebaec90eSSamuel Kayode * This memory is accessed indirectly by writing valid keys to specific 162*ebaec90eSSamuel Kayode * registers of the PMIC. To read the OTP memory after writing the valid keys, 163*ebaec90eSSamuel Kayode * the OTP register address to be read is written to pf1550 register 0xc4 and 164*ebaec90eSSamuel Kayode * its value read from pf1550 register 0xc5. 165*ebaec90eSSamuel Kayode */ 166*ebaec90eSSamuel Kayode static int pf1550_read_otp(const struct pf1550_ddata *pf1550, unsigned int index, 167*ebaec90eSSamuel Kayode unsigned int *val) 168*ebaec90eSSamuel Kayode { 169*ebaec90eSSamuel Kayode int ret = 0; 170*ebaec90eSSamuel Kayode 171*ebaec90eSSamuel Kayode ret = regmap_write(pf1550->regmap, PF1550_PMIC_REG_KEY, PF1550_OTP_PMIC_KEY); 172*ebaec90eSSamuel Kayode if (ret) 173*ebaec90eSSamuel Kayode goto read_err; 174*ebaec90eSSamuel Kayode 175*ebaec90eSSamuel Kayode ret = regmap_write(pf1550->regmap, PF1550_CHARG_REG_CHGR_KEY2, PF1550_OTP_CHGR_KEY); 176*ebaec90eSSamuel Kayode if (ret) 177*ebaec90eSSamuel Kayode goto read_err; 178*ebaec90eSSamuel Kayode 179*ebaec90eSSamuel Kayode ret = regmap_write(pf1550->regmap, PF1550_TEST_REG_KEY3, PF1550_OTP_TEST_KEY); 180*ebaec90eSSamuel Kayode if (ret) 181*ebaec90eSSamuel Kayode goto read_err; 182*ebaec90eSSamuel Kayode 183*ebaec90eSSamuel Kayode ret = regmap_write(pf1550->regmap, PF1550_TEST_REG_FMRADDR, index); 184*ebaec90eSSamuel Kayode if (ret) 185*ebaec90eSSamuel Kayode goto read_err; 186*ebaec90eSSamuel Kayode 187*ebaec90eSSamuel Kayode ret = regmap_read(pf1550->regmap, PF1550_TEST_REG_FMRDATA, val); 188*ebaec90eSSamuel Kayode if (ret) 189*ebaec90eSSamuel Kayode goto read_err; 190*ebaec90eSSamuel Kayode 191*ebaec90eSSamuel Kayode return 0; 192*ebaec90eSSamuel Kayode 193*ebaec90eSSamuel Kayode read_err: 194*ebaec90eSSamuel Kayode return dev_err_probe(pf1550->dev, ret, "OTP reg %x not found!\n", index); 195*ebaec90eSSamuel Kayode } 196*ebaec90eSSamuel Kayode 197*ebaec90eSSamuel Kayode static int pf1550_i2c_probe(struct i2c_client *i2c) 198*ebaec90eSSamuel Kayode { 199*ebaec90eSSamuel Kayode const struct mfd_cell *regulator = &pf1550_regulator_cell; 200*ebaec90eSSamuel Kayode const struct mfd_cell *charger = &pf1550_charger_cell; 201*ebaec90eSSamuel Kayode const struct mfd_cell *onkey = &pf1550_onkey_cell; 202*ebaec90eSSamuel Kayode unsigned int reg_data = 0, otp_data = 0; 203*ebaec90eSSamuel Kayode struct pf1550_ddata *pf1550; 204*ebaec90eSSamuel Kayode struct irq_domain *domain; 205*ebaec90eSSamuel Kayode int irq, ret = 0; 206*ebaec90eSSamuel Kayode 207*ebaec90eSSamuel Kayode pf1550 = devm_kzalloc(&i2c->dev, sizeof(*pf1550), GFP_KERNEL); 208*ebaec90eSSamuel Kayode if (!pf1550) 209*ebaec90eSSamuel Kayode return -ENOMEM; 210*ebaec90eSSamuel Kayode 211*ebaec90eSSamuel Kayode i2c_set_clientdata(i2c, pf1550); 212*ebaec90eSSamuel Kayode pf1550->dev = &i2c->dev; 213*ebaec90eSSamuel Kayode pf1550->irq = i2c->irq; 214*ebaec90eSSamuel Kayode 215*ebaec90eSSamuel Kayode pf1550->regmap = devm_regmap_init_i2c(i2c, &pf1550_regmap_config); 216*ebaec90eSSamuel Kayode if (IS_ERR(pf1550->regmap)) 217*ebaec90eSSamuel Kayode return dev_err_probe(pf1550->dev, PTR_ERR(pf1550->regmap), 218*ebaec90eSSamuel Kayode "failed to allocate register map\n"); 219*ebaec90eSSamuel Kayode 220*ebaec90eSSamuel Kayode ret = regmap_read(pf1550->regmap, PF1550_PMIC_REG_DEVICE_ID, ®_data); 221*ebaec90eSSamuel Kayode if (ret < 0) 222*ebaec90eSSamuel Kayode return dev_err_probe(pf1550->dev, ret, "cannot read chip ID\n"); 223*ebaec90eSSamuel Kayode if (reg_data != PF1550_DEVICE_ID) 224*ebaec90eSSamuel Kayode return dev_err_probe(pf1550->dev, -ENODEV, "invalid device ID: 0x%02x\n", reg_data); 225*ebaec90eSSamuel Kayode 226*ebaec90eSSamuel Kayode /* Regulator DVS for SW2 */ 227*ebaec90eSSamuel Kayode ret = pf1550_read_otp(pf1550, PF1550_OTP_SW2_SW3, &otp_data); 228*ebaec90eSSamuel Kayode if (ret) 229*ebaec90eSSamuel Kayode return ret; 230*ebaec90eSSamuel Kayode 231*ebaec90eSSamuel Kayode /* When clear, DVS should be enabled */ 232*ebaec90eSSamuel Kayode if (!(otp_data & OTP_SW2_DVS_ENB)) 233*ebaec90eSSamuel Kayode pf1550->dvs2_enable = true; 234*ebaec90eSSamuel Kayode 235*ebaec90eSSamuel Kayode /* Regulator DVS for SW1 */ 236*ebaec90eSSamuel Kayode ret = pf1550_read_otp(pf1550, PF1550_OTP_SW1_SW2, &otp_data); 237*ebaec90eSSamuel Kayode if (ret) 238*ebaec90eSSamuel Kayode return ret; 239*ebaec90eSSamuel Kayode 240*ebaec90eSSamuel Kayode if (!(otp_data & OTP_SW1_DVS_ENB)) 241*ebaec90eSSamuel Kayode pf1550->dvs1_enable = true; 242*ebaec90eSSamuel Kayode 243*ebaec90eSSamuel Kayode /* Add top level interrupts */ 244*ebaec90eSSamuel Kayode ret = devm_regmap_add_irq_chip(pf1550->dev, pf1550->regmap, pf1550->irq, 245*ebaec90eSSamuel Kayode IRQF_ONESHOT | IRQF_SHARED | 246*ebaec90eSSamuel Kayode IRQF_TRIGGER_FALLING, 247*ebaec90eSSamuel Kayode 0, &pf1550_irq_chip, 248*ebaec90eSSamuel Kayode &pf1550->irq_data); 249*ebaec90eSSamuel Kayode if (ret) 250*ebaec90eSSamuel Kayode return ret; 251*ebaec90eSSamuel Kayode 252*ebaec90eSSamuel Kayode /* Add regulator */ 253*ebaec90eSSamuel Kayode irq = regmap_irq_get_virq(pf1550->irq_data, PF1550_IRQ_REGULATOR); 254*ebaec90eSSamuel Kayode if (irq < 0) 255*ebaec90eSSamuel Kayode return dev_err_probe(pf1550->dev, irq, 256*ebaec90eSSamuel Kayode "Failed to get parent vIRQ(%d) for chip %s\n", 257*ebaec90eSSamuel Kayode PF1550_IRQ_REGULATOR, pf1550_irq_chip.name); 258*ebaec90eSSamuel Kayode 259*ebaec90eSSamuel Kayode ret = devm_regmap_add_irq_chip(pf1550->dev, pf1550->regmap, irq, 260*ebaec90eSSamuel Kayode IRQF_ONESHOT | IRQF_SHARED | 261*ebaec90eSSamuel Kayode IRQF_TRIGGER_FALLING, 0, 262*ebaec90eSSamuel Kayode &pf1550_regulator_irq_chip, 263*ebaec90eSSamuel Kayode &pf1550->irq_data_regulator); 264*ebaec90eSSamuel Kayode if (ret) 265*ebaec90eSSamuel Kayode return dev_err_probe(pf1550->dev, ret, "Failed to add %s IRQ chip\n", 266*ebaec90eSSamuel Kayode pf1550_regulator_irq_chip.name); 267*ebaec90eSSamuel Kayode 268*ebaec90eSSamuel Kayode domain = regmap_irq_get_domain(pf1550->irq_data_regulator); 269*ebaec90eSSamuel Kayode 270*ebaec90eSSamuel Kayode ret = devm_mfd_add_devices(pf1550->dev, PLATFORM_DEVID_NONE, regulator, 1, NULL, 0, domain); 271*ebaec90eSSamuel Kayode if (ret) 272*ebaec90eSSamuel Kayode return ret; 273*ebaec90eSSamuel Kayode 274*ebaec90eSSamuel Kayode /* Add onkey */ 275*ebaec90eSSamuel Kayode irq = regmap_irq_get_virq(pf1550->irq_data, PF1550_IRQ_ONKEY); 276*ebaec90eSSamuel Kayode if (irq < 0) 277*ebaec90eSSamuel Kayode return dev_err_probe(pf1550->dev, irq, 278*ebaec90eSSamuel Kayode "Failed to get parent vIRQ(%d) for chip %s\n", 279*ebaec90eSSamuel Kayode PF1550_IRQ_ONKEY, pf1550_irq_chip.name); 280*ebaec90eSSamuel Kayode 281*ebaec90eSSamuel Kayode ret = devm_regmap_add_irq_chip(pf1550->dev, pf1550->regmap, irq, 282*ebaec90eSSamuel Kayode IRQF_ONESHOT | IRQF_SHARED | 283*ebaec90eSSamuel Kayode IRQF_TRIGGER_FALLING, 0, 284*ebaec90eSSamuel Kayode &pf1550_onkey_irq_chip, 285*ebaec90eSSamuel Kayode &pf1550->irq_data_onkey); 286*ebaec90eSSamuel Kayode if (ret) 287*ebaec90eSSamuel Kayode return dev_err_probe(pf1550->dev, ret, "Failed to add %s IRQ chip\n", 288*ebaec90eSSamuel Kayode pf1550_onkey_irq_chip.name); 289*ebaec90eSSamuel Kayode 290*ebaec90eSSamuel Kayode domain = regmap_irq_get_domain(pf1550->irq_data_onkey); 291*ebaec90eSSamuel Kayode 292*ebaec90eSSamuel Kayode ret = devm_mfd_add_devices(pf1550->dev, PLATFORM_DEVID_NONE, onkey, 1, NULL, 0, domain); 293*ebaec90eSSamuel Kayode if (ret) 294*ebaec90eSSamuel Kayode return ret; 295*ebaec90eSSamuel Kayode 296*ebaec90eSSamuel Kayode /* Add battery charger */ 297*ebaec90eSSamuel Kayode irq = regmap_irq_get_virq(pf1550->irq_data, PF1550_IRQ_CHG); 298*ebaec90eSSamuel Kayode if (irq < 0) 299*ebaec90eSSamuel Kayode return dev_err_probe(pf1550->dev, irq, 300*ebaec90eSSamuel Kayode "Failed to get parent vIRQ(%d) for chip %s\n", 301*ebaec90eSSamuel Kayode PF1550_IRQ_CHG, pf1550_irq_chip.name); 302*ebaec90eSSamuel Kayode 303*ebaec90eSSamuel Kayode ret = devm_regmap_add_irq_chip(pf1550->dev, pf1550->regmap, irq, 304*ebaec90eSSamuel Kayode IRQF_ONESHOT | IRQF_SHARED | 305*ebaec90eSSamuel Kayode IRQF_TRIGGER_FALLING, 0, 306*ebaec90eSSamuel Kayode &pf1550_charger_irq_chip, 307*ebaec90eSSamuel Kayode &pf1550->irq_data_charger); 308*ebaec90eSSamuel Kayode if (ret) 309*ebaec90eSSamuel Kayode return dev_err_probe(pf1550->dev, ret, "Failed to add %s IRQ chip\n", 310*ebaec90eSSamuel Kayode pf1550_charger_irq_chip.name); 311*ebaec90eSSamuel Kayode 312*ebaec90eSSamuel Kayode domain = regmap_irq_get_domain(pf1550->irq_data_charger); 313*ebaec90eSSamuel Kayode 314*ebaec90eSSamuel Kayode return devm_mfd_add_devices(pf1550->dev, PLATFORM_DEVID_NONE, charger, 1, NULL, 0, domain); 315*ebaec90eSSamuel Kayode } 316*ebaec90eSSamuel Kayode 317*ebaec90eSSamuel Kayode static int pf1550_suspend(struct device *dev) 318*ebaec90eSSamuel Kayode { 319*ebaec90eSSamuel Kayode struct pf1550_ddata *pf1550 = dev_get_drvdata(dev); 320*ebaec90eSSamuel Kayode 321*ebaec90eSSamuel Kayode if (device_may_wakeup(dev)) { 322*ebaec90eSSamuel Kayode enable_irq_wake(pf1550->irq); 323*ebaec90eSSamuel Kayode disable_irq(pf1550->irq); 324*ebaec90eSSamuel Kayode } 325*ebaec90eSSamuel Kayode 326*ebaec90eSSamuel Kayode return 0; 327*ebaec90eSSamuel Kayode } 328*ebaec90eSSamuel Kayode 329*ebaec90eSSamuel Kayode static int pf1550_resume(struct device *dev) 330*ebaec90eSSamuel Kayode { 331*ebaec90eSSamuel Kayode struct pf1550_ddata *pf1550 = dev_get_drvdata(dev); 332*ebaec90eSSamuel Kayode 333*ebaec90eSSamuel Kayode if (device_may_wakeup(dev)) { 334*ebaec90eSSamuel Kayode disable_irq_wake(pf1550->irq); 335*ebaec90eSSamuel Kayode enable_irq(pf1550->irq); 336*ebaec90eSSamuel Kayode } 337*ebaec90eSSamuel Kayode 338*ebaec90eSSamuel Kayode return 0; 339*ebaec90eSSamuel Kayode } 340*ebaec90eSSamuel Kayode static DEFINE_SIMPLE_DEV_PM_OPS(pf1550_pm, pf1550_suspend, pf1550_resume); 341*ebaec90eSSamuel Kayode 342*ebaec90eSSamuel Kayode static const struct i2c_device_id pf1550_i2c_id[] = { 343*ebaec90eSSamuel Kayode { "pf1550" }, 344*ebaec90eSSamuel Kayode { /* sentinel */ } 345*ebaec90eSSamuel Kayode }; 346*ebaec90eSSamuel Kayode MODULE_DEVICE_TABLE(i2c, pf1550_i2c_id); 347*ebaec90eSSamuel Kayode 348*ebaec90eSSamuel Kayode static const struct of_device_id pf1550_dt_match[] = { 349*ebaec90eSSamuel Kayode { .compatible = "nxp,pf1550" }, 350*ebaec90eSSamuel Kayode { /* sentinel */ } 351*ebaec90eSSamuel Kayode }; 352*ebaec90eSSamuel Kayode MODULE_DEVICE_TABLE(of, pf1550_dt_match); 353*ebaec90eSSamuel Kayode 354*ebaec90eSSamuel Kayode static struct i2c_driver pf1550_i2c_driver = { 355*ebaec90eSSamuel Kayode .driver = { 356*ebaec90eSSamuel Kayode .name = "pf1550", 357*ebaec90eSSamuel Kayode .pm = pm_sleep_ptr(&pf1550_pm), 358*ebaec90eSSamuel Kayode .of_match_table = pf1550_dt_match, 359*ebaec90eSSamuel Kayode }, 360*ebaec90eSSamuel Kayode .probe = pf1550_i2c_probe, 361*ebaec90eSSamuel Kayode .id_table = pf1550_i2c_id, 362*ebaec90eSSamuel Kayode }; 363*ebaec90eSSamuel Kayode module_i2c_driver(pf1550_i2c_driver); 364*ebaec90eSSamuel Kayode 365*ebaec90eSSamuel Kayode MODULE_DESCRIPTION("NXP PF1550 core driver"); 366*ebaec90eSSamuel Kayode MODULE_AUTHOR("Robin Gong <yibin.gong@freescale.com>"); 367*ebaec90eSSamuel Kayode MODULE_LICENSE("GPL"); 368