Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 //
0003 // Copyright (C) 2019 ROHM Semiconductors
0004 //
0005 // ROHM BD71828/BD71815 PMIC driver
0006 
0007 #include <linux/gpio_keys.h>
0008 #include <linux/i2c.h>
0009 #include <linux/input.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/ioport.h>
0012 #include <linux/irq.h>
0013 #include <linux/mfd/core.h>
0014 #include <linux/mfd/rohm-bd71815.h>
0015 #include <linux/mfd/rohm-bd71828.h>
0016 #include <linux/mfd/rohm-generic.h>
0017 #include <linux/module.h>
0018 #include <linux/of_device.h>
0019 #include <linux/regmap.h>
0020 #include <linux/types.h>
0021 
0022 static struct gpio_keys_button button = {
0023     .code = KEY_POWER,
0024     .gpio = -1,
0025     .type = EV_KEY,
0026 };
0027 
0028 static struct gpio_keys_platform_data bd71828_powerkey_data = {
0029     .buttons = &button,
0030     .nbuttons = 1,
0031     .name = "bd71828-pwrkey",
0032 };
0033 
0034 static const struct resource bd71815_rtc_irqs[] = {
0035     DEFINE_RES_IRQ_NAMED(BD71815_INT_RTC0, "bd71815-rtc-alm-0"),
0036     DEFINE_RES_IRQ_NAMED(BD71815_INT_RTC1, "bd71815-rtc-alm-1"),
0037     DEFINE_RES_IRQ_NAMED(BD71815_INT_RTC2, "bd71815-rtc-alm-2"),
0038 };
0039 
0040 static const struct resource bd71828_rtc_irqs[] = {
0041     DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC0, "bd71828-rtc-alm-0"),
0042     DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC1, "bd71828-rtc-alm-1"),
0043     DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC2, "bd71828-rtc-alm-2"),
0044 };
0045 
0046 static struct resource bd71815_power_irqs[] = {
0047     DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_RMV, "bd71815-dcin-rmv"),
0048     DEFINE_RES_IRQ_NAMED(BD71815_INT_CLPS_OUT, "bd71815-clps-out"),
0049     DEFINE_RES_IRQ_NAMED(BD71815_INT_CLPS_IN, "bd71815-clps-in"),
0050     DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_OVP_RES, "bd71815-dcin-ovp-res"),
0051     DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_OVP_DET, "bd71815-dcin-ovp-det"),
0052     DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_MON_RES, "bd71815-dcin-mon-res"),
0053     DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_MON_DET, "bd71815-dcin-mon-det"),
0054     DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_UV_RES, "bd71815-vsys-uv-res"),
0055     DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_UV_DET, "bd71815-vsys-uv-det"),
0056     DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_LOW_RES, "bd71815-vsys-low-res"),
0057     DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_LOW_DET, "bd71815-vsys-low-det"),
0058     DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_MON_RES, "bd71815-vsys-mon-res"),
0059     DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_MON_RES, "bd71815-vsys-mon-det"),
0060     DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_WDG_TEMP, "bd71815-chg-wdg-temp"),
0061     DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_WDG_TIME, "bd71815-chg-wdg"),
0062     DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_RECHARGE_RES, "bd71815-rechg-res"),
0063     DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_RECHARGE_DET, "bd71815-rechg-det"),
0064     DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_RANGED_TEMP_TRANSITION, "bd71815-ranged-temp-transit"),
0065     DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_STATE_TRANSITION, "bd71815-chg-state-change"),
0066     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_TEMP_NORMAL, "bd71815-bat-temp-normal"),
0067     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_TEMP_ERANGE, "bd71815-bat-temp-erange"),
0068     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_REMOVED, "bd71815-bat-rmv"),
0069     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_DETECTED, "bd71815-bat-det"),
0070     DEFINE_RES_IRQ_NAMED(BD71815_INT_THERM_REMOVED, "bd71815-therm-rmv"),
0071     DEFINE_RES_IRQ_NAMED(BD71815_INT_THERM_DETECTED, "bd71815-therm-det"),
0072     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_DEAD, "bd71815-bat-dead"),
0073     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_SHORTC_RES, "bd71815-bat-short-res"),
0074     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_SHORTC_DET, "bd71815-bat-short-det"),
0075     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_LOW_VOLT_RES, "bd71815-bat-low-res"),
0076     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_LOW_VOLT_DET, "bd71815-bat-low-det"),
0077     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_VOLT_RES, "bd71815-bat-over-res"),
0078     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_VOLT_DET, "bd71815-bat-over-det"),
0079     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_MON_RES, "bd71815-bat-mon-res"),
0080     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_MON_DET, "bd71815-bat-mon-det"),
0081     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_CC_MON1, "bd71815-bat-cc-mon1"),
0082     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_CC_MON2, "bd71815-bat-cc-mon2"),
0083     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_CC_MON3, "bd71815-bat-cc-mon3"),
0084     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_1_RES, "bd71815-bat-oc1-res"),
0085     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_1_DET, "bd71815-bat-oc1-det"),
0086     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_2_RES, "bd71815-bat-oc2-res"),
0087     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_2_DET, "bd71815-bat-oc2-det"),
0088     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_3_RES, "bd71815-bat-oc3-res"),
0089     DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_3_DET, "bd71815-bat-oc3-det"),
0090     DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_LOW_RES, "bd71815-bat-low-res"),
0091     DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_LOW_DET, "bd71815-bat-low-det"),
0092     DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_HI_RES, "bd71815-bat-hi-res"),
0093     DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_HI_DET, "bd71815-bat-hi-det"),
0094 };
0095 
0096 static struct mfd_cell bd71815_mfd_cells[] = {
0097     { .name = "bd71815-pmic", },
0098     { .name = "bd71815-clk", },
0099     { .name = "bd71815-gpo", },
0100     {
0101         .name = "bd71815-power",
0102         .num_resources = ARRAY_SIZE(bd71815_power_irqs),
0103         .resources = &bd71815_power_irqs[0],
0104     },
0105     {
0106         .name = "bd71815-rtc",
0107         .num_resources = ARRAY_SIZE(bd71815_rtc_irqs),
0108         .resources = &bd71815_rtc_irqs[0],
0109     },
0110 };
0111 
0112 static struct mfd_cell bd71828_mfd_cells[] = {
0113     { .name = "bd71828-pmic", },
0114     { .name = "bd71828-gpio", },
0115     { .name = "bd71828-led", .of_compatible = "rohm,bd71828-leds" },
0116     /*
0117      * We use BD71837 driver to drive the clock block. Only differences to
0118      * BD70528 clock gate are the register address and mask.
0119      */
0120     { .name = "bd71828-clk", },
0121     { .name = "bd71827-power", },
0122     {
0123         .name = "bd71828-rtc",
0124         .resources = bd71828_rtc_irqs,
0125         .num_resources = ARRAY_SIZE(bd71828_rtc_irqs),
0126     }, {
0127         .name = "gpio-keys",
0128         .platform_data = &bd71828_powerkey_data,
0129         .pdata_size = sizeof(bd71828_powerkey_data),
0130     },
0131 };
0132 
0133 static const struct regmap_range bd71815_volatile_ranges[] = {
0134     {
0135         .range_min = BD71815_REG_SEC,
0136         .range_max = BD71815_REG_YEAR,
0137     }, {
0138         .range_min = BD71815_REG_CONF,
0139         .range_max = BD71815_REG_BAT_TEMP,
0140     }, {
0141         .range_min = BD71815_REG_VM_IBAT_U,
0142         .range_max = BD71815_REG_CC_CTRL,
0143     }, {
0144         .range_min = BD71815_REG_CC_STAT,
0145         .range_max = BD71815_REG_CC_CURCD_L,
0146     }, {
0147         .range_min = BD71815_REG_VM_BTMP_MON,
0148         .range_max = BD71815_REG_VM_BTMP_MON,
0149     }, {
0150         .range_min = BD71815_REG_INT_STAT,
0151         .range_max = BD71815_REG_INT_UPDATE,
0152     }, {
0153         .range_min = BD71815_REG_VM_VSYS_U,
0154         .range_max = BD71815_REG_REX_CTRL_1,
0155     }, {
0156         .range_min = BD71815_REG_FULL_CCNTD_3,
0157         .range_max = BD71815_REG_CCNTD_CHG_2,
0158     },
0159 };
0160 
0161 static const struct regmap_range bd71828_volatile_ranges[] = {
0162     {
0163         .range_min = BD71828_REG_PS_CTRL_1,
0164         .range_max = BD71828_REG_PS_CTRL_1,
0165     }, {
0166         .range_min = BD71828_REG_PS_CTRL_3,
0167         .range_max = BD71828_REG_PS_CTRL_3,
0168     }, {
0169         .range_min = BD71828_REG_RTC_SEC,
0170         .range_max = BD71828_REG_RTC_YEAR,
0171     }, {
0172         /*
0173          * For now make all charger registers volatile because many
0174          * needs to be and because the charger block is not that
0175          * performance critical.
0176          */
0177         .range_min = BD71828_REG_CHG_STATE,
0178         .range_max = BD71828_REG_CHG_FULL,
0179     }, {
0180         .range_min = BD71828_REG_INT_MAIN,
0181         .range_max = BD71828_REG_IO_STAT,
0182     },
0183 };
0184 
0185 static const struct regmap_access_table bd71815_volatile_regs = {
0186     .yes_ranges = &bd71815_volatile_ranges[0],
0187     .n_yes_ranges = ARRAY_SIZE(bd71815_volatile_ranges),
0188 };
0189 
0190 static const struct regmap_access_table bd71828_volatile_regs = {
0191     .yes_ranges = &bd71828_volatile_ranges[0],
0192     .n_yes_ranges = ARRAY_SIZE(bd71828_volatile_ranges),
0193 };
0194 
0195 static const struct regmap_config bd71815_regmap = {
0196     .reg_bits = 8,
0197     .val_bits = 8,
0198     .volatile_table = &bd71815_volatile_regs,
0199     .max_register = BD71815_MAX_REGISTER - 1,
0200     .cache_type = REGCACHE_RBTREE,
0201 };
0202 
0203 static const struct regmap_config bd71828_regmap = {
0204     .reg_bits = 8,
0205     .val_bits = 8,
0206     .volatile_table = &bd71828_volatile_regs,
0207     .max_register = BD71828_MAX_REGISTER,
0208     .cache_type = REGCACHE_RBTREE,
0209 };
0210 
0211 /*
0212  * Mapping of main IRQ register bits to sub-IRQ register offsets so that we can
0213  * access corect sub-IRQ registers based on bits that are set in main IRQ
0214  * register. BD71815 and BD71828 have same sub-register-block offests.
0215  */
0216 
0217 static unsigned int bit0_offsets[] = {11};      /* RTC IRQ */
0218 static unsigned int bit1_offsets[] = {10};      /* TEMP IRQ */
0219 static unsigned int bit2_offsets[] = {6, 7, 8, 9};  /* BAT MON IRQ */
0220 static unsigned int bit3_offsets[] = {5};       /* BAT IRQ */
0221 static unsigned int bit4_offsets[] = {4};       /* CHG IRQ */
0222 static unsigned int bit5_offsets[] = {3};       /* VSYS IRQ */
0223 static unsigned int bit6_offsets[] = {1, 2};        /* DCIN IRQ */
0224 static unsigned int bit7_offsets[] = {0};       /* BUCK IRQ */
0225 
0226 static struct regmap_irq_sub_irq_map bd718xx_sub_irq_offsets[] = {
0227     REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
0228     REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets),
0229     REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets),
0230     REGMAP_IRQ_MAIN_REG_OFFSET(bit3_offsets),
0231     REGMAP_IRQ_MAIN_REG_OFFSET(bit4_offsets),
0232     REGMAP_IRQ_MAIN_REG_OFFSET(bit5_offsets),
0233     REGMAP_IRQ_MAIN_REG_OFFSET(bit6_offsets),
0234     REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets),
0235 };
0236 
0237 static const struct regmap_irq bd71815_irqs[] = {
0238     REGMAP_IRQ_REG(BD71815_INT_BUCK1_OCP, 0, BD71815_INT_BUCK1_OCP_MASK),
0239     REGMAP_IRQ_REG(BD71815_INT_BUCK2_OCP, 0, BD71815_INT_BUCK2_OCP_MASK),
0240     REGMAP_IRQ_REG(BD71815_INT_BUCK3_OCP, 0, BD71815_INT_BUCK3_OCP_MASK),
0241     REGMAP_IRQ_REG(BD71815_INT_BUCK4_OCP, 0, BD71815_INT_BUCK4_OCP_MASK),
0242     REGMAP_IRQ_REG(BD71815_INT_BUCK5_OCP, 0, BD71815_INT_BUCK5_OCP_MASK),
0243     REGMAP_IRQ_REG(BD71815_INT_LED_OVP, 0, BD71815_INT_LED_OVP_MASK),
0244     REGMAP_IRQ_REG(BD71815_INT_LED_OCP, 0, BD71815_INT_LED_OCP_MASK),
0245     REGMAP_IRQ_REG(BD71815_INT_LED_SCP, 0, BD71815_INT_LED_SCP_MASK),
0246     /* DCIN1 interrupts */
0247     REGMAP_IRQ_REG(BD71815_INT_DCIN_RMV, 1, BD71815_INT_DCIN_RMV_MASK),
0248     REGMAP_IRQ_REG(BD71815_INT_CLPS_OUT, 1, BD71815_INT_CLPS_OUT_MASK),
0249     REGMAP_IRQ_REG(BD71815_INT_CLPS_IN, 1, BD71815_INT_CLPS_IN_MASK),
0250     REGMAP_IRQ_REG(BD71815_INT_DCIN_OVP_RES, 1, BD71815_INT_DCIN_OVP_RES_MASK),
0251     REGMAP_IRQ_REG(BD71815_INT_DCIN_OVP_DET, 1, BD71815_INT_DCIN_OVP_DET_MASK),
0252     /* DCIN2 interrupts */
0253     REGMAP_IRQ_REG(BD71815_INT_DCIN_MON_RES, 2, BD71815_INT_DCIN_MON_RES_MASK),
0254     REGMAP_IRQ_REG(BD71815_INT_DCIN_MON_DET, 2, BD71815_INT_DCIN_MON_DET_MASK),
0255     REGMAP_IRQ_REG(BD71815_INT_WDOG, 2, BD71815_INT_WDOG_MASK),
0256     /* Vsys */
0257     REGMAP_IRQ_REG(BD71815_INT_VSYS_UV_RES, 3, BD71815_INT_VSYS_UV_RES_MASK),
0258     REGMAP_IRQ_REG(BD71815_INT_VSYS_UV_DET, 3, BD71815_INT_VSYS_UV_DET_MASK),
0259     REGMAP_IRQ_REG(BD71815_INT_VSYS_LOW_RES, 3, BD71815_INT_VSYS_LOW_RES_MASK),
0260     REGMAP_IRQ_REG(BD71815_INT_VSYS_LOW_DET, 3, BD71815_INT_VSYS_LOW_DET_MASK),
0261     REGMAP_IRQ_REG(BD71815_INT_VSYS_MON_RES, 3, BD71815_INT_VSYS_MON_RES_MASK),
0262     REGMAP_IRQ_REG(BD71815_INT_VSYS_MON_DET, 3, BD71815_INT_VSYS_MON_DET_MASK),
0263     /* Charger */
0264     REGMAP_IRQ_REG(BD71815_INT_CHG_WDG_TEMP, 4, BD71815_INT_CHG_WDG_TEMP_MASK),
0265     REGMAP_IRQ_REG(BD71815_INT_CHG_WDG_TIME, 4, BD71815_INT_CHG_WDG_TIME_MASK),
0266     REGMAP_IRQ_REG(BD71815_INT_CHG_RECHARGE_RES, 4, BD71815_INT_CHG_RECHARGE_RES_MASK),
0267     REGMAP_IRQ_REG(BD71815_INT_CHG_RECHARGE_DET, 4, BD71815_INT_CHG_RECHARGE_DET_MASK),
0268     REGMAP_IRQ_REG(BD71815_INT_CHG_RANGED_TEMP_TRANSITION, 4,
0269                BD71815_INT_CHG_RANGED_TEMP_TRANSITION_MASK),
0270     REGMAP_IRQ_REG(BD71815_INT_CHG_STATE_TRANSITION, 4, BD71815_INT_CHG_STATE_TRANSITION_MASK),
0271     /* Battery */
0272     REGMAP_IRQ_REG(BD71815_INT_BAT_TEMP_NORMAL, 5, BD71815_INT_BAT_TEMP_NORMAL_MASK),
0273     REGMAP_IRQ_REG(BD71815_INT_BAT_TEMP_ERANGE, 5, BD71815_INT_BAT_TEMP_ERANGE_MASK),
0274     REGMAP_IRQ_REG(BD71815_INT_BAT_REMOVED, 5, BD71815_INT_BAT_REMOVED_MASK),
0275     REGMAP_IRQ_REG(BD71815_INT_BAT_DETECTED, 5, BD71815_INT_BAT_DETECTED_MASK),
0276     REGMAP_IRQ_REG(BD71815_INT_THERM_REMOVED, 5, BD71815_INT_THERM_REMOVED_MASK),
0277     REGMAP_IRQ_REG(BD71815_INT_THERM_DETECTED, 5, BD71815_INT_THERM_DETECTED_MASK),
0278     /* Battery Mon 1 */
0279     REGMAP_IRQ_REG(BD71815_INT_BAT_DEAD, 6, BD71815_INT_BAT_DEAD_MASK),
0280     REGMAP_IRQ_REG(BD71815_INT_BAT_SHORTC_RES, 6, BD71815_INT_BAT_SHORTC_RES_MASK),
0281     REGMAP_IRQ_REG(BD71815_INT_BAT_SHORTC_DET, 6, BD71815_INT_BAT_SHORTC_DET_MASK),
0282     REGMAP_IRQ_REG(BD71815_INT_BAT_LOW_VOLT_RES, 6, BD71815_INT_BAT_LOW_VOLT_RES_MASK),
0283     REGMAP_IRQ_REG(BD71815_INT_BAT_LOW_VOLT_DET, 6, BD71815_INT_BAT_LOW_VOLT_DET_MASK),
0284     REGMAP_IRQ_REG(BD71815_INT_BAT_OVER_VOLT_RES, 6, BD71815_INT_BAT_OVER_VOLT_RES_MASK),
0285     REGMAP_IRQ_REG(BD71815_INT_BAT_OVER_VOLT_DET, 6, BD71815_INT_BAT_OVER_VOLT_DET_MASK),
0286     /* Battery Mon 2 */
0287     REGMAP_IRQ_REG(BD71815_INT_BAT_MON_RES, 7, BD71815_INT_BAT_MON_RES_MASK),
0288     REGMAP_IRQ_REG(BD71815_INT_BAT_MON_DET, 7, BD71815_INT_BAT_MON_DET_MASK),
0289     /* Battery Mon 3 (Coulomb counter) */
0290     REGMAP_IRQ_REG(BD71815_INT_BAT_CC_MON1, 8, BD71815_INT_BAT_CC_MON1_MASK),
0291     REGMAP_IRQ_REG(BD71815_INT_BAT_CC_MON2, 8, BD71815_INT_BAT_CC_MON2_MASK),
0292     REGMAP_IRQ_REG(BD71815_INT_BAT_CC_MON3, 8, BD71815_INT_BAT_CC_MON3_MASK),
0293     /* Battery Mon 4 */
0294     REGMAP_IRQ_REG(BD71815_INT_BAT_OVER_CURR_1_RES, 9, BD71815_INT_BAT_OVER_CURR_1_RES_MASK),
0295     REGMAP_IRQ_REG(BD71815_INT_BAT_OVER_CURR_1_DET, 9, BD71815_INT_BAT_OVER_CURR_1_DET_MASK),
0296     REGMAP_IRQ_REG(BD71815_INT_BAT_OVER_CURR_2_RES, 9, BD71815_INT_BAT_OVER_CURR_2_RES_MASK),
0297     REGMAP_IRQ_REG(BD71815_INT_BAT_OVER_CURR_2_DET, 9, BD71815_INT_BAT_OVER_CURR_2_DET_MASK),
0298     REGMAP_IRQ_REG(BD71815_INT_BAT_OVER_CURR_3_RES, 9, BD71815_INT_BAT_OVER_CURR_3_RES_MASK),
0299     REGMAP_IRQ_REG(BD71815_INT_BAT_OVER_CURR_3_DET, 9, BD71815_INT_BAT_OVER_CURR_3_DET_MASK),
0300     /* Temperature */
0301     REGMAP_IRQ_REG(BD71815_INT_TEMP_BAT_LOW_RES, 10, BD71815_INT_TEMP_BAT_LOW_RES_MASK),
0302     REGMAP_IRQ_REG(BD71815_INT_TEMP_BAT_LOW_DET, 10, BD71815_INT_TEMP_BAT_LOW_DET_MASK),
0303     REGMAP_IRQ_REG(BD71815_INT_TEMP_BAT_HI_RES, 10, BD71815_INT_TEMP_BAT_HI_RES_MASK),
0304     REGMAP_IRQ_REG(BD71815_INT_TEMP_BAT_HI_DET, 10, BD71815_INT_TEMP_BAT_HI_DET_MASK),
0305     REGMAP_IRQ_REG(BD71815_INT_TEMP_CHIP_OVER_125_RES, 10,
0306                BD71815_INT_TEMP_CHIP_OVER_125_RES_MASK),
0307     REGMAP_IRQ_REG(BD71815_INT_TEMP_CHIP_OVER_125_DET, 10,
0308                BD71815_INT_TEMP_CHIP_OVER_125_DET_MASK),
0309     REGMAP_IRQ_REG(BD71815_INT_TEMP_CHIP_OVER_VF_RES, 10,
0310                BD71815_INT_TEMP_CHIP_OVER_VF_RES_MASK),
0311     REGMAP_IRQ_REG(BD71815_INT_TEMP_CHIP_OVER_VF_DET, 10,
0312                BD71815_INT_TEMP_CHIP_OVER_VF_DET_MASK),
0313     /* RTC Alarm */
0314     REGMAP_IRQ_REG(BD71815_INT_RTC0, 11, BD71815_INT_RTC0_MASK),
0315     REGMAP_IRQ_REG(BD71815_INT_RTC1, 11, BD71815_INT_RTC1_MASK),
0316     REGMAP_IRQ_REG(BD71815_INT_RTC2, 11, BD71815_INT_RTC2_MASK),
0317 };
0318 
0319 static struct regmap_irq bd71828_irqs[] = {
0320     REGMAP_IRQ_REG(BD71828_INT_BUCK1_OCP, 0, BD71828_INT_BUCK1_OCP_MASK),
0321     REGMAP_IRQ_REG(BD71828_INT_BUCK2_OCP, 0, BD71828_INT_BUCK2_OCP_MASK),
0322     REGMAP_IRQ_REG(BD71828_INT_BUCK3_OCP, 0, BD71828_INT_BUCK3_OCP_MASK),
0323     REGMAP_IRQ_REG(BD71828_INT_BUCK4_OCP, 0, BD71828_INT_BUCK4_OCP_MASK),
0324     REGMAP_IRQ_REG(BD71828_INT_BUCK5_OCP, 0, BD71828_INT_BUCK5_OCP_MASK),
0325     REGMAP_IRQ_REG(BD71828_INT_BUCK6_OCP, 0, BD71828_INT_BUCK6_OCP_MASK),
0326     REGMAP_IRQ_REG(BD71828_INT_BUCK7_OCP, 0, BD71828_INT_BUCK7_OCP_MASK),
0327     REGMAP_IRQ_REG(BD71828_INT_PGFAULT, 0, BD71828_INT_PGFAULT_MASK),
0328     /* DCIN1 interrupts */
0329     REGMAP_IRQ_REG(BD71828_INT_DCIN_DET, 1, BD71828_INT_DCIN_DET_MASK),
0330     REGMAP_IRQ_REG(BD71828_INT_DCIN_RMV, 1, BD71828_INT_DCIN_RMV_MASK),
0331     REGMAP_IRQ_REG(BD71828_INT_CLPS_OUT, 1, BD71828_INT_CLPS_OUT_MASK),
0332     REGMAP_IRQ_REG(BD71828_INT_CLPS_IN, 1, BD71828_INT_CLPS_IN_MASK),
0333     /* DCIN2 interrupts */
0334     REGMAP_IRQ_REG(BD71828_INT_DCIN_MON_RES, 2, BD71828_INT_DCIN_MON_RES_MASK),
0335     REGMAP_IRQ_REG(BD71828_INT_DCIN_MON_DET, 2, BD71828_INT_DCIN_MON_DET_MASK),
0336     REGMAP_IRQ_REG(BD71828_INT_LONGPUSH, 2, BD71828_INT_LONGPUSH_MASK),
0337     REGMAP_IRQ_REG(BD71828_INT_MIDPUSH, 2, BD71828_INT_MIDPUSH_MASK),
0338     REGMAP_IRQ_REG(BD71828_INT_SHORTPUSH, 2, BD71828_INT_SHORTPUSH_MASK),
0339     REGMAP_IRQ_REG(BD71828_INT_PUSH, 2, BD71828_INT_PUSH_MASK),
0340     REGMAP_IRQ_REG(BD71828_INT_WDOG, 2, BD71828_INT_WDOG_MASK),
0341     REGMAP_IRQ_REG(BD71828_INT_SWRESET, 2, BD71828_INT_SWRESET_MASK),
0342     /* Vsys */
0343     REGMAP_IRQ_REG(BD71828_INT_VSYS_UV_RES, 3, BD71828_INT_VSYS_UV_RES_MASK),
0344     REGMAP_IRQ_REG(BD71828_INT_VSYS_UV_DET, 3, BD71828_INT_VSYS_UV_DET_MASK),
0345     REGMAP_IRQ_REG(BD71828_INT_VSYS_LOW_RES, 3, BD71828_INT_VSYS_LOW_RES_MASK),
0346     REGMAP_IRQ_REG(BD71828_INT_VSYS_LOW_DET, 3, BD71828_INT_VSYS_LOW_DET_MASK),
0347     REGMAP_IRQ_REG(BD71828_INT_VSYS_HALL_IN, 3, BD71828_INT_VSYS_HALL_IN_MASK),
0348     REGMAP_IRQ_REG(BD71828_INT_VSYS_HALL_TOGGLE, 3, BD71828_INT_VSYS_HALL_TOGGLE_MASK),
0349     REGMAP_IRQ_REG(BD71828_INT_VSYS_MON_RES, 3, BD71828_INT_VSYS_MON_RES_MASK),
0350     REGMAP_IRQ_REG(BD71828_INT_VSYS_MON_DET, 3, BD71828_INT_VSYS_MON_DET_MASK),
0351     /* Charger */
0352     REGMAP_IRQ_REG(BD71828_INT_CHG_DCIN_ILIM, 4, BD71828_INT_CHG_DCIN_ILIM_MASK),
0353     REGMAP_IRQ_REG(BD71828_INT_CHG_TOPOFF_TO_DONE, 4, BD71828_INT_CHG_TOPOFF_TO_DONE_MASK),
0354     REGMAP_IRQ_REG(BD71828_INT_CHG_WDG_TEMP, 4, BD71828_INT_CHG_WDG_TEMP_MASK),
0355     REGMAP_IRQ_REG(BD71828_INT_CHG_WDG_TIME, 4, BD71828_INT_CHG_WDG_TIME_MASK),
0356     REGMAP_IRQ_REG(BD71828_INT_CHG_RECHARGE_RES, 4, BD71828_INT_CHG_RECHARGE_RES_MASK),
0357     REGMAP_IRQ_REG(BD71828_INT_CHG_RECHARGE_DET, 4, BD71828_INT_CHG_RECHARGE_DET_MASK),
0358     REGMAP_IRQ_REG(BD71828_INT_CHG_RANGED_TEMP_TRANSITION, 4,
0359                BD71828_INT_CHG_RANGED_TEMP_TRANSITION_MASK),
0360     REGMAP_IRQ_REG(BD71828_INT_CHG_STATE_TRANSITION, 4, BD71828_INT_CHG_STATE_TRANSITION_MASK),
0361     /* Battery */
0362     REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_NORMAL, 5, BD71828_INT_BAT_TEMP_NORMAL_MASK),
0363     REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_ERANGE, 5, BD71828_INT_BAT_TEMP_ERANGE_MASK),
0364     REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_WARN, 5, BD71828_INT_BAT_TEMP_WARN_MASK),
0365     REGMAP_IRQ_REG(BD71828_INT_BAT_REMOVED, 5, BD71828_INT_BAT_REMOVED_MASK),
0366     REGMAP_IRQ_REG(BD71828_INT_BAT_DETECTED, 5, BD71828_INT_BAT_DETECTED_MASK),
0367     REGMAP_IRQ_REG(BD71828_INT_THERM_REMOVED, 5, BD71828_INT_THERM_REMOVED_MASK),
0368     REGMAP_IRQ_REG(BD71828_INT_THERM_DETECTED, 5, BD71828_INT_THERM_DETECTED_MASK),
0369     /* Battery Mon 1 */
0370     REGMAP_IRQ_REG(BD71828_INT_BAT_DEAD, 6, BD71828_INT_BAT_DEAD_MASK),
0371     REGMAP_IRQ_REG(BD71828_INT_BAT_SHORTC_RES, 6, BD71828_INT_BAT_SHORTC_RES_MASK),
0372     REGMAP_IRQ_REG(BD71828_INT_BAT_SHORTC_DET, 6, BD71828_INT_BAT_SHORTC_DET_MASK),
0373     REGMAP_IRQ_REG(BD71828_INT_BAT_LOW_VOLT_RES, 6, BD71828_INT_BAT_LOW_VOLT_RES_MASK),
0374     REGMAP_IRQ_REG(BD71828_INT_BAT_LOW_VOLT_DET, 6, BD71828_INT_BAT_LOW_VOLT_DET_MASK),
0375     REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_VOLT_RES, 6, BD71828_INT_BAT_OVER_VOLT_RES_MASK),
0376     REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_VOLT_DET, 6, BD71828_INT_BAT_OVER_VOLT_DET_MASK),
0377     /* Battery Mon 2 */
0378     REGMAP_IRQ_REG(BD71828_INT_BAT_MON_RES, 7, BD71828_INT_BAT_MON_RES_MASK),
0379     REGMAP_IRQ_REG(BD71828_INT_BAT_MON_DET, 7, BD71828_INT_BAT_MON_DET_MASK),
0380     /* Battery Mon 3 (Coulomb counter) */
0381     REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON1, 8, BD71828_INT_BAT_CC_MON1_MASK),
0382     REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON2, 8, BD71828_INT_BAT_CC_MON2_MASK),
0383     REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON3, 8, BD71828_INT_BAT_CC_MON3_MASK),
0384     /* Battery Mon 4 */
0385     REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_1_RES, 9, BD71828_INT_BAT_OVER_CURR_1_RES_MASK),
0386     REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_1_DET, 9, BD71828_INT_BAT_OVER_CURR_1_DET_MASK),
0387     REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_2_RES, 9, BD71828_INT_BAT_OVER_CURR_2_RES_MASK),
0388     REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_2_DET, 9, BD71828_INT_BAT_OVER_CURR_2_DET_MASK),
0389     REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_3_RES, 9, BD71828_INT_BAT_OVER_CURR_3_RES_MASK),
0390     REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_3_DET, 9, BD71828_INT_BAT_OVER_CURR_3_DET_MASK),
0391     /* Temperature */
0392     REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_LOW_RES, 10, BD71828_INT_TEMP_BAT_LOW_RES_MASK),
0393     REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_LOW_DET, 10, BD71828_INT_TEMP_BAT_LOW_DET_MASK),
0394     REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_HI_RES, 10, BD71828_INT_TEMP_BAT_HI_RES_MASK),
0395     REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_HI_DET, 10, BD71828_INT_TEMP_BAT_HI_DET_MASK),
0396     REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_125_RES, 10,
0397                BD71828_INT_TEMP_CHIP_OVER_125_RES_MASK),
0398     REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_125_DET, 10,
0399                BD71828_INT_TEMP_CHIP_OVER_125_DET_MASK),
0400     REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_VF_DET, 10,
0401                BD71828_INT_TEMP_CHIP_OVER_VF_DET_MASK),
0402     REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_VF_RES, 10,
0403                BD71828_INT_TEMP_CHIP_OVER_VF_RES_MASK),
0404     /* RTC Alarm */
0405     REGMAP_IRQ_REG(BD71828_INT_RTC0, 11, BD71828_INT_RTC0_MASK),
0406     REGMAP_IRQ_REG(BD71828_INT_RTC1, 11, BD71828_INT_RTC1_MASK),
0407     REGMAP_IRQ_REG(BD71828_INT_RTC2, 11, BD71828_INT_RTC2_MASK),
0408 };
0409 
0410 static struct regmap_irq_chip bd71828_irq_chip = {
0411     .name = "bd71828_irq",
0412     .main_status = BD71828_REG_INT_MAIN,
0413     .irqs = &bd71828_irqs[0],
0414     .num_irqs = ARRAY_SIZE(bd71828_irqs),
0415     .status_base = BD71828_REG_INT_BUCK,
0416     .mask_base = BD71828_REG_INT_MASK_BUCK,
0417     .ack_base = BD71828_REG_INT_BUCK,
0418     .mask_invert = true,
0419     .init_ack_masked = true,
0420     .num_regs = 12,
0421     .num_main_regs = 1,
0422     .sub_reg_offsets = &bd718xx_sub_irq_offsets[0],
0423     .num_main_status_bits = 8,
0424     .irq_reg_stride = 1,
0425 };
0426 
0427 static struct regmap_irq_chip bd71815_irq_chip = {
0428     .name = "bd71815_irq",
0429     .main_status = BD71815_REG_INT_STAT,
0430     .irqs = &bd71815_irqs[0],
0431     .num_irqs = ARRAY_SIZE(bd71815_irqs),
0432     .status_base = BD71815_REG_INT_STAT_01,
0433     .mask_base = BD71815_REG_INT_EN_01,
0434     .ack_base = BD71815_REG_INT_STAT_01,
0435     .mask_invert = true,
0436     .init_ack_masked = true,
0437     .num_regs = 12,
0438     .num_main_regs = 1,
0439     .sub_reg_offsets = &bd718xx_sub_irq_offsets[0],
0440     .num_main_status_bits = 8,
0441     .irq_reg_stride = 1,
0442 };
0443 
0444 static int set_clk_mode(struct device *dev, struct regmap *regmap,
0445             int clkmode_reg)
0446 {
0447     int ret;
0448     unsigned int open_drain;
0449 
0450     ret = of_property_read_u32(dev->of_node, "rohm,clkout-open-drain", &open_drain);
0451     if (ret) {
0452         if (ret == -EINVAL)
0453             return 0;
0454         return ret;
0455     }
0456     if (open_drain > 1) {
0457         dev_err(dev, "bad clk32kout mode configuration");
0458         return -EINVAL;
0459     }
0460 
0461     if (open_drain)
0462         return regmap_update_bits(regmap, clkmode_reg, OUT32K_MODE,
0463                       OUT32K_MODE_OPEN_DRAIN);
0464 
0465     return regmap_update_bits(regmap, clkmode_reg, OUT32K_MODE,
0466                   OUT32K_MODE_CMOS);
0467 }
0468 
0469 static int bd71828_i2c_probe(struct i2c_client *i2c)
0470 {
0471     struct regmap_irq_chip_data *irq_data;
0472     int ret;
0473     struct regmap *regmap;
0474     const struct regmap_config *regmap_config;
0475     struct regmap_irq_chip *irqchip;
0476     unsigned int chip_type;
0477     struct mfd_cell *mfd;
0478     int cells;
0479     int button_irq;
0480     int clkmode_reg;
0481 
0482     if (!i2c->irq) {
0483         dev_err(&i2c->dev, "No IRQ configured\n");
0484         return -EINVAL;
0485     }
0486 
0487     chip_type = (unsigned int)(uintptr_t)
0488             of_device_get_match_data(&i2c->dev);
0489     switch (chip_type) {
0490     case ROHM_CHIP_TYPE_BD71828:
0491         mfd = bd71828_mfd_cells;
0492         cells = ARRAY_SIZE(bd71828_mfd_cells);
0493         regmap_config = &bd71828_regmap;
0494         irqchip = &bd71828_irq_chip;
0495         clkmode_reg = BD71828_REG_OUT32K;
0496         button_irq = BD71828_INT_SHORTPUSH;
0497         break;
0498     case ROHM_CHIP_TYPE_BD71815:
0499         mfd = bd71815_mfd_cells;
0500         cells = ARRAY_SIZE(bd71815_mfd_cells);
0501         regmap_config = &bd71815_regmap;
0502         irqchip = &bd71815_irq_chip;
0503         clkmode_reg = BD71815_REG_OUT32K;
0504         /*
0505          * If BD71817 support is needed we should be able to handle it
0506          * with proper DT configs + BD71815 drivers + power-button.
0507          * BD71815 data-sheet does not list the power-button IRQ so we
0508          * don't use it.
0509          */
0510         button_irq = 0;
0511         break;
0512     default:
0513         dev_err(&i2c->dev, "Unknown device type");
0514         return -EINVAL;
0515     }
0516 
0517     regmap = devm_regmap_init_i2c(i2c, regmap_config);
0518     if (IS_ERR(regmap)) {
0519         dev_err(&i2c->dev, "Failed to initialize Regmap\n");
0520         return PTR_ERR(regmap);
0521     }
0522 
0523     ret = devm_regmap_add_irq_chip(&i2c->dev, regmap, i2c->irq,
0524                        IRQF_ONESHOT, 0, irqchip, &irq_data);
0525     if (ret) {
0526         dev_err(&i2c->dev, "Failed to add IRQ chip\n");
0527         return ret;
0528     }
0529 
0530     dev_dbg(&i2c->dev, "Registered %d IRQs for chip\n",
0531         irqchip->num_irqs);
0532 
0533     if (button_irq) {
0534         ret = regmap_irq_get_virq(irq_data, button_irq);
0535         if (ret < 0) {
0536             dev_err(&i2c->dev, "Failed to get the power-key IRQ\n");
0537             return ret;
0538         }
0539 
0540         button.irq = ret;
0541     }
0542 
0543     ret = set_clk_mode(&i2c->dev, regmap, clkmode_reg);
0544     if (ret)
0545         return ret;
0546 
0547     ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, mfd, cells,
0548                    NULL, 0, regmap_irq_get_domain(irq_data));
0549     if (ret)
0550         dev_err(&i2c->dev, "Failed to create subdevices\n");
0551 
0552     return ret;
0553 }
0554 
0555 static const struct of_device_id bd71828_of_match[] = {
0556     {
0557         .compatible = "rohm,bd71828",
0558         .data = (void *)ROHM_CHIP_TYPE_BD71828,
0559     }, {
0560         .compatible = "rohm,bd71815",
0561         .data = (void *)ROHM_CHIP_TYPE_BD71815,
0562      },
0563     { },
0564 };
0565 MODULE_DEVICE_TABLE(of, bd71828_of_match);
0566 
0567 static struct i2c_driver bd71828_drv = {
0568     .driver = {
0569         .name = "rohm-bd71828",
0570         .of_match_table = bd71828_of_match,
0571     },
0572     .probe_new = &bd71828_i2c_probe,
0573 };
0574 module_i2c_driver(bd71828_drv);
0575 
0576 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
0577 MODULE_DESCRIPTION("ROHM BD71828 Power Management IC driver");
0578 MODULE_LICENSE("GPL");