Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mfd: adp5585: Refactor how regmap defaults are handled

The only thing changing between variants is the regmap default
registers. Hence, instead of having a regmap configuration for every
variant (duplicating lots of fields), add a chip info type of structure
with a regmap ID to identify which defaults to use and populate
regmap_config at runtime given a template plus the id. Also note that
between variants, the defaults can be the same which means the chip info
structure can be used in more than one compatible.

This will also make it simpler adding new chips with more variants.

Also note that the chip info structures are deliberately not const as
they will also contain lots of members that are the same between the
different devices variants and so we will fill those at runtime.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
Link: https://lore.kernel.org/r/20250701-dev-adp5589-fw-v7-6-b1fcfe9e9826@analog.com
Signed-off-by: Lee Jones <lee@kernel.org>

authored by

Nuno Sá and committed by
Lee Jones
1a4eabf6 e65e2b0d

+52 -39
+41 -39
drivers/mfd/adp5585.c
··· 81 81 /* 0x38 */ 0x00, 0x00, 0x00, 0x00, 0x00, 82 82 }; 83 83 84 - enum adp5585_regmap_type { 85 - ADP5585_REGMAP_00, 86 - ADP5585_REGMAP_02, 87 - ADP5585_REGMAP_04, 84 + static const u8 *adp5585_regmap_defaults[ADP5585_MAX] = { 85 + [ADP5585_00] = adp5585_regmap_defaults_00, 86 + [ADP5585_01] = adp5585_regmap_defaults_00, 87 + [ADP5585_02] = adp5585_regmap_defaults_02, 88 + [ADP5585_03] = adp5585_regmap_defaults_00, 89 + [ADP5585_04] = adp5585_regmap_defaults_04, 88 90 }; 89 91 90 - static const struct regmap_config adp5585_regmap_configs[] = { 91 - [ADP5585_REGMAP_00] = { 92 - .reg_bits = 8, 93 - .val_bits = 8, 94 - .max_register = ADP5585_MAX_REG, 95 - .volatile_table = &adp5585_volatile_regs, 96 - .cache_type = REGCACHE_MAPLE, 97 - .reg_defaults_raw = adp5585_regmap_defaults_00, 98 - .num_reg_defaults_raw = sizeof(adp5585_regmap_defaults_00), 99 - }, 100 - [ADP5585_REGMAP_02] = { 101 - .reg_bits = 8, 102 - .val_bits = 8, 103 - .max_register = ADP5585_MAX_REG, 104 - .volatile_table = &adp5585_volatile_regs, 105 - .cache_type = REGCACHE_MAPLE, 106 - .reg_defaults_raw = adp5585_regmap_defaults_02, 107 - .num_reg_defaults_raw = sizeof(adp5585_regmap_defaults_02), 108 - }, 109 - [ADP5585_REGMAP_04] = { 110 - .reg_bits = 8, 111 - .val_bits = 8, 112 - .max_register = ADP5585_MAX_REG, 113 - .volatile_table = &adp5585_volatile_regs, 114 - .cache_type = REGCACHE_MAPLE, 115 - .reg_defaults_raw = adp5585_regmap_defaults_04, 116 - .num_reg_defaults_raw = sizeof(adp5585_regmap_defaults_04), 117 - }, 92 + static const struct regmap_config adp5585_regmap_config_template = { 93 + .reg_bits = 8, 94 + .val_bits = 8, 95 + .max_register = ADP5585_MAX_REG, 96 + .volatile_table = &adp5585_volatile_regs, 97 + .cache_type = REGCACHE_MAPLE, 98 + .num_reg_defaults_raw = ADP5585_MAX_REG + 1, 118 99 }; 100 + 101 + static struct regmap_config *adp5585_fill_regmap_config(const struct adp5585_dev *adp5585) 102 + { 103 + struct regmap_config *regmap_config; 104 + 105 + regmap_config = devm_kmemdup(adp5585->dev, &adp5585_regmap_config_template, 106 + sizeof(*regmap_config), GFP_KERNEL); 107 + if (!regmap_config) 108 + return ERR_PTR(-ENOMEM); 109 + 110 + regmap_config->reg_defaults_raw = adp5585_regmap_defaults[adp5585->variant]; 111 + return regmap_config; 112 + } 119 113 120 114 static int adp5585_add_devices(struct device *dev) 121 115 { ··· 141 147 142 148 static int adp5585_i2c_probe(struct i2c_client *i2c) 143 149 { 144 - const struct regmap_config *regmap_config; 150 + struct regmap_config *regmap_config; 145 151 struct adp5585_dev *adp5585; 146 152 unsigned int id; 147 153 int ret; ··· 151 157 return -ENOMEM; 152 158 153 159 i2c_set_clientdata(i2c, adp5585); 160 + adp5585->dev = &i2c->dev; 154 161 155 - regmap_config = i2c_get_match_data(i2c); 162 + adp5585->variant = (enum adp5585_variant)(uintptr_t)i2c_get_match_data(i2c); 163 + if (!adp5585->variant) 164 + return -ENODEV; 165 + 166 + regmap_config = adp5585_fill_regmap_config(adp5585); 167 + if (IS_ERR(regmap_config)) 168 + return PTR_ERR(regmap_config); 169 + 156 170 adp5585->regmap = devm_regmap_init_i2c(i2c, regmap_config); 157 171 if (IS_ERR(adp5585->regmap)) 158 172 return dev_err_probe(&i2c->dev, PTR_ERR(adp5585->regmap), ··· 214 212 static const struct of_device_id adp5585_of_match[] = { 215 213 { 216 214 .compatible = "adi,adp5585-00", 217 - .data = &adp5585_regmap_configs[ADP5585_REGMAP_00], 215 + .data = (void *)ADP5585_00, 218 216 }, { 219 217 .compatible = "adi,adp5585-01", 220 - .data = &adp5585_regmap_configs[ADP5585_REGMAP_00], 218 + .data = (void *)ADP5585_01, 221 219 }, { 222 220 .compatible = "adi,adp5585-02", 223 - .data = &adp5585_regmap_configs[ADP5585_REGMAP_02], 221 + .data = (void *)ADP5585_02, 224 222 }, { 225 223 .compatible = "adi,adp5585-03", 226 - .data = &adp5585_regmap_configs[ADP5585_REGMAP_00], 224 + .data = (void *)ADP5585_03, 227 225 }, { 228 226 .compatible = "adi,adp5585-04", 229 - .data = &adp5585_regmap_configs[ADP5585_REGMAP_04], 227 + .data = (void *)ADP5585_04, 230 228 }, 231 229 { /* sentinel */ } 232 230 };
+11
include/linux/mfd/adp5585.h
··· 119 119 120 120 struct regmap; 121 121 122 + enum adp5585_variant { 123 + ADP5585_00 = 1, 124 + ADP5585_01, 125 + ADP5585_02, 126 + ADP5585_03, 127 + ADP5585_04, 128 + ADP5585_MAX 129 + }; 130 + 122 131 struct adp5585_dev { 132 + struct device *dev; 123 133 struct regmap *regmap; 134 + enum adp5585_variant variant; 124 135 }; 125 136 126 137 #endif