regulator: bcm590xx: Store regulator descriptions in table
authorArtur Weber <aweber.kernel@gmail.com>
Thu, 15 May 2025 14:16:33 +0000 (16:16 +0200)
committerLee Jones <lee@kernel.org>
Thu, 22 May 2025 09:57:26 +0000 (10:57 +0100)
Instead of filling in the regulator description programatically,
store the data in a struct. This will make it a bit nicer to
introduce support for other BCM590xx chips besides the BCM59056.

To do this, add a new struct type, bcm590xx_reg_data, to store
all of the necessary information. Drop the old IS_LDO, IS_GPLDO...
macros in favor of the "type" field in this struct. Adapt the
old bcm590xx_reg struct to the new types.

Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
Reviewed-by: Stanislav Jakubek <stano.jakubek@gmail.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20250515-bcm59054-v9-6-14ba0ea2ea5b@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>
drivers/regulator/bcm590xx-regulator.c
include/linux/mfd/bcm590xx.h

index a17311f..c2427ea 100644 (file)
 
 /* I2C slave 0 registers */
 #define BCM590XX_RFLDOPMCTRL1  0x60
+#define BCM590XX_CAMLDO1PMCTRL1        0x62
+#define BCM590XX_CAMLDO2PMCTRL1        0x64
+#define BCM590XX_SIMLDO1PMCTRL1        0x66
+#define BCM590XX_SIMLDO2PMCTRL1        0x68
+#define BCM590XX_SDLDOPMCTRL1  0x6a
+#define BCM590XX_SDXLDOPMCTRL1 0x6c
+#define BCM590XX_MMCLDO1PMCTRL1        0x6e
+#define BCM590XX_MMCLDO2PMCTRL1        0x70
+#define BCM590XX_AUDLDOPMCTRL1 0x72
+#define BCM590XX_MICLDOPMCTRL1 0x74
+#define BCM590XX_USBLDOPMCTRL1 0x76
+#define BCM590XX_VIBLDOPMCTRL1 0x78
 #define BCM590XX_IOSR1PMCTRL1  0x7a
 #define BCM590XX_IOSR2PMCTRL1  0x7c
 #define BCM590XX_CSRPMCTRL1    0x7e
 #define BCM590XX_MSRPMCTRL1    0x8a
 #define BCM590XX_VSRPMCTRL1    0x8e
 #define BCM590XX_RFLDOCTRL     0x96
+#define BCM590XX_CAMLDO1CTRL   0x97
+#define BCM590XX_CAMLDO2CTRL   0x98
+#define BCM590XX_SIMLDO1CTRL   0x99
+#define BCM590XX_SIMLDO2CTRL   0x9a
+#define BCM590XX_SDLDOCTRL     0x9b
+#define BCM590XX_SDXLDOCTRL    0x9c
+#define BCM590XX_MMCLDO1CTRL   0x9d
+#define BCM590XX_MMCLDO2CTRL   0x9e
+#define BCM590XX_AUDLDOCTRL    0x9f
+#define BCM590XX_MICLDOCTRL    0xa0
+#define BCM590XX_USBLDOCTRL    0xa1
+#define BCM590XX_VIBLDOCTRL    0xa2
 #define BCM590XX_CSRVOUT1      0xc0
+#define BCM590XX_IOSR1VOUT1    0xc3
+#define BCM590XX_IOSR2VOUT1    0xc6
+#define BCM590XX_MSRVOUT1      0xc9
+#define BCM590XX_SDSR1VOUT1    0xcc
+#define BCM590XX_SDSR2VOUT1    0xcf
+#define BCM590XX_VSRVOUT1      0xd2
 
 /* I2C slave 1 registers */
 #define BCM590XX_GPLDO5PMCTRL1 0x16
 
 #define BCM590XX_NUM_REGS      27
 
