diff options
author | Jonghwa Lee <jonghwa3.lee@samsung.com> | 2013-10-25 00:55:02 -0400 |
---|---|---|
committer | Anton Vorontsov <anton@enomsg.org> | 2013-10-25 19:54:33 -0400 |
commit | 39e7213edc4f31b0650dcc5630e175a6bd278b9b (patch) | |
tree | b824d3bb6c4ff30afe384936038da0ce04a07017 /drivers/power/max17042_battery.c | |
parent | 3d23c7f457ed86f27425cb3f229b76720855a26d (diff) |
max17042_battery: Support regmap to access device's registers
This patch makes max17042 fuelguage driver uses regmap API to access its
device's registers.
Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
Signed-off-by: Myungjoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Anton Vorontsov <anton@enomsg.org>
Diffstat (limited to 'drivers/power/max17042_battery.c')
-rw-r--r-- | drivers/power/max17042_battery.c | 357 |
1 files changed, 174 insertions, 183 deletions
diff --git a/drivers/power/max17042_battery.c b/drivers/power/max17042_battery.c index bd72b0f7f729..e0b22f9b6fdd 100644 --- a/drivers/power/max17042_battery.c +++ b/drivers/power/max17042_battery.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/power_supply.h> | 33 | #include <linux/power_supply.h> |
34 | #include <linux/power/max17042_battery.h> | 34 | #include <linux/power/max17042_battery.h> |
35 | #include <linux/of.h> | 35 | #include <linux/of.h> |
36 | #include <linux/regmap.h> | ||
36 | 37 | ||
37 | /* Status register bits */ | 38 | /* Status register bits */ |
38 | #define STATUS_POR_BIT (1 << 1) | 39 | #define STATUS_POR_BIT (1 << 1) |
@@ -67,6 +68,7 @@ | |||
67 | 68 | ||
68 | struct max17042_chip { | 69 | struct max17042_chip { |
69 | struct i2c_client *client; | 70 | struct i2c_client *client; |
71 | struct regmap *regmap; | ||
70 | struct power_supply battery; | 72 | struct power_supply battery; |
71 | enum max170xx_chip_type chip_type; | 73 | enum max170xx_chip_type chip_type; |
72 | struct max17042_platform_data *pdata; | 74 | struct max17042_platform_data *pdata; |
@@ -74,35 +76,6 @@ struct max17042_chip { | |||
74 | int init_complete; | 76 | int init_complete; |
75 | }; | 77 | }; |
76 | 78 | ||
77 | static int max17042_write_reg(struct i2c_client *client, u8 reg, u16 value) | ||
78 | { | ||
79 | int ret = i2c_smbus_write_word_data(client, reg, value); | ||
80 | |||
81 | if (ret < 0) | ||
82 | dev_err(&client->dev, "%s: err %d\n", __func__, ret); | ||
83 | |||
84 | return ret; | ||
85 | } | ||
86 | |||
87 | static int max17042_read_reg(struct i2c_client *client, u8 reg) | ||
88 | { | ||
89 | int ret = i2c_smbus_read_word_data(client, reg); | ||
90 | |||
91 | if (ret < 0) | ||
92 | dev_err(&client->dev, "%s: err %d\n", __func__, ret); | ||
93 | |||
94 | return ret; | ||
95 | } | ||
96 | |||
97 | static void max17042_set_reg(struct i2c_client *client, | ||
98 | struct max17042_reg_data *data, int size) | ||
99 | { | ||
100 | int i; | ||
101 | |||
102 | for (i = 0; i < size; i++) | ||
103 | max17042_write_reg(client, data[i].addr, data[i].data); | ||
104 | } | ||
105 | |||
106 | static enum power_supply_property max17042_battery_props[] = { | 79 | static enum power_supply_property max17042_battery_props[] = { |
107 | POWER_SUPPLY_PROP_PRESENT, | 80 | POWER_SUPPLY_PROP_PRESENT, |
108 | POWER_SUPPLY_PROP_CYCLE_COUNT, | 81 | POWER_SUPPLY_PROP_CYCLE_COUNT, |
@@ -125,96 +98,98 @@ static int max17042_get_property(struct power_supply *psy, | |||
125 | { | 98 | { |
126 | struct max17042_chip *chip = container_of(psy, | 99 | struct max17042_chip *chip = container_of(psy, |
127 | struct max17042_chip, battery); | 100 | struct max17042_chip, battery); |
101 | struct regmap *map = chip->regmap; | ||
128 | int ret; | 102 | int ret; |
103 | u32 data; | ||
129 | 104 | ||
130 | if (!chip->init_complete) | 105 | if (!chip->init_complete) |
131 | return -EAGAIN; | 106 | return -EAGAIN; |
132 | 107 | ||
133 | switch (psp) { | 108 | switch (psp) { |
134 | case POWER_SUPPLY_PROP_PRESENT: | 109 | case POWER_SUPPLY_PROP_PRESENT: |
135 | ret = max17042_read_reg(chip->client, MAX17042_STATUS); | 110 | ret = regmap_read(map, MAX17042_STATUS, &data); |
136 | if (ret < 0) | 111 | if (ret < 0) |
137 | return ret; | 112 | return ret; |
138 | 113 | ||
139 | if (ret & MAX17042_STATUS_BattAbsent) | 114 | if (data & MAX17042_STATUS_BattAbsent) |
140 | val->intval = 0; | 115 | val->intval = 0; |
141 | else | 116 | else |
142 | val->intval = 1; | 117 | val->intval = 1; |
143 | break; | 118 | break; |
144 | case POWER_SUPPLY_PROP_CYCLE_COUNT: | 119 | case POWER_SUPPLY_PROP_CYCLE_COUNT: |
145 | ret = max17042_read_reg(chip->client, MAX17042_Cycles); | 120 | ret = regmap_read(map, MAX17042_Cycles, &data); |
146 | if (ret < 0) | 121 | if (ret < 0) |
147 | return ret; | 122 | return ret; |
148 | 123 | ||
149 | val->intval = ret; | 124 | val->intval = data; |
150 | break; | 125 | break; |
151 | case POWER_SUPPLY_PROP_VOLTAGE_MAX: | 126 | case POWER_SUPPLY_PROP_VOLTAGE_MAX: |
152 | ret = max17042_read_reg(chip->client, MAX17042_MinMaxVolt); | 127 | ret = regmap_read(map, MAX17042_MinMaxVolt, &data); |
153 | if (ret < 0) | 128 | if (ret < 0) |
154 | return ret; | 129 | return ret; |
155 | 130 | ||
156 | val->intval = ret >> 8; | 131 | val->intval = data >> 8; |
157 | val->intval *= 20000; /* Units of LSB = 20mV */ | 132 | val->intval *= 20000; /* Units of LSB = 20mV */ |
158 | break; | 133 | break; |
159 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: | 134 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: |
160 | if (chip->chip_type == MAX17042) | 135 | if (chip->chip_type == MAX17042) |
161 | ret = max17042_read_reg(chip->client, MAX17042_V_empty); | 136 | ret = regmap_read(map, MAX17042_V_empty, &data); |
162 | else | 137 | else |
163 | ret = max17042_read_reg(chip->client, MAX17047_V_empty); | 138 | ret = regmap_read(map, MAX17047_V_empty, &data); |
164 | if (ret < 0) | 139 | if (ret < 0) |
165 | return ret; | 140 | return ret; |
166 | 141 | ||
167 | val->intval = ret >> 7; | 142 | val->intval = data >> 7; |
168 | val->intval *= 10000; /* Units of LSB = 10mV */ | 143 | val->intval *= 10000; /* Units of LSB = 10mV */ |
169 | break; | 144 | break; |
170 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: | 145 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: |
171 | ret = max17042_read_reg(chip->client, MAX17042_VCELL); | 146 | ret = regmap_read(map, MAX17042_VCELL, &data); |
172 | if (ret < 0) | 147 | if (ret < 0) |
173 | return ret; | 148 | return ret; |
174 | 149 | ||
175 | val->intval = ret * 625 / 8; | 150 | val->intval = data * 625 / 8; |
176 | break; | 151 | break; |
177 | case POWER_SUPPLY_PROP_VOLTAGE_AVG: | 152 | case POWER_SUPPLY_PROP_VOLTAGE_AVG: |
178 | ret = max17042_read_reg(chip->client, MAX17042_AvgVCELL); | 153 | ret = regmap_read(map, MAX17042_AvgVCELL, &data); |
179 | if (ret < 0) | 154 | if (ret < 0) |
180 | return ret; | 155 | return ret; |
181 | 156 | ||
182 | val->intval = ret * 625 / 8; | 157 | val->intval = data * 625 / 8; |
183 | break; | 158 | break; |
184 | case POWER_SUPPLY_PROP_VOLTAGE_OCV: | 159 | case POWER_SUPPLY_PROP_VOLTAGE_OCV: |
185 | ret = max17042_read_reg(chip->client, MAX17042_OCVInternal); | 160 | ret = regmap_read(map, MAX17042_OCVInternal, &data); |
186 | if (ret < 0) | 161 | if (ret < 0) |
187 | return ret; | 162 | return ret; |
188 | 163 | ||
189 | val->intval = ret * 625 / 8; | 164 | val->intval = data * 625 / 8; |
190 | break; | 165 | break; |
191 | case POWER_SUPPLY_PROP_CAPACITY: | 166 | case POWER_SUPPLY_PROP_CAPACITY: |
192 | ret = max17042_read_reg(chip->client, MAX17042_RepSOC); | 167 | ret = regmap_read(map, MAX17042_RepSOC, &data); |
193 | if (ret < 0) | 168 | if (ret < 0) |
194 | return ret; | 169 | return ret; |
195 | 170 | ||
196 | val->intval = ret >> 8; | 171 | val->intval = data >> 8; |
197 | break; | 172 | break; |
198 | case POWER_SUPPLY_PROP_CHARGE_FULL: | 173 | case POWER_SUPPLY_PROP_CHARGE_FULL: |
199 | ret = max17042_read_reg(chip->client, MAX17042_FullCAP); | 174 | ret = regmap_read(map, MAX17042_FullCAP, &data); |
200 | if (ret < 0) | 175 | if (ret < 0) |
201 | return ret; | 176 | return ret; |
202 | 177 | ||
203 | val->intval = ret * 1000 / 2; | 178 | val->intval = data * 1000 / 2; |
204 | break; | 179 | break; |
205 | case POWER_SUPPLY_PROP_CHARGE_COUNTER: | 180 | case POWER_SUPPLY_PROP_CHARGE_COUNTER: |
206 | ret = max17042_read_reg(chip->client, MAX17042_QH); | 181 | ret = regmap_read(map, MAX17042_QH, &data); |
207 | if (ret < 0) | 182 | if (ret < 0) |
208 | return ret; | 183 | return ret; |
209 | 184 | ||
210 | val->intval = ret * 1000 / 2; | 185 | val->intval = data * 1000 / 2; |
211 | break; | 186 | break; |
212 | case POWER_SUPPLY_PROP_TEMP: | 187 | case POWER_SUPPLY_PROP_TEMP: |
213 | ret = max17042_read_reg(chip->client, MAX17042_TEMP); | 188 | ret = regmap_read(map, MAX17042_TEMP, &data); |
214 | if (ret < 0) | 189 | if (ret < 0) |
215 | return ret; | 190 | return ret; |
216 | 191 | ||
217 | val->intval = ret; | 192 | val->intval = data; |
218 | /* The value is signed. */ | 193 | /* The value is signed. */ |
219 | if (val->intval & 0x8000) { | 194 | if (val->intval & 0x8000) { |
220 | val->intval = (0x7fff & ~val->intval) + 1; | 195 | val->intval = (0x7fff & ~val->intval) + 1; |
@@ -226,11 +201,11 @@ static int max17042_get_property(struct power_supply *psy, | |||
226 | break; | 201 | break; |
227 | case POWER_SUPPLY_PROP_CURRENT_NOW: | 202 | case POWER_SUPPLY_PROP_CURRENT_NOW: |
228 | if (chip->pdata->enable_current_sense) { | 203 | if (chip->pdata->enable_current_sense) { |
229 | ret = max17042_read_reg(chip->client, MAX17042_Current); | 204 | ret = regmap_read(map, MAX17042_Current, &data); |
230 | if (ret < 0) | 205 | if (ret < 0) |
231 | return ret; | 206 | return ret; |
232 | 207 | ||
233 | val->intval = ret; | 208 | val->intval = data; |
234 | if (val->intval & 0x8000) { | 209 | if (val->intval & 0x8000) { |
235 | /* Negative */ | 210 | /* Negative */ |
236 | val->intval = ~val->intval & 0x7fff; | 211 | val->intval = ~val->intval & 0x7fff; |
@@ -244,12 +219,11 @@ static int max17042_get_property(struct power_supply *psy, | |||
244 | break; | 219 | break; |
245 | case POWER_SUPPLY_PROP_CURRENT_AVG: | 220 | case POWER_SUPPLY_PROP_CURRENT_AVG: |
246 | if (chip->pdata->enable_current_sense) { | 221 | if (chip->pdata->enable_current_sense) { |
247 | ret = max17042_read_reg(chip->client, | 222 | ret = regmap_read(map, MAX17042_AvgCurrent, &data); |
248 | MAX17042_AvgCurrent); | ||
249 | if (ret < 0) | 223 | if (ret < 0) |
250 | return ret; | 224 | return ret; |
251 | 225 | ||
252 | val->intval = ret; | 226 | val->intval = data; |
253 | if (val->intval & 0x8000) { | 227 | if (val->intval & 0x8000) { |
254 | /* Negative */ | 228 | /* Negative */ |
255 | val->intval = ~val->intval & 0x7fff; | 229 | val->intval = ~val->intval & 0x7fff; |
@@ -267,16 +241,15 @@ static int max17042_get_property(struct power_supply *psy, | |||
267 | return 0; | 241 | return 0; |
268 | } | 242 | } |
269 | 243 | ||
270 | static int max17042_write_verify_reg(struct i2c_client *client, | 244 | static int max17042_write_verify_reg(struct regmap *map, u8 reg, u32 value) |
271 | u8 reg, u16 value) | ||
272 | { | 245 | { |
273 | int retries = 8; | 246 | int retries = 8; |
274 | int ret; | 247 | int ret; |
275 | u16 read_value; | 248 | u32 read_value; |
276 | 249 | ||
277 | do { | 250 | do { |
278 | ret = i2c_smbus_write_word_data(client, reg, value); | 251 | ret = regmap_write(map, reg, value); |
279 | read_value = max17042_read_reg(client, reg); | 252 | regmap_read(map, reg, &read_value); |
280 | if (read_value != value) { | 253 | if (read_value != value) { |
281 | ret = -EIO; | 254 | ret = -EIO; |
282 | retries--; | 255 | retries--; |
@@ -284,50 +257,51 @@ static int max17042_write_verify_reg(struct i2c_client *client, | |||
284 | } while (retries && read_value != value); | 257 | } while (retries && read_value != value); |
285 | 258 | ||
286 | if (ret < 0) | 259 | if (ret < 0) |
287 | dev_err(&client->dev, "%s: err %d\n", __func__, ret); | 260 | pr_err("%s: err %d\n", __func__, ret); |
288 | 261 | ||
289 | return ret; | 262 | return ret; |
290 | } | 263 | } |
291 | 264 | ||
292 | static inline void max17042_override_por( | 265 | static inline void max17042_override_por(struct regmap *map, |
293 | struct i2c_client *client, u8 reg, u16 value) | 266 | u8 reg, u16 value) |
294 | { | 267 | { |
295 | if (value) | 268 | if (value) |
296 | max17042_write_reg(client, reg, value); | 269 | regmap_write(map, reg, value); |
297 | } | 270 | } |
298 | 271 | ||
299 | static inline void max10742_unlock_model(struct max17042_chip *chip) | 272 | static inline void max10742_unlock_model(struct max17042_chip *chip) |
300 | { | 273 | { |
301 | struct i2c_client *client = chip->client; | 274 | struct regmap *map = chip->regmap; |
302 | max17042_write_reg(client, MAX17042_MLOCKReg1, MODEL_UNLOCK1); | 275 | regmap_write(map, MAX17042_MLOCKReg1, MODEL_UNLOCK1); |
303 | max17042_write_reg(client, MAX17042_MLOCKReg2, MODEL_UNLOCK2); | 276 | regmap_write(map, MAX17042_MLOCKReg2, MODEL_UNLOCK2); |
304 | } | 277 | } |
305 | 278 | ||
306 | static inline void max10742_lock_model(struct max17042_chip *chip) | 279 | static inline void max10742_lock_model(struct max17042_chip *chip) |
307 | { | 280 | { |
308 | struct i2c_client *client = chip->client; | 281 | struct regmap *map = chip->regmap; |
309 | max17042_write_reg(client, MAX17042_MLOCKReg1, MODEL_LOCK1); | 282 | |
310 | max17042_write_reg(client, MAX17042_MLOCKReg2, MODEL_LOCK2); | 283 | regmap_write(map, MAX17042_MLOCKReg1, MODEL_LOCK1); |
284 | regmap_write(map, MAX17042_MLOCKReg2, MODEL_LOCK2); | ||
311 | } | 285 | } |
312 | 286 | ||
313 | static inline void max17042_write_model_data(struct max17042_chip *chip, | 287 | static inline void max17042_write_model_data(struct max17042_chip *chip, |
314 | u8 addr, int size) | 288 | u8 addr, int size) |
315 | { | 289 | { |
316 | struct i2c_client *client = chip->client; | 290 | struct regmap *map = chip->regmap; |
317 | int i; | 291 | int i; |
318 | for (i = 0; i < size; i++) | 292 | for (i = 0; i < size; i++) |
319 | max17042_write_reg(client, addr + i, | 293 | regmap_write(map, addr + i, |
320 | chip->pdata->config_data->cell_char_tbl[i]); | 294 | chip->pdata->config_data->cell_char_tbl[i]); |
321 | } | 295 | } |
322 | 296 | ||
323 | static inline void max17042_read_model_data(struct max17042_chip *chip, | 297 | static inline void max17042_read_model_data(struct max17042_chip *chip, |
324 | u8 addr, u16 *data, int size) | 298 | u8 addr, u32 *data, int size) |
325 | { | 299 | { |
326 | struct i2c_client *client = chip->client; | 300 | struct regmap *map = chip->regmap; |
327 | int i; | 301 | int i; |
328 | 302 | ||
329 | for (i = 0; i < size; i++) | 303 | for (i = 0; i < size; i++) |
330 | data[i] = max17042_read_reg(client, addr + i); | 304 | regmap_read(map, addr + i, &data[i]); |
331 | } | 305 | } |
332 | 306 | ||
333 | static inline int max17042_model_data_compare(struct max17042_chip *chip, | 307 | static inline int max17042_model_data_compare(struct max17042_chip *chip, |
@@ -350,7 +324,7 @@ static int max17042_init_model(struct max17042_chip *chip) | |||
350 | { | 324 | { |
351 | int ret; | 325 | int ret; |
352 | int table_size = ARRAY_SIZE(chip->pdata->config_data->cell_char_tbl); | 326 | int table_size = ARRAY_SIZE(chip->pdata->config_data->cell_char_tbl); |
353 | u16 *temp_data; | 327 | u32 *temp_data; |
354 | 328 | ||
355 | temp_data = kcalloc(table_size, sizeof(*temp_data), GFP_KERNEL); | 329 | temp_data = kcalloc(table_size, sizeof(*temp_data), GFP_KERNEL); |
356 | if (!temp_data) | 330 | if (!temp_data) |
@@ -365,7 +339,7 @@ static int max17042_init_model(struct max17042_chip *chip) | |||
365 | ret = max17042_model_data_compare( | 339 | ret = max17042_model_data_compare( |
366 | chip, | 340 | chip, |
367 | chip->pdata->config_data->cell_char_tbl, | 341 | chip->pdata->config_data->cell_char_tbl, |
368 | temp_data, | 342 | (u16 *)temp_data, |
369 | table_size); | 343 | table_size); |
370 | 344 | ||
371 | max10742_lock_model(chip); | 345 | max10742_lock_model(chip); |
@@ -378,7 +352,7 @@ static int max17042_verify_model_lock(struct max17042_chip *chip) | |||
378 | { | 352 | { |
379 | int i; | 353 | int i; |
380 | int table_size = ARRAY_SIZE(chip->pdata->config_data->cell_char_tbl); | 354 | int table_size = ARRAY_SIZE(chip->pdata->config_data->cell_char_tbl); |
381 | u16 *temp_data; | 355 | u32 *temp_data; |
382 | int ret = 0; | 356 | int ret = 0; |
383 | 357 | ||
384 | temp_data = kcalloc(table_size, sizeof(*temp_data), GFP_KERNEL); | 358 | temp_data = kcalloc(table_size, sizeof(*temp_data), GFP_KERNEL); |
@@ -398,40 +372,38 @@ static int max17042_verify_model_lock(struct max17042_chip *chip) | |||
398 | static void max17042_write_config_regs(struct max17042_chip *chip) | 372 | static void max17042_write_config_regs(struct max17042_chip *chip) |
399 | { | 373 | { |
400 | struct max17042_config_data *config = chip->pdata->config_data; | 374 | struct max17042_config_data *config = chip->pdata->config_data; |
375 | struct regmap *map = chip->regmap; | ||
401 | 376 | ||
402 | max17042_write_reg(chip->client, MAX17042_CONFIG, config->config); | 377 | regmap_write(map, MAX17042_CONFIG, config->config); |
403 | max17042_write_reg(chip->client, MAX17042_LearnCFG, config->learn_cfg); | 378 | regmap_write(map, MAX17042_LearnCFG, config->learn_cfg); |
404 | max17042_write_reg(chip->client, MAX17042_FilterCFG, | 379 | regmap_write(map, MAX17042_FilterCFG, |
405 | config->filter_cfg); | 380 | config->filter_cfg); |
406 | max17042_write_reg(chip->client, MAX17042_RelaxCFG, config->relax_cfg); | 381 | regmap_write(map, MAX17042_RelaxCFG, config->relax_cfg); |
407 | if (chip->chip_type == MAX17047) | 382 | if (chip->chip_type == MAX17047) |
408 | max17042_write_reg(chip->client, MAX17047_FullSOCThr, | 383 | regmap_write(map, MAX17047_FullSOCThr, |
409 | config->full_soc_thresh); | 384 | config->full_soc_thresh); |
410 | } | 385 | } |
411 | 386 | ||
412 | static void max17042_write_custom_regs(struct max17042_chip *chip) | 387 | static void max17042_write_custom_regs(struct max17042_chip *chip) |
413 | { | 388 | { |
414 | struct max17042_config_data *config = chip->pdata->config_data; | 389 | struct max17042_config_data *config = chip->pdata->config_data; |
390 | struct regmap *map = chip->regmap; | ||
415 | 391 | ||
416 | max17042_write_verify_reg(chip->client, MAX17042_RCOMP0, | 392 | max17042_write_verify_reg(map, MAX17042_RCOMP0, config->rcomp0); |
417 | config->rcomp0); | 393 | max17042_write_verify_reg(map, MAX17042_TempCo, config->tcompc0); |
418 | max17042_write_verify_reg(chip->client, MAX17042_TempCo, | 394 | max17042_write_verify_reg(map, MAX17042_ICHGTerm, config->ichgt_term); |
419 | config->tcompc0); | ||
420 | max17042_write_verify_reg(chip->client, MAX17042_ICHGTerm, | ||
421 | config->ichgt_term); | ||
422 | if (chip->chip_type == MAX17042) { | 395 | if (chip->chip_type == MAX17042) { |
423 | max17042_write_reg(chip->client, MAX17042_EmptyTempCo, | 396 | regmap_write(map, MAX17042_EmptyTempCo, config->empty_tempco); |
424 | config->empty_tempco); | 397 | max17042_write_verify_reg(map, MAX17042_K_empty0, |
425 | max17042_write_verify_reg(chip->client, MAX17042_K_empty0, | ||
426 | config->kempty0); | 398 | config->kempty0); |
427 | } else { | 399 | } else { |
428 | max17042_write_verify_reg(chip->client, MAX17047_QRTbl00, | 400 | max17042_write_verify_reg(map, MAX17047_QRTbl00, |
429 | config->qrtbl00); | 401 | config->qrtbl00); |
430 | max17042_write_verify_reg(chip->client, MAX17047_QRTbl10, | 402 | max17042_write_verify_reg(map, MAX17047_QRTbl10, |
431 | config->qrtbl10); | 403 | config->qrtbl10); |
432 | max17042_write_verify_reg(chip->client, MAX17047_QRTbl20, | 404 | max17042_write_verify_reg(map, MAX17047_QRTbl20, |
433 | config->qrtbl20); | 405 | config->qrtbl20); |
434 | max17042_write_verify_reg(chip->client, MAX17047_QRTbl30, | 406 | max17042_write_verify_reg(map, MAX17047_QRTbl30, |
435 | config->qrtbl30); | 407 | config->qrtbl30); |
436 | } | 408 | } |
437 | } | 409 | } |
@@ -439,58 +411,60 @@ static void max17042_write_custom_regs(struct max17042_chip *chip) | |||
439 | static void max17042_update_capacity_regs(struct max17042_chip *chip) | 411 | static void max17042_update_capacity_regs(struct max17042_chip *chip) |
440 | { | 412 | { |
441 | struct max17042_config_data *config = chip->pdata->config_data; | 413 | struct max17042_config_data *config = chip->pdata->config_data; |
414 | struct regmap *map = chip->regmap; | ||
442 | 415 | ||
443 | max17042_write_verify_reg(chip->client, MAX17042_FullCAP, | 416 | max17042_write_verify_reg(map, MAX17042_FullCAP, |
444 | config->fullcap); | 417 | config->fullcap); |
445 | max17042_write_reg(chip->client, MAX17042_DesignCap, | 418 | regmap_write(map, MAX17042_DesignCap, config->design_cap); |
446 | config->design_cap); | 419 | max17042_write_verify_reg(map, MAX17042_FullCAPNom, |
447 | max17042_write_verify_reg(chip->client, MAX17042_FullCAPNom, | ||
448 | config->fullcapnom); | 420 | config->fullcapnom); |
449 | } | 421 | } |
450 | 422 | ||
451 | static void max17042_reset_vfsoc0_reg(struct max17042_chip *chip) | 423 | static void max17042_reset_vfsoc0_reg(struct max17042_chip *chip) |
452 | { | 424 | { |
453 | u16 vfSoc; | 425 | unsigned int vfSoc; |
426 | struct regmap *map = chip->regmap; | ||
454 | 427 | ||
455 | vfSoc = max17042_read_reg(chip->client, MAX17042_VFSOC); | 428 | regmap_read(map, MAX17042_VFSOC, &vfSoc); |
456 | max17042_write_reg(chip->client, MAX17042_VFSOC0Enable, VFSOC0_UNLOCK); | 429 | regmap_write(map, MAX17042_VFSOC0Enable, VFSOC0_UNLOCK); |
457 | max17042_write_verify_reg(chip->client, MAX17042_VFSOC0, vfSoc); | 430 | max17042_write_verify_reg(map, MAX17042_VFSOC0, vfSoc); |
458 | max17042_write_reg(chip->client, MAX17042_VFSOC0Enable, VFSOC0_LOCK); | 431 | regmap_write(map, MAX17042_VFSOC0Enable, VFSOC0_LOCK); |
459 | } | 432 | } |
460 | 433 | ||
461 | static void max17042_load_new_capacity_params(struct max17042_chip *chip) | 434 | static void max17042_load_new_capacity_params(struct max17042_chip *chip) |
462 | { | 435 | { |
463 | u16 full_cap0, rep_cap, dq_acc, vfSoc; | 436 | u32 full_cap0, rep_cap, dq_acc, vfSoc; |
464 | u32 rem_cap; | 437 | u32 rem_cap; |
465 | 438 | ||
466 | struct max17042_config_data *config = chip->pdata->config_data; | 439 | struct max17042_config_data *config = chip->pdata->config_data; |
440 | struct regmap *map = chip->regmap; | ||
467 | 441 | ||
468 | full_cap0 = max17042_read_reg(chip->client, MAX17042_FullCAP0); | 442 | regmap_read(map, MAX17042_FullCAP0, &full_cap0); |
469 | vfSoc = max17042_read_reg(chip->client, MAX17042_VFSOC); | 443 | regmap_read(map, MAX17042_VFSOC, &vfSoc); |
470 | 444 | ||
471 | /* fg_vfSoc needs to shifted by 8 bits to get the | 445 | /* fg_vfSoc needs to shifted by 8 bits to get the |
472 | * perc in 1% accuracy, to get the right rem_cap multiply | 446 | * perc in 1% accuracy, to get the right rem_cap multiply |
473 | * full_cap0, fg_vfSoc and devide by 100 | 447 | * full_cap0, fg_vfSoc and devide by 100 |
474 | */ | 448 | */ |
475 | rem_cap = ((vfSoc >> 8) * full_cap0) / 100; | 449 | rem_cap = ((vfSoc >> 8) * full_cap0) / 100; |
476 | max17042_write_verify_reg(chip->client, MAX17042_RemCap, (u16)rem_cap); | 450 | max17042_write_verify_reg(map, MAX17042_RemCap, rem_cap); |
477 | 451 | ||
478 | rep_cap = (u16)rem_cap; | 452 | rep_cap = rem_cap; |
479 | max17042_write_verify_reg(chip->client, MAX17042_RepCap, rep_cap); | 453 | max17042_write_verify_reg(map, MAX17042_RepCap, rep_cap); |
480 | 454 | ||
481 | /* Write dQ_acc to 200% of Capacity and dP_acc to 200% */ | 455 | /* Write dQ_acc to 200% of Capacity and dP_acc to 200% */ |
482 | dq_acc = config->fullcap / dQ_ACC_DIV; | 456 | dq_acc = config->fullcap / dQ_ACC_DIV; |
483 | max17042_write_verify_reg(chip->client, MAX17042_dQacc, dq_acc); | 457 | max17042_write_verify_reg(map, MAX17042_dQacc, dq_acc); |
484 | max17042_write_verify_reg(chip->client, MAX17042_dPacc, dP_ACC_200); | 458 | max17042_write_verify_reg(map, MAX17042_dPacc, dP_ACC_200); |
485 | 459 | ||
486 | max17042_write_verify_reg(chip->client, MAX17042_FullCAP, | 460 | max17042_write_verify_reg(map, MAX17042_FullCAP, |
487 | config->fullcap); | 461 | config->fullcap); |
488 | max17042_write_reg(chip->client, MAX17042_DesignCap, | 462 | regmap_write(map, MAX17042_DesignCap, |
489 | config->design_cap); | 463 | config->design_cap); |
490 | max17042_write_verify_reg(chip->client, MAX17042_FullCAPNom, | 464 | max17042_write_verify_reg(map, MAX17042_FullCAPNom, |
491 | config->fullcapnom); | 465 | config->fullcapnom); |
492 | /* Update SOC register with new SOC */ | 466 | /* Update SOC register with new SOC */ |
493 | max17042_write_reg(chip->client, MAX17042_RepSOC, vfSoc); | 467 | regmap_write(map, MAX17042_RepSOC, vfSoc); |
494 | } | 468 | } |
495 | 469 | ||
496 | /* | 470 | /* |
@@ -500,59 +474,60 @@ static void max17042_load_new_capacity_params(struct max17042_chip *chip) | |||
500 | */ | 474 | */ |
501 | static inline void max17042_override_por_values(struct max17042_chip *chip) | 475 | static inline void max17042_override_por_values(struct max17042_chip *chip) |
502 | { | 476 | { |
503 | struct i2c_client *client = chip->client; | 477 | struct regmap *map = chip->regmap; |
504 | struct max17042_config_data *config = chip->pdata->config_data; | 478 | struct max17042_config_data *config = chip->pdata->config_data; |
505 | 479 | ||
506 | max17042_override_por(client, MAX17042_TGAIN, config->tgain); | 480 | max17042_override_por(map, MAX17042_TGAIN, config->tgain); |
507 | max17042_override_por(client, MAx17042_TOFF, config->toff); | 481 | max17042_override_por(map, MAx17042_TOFF, config->toff); |
508 | max17042_override_por(client, MAX17042_CGAIN, config->cgain); | 482 | max17042_override_por(map, MAX17042_CGAIN, config->cgain); |
509 | max17042_override_por(client, MAX17042_COFF, config->coff); | 483 | max17042_override_por(map, MAX17042_COFF, config->coff); |
510 | 484 | ||
511 | max17042_override_por(client, MAX17042_VALRT_Th, config->valrt_thresh); | 485 | max17042_override_por(map, MAX17042_VALRT_Th, config->valrt_thresh); |
512 | max17042_override_por(client, MAX17042_TALRT_Th, config->talrt_thresh); | 486 | max17042_override_por(map, MAX17042_TALRT_Th, config->talrt_thresh); |
513 | max17042_override_por(client, MAX17042_SALRT_Th, | 487 | max17042_override_por(map, MAX17042_SALRT_Th, |
514 | config->soc_alrt_thresh); | 488 | config->soc_alrt_thresh); |
515 | max17042_override_por(client, MAX17042_CONFIG, config->config); | 489 | max17042_override_por(map, MAX17042_CONFIG, config->config); |
516 | max17042_override_por(client, MAX17042_SHDNTIMER, config->shdntimer); | 490 | max17042_override_por(map, MAX17042_SHDNTIMER, config->shdntimer); |
517 | 491 | ||
518 | max17042_override_por(client, MAX17042_DesignCap, config->design_cap); | 492 | max17042_override_por(map, MAX17042_DesignCap, config->design_cap); |
519 | max17042_override_por(client, MAX17042_ICHGTerm, config->ichgt_term); | 493 | max17042_override_por(map, MAX17042_ICHGTerm, config->ichgt_term); |
520 | 494 | ||
521 | max17042_override_por(client, MAX17042_AtRate, config->at_rate); | 495 | max17042_override_por(map, MAX17042_AtRate, config->at_rate); |
522 | max17042_override_por(client, MAX17042_LearnCFG, config->learn_cfg); | 496 | max17042_override_por(map, MAX17042_LearnCFG, config->learn_cfg); |
523 | max17042_override_por(client, MAX17042_FilterCFG, config->filter_cfg); | 497 | max17042_override_por(map, MAX17042_FilterCFG, config->filter_cfg); |
524 | max17042_override_por(client, MAX17042_RelaxCFG, config->relax_cfg); | 498 | max17042_override_por(map, MAX17042_RelaxCFG, config->relax_cfg); |
525 | max17042_override_por(client, MAX17042_MiscCFG, config->misc_cfg); | 499 | max17042_override_por(map, MAX17042_MiscCFG, config->misc_cfg); |
526 | max17042_override_por(client, MAX17042_MaskSOC, config->masksoc); | 500 | max17042_override_por(map, MAX17042_MaskSOC, config->masksoc); |
527 | 501 | ||
528 | max17042_override_por(client, MAX17042_FullCAP, config->fullcap); | 502 | max17042_override_por(map, MAX17042_FullCAP, config->fullcap); |
529 | max17042_override_por(client, MAX17042_FullCAPNom, config->fullcapnom); | 503 | max17042_override_por(map, MAX17042_FullCAPNom, config->fullcapnom); |
530 | if (chip->chip_type == MAX17042) | 504 | if (chip->chip_type == MAX17042) |
531 | max17042_override_por(client, MAX17042_SOC_empty, | 505 | max17042_override_por(map, MAX17042_SOC_empty, |
532 | config->socempty); | 506 | config->socempty); |
533 | max17042_override_por(client, MAX17042_LAvg_empty, config->lavg_empty); | 507 | max17042_override_por(map, MAX17042_LAvg_empty, config->lavg_empty); |
534 | max17042_override_por(client, MAX17042_dQacc, config->dqacc); | 508 | max17042_override_por(map, MAX17042_dQacc, config->dqacc); |
535 | max17042_override_por(client, MAX17042_dPacc, config->dpacc); | 509 | max17042_override_por(map, MAX17042_dPacc, config->dpacc); |
536 | 510 | ||
537 | if (chip->chip_type == MAX17042) | 511 | if (chip->chip_type == MAX17042) |
538 | max17042_override_por(client, MAX17042_V_empty, config->vempty); | 512 | max17042_override_por(map, MAX17042_V_empty, config->vempty); |
539 | else | 513 | else |
540 | max17042_override_por(client, MAX17047_V_empty, config->vempty); | 514 | max17042_override_por(map, MAX17047_V_empty, config->vempty); |
541 | max17042_override_por(client, MAX17042_TempNom, config->temp_nom); | 515 | max17042_override_por(map, MAX17042_TempNom, config->temp_nom); |
542 | max17042_override_por(client, MAX17042_TempLim, config->temp_lim); | 516 | max17042_override_por(map, MAX17042_TempLim, config->temp_lim); |
543 | max17042_override_por(client, MAX17042_FCTC, config->fctc); | 517 | max17042_override_por(map, MAX17042_FCTC, config->fctc); |
544 | max17042_override_por(client, MAX17042_RCOMP0, config->rcomp0); | 518 | max17042_override_por(map, MAX17042_RCOMP0, config->rcomp0); |
545 | max17042_override_por(client, MAX17042_TempCo, config->tcompc0); | 519 | max17042_override_por(map, MAX17042_TempCo, config->tcompc0); |
546 | if (chip->chip_type) { | 520 | if (chip->chip_type) { |
547 | max17042_override_por(client, MAX17042_EmptyTempCo, | 521 | max17042_override_por(map, MAX17042_EmptyTempCo, |
548 | config->empty_tempco); | 522 | config->empty_tempco); |
549 | max17042_override_por(client, MAX17042_K_empty0, | 523 | max17042_override_por(map, MAX17042_K_empty0, |
550 | config->kempty0); | 524 | config->kempty0); |
551 | } | 525 | } |
552 | } | 526 | } |
553 | 527 | ||
554 | static int max17042_init_chip(struct max17042_chip *chip) | 528 | static int max17042_init_chip(struct max17042_chip *chip) |
555 | { | 529 | { |
530 | struct regmap *map = chip->regmap; | ||
556 | int ret; | 531 | int ret; |
557 | int val; | 532 | int val; |
558 | 533 | ||
@@ -597,31 +572,32 @@ static int max17042_init_chip(struct max17042_chip *chip) | |||
597 | max17042_load_new_capacity_params(chip); | 572 | max17042_load_new_capacity_params(chip); |
598 | 573 | ||
599 | /* Init complete, Clear the POR bit */ | 574 | /* Init complete, Clear the POR bit */ |
600 | val = max17042_read_reg(chip->client, MAX17042_STATUS); | 575 | regmap_read(map, MAX17042_STATUS, &val); |
601 | max17042_write_reg(chip->client, MAX17042_STATUS, | 576 | regmap_write(map, MAX17042_STATUS, val & (~STATUS_POR_BIT)); |
602 | val & (~STATUS_POR_BIT)); | ||
603 | return 0; | 577 | return 0; |
604 | } | 578 | } |
605 | 579 | ||
606 | static void max17042_set_soc_threshold(struct max17042_chip *chip, u16 off) | 580 | static void max17042_set_soc_threshold(struct max17042_chip *chip, u16 off) |
607 | { | 581 | { |
608 | u16 soc, soc_tr; | 582 | struct regmap *map = chip->regmap; |
583 | u32 soc, soc_tr; | ||
609 | 584 | ||
610 | /* program interrupt thesholds such that we should | 585 | /* program interrupt thesholds such that we should |
611 | * get interrupt for every 'off' perc change in the soc | 586 | * get interrupt for every 'off' perc change in the soc |
612 | */ | 587 | */ |
613 | soc = max17042_read_reg(chip->client, MAX17042_RepSOC) >> 8; | 588 | regmap_read(map, MAX17042_RepSOC, &soc); |
589 | soc >>= 8; | ||
614 | soc_tr = (soc + off) << 8; | 590 | soc_tr = (soc + off) << 8; |
615 | soc_tr |= (soc - off); | 591 | soc_tr |= (soc - off); |
616 | max17042_write_reg(chip->client, MAX17042_SALRT_Th, soc_tr); | 592 | regmap_write(map, MAX17042_SALRT_Th, soc_tr); |
617 | } | 593 | } |
618 | 594 | ||
619 | static irqreturn_t max17042_thread_handler(int id, void *dev) | 595 | static irqreturn_t max17042_thread_handler(int id, void *dev) |
620 | { | 596 | { |
621 | struct max17042_chip *chip = dev; | 597 | struct max17042_chip *chip = dev; |
622 | u16 val; | 598 | u32 val; |
623 | 599 | ||
624 | val = max17042_read_reg(chip->client, MAX17042_STATUS); | 600 | regmap_read(chip->regmap, MAX17042_STATUS, &val); |
625 | if ((val & STATUS_INTR_SOCMIN_BIT) || | 601 | if ((val & STATUS_INTR_SOCMIN_BIT) || |
626 | (val & STATUS_INTR_SOCMAX_BIT)) { | 602 | (val & STATUS_INTR_SOCMAX_BIT)) { |
627 | dev_info(&chip->client->dev, "SOC threshold INTR\n"); | 603 | dev_info(&chip->client->dev, "SOC threshold INTR\n"); |
@@ -682,13 +658,20 @@ max17042_get_pdata(struct device *dev) | |||
682 | } | 658 | } |
683 | #endif | 659 | #endif |
684 | 660 | ||
661 | static struct regmap_config max17042_regmap_config = { | ||
662 | .reg_bits = 8, | ||
663 | .val_bits = 16, | ||
664 | .val_format_endian = REGMAP_ENDIAN_NATIVE, | ||
665 | }; | ||
666 | |||
685 | static int max17042_probe(struct i2c_client *client, | 667 | static int max17042_probe(struct i2c_client *client, |
686 | const struct i2c_device_id *id) | 668 | const struct i2c_device_id *id) |
687 | { | 669 | { |
688 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 670 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
689 | struct max17042_chip *chip; | 671 | struct max17042_chip *chip; |
690 | int ret; | 672 | int ret; |
691 | int reg; | 673 | int i; |
674 | u32 val; | ||
692 | 675 | ||
693 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) | 676 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) |
694 | return -EIO; | 677 | return -EIO; |
@@ -698,6 +681,12 @@ static int max17042_probe(struct i2c_client *client, | |||
698 | return -ENOMEM; | 681 | return -ENOMEM; |
699 | 682 | ||
700 | chip->client = client; | 683 | chip->client = client; |
684 | chip->regmap = devm_regmap_init_i2c(client, &max17042_regmap_config); | ||
685 | if (IS_ERR(chip->regmap)) { | ||
686 | dev_err(&client->dev, "Failed to initialize regmap\n"); | ||
687 | return -EINVAL; | ||
688 | } | ||
689 | |||
701 | chip->pdata = max17042_get_pdata(&client->dev); | 690 | chip->pdata = max17042_get_pdata(&client->dev); |
702 | if (!chip->pdata) { | 691 | if (!chip->pdata) { |
703 | dev_err(&client->dev, "no platform data provided\n"); | 692 | dev_err(&client->dev, "no platform data provided\n"); |
@@ -706,15 +695,15 @@ static int max17042_probe(struct i2c_client *client, | |||
706 | 695 | ||
707 | i2c_set_clientdata(client, chip); | 696 | i2c_set_clientdata(client, chip); |
708 | 697 | ||
709 | ret = max17042_read_reg(chip->client, MAX17042_DevName); | 698 | regmap_read(chip->regmap, MAX17042_DevName, &val); |
710 | if (ret == MAX17042_IC_VERSION) { | 699 | if (val == MAX17042_IC_VERSION) { |
711 | dev_dbg(&client->dev, "chip type max17042 detected\n"); | 700 | dev_dbg(&client->dev, "chip type max17042 detected\n"); |
712 | chip->chip_type = MAX17042; | 701 | chip->chip_type = MAX17042; |
713 | } else if (ret == MAX17047_IC_VERSION) { | 702 | } else if (val == MAX17047_IC_VERSION) { |
714 | dev_dbg(&client->dev, "chip type max17047/50 detected\n"); | 703 | dev_dbg(&client->dev, "chip type max17047/50 detected\n"); |
715 | chip->chip_type = MAX17047; | 704 | chip->chip_type = MAX17047; |
716 | } else { | 705 | } else { |
717 | dev_err(&client->dev, "device version mismatch: %x\n", ret); | 706 | dev_err(&client->dev, "device version mismatch: %x\n", val); |
718 | return -EIO; | 707 | return -EIO; |
719 | } | 708 | } |
720 | 709 | ||
@@ -733,13 +722,15 @@ static int max17042_probe(struct i2c_client *client, | |||
733 | chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR; | 722 | chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR; |
734 | 723 | ||
735 | if (chip->pdata->init_data) | 724 | if (chip->pdata->init_data) |
736 | max17042_set_reg(client, chip->pdata->init_data, | 725 | for (i = 0; i < chip->pdata->num_init_data; i++) |
737 | chip->pdata->num_init_data); | 726 | regmap_write(chip->regmap, |
727 | chip->pdata->init_data[i].addr, | ||
728 | chip->pdata->init_data[i].data); | ||
738 | 729 | ||
739 | if (!chip->pdata->enable_current_sense) { | 730 | if (!chip->pdata->enable_current_sense) { |
740 | max17042_write_reg(client, MAX17042_CGAIN, 0x0000); | 731 | regmap_write(chip->regmap, MAX17042_CGAIN, 0x0000); |
741 | max17042_write_reg(client, MAX17042_MiscCFG, 0x0003); | 732 | regmap_write(chip->regmap, MAX17042_MiscCFG, 0x0003); |
742 | max17042_write_reg(client, MAX17042_LearnCFG, 0x0007); | 733 | regmap_write(chip->regmap, MAX17042_LearnCFG, 0x0007); |
743 | } | 734 | } |
744 | 735 | ||
745 | ret = power_supply_register(&client->dev, &chip->battery); | 736 | ret = power_supply_register(&client->dev, &chip->battery); |
@@ -754,9 +745,9 @@ static int max17042_probe(struct i2c_client *client, | |||
754 | IRQF_TRIGGER_FALLING, | 745 | IRQF_TRIGGER_FALLING, |
755 | chip->battery.name, chip); | 746 | chip->battery.name, chip); |
756 | if (!ret) { | 747 | if (!ret) { |
757 | reg = max17042_read_reg(client, MAX17042_CONFIG); | 748 | regmap_read(chip->regmap, MAX17042_CONFIG, &val); |
758 | reg |= CONFIG_ALRT_BIT_ENBL; | 749 | val |= CONFIG_ALRT_BIT_ENBL; |
759 | max17042_write_reg(client, MAX17042_CONFIG, reg); | 750 | regmap_write(chip->regmap, MAX17042_CONFIG, val); |
760 | max17042_set_soc_threshold(chip, 1); | 751 | max17042_set_soc_threshold(chip, 1); |
761 | } else { | 752 | } else { |
762 | client->irq = 0; | 753 | client->irq = 0; |
@@ -765,8 +756,8 @@ static int max17042_probe(struct i2c_client *client, | |||
765 | } | 756 | } |
766 | } | 757 | } |
767 | 758 | ||
768 | reg = max17042_read_reg(chip->client, MAX17042_STATUS); | 759 | regmap_read(chip->regmap, MAX17042_STATUS, &val); |
769 | if (reg & STATUS_POR_BIT) { | 760 | if (val & STATUS_POR_BIT) { |
770 | INIT_WORK(&chip->work, max17042_init_worker); | 761 | INIT_WORK(&chip->work, max17042_init_worker); |
771 | schedule_work(&chip->work); | 762 | schedule_work(&chip->work); |
772 | } else { | 763 | } else { |