-#define BCM590XX_REG_IS_LDO(n) (n < BCM590XX_REG_CSR)
-#define BCM590XX_REG_IS_GPLDO(n) \
-       ((n > BCM590XX_REG_VSR) && (n < BCM590XX_REG_VBUS))
-#define BCM590XX_REG_IS_VBUS(n)        (n == BCM590XX_REG_VBUS)
-
 /* LDO group A: supported voltages in microvolts */
 static const unsigned int ldo_a_table[] = {
        1200000, 1800000, 2500000, 2700000, 2800000,
@@ -111,10 +136,6 @@ static const unsigned int ldo_c_table[] = {
        2900000, 3000000, 3300000,
 };
 
-static const unsigned int ldo_vbus[] = {
-       5000000,
-};
-
 /* DCDC group CSR: supported voltages in microvolts */
 static const struct linear_range dcdc_csr_ranges[] = {
        REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000),
@@ -137,115 +158,25 @@ static const struct linear_range dcdc_sdsr1_ranges[] = {
        REGULATOR_LINEAR_RANGE(900000, 52, 63, 0),
 };
 
-struct bcm590xx_info {
-       const char *name;
-       const char *vin_name;
-       u8 n_voltages;
-       const unsigned int *volt_table;
-       u8 n_linear_ranges;
-       const struct linear_range *linear_ranges;
+enum bcm590xx_reg_type {
+       BCM590XX_REG_TYPE_LDO,
+       BCM590XX_REG_TYPE_GPLDO,
+       BCM590XX_REG_TYPE_SR,
+       BCM590XX_REG_TYPE_VBUS
 };
 
-#define BCM590XX_REG_TABLE(_name, _table) \
-       { \
-               .name = #_name, \
-               .n_voltages = ARRAY_SIZE(_table), \
-               .volt_table = _table, \
-       }
-
-#define BCM590XX_REG_RANGES(_name, _ranges) \
-       { \
-               .name = #_name, \
-               .n_voltages = 64, \
-               .n_linear_ranges = ARRAY_SIZE(_ranges), \
-               .linear_ranges = _ranges, \
-       }
-
-static struct bcm590xx_info bcm590xx_regs[] = {
-       BCM590XX_REG_TABLE(rfldo, ldo_a_table),
-       BCM590XX_REG_TABLE(camldo1, ldo_c_table),
-       BCM590XX_REG_TABLE(camldo2, ldo_c_table),
-       BCM590XX_REG_TABLE(simldo1, ldo_a_table),
-       BCM590XX_REG_TABLE(simldo2, ldo_a_table),
-       BCM590XX_REG_TABLE(sdldo, ldo_c_table),
-       BCM590XX_REG_TABLE(sdxldo, ldo_a_table),
-       BCM590XX_REG_TABLE(mmcldo1, ldo_a_table),
-       BCM590XX_REG_TABLE(mmcldo2, ldo_a_table),
-       BCM590XX_REG_TABLE(audldo, ldo_a_table),
-       BCM590XX_REG_TABLE(micldo, ldo_a_table),
-       BCM590XX_REG_TABLE(usbldo, ldo_a_table),
-       BCM590XX_REG_TABLE(vibldo, ldo_c_table),
-       BCM590XX_REG_RANGES(csr, dcdc_csr_ranges),
-       BCM590XX_REG_RANGES(iosr1, dcdc_iosr1_ranges),
-       BCM590XX_REG_RANGES(iosr2, dcdc_iosr1_ranges),
-       BCM590XX_REG_RANGES(msr, dcdc_iosr1_ranges),
-       BCM590XX_REG_RANGES(sdsr1, dcdc_sdsr1_ranges),
-       BCM590XX_REG_RANGES(sdsr2, dcdc_iosr1_ranges),
-       BCM590XX_REG_RANGES(vsr, dcdc_iosr1_ranges),
-       BCM590XX_REG_TABLE(gpldo1, ldo_a_table),
-       BCM590XX_REG_TABLE(gpldo2, ldo_a_table),
-       BCM590XX_REG_TABLE(gpldo3, ldo_a_table),
-       BCM590XX_REG_TABLE(gpldo4, ldo_a_table),
-       BCM590XX_REG_TABLE(gpldo5, ldo_a_table),
-       BCM590XX_REG_TABLE(gpldo6, ldo_a_table),
-       BCM590XX_REG_TABLE(vbus, ldo_vbus),
+struct bcm590xx_reg_data {
+       enum bcm590xx_reg_type type;
+       enum bcm590xx_regmap_type regmap;
+       const struct regulator_desc desc;
 };
 
 struct bcm590xx_reg {
-       struct regulator_desc *desc;
        struct bcm590xx *mfd;
+       unsigned int n_regulators;
+       const struct bcm590xx_reg_data *regs;
 };
 
-static int bcm590xx_get_vsel_register(int id)
-{
-       if (BCM590XX_REG_IS_LDO(id))
-               return BCM590XX_RFLDOCTRL + id;
-       else if (BCM590XX_REG_IS_GPLDO(id))
-               return BCM590XX_GPLDO1CTRL + id;
-       else
-               return BCM590XX_CSRVOUT1 + (id - BCM590XX_REG_CSR) * 3;
-}
-
-static int bcm590xx_get_enable_register(int id)
-{
-       int reg = 0;
-
-       if (BCM590XX_REG_IS_LDO(id))
-               reg = BCM590XX_RFLDOPMCTRL1 + id * 2;
-       else if (BCM590XX_REG_IS_GPLDO(id))
-               reg = BCM590XX_GPLDO1PMCTRL1 + id * 2;
-       else
-               switch (id) {
-               case BCM590XX_REG_CSR:
-                       reg = BCM590XX_CSRPMCTRL1;
-                       break;
-               case BCM590XX_REG_IOSR1:
-                       reg = BCM590XX_IOSR1PMCTRL1;
-                       break;
-               case BCM590XX_REG_IOSR2:
-                       reg = BCM590XX_IOSR2PMCTRL1;
-                       break;
-               case BCM590XX_REG_MSR:
-                       reg = BCM590XX_MSRPMCTRL1;
-                       break;
-               case BCM590XX_REG_SDSR1:
-                       reg = BCM590XX_SDSR1PMCTRL1;
-                       break;
-               case BCM590XX_REG_SDSR2:
-                       reg = BCM590XX_SDSR2PMCTRL1;
-                       break;
-               case BCM590XX_REG_VSR:
-                       reg = BCM590XX_VSRPMCTRL1;
-                       break;
-               case BCM590XX_REG_VBUS:
-                       reg = BCM590XX_OTG_CTRL;
-                       break;
-               }
-
-
-       return reg;
-}
-
 static const struct regulator_ops bcm590xx_ops_ldo = {
        .is_enabled             = regulator_is_enabled_regmap,
        .enable                 = regulator_enable_regmap,
@@ -272,73 +203,301 @@ static const struct regulator_ops bcm590xx_ops_vbus = {
        .disable                = regulator_disable_regmap,
 };
 
+#define BCM590XX_REG_DESC(_name, _name_lower)                          \
+       .id = BCM590XX_REG_##_name,                                     \
+       .name = #_name_lower,                                           \
+       .of_match = of_match_ptr(#_name_lower),                         \
+       .regulators_node = of_match_ptr("regulators"),                  \
+       .type = REGULATOR_VOLTAGE,                                      \
+       .owner = THIS_MODULE                                            \
+
+#define BCM590XX_LDO_DESC(_name, _name_lower, _table)                  \
+       BCM590XX_REG_DESC(_name, _name_lower),                          \
+       .ops = &bcm590xx_ops_ldo,                                       \
+       .n_voltages = ARRAY_SIZE(_table),                               \
+       .volt_table = _table,                                           \
+       .vsel_reg = BCM590XX_##_name##CTRL,                             \
+       .vsel_mask = BCM590XX_LDO_VSEL_MASK,                            \
+       .enable_reg = BCM590XX_##_name##PMCTRL1,                        \
+       .enable_mask = BCM590XX_REG_ENABLE,                             \
+       .enable_is_inverted = true
+
+#define BCM590XX_SR_DESC(_name, _name_lower, _ranges)                  \
+       BCM590XX_REG_DESC(_name, _name_lower),                          \
+       .ops = &bcm590xx_ops_dcdc,                                      \
+       .n_voltages = 64,                                               \
+       .linear_ranges = _ranges,                                       \
+       .n_linear_ranges = ARRAY_SIZE(_ranges),                         \
+       .vsel_reg = BCM590XX_##_name##VOUT1,                            \
+       .vsel_mask = BCM590XX_SR_VSEL_MASK,                             \
+       .enable_reg = BCM590XX_##_name##PMCTRL1,                        \
+       .enable_mask = BCM590XX_REG_ENABLE,                             \
+       .enable_is_inverted = true
+
+static const struct bcm590xx_reg_data bcm590xx_regs[BCM590XX_NUM_REGS] = {
+       {
+               .type = BCM590XX_REG_TYPE_LDO,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_LDO_DESC(RFLDO, rfldo, ldo_a_table),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_LDO,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_LDO_DESC(CAMLDO1, camldo1, ldo_c_table),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_LDO,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_LDO_DESC(CAMLDO2, camldo2, ldo_c_table),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_LDO,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_LDO_DESC(SIMLDO1, simldo1, ldo_a_table),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_LDO,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_LDO_DESC(SIMLDO2, simldo2, ldo_a_table),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_LDO,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_LDO_DESC(SDLDO, sdldo, ldo_c_table),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_LDO,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_LDO_DESC(SDXLDO, sdxldo, ldo_a_table),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_LDO,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_LDO_DESC(MMCLDO1, mmcldo1, ldo_a_table),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_LDO,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_LDO_DESC(MMCLDO2, mmcldo2, ldo_a_table),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_LDO,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_LDO_DESC(AUDLDO, audldo, ldo_a_table),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_LDO,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_LDO_DESC(MICLDO, micldo, ldo_a_table),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_LDO,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_LDO_DESC(USBLDO, usbldo, ldo_a_table),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_LDO,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_LDO_DESC(VIBLDO, vibldo, ldo_c_table),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_SR,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_SR_DESC(CSR, csr, dcdc_csr_ranges),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_SR,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_SR_DESC(IOSR1, iosr1, dcdc_iosr1_ranges),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_SR,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_SR_DESC(IOSR2, iosr2, dcdc_iosr1_ranges),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_SR,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_SR_DESC(MSR, msr, dcdc_iosr1_ranges),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_SR,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_SR_DESC(SDSR1, sdsr1, dcdc_sdsr1_ranges),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_SR,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_SR_DESC(SDSR2, sdsr2, dcdc_iosr1_ranges),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_SR,
+               .regmap = BCM590XX_REGMAP_PRI,
+               .desc = {
+                       BCM590XX_SR_DESC(VSR, vsr, dcdc_iosr1_ranges),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_GPLDO,
+               .regmap = BCM590XX_REGMAP_SEC,
+               .desc = {
+                       BCM590XX_LDO_DESC(GPLDO1, gpldo1, ldo_a_table),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_GPLDO,
+               .regmap = BCM590XX_REGMAP_SEC,
+               .desc = {
+                       BCM590XX_LDO_DESC(GPLDO2, gpldo2, ldo_a_table),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_GPLDO,
+               .regmap = BCM590XX_REGMAP_SEC,
+               .desc = {
+                       BCM590XX_LDO_DESC(GPLDO3, gpldo3, ldo_a_table),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_GPLDO,
+               .regmap = BCM590XX_REGMAP_SEC,
+               .desc = {
+                       BCM590XX_LDO_DESC(GPLDO4, gpldo4, ldo_a_table),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_GPLDO,
+               .regmap = BCM590XX_REGMAP_SEC,
+               .desc = {
+                       BCM590XX_LDO_DESC(GPLDO5, gpldo5, ldo_a_table),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_GPLDO,
+               .regmap = BCM590XX_REGMAP_SEC,
+               .desc = {
+                       BCM590XX_LDO_DESC(GPLDO6, gpldo6, ldo_a_table),
+               },
+       },
+
+       {
+               .type = BCM590XX_REG_TYPE_VBUS,
+               .regmap = BCM590XX_REGMAP_SEC,
+               .desc = {
+                       BCM590XX_REG_DESC(VBUS, vbus),
+                       .ops = &bcm590xx_ops_vbus,
+                       .n_voltages = 1,
+                       .fixed_uV = 5000000,
+                       .enable_reg = BCM590XX_OTG_CTRL,
+                       .enable_mask = BCM590XX_VBUS_ENABLE,
+               },
+       },
+};
+
 static int bcm590xx_probe(struct platform_device *pdev)
 {
        struct bcm590xx *bcm590xx = dev_get_drvdata(pdev->dev.parent);
        struct bcm590xx_reg *pmu;
+       const struct bcm590xx_reg_data *info;
        struct regulator_config config = { };
-       struct bcm590xx_info *info;
        struct regulator_dev *rdev;
-       int i;
+       unsigned int i;
 
        pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL);
        if (!pmu)
                return -ENOMEM;
 
        pmu->mfd = bcm590xx;
+       pmu->n_regulators = BCM590XX_NUM_REGS;
+       pmu->regs = bcm590xx_regs;
 
        platform_set_drvdata(pdev, pmu);
 
-       pmu->desc = devm_kcalloc(&pdev->dev,
-                                BCM590XX_NUM_REGS,
-                                sizeof(struct regulator_desc),
-                                GFP_KERNEL);
-       if (!pmu->desc)
-               return -ENOMEM;
-
-       info = bcm590xx_regs;
-
-       for (i = 0; i < BCM590XX_NUM_REGS; i++, info++) {
-               /* Register the regulators */
-               pmu->desc[i].name = info->name;
-               pmu->desc[i].of_match = of_match_ptr(info->name);
-               pmu->desc[i].regulators_node = of_match_ptr("regulators");
-               pmu->desc[i].supply_name = info->vin_name;
-               pmu->desc[i].id = i;
-               pmu->desc[i].volt_table = info->volt_table;
-               pmu->desc[i].n_voltages = info->n_voltages;
-               pmu->desc[i].linear_ranges = info->linear_ranges;
-               pmu->desc[i].n_linear_ranges = info->n_linear_ranges;
-
-               if ((BCM590XX_REG_IS_LDO(i)) || (BCM590XX_REG_IS_GPLDO(i))) {
-                       pmu->desc[i].ops = &bcm590xx_ops_ldo;
-                       pmu->desc[i].vsel_mask = BCM590XX_LDO_VSEL_MASK;
-               } else if (BCM590XX_REG_IS_VBUS(i))
-                       pmu->desc[i].ops = &bcm590xx_ops_vbus;
-               else {
-                       pmu->desc[i].ops = &bcm590xx_ops_dcdc;
-                       pmu->desc[i].vsel_mask = BCM590XX_SR_VSEL_MASK;
-               }
-
-               if (BCM590XX_REG_IS_VBUS(i))
-                       pmu->desc[i].enable_mask = BCM590XX_VBUS_ENABLE;
-               else {
-                       pmu->desc[i].vsel_reg = bcm590xx_get_vsel_register(i);
-                       pmu->desc[i].enable_is_inverted = true;
-                       pmu->desc[i].enable_mask = BCM590XX_REG_ENABLE;
-               }
-               pmu->desc[i].enable_reg = bcm590xx_get_enable_register(i);
-               pmu->desc[i].type = REGULATOR_VOLTAGE;
-               pmu->desc[i].owner = THIS_MODULE;
+       /* Register the regulators */
+       for (i = 0; i < pmu->n_regulators; i++) {
+               info = &pmu->regs[i];
 
                config.dev = bcm590xx->dev;
                config.driver_data = pmu;
-               if (BCM590XX_REG_IS_GPLDO(i) || BCM590XX_REG_IS_VBUS(i))
-                       config.regmap = bcm590xx->regmap_sec;
-               else
+
+               switch (info->regmap) {
+               case BCM590XX_REGMAP_PRI:
                        config.regmap = bcm590xx->regmap_pri;
+                       break;
+               case BCM590XX_REGMAP_SEC:
+                       config.regmap = bcm590xx->regmap_sec;
+                       break;
+               default:
+                       dev_err(bcm590xx->dev,
+                               "invalid regmap for %s regulator; this is a driver bug\n",
+                               pdev->name);
+                       return -EINVAL;
+               }
 
-               rdev = devm_regulator_register(&pdev->dev, &pmu->desc[i],
+               rdev = devm_regulator_register(&pdev->dev, &info->desc,
                                               &config);
                if (IS_ERR(rdev))
                        return dev_err_probe(bcm590xx->dev, PTR_ERR(rdev),
index a54c50b..09d4ae0 100644 (file)
 #define BCM59056_REV_DIGITAL_B0                2
 #define BCM59056_REV_ANALOG_B0         2
 
+/* regmap types */
+enum bcm590xx_regmap_type {
+       BCM590XX_REGMAP_PRI,
+       BCM590XX_REGMAP_SEC,
+};
+
 /* max register address */
 #define BCM590XX_MAX_REGISTER_PRI      0xe7
 #define BCM590XX_MAX_REGISTER_SEC      0xf0