hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/drivers/power/supply/max17040_battery.c
....@@ -1,14 +1,10 @@
1
-/*
2
- * max17040_battery.c
3
- * fuel-gauge systems for lithium-ion (Li+) batteries
4
- *
5
- * Copyright (C) 2009 Samsung Electronics
6
- * Minkyu Kang <mk7.kang@samsung.com>
7
- *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License version 2 as
10
- * published by the Free Software Foundation.
11
- */
1
+// SPDX-License-Identifier: GPL-2.0
2
+//
3
+// max17040_battery.c
4
+// fuel-gauge systems for lithium-ion (Li+) batteries
5
+//
6
+// Copyright (C) 2009 Samsung Electronics
7
+// Minkyu Kang <mk7.kang@samsung.com>
128
139 #include <linux/module.h>
1410 #include <linux/init.h>
....@@ -17,36 +13,401 @@
1713 #include <linux/err.h>
1814 #include <linux/i2c.h>
1915 #include <linux/delay.h>
16
+#include <linux/interrupt.h>
2017 #include <linux/power_supply.h>
18
+#include <linux/of_device.h>
2119 #include <linux/max17040_battery.h>
20
+#include <linux/regmap.h>
2221 #include <linux/slab.h>
2322
2423 #define MAX17040_VCELL 0x02
2524 #define MAX17040_SOC 0x04
2625 #define MAX17040_MODE 0x06
2726 #define MAX17040_VER 0x08
28
-#define MAX17040_RCOMP 0x0C
27
+#define MAX17040_CONFIG 0x0C
28
+#define MAX17040_STATUS 0x1A
2929 #define MAX17040_CMD 0xFE
3030
3131
3232 #define MAX17040_DELAY 1000
3333 #define MAX17040_BATTERY_FULL 95
34
+#define MAX17040_RCOMP_DEFAULT 0x9700
35
+
36
+#define MAX17040_ATHD_MASK 0x3f
37
+#define MAX17040_ALSC_MASK 0x40
38
+#define MAX17040_ATHD_DEFAULT_POWER_UP 4
39
+#define MAX17040_STATUS_HD_MASK 0x1000
40
+#define MAX17040_STATUS_SC_MASK 0x2000
41
+#define MAX17040_CFG_RCOMP_MASK 0xff00
42
+
43
+enum chip_id {
44
+ ID_MAX17040,
45
+ ID_MAX17041,
46
+ ID_MAX17043,
47
+ ID_MAX17044,
48
+ ID_MAX17048,
49
+ ID_MAX17049,
50
+ ID_MAX17058,
51
+ ID_MAX17059,
52
+};
53
+
54
+/* values that differ by chip_id */
55
+struct chip_data {
56
+ u16 reset_val;
57
+ u16 vcell_shift;
58
+ u16 vcell_mul;
59
+ u16 vcell_div;
60
+ u8 has_low_soc_alert;
61
+ u8 rcomp_bytes;
62
+ u8 has_soc_alert;
63
+};
64
+
65
+static struct chip_data max17040_family[] = {
66
+ [ID_MAX17040] = {
67
+ .reset_val = 0x0054,
68
+ .vcell_shift = 4,
69
+ .vcell_mul = 1250,
70
+ .vcell_div = 1,
71
+ .has_low_soc_alert = 0,
72
+ .rcomp_bytes = 2,
73
+ .has_soc_alert = 0,
74
+ },
75
+ [ID_MAX17041] = {
76
+ .reset_val = 0x0054,
77
+ .vcell_shift = 4,
78
+ .vcell_mul = 2500,
79
+ .vcell_div = 1,
80
+ .has_low_soc_alert = 0,
81
+ .rcomp_bytes = 2,
82
+ .has_soc_alert = 0,
83
+ },
84
+ [ID_MAX17043] = {
85
+ .reset_val = 0x0054,
86
+ .vcell_shift = 4,
87
+ .vcell_mul = 1250,
88
+ .vcell_div = 1,
89
+ .has_low_soc_alert = 1,
90
+ .rcomp_bytes = 1,
91
+ .has_soc_alert = 0,
92
+ },
93
+ [ID_MAX17044] = {
94
+ .reset_val = 0x0054,
95
+ .vcell_shift = 4,
96
+ .vcell_mul = 2500,
97
+ .vcell_div = 1,
98
+ .has_low_soc_alert = 1,
99
+ .rcomp_bytes = 1,
100
+ .has_soc_alert = 0,
101
+ },
102
+ [ID_MAX17048] = {
103
+ .reset_val = 0x5400,
104
+ .vcell_shift = 0,
105
+ .vcell_mul = 625,
106
+ .vcell_div = 8,
107
+ .has_low_soc_alert = 1,
108
+ .rcomp_bytes = 1,
109
+ .has_soc_alert = 1,
110
+ },
111
+ [ID_MAX17049] = {
112
+ .reset_val = 0x5400,
113
+ .vcell_shift = 0,
114
+ .vcell_mul = 625,
115
+ .vcell_div = 4,
116
+ .has_low_soc_alert = 1,
117
+ .rcomp_bytes = 1,
118
+ .has_soc_alert = 1,
119
+ },
120
+ [ID_MAX17058] = {
121
+ .reset_val = 0x5400,
122
+ .vcell_shift = 0,
123
+ .vcell_mul = 625,
124
+ .vcell_div = 8,
125
+ .has_low_soc_alert = 1,
126
+ .rcomp_bytes = 1,
127
+ .has_soc_alert = 0,
128
+ },
129
+ [ID_MAX17059] = {
130
+ .reset_val = 0x5400,
131
+ .vcell_shift = 0,
132
+ .vcell_mul = 625,
133
+ .vcell_div = 4,
134
+ .has_low_soc_alert = 1,
135
+ .rcomp_bytes = 1,
136
+ .has_soc_alert = 0,
137
+ },
138
+};
34139
35140 struct max17040_chip {
36141 struct i2c_client *client;
142
+ struct regmap *regmap;
37143 struct delayed_work work;
38144 struct power_supply *battery;
39145 struct max17040_platform_data *pdata;
146
+ struct chip_data data;
40147
41
- /* State Of Connect */
42
- int online;
43
- /* battery voltage */
44
- int vcell;
45148 /* battery capacity */
46149 int soc;
47150 /* State Of Charge */
48151 int status;
152
+ /* Low alert threshold from 32% to 1% of the State of Charge */
153
+ u32 low_soc_alert;
154
+ /* some devices return twice the capacity */
155
+ bool quirk_double_soc;
156
+ /* higher 8 bits for 17043+, 16 bits for 17040,41 */
157
+ u16 rcomp;
49158 };
159
+
160
+static int max17040_reset(struct max17040_chip *chip)
161
+{
162
+ return regmap_write(chip->regmap, MAX17040_CMD, chip->data.reset_val);
163
+}
164
+
165
+static int max17040_set_low_soc_alert(struct max17040_chip *chip, u32 level)
166
+{
167
+ level = 32 - level * (chip->quirk_double_soc ? 2 : 1);
168
+ return regmap_update_bits(chip->regmap, MAX17040_CONFIG,
169
+ MAX17040_ATHD_MASK, level);
170
+}
171
+
172
+static int max17040_set_soc_alert(struct max17040_chip *chip, bool enable)
173
+{
174
+ return regmap_update_bits(chip->regmap, MAX17040_CONFIG,
175
+ MAX17040_ALSC_MASK, enable ? MAX17040_ALSC_MASK : 0);
176
+}
177
+
178
+static int max17040_set_rcomp(struct max17040_chip *chip, u16 rcomp)
179
+{
180
+ u16 mask = chip->data.rcomp_bytes == 2 ?
181
+ 0xffff : MAX17040_CFG_RCOMP_MASK;
182
+
183
+ return regmap_update_bits(chip->regmap, MAX17040_CONFIG, mask, rcomp);
184
+}
185
+
186
+static int max17040_raw_vcell_to_uvolts(struct max17040_chip *chip, u16 vcell)
187
+{
188
+ struct chip_data *d = &chip->data;
189
+
190
+ return (vcell >> d->vcell_shift) * d->vcell_mul / d->vcell_div;
191
+}
192
+
193
+
194
+static int max17040_get_vcell(struct max17040_chip *chip)
195
+{
196
+ u32 vcell;
197
+
198
+ regmap_read(chip->regmap, MAX17040_VCELL, &vcell);
199
+
200
+ return max17040_raw_vcell_to_uvolts(chip, vcell);
201
+}
202
+
203
+static int max17040_get_soc(struct max17040_chip *chip)
204
+{
205
+ u32 soc;
206
+
207
+ regmap_read(chip->regmap, MAX17040_SOC, &soc);
208
+
209
+ return soc >> (chip->quirk_double_soc ? 9 : 8);
210
+}
211
+
212
+static int max17040_get_version(struct max17040_chip *chip)
213
+{
214
+ int ret;
215
+ u32 version;
216
+
217
+ ret = regmap_read(chip->regmap, MAX17040_VER, &version);
218
+
219
+ return ret ? ret : version;
220
+}
221
+
222
+static int max17040_get_online(struct max17040_chip *chip)
223
+{
224
+ return chip->pdata && chip->pdata->battery_online ?
225
+ chip->pdata->battery_online() : 1;
226
+}
227
+
228
+static int max17040_get_status(struct max17040_chip *chip)
229
+{
230
+ if (!chip->pdata || !chip->pdata->charger_online
231
+ || !chip->pdata->charger_enable)
232
+ return POWER_SUPPLY_STATUS_UNKNOWN;
233
+
234
+ if (max17040_get_soc(chip) > MAX17040_BATTERY_FULL)
235
+ return POWER_SUPPLY_STATUS_FULL;
236
+
237
+ if (chip->pdata->charger_online())
238
+ if (chip->pdata->charger_enable())
239
+ return POWER_SUPPLY_STATUS_CHARGING;
240
+ else
241
+ return POWER_SUPPLY_STATUS_NOT_CHARGING;
242
+ else
243
+ return POWER_SUPPLY_STATUS_DISCHARGING;
244
+}
245
+
246
+static int max17040_get_of_data(struct max17040_chip *chip)
247
+{
248
+ struct device *dev = &chip->client->dev;
249
+ struct chip_data *data = &max17040_family[
250
+ (uintptr_t) of_device_get_match_data(dev)];
251
+ int rcomp_len;
252
+ u8 rcomp[2];
253
+
254
+ chip->quirk_double_soc = device_property_read_bool(dev,
255
+ "maxim,double-soc");
256
+
257
+ chip->low_soc_alert = MAX17040_ATHD_DEFAULT_POWER_UP;
258
+ device_property_read_u32(dev,
259
+ "maxim,alert-low-soc-level",
260
+ &chip->low_soc_alert);
261
+
262
+ if (chip->low_soc_alert <= 0 ||
263
+ chip->low_soc_alert > (chip->quirk_double_soc ? 16 : 32)) {
264
+ dev_err(dev, "maxim,alert-low-soc-level out of bounds\n");
265
+ return -EINVAL;
266
+ }
267
+
268
+ rcomp_len = device_property_count_u8(dev, "maxim,rcomp");
269
+ chip->rcomp = MAX17040_RCOMP_DEFAULT;
270
+ if (rcomp_len == data->rcomp_bytes) {
271
+ device_property_read_u8_array(dev, "maxim,rcomp",
272
+ rcomp, rcomp_len);
273
+ chip->rcomp = rcomp_len == 2 ?
274
+ rcomp[0] << 8 | rcomp[1] :
275
+ rcomp[0] << 8;
276
+ } else if (rcomp_len > 0) {
277
+ dev_err(dev, "maxim,rcomp has incorrect length\n");
278
+ return -EINVAL;
279
+ }
280
+
281
+ return 0;
282
+}
283
+
284
+static void max17040_check_changes(struct max17040_chip *chip)
285
+{
286
+ chip->soc = max17040_get_soc(chip);
287
+ chip->status = max17040_get_status(chip);
288
+}
289
+
290
+static void max17040_queue_work(struct max17040_chip *chip)
291
+{
292
+ queue_delayed_work(system_power_efficient_wq, &chip->work,
293
+ MAX17040_DELAY);
294
+}
295
+
296
+static void max17040_stop_work(void *data)
297
+{
298
+ struct max17040_chip *chip = data;
299
+
300
+ cancel_delayed_work_sync(&chip->work);
301
+}
302
+
303
+static void max17040_work(struct work_struct *work)
304
+{
305
+ struct max17040_chip *chip;
306
+ int last_soc, last_status;
307
+
308
+ chip = container_of(work, struct max17040_chip, work.work);
309
+
310
+ /* store SOC and status to check changes */
311
+ last_soc = chip->soc;
312
+ last_status = chip->status;
313
+ max17040_check_changes(chip);
314
+
315
+ /* check changes and send uevent */
316
+ if (last_soc != chip->soc || last_status != chip->status)
317
+ power_supply_changed(chip->battery);
318
+
319
+ max17040_queue_work(chip);
320
+}
321
+
322
+/* Returns true if alert cause was SOC change, not low SOC */
323
+static bool max17040_handle_soc_alert(struct max17040_chip *chip)
324
+{
325
+ bool ret = true;
326
+ u32 data;
327
+
328
+ regmap_read(chip->regmap, MAX17040_STATUS, &data);
329
+
330
+ if (data & MAX17040_STATUS_HD_MASK) {
331
+ // this alert was caused by low soc
332
+ ret = false;
333
+ }
334
+ if (data & MAX17040_STATUS_SC_MASK) {
335
+ // soc change bit -- deassert to mark as handled
336
+ regmap_write(chip->regmap, MAX17040_STATUS,
337
+ data & ~MAX17040_STATUS_SC_MASK);
338
+ }
339
+
340
+ return ret;
341
+}
342
+
343
+static irqreturn_t max17040_thread_handler(int id, void *dev)
344
+{
345
+ struct max17040_chip *chip = dev;
346
+
347
+ if (!(chip->data.has_soc_alert && max17040_handle_soc_alert(chip)))
348
+ dev_warn(&chip->client->dev, "IRQ: Alert battery low level\n");
349
+
350
+ /* read registers */
351
+ max17040_check_changes(chip);
352
+
353
+ /* send uevent */
354
+ power_supply_changed(chip->battery);
355
+
356
+ /* reset alert bit */
357
+ max17040_set_low_soc_alert(chip, chip->low_soc_alert);
358
+
359
+ return IRQ_HANDLED;
360
+}
361
+
362
+static int max17040_enable_alert_irq(struct max17040_chip *chip)
363
+{
364
+ struct i2c_client *client = chip->client;
365
+ unsigned int flags;
366
+ int ret;
367
+
368
+ flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
369
+ ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
370
+ max17040_thread_handler, flags,
371
+ chip->battery->desc->name, chip);
372
+
373
+ return ret;
374
+}
375
+
376
+static int max17040_prop_writeable(struct power_supply *psy,
377
+ enum power_supply_property psp)
378
+{
379
+ switch (psp) {
380
+ case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN:
381
+ return 1;
382
+ default:
383
+ return 0;
384
+ }
385
+}
386
+
387
+static int max17040_set_property(struct power_supply *psy,
388
+ enum power_supply_property psp,
389
+ const union power_supply_propval *val)
390
+{
391
+ struct max17040_chip *chip = power_supply_get_drvdata(psy);
392
+ int ret;
393
+
394
+ switch (psp) {
395
+ case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN:
396
+ /* alert threshold can be programmed from 1% up to 16/32% */
397
+ if ((val->intval < 1) ||
398
+ (val->intval > (chip->quirk_double_soc ? 16 : 32))) {
399
+ ret = -EINVAL;
400
+ break;
401
+ }
402
+ ret = max17040_set_low_soc_alert(chip, val->intval);
403
+ chip->low_soc_alert = val->intval;
404
+ break;
405
+ default:
406
+ ret = -EINVAL;
407
+ }
408
+
409
+ return ret;
410
+}
50411
51412 static int max17040_get_property(struct power_supply *psy,
52413 enum power_supply_property psp,
....@@ -56,16 +417,19 @@
56417
57418 switch (psp) {
58419 case POWER_SUPPLY_PROP_STATUS:
59
- val->intval = chip->status;
420
+ val->intval = max17040_get_status(chip);
60421 break;
61422 case POWER_SUPPLY_PROP_ONLINE:
62
- val->intval = chip->online;
423
+ val->intval = max17040_get_online(chip);
63424 break;
64425 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
65
- val->intval = chip->vcell;
426
+ val->intval = max17040_get_vcell(chip);
66427 break;
67428 case POWER_SUPPLY_PROP_CAPACITY:
68
- val->intval = chip->soc;
429
+ val->intval = max17040_get_soc(chip);
430
+ break;
431
+ case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN:
432
+ val->intval = chip->low_soc_alert;
69433 break;
70434 default:
71435 return -EINVAL;
....@@ -73,133 +437,40 @@
73437 return 0;
74438 }
75439
76
-static int max17040_write_reg(struct i2c_client *client, int reg, u16 value)
77
-{
78
- int ret;
79
-
80
- ret = i2c_smbus_write_word_swapped(client, reg, value);
81
-
82
- if (ret < 0)
83
- dev_err(&client->dev, "%s: err %d\n", __func__, ret);
84
-
85
- return ret;
86
-}
87
-
88
-static int max17040_read_reg(struct i2c_client *client, int reg)
89
-{
90
- int ret;
91
-
92
- ret = i2c_smbus_read_word_swapped(client, reg);
93
-
94
- if (ret < 0)
95
- dev_err(&client->dev, "%s: err %d\n", __func__, ret);
96
-
97
- return ret;
98
-}
99
-
100
-static void max17040_reset(struct i2c_client *client)
101
-{
102
- max17040_write_reg(client, MAX17040_CMD, 0x0054);
103
-}
104
-
105
-static void max17040_get_vcell(struct i2c_client *client)
106
-{
107
- struct max17040_chip *chip = i2c_get_clientdata(client);
108
- u16 vcell;
109
-
110
- vcell = max17040_read_reg(client, MAX17040_VCELL);
111
-
112
- chip->vcell = (vcell >> 4) * 1250;
113
-}
114
-
115
-static void max17040_get_soc(struct i2c_client *client)
116
-{
117
- struct max17040_chip *chip = i2c_get_clientdata(client);
118
- u16 soc;
119
-
120
- soc = max17040_read_reg(client, MAX17040_SOC);
121
-
122
- chip->soc = (soc >> 8);
123
-}
124
-
125
-static void max17040_get_version(struct i2c_client *client)
126
-{
127
- u16 version;
128
-
129
- version = max17040_read_reg(client, MAX17040_VER);
130
-
131
- dev_info(&client->dev, "MAX17040 Fuel-Gauge Ver 0x%x\n", version);
132
-}
133
-
134
-static void max17040_get_online(struct i2c_client *client)
135
-{
136
- struct max17040_chip *chip = i2c_get_clientdata(client);
137
-
138
- if (chip->pdata && chip->pdata->battery_online)
139
- chip->online = chip->pdata->battery_online();
140
- else
141
- chip->online = 1;
142
-}
143
-
144
-static void max17040_get_status(struct i2c_client *client)
145
-{
146
- struct max17040_chip *chip = i2c_get_clientdata(client);
147
-
148
- if (!chip->pdata || !chip->pdata->charger_online
149
- || !chip->pdata->charger_enable) {
150
- chip->status = POWER_SUPPLY_STATUS_UNKNOWN;
151
- return;
152
- }
153
-
154
- if (chip->pdata->charger_online()) {
155
- if (chip->pdata->charger_enable())
156
- chip->status = POWER_SUPPLY_STATUS_CHARGING;
157
- else
158
- chip->status = POWER_SUPPLY_STATUS_NOT_CHARGING;
159
- } else {
160
- chip->status = POWER_SUPPLY_STATUS_DISCHARGING;
161
- }
162
-
163
- if (chip->soc > MAX17040_BATTERY_FULL)
164
- chip->status = POWER_SUPPLY_STATUS_FULL;
165
-}
166
-
167
-static void max17040_work(struct work_struct *work)
168
-{
169
- struct max17040_chip *chip;
170
-
171
- chip = container_of(work, struct max17040_chip, work.work);
172
-
173
- max17040_get_vcell(chip->client);
174
- max17040_get_soc(chip->client);
175
- max17040_get_online(chip->client);
176
- max17040_get_status(chip->client);
177
-
178
- queue_delayed_work(system_power_efficient_wq, &chip->work,
179
- MAX17040_DELAY);
180
-}
440
+static const struct regmap_config max17040_regmap = {
441
+ .reg_bits = 8,
442
+ .reg_stride = 2,
443
+ .val_bits = 16,
444
+ .val_format_endian = REGMAP_ENDIAN_BIG,
445
+};
181446
182447 static enum power_supply_property max17040_battery_props[] = {
183448 POWER_SUPPLY_PROP_STATUS,
184449 POWER_SUPPLY_PROP_ONLINE,
185450 POWER_SUPPLY_PROP_VOLTAGE_NOW,
186451 POWER_SUPPLY_PROP_CAPACITY,
452
+ POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN,
187453 };
188454
189455 static const struct power_supply_desc max17040_battery_desc = {
190
- .name = "battery",
191
- .type = POWER_SUPPLY_TYPE_BATTERY,
192
- .get_property = max17040_get_property,
193
- .properties = max17040_battery_props,
194
- .num_properties = ARRAY_SIZE(max17040_battery_props),
456
+ .name = "battery",
457
+ .type = POWER_SUPPLY_TYPE_BATTERY,
458
+ .get_property = max17040_get_property,
459
+ .set_property = max17040_set_property,
460
+ .property_is_writeable = max17040_prop_writeable,
461
+ .properties = max17040_battery_props,
462
+ .num_properties = ARRAY_SIZE(max17040_battery_props),
195463 };
196464
197465 static int max17040_probe(struct i2c_client *client,
198466 const struct i2c_device_id *id)
199467 {
200
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
468
+ struct i2c_adapter *adapter = client->adapter;
201469 struct power_supply_config psy_cfg = {};
202470 struct max17040_chip *chip;
471
+ enum chip_id chip_id;
472
+ bool enable_irq = false;
473
+ int ret;
203474
204475 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
205476 return -EIO;
....@@ -209,34 +480,78 @@
209480 return -ENOMEM;
210481
211482 chip->client = client;
483
+ chip->regmap = devm_regmap_init_i2c(client, &max17040_regmap);
212484 chip->pdata = client->dev.platform_data;
485
+ if (IS_ERR(chip->regmap))
486
+ return PTR_ERR(chip->regmap);
487
+ chip_id = (enum chip_id) id->driver_data;
488
+ if (client->dev.of_node) {
489
+ ret = max17040_get_of_data(chip);
490
+ if (ret)
491
+ return ret;
492
+ chip_id = (enum chip_id) (uintptr_t)
493
+ of_device_get_match_data(&client->dev);
494
+ }
495
+ chip->data = max17040_family[chip_id];
213496
214497 i2c_set_clientdata(client, chip);
215498 psy_cfg.drv_data = chip;
216499
217
- chip->battery = power_supply_register(&client->dev,
500
+ chip->battery = devm_power_supply_register(&client->dev,
218501 &max17040_battery_desc, &psy_cfg);
219502 if (IS_ERR(chip->battery)) {
220503 dev_err(&client->dev, "failed: power supply register\n");
221504 return PTR_ERR(chip->battery);
222505 }
223506
224
- max17040_reset(client);
225
- max17040_get_version(client);
507
+ ret = max17040_get_version(chip);
508
+ if (ret < 0)
509
+ return ret;
510
+ dev_dbg(&chip->client->dev, "MAX17040 Fuel-Gauge Ver 0x%x\n", ret);
226511
227
- INIT_DEFERRABLE_WORK(&chip->work, max17040_work);
228
- queue_delayed_work(system_power_efficient_wq, &chip->work,
229
- MAX17040_DELAY);
512
+ if (chip_id == ID_MAX17040 || chip_id == ID_MAX17041)
513
+ max17040_reset(chip);
230514
231
- return 0;
232
-}
515
+ max17040_set_rcomp(chip, chip->rcomp);
233516
234
-static int max17040_remove(struct i2c_client *client)
235
-{
236
- struct max17040_chip *chip = i2c_get_clientdata(client);
517
+ /* check interrupt */
518
+ if (client->irq && chip->data.has_low_soc_alert) {
519
+ ret = max17040_set_low_soc_alert(chip, chip->low_soc_alert);
520
+ if (ret) {
521
+ dev_err(&client->dev,
522
+ "Failed to set low SOC alert: err %d\n", ret);
523
+ return ret;
524
+ }
237525
238
- power_supply_unregister(chip->battery);
239
- cancel_delayed_work(&chip->work);
526
+ enable_irq = true;
527
+ }
528
+
529
+ if (client->irq && chip->data.has_soc_alert) {
530
+ ret = max17040_set_soc_alert(chip, 1);
531
+ if (ret) {
532
+ dev_err(&client->dev,
533
+ "Failed to set SOC alert: err %d\n", ret);
534
+ return ret;
535
+ }
536
+ enable_irq = true;
537
+ } else {
538
+ /* soc alerts negate the need for polling */
539
+ INIT_DEFERRABLE_WORK(&chip->work, max17040_work);
540
+ ret = devm_add_action(&client->dev, max17040_stop_work, chip);
541
+ if (ret)
542
+ return ret;
543
+ max17040_queue_work(chip);
544
+ }
545
+
546
+ if (enable_irq) {
547
+ ret = max17040_enable_alert_irq(chip);
548
+ if (ret) {
549
+ client->irq = 0;
550
+ dev_warn(&client->dev,
551
+ "Failed to get IRQ err %d\n", ret);
552
+ }
553
+ }
554
+
240555 return 0;
241556 }
242557
....@@ -247,7 +562,15 @@
247562 struct i2c_client *client = to_i2c_client(dev);
248563 struct max17040_chip *chip = i2c_get_clientdata(client);
249564
250
- cancel_delayed_work(&chip->work);
565
+ if (client->irq && chip->data.has_soc_alert)
566
+ // disable soc alert to prevent wakeup
567
+ max17040_set_soc_alert(chip, 0);
568
+ else
569
+ cancel_delayed_work(&chip->work);
570
+
571
+ if (client->irq && device_may_wakeup(dev))
572
+ enable_irq_wake(client->irq);
573
+
251574 return 0;
252575 }
253576
....@@ -256,8 +579,14 @@
256579 struct i2c_client *client = to_i2c_client(dev);
257580 struct max17040_chip *chip = i2c_get_clientdata(client);
258581
259
- queue_delayed_work(system_power_efficient_wq, &chip->work,
260
- MAX17040_DELAY);
582
+ if (client->irq && device_may_wakeup(dev))
583
+ disable_irq_wake(client->irq);
584
+
585
+ if (client->irq && chip->data.has_soc_alert)
586
+ max17040_set_soc_alert(chip, 1);
587
+ else
588
+ max17040_queue_work(chip);
589
+
261590 return 0;
262591 }
263592
....@@ -271,16 +600,30 @@
271600 #endif /* CONFIG_PM_SLEEP */
272601
273602 static const struct i2c_device_id max17040_id[] = {
274
- { "max17040" },
275
- { "max77836-battery" },
276
- { }
603
+ { "max17040", ID_MAX17040 },
604
+ { "max17041", ID_MAX17041 },
605
+ { "max17043", ID_MAX17043 },
606
+ { "max77836-battery", ID_MAX17043 },
607
+ { "max17044", ID_MAX17044 },
608
+ { "max17048", ID_MAX17048 },
609
+ { "max17049", ID_MAX17049 },
610
+ { "max17058", ID_MAX17058 },
611
+ { "max17059", ID_MAX17059 },
612
+ { /* sentinel */ }
277613 };
278614 MODULE_DEVICE_TABLE(i2c, max17040_id);
279615
280616 static const struct of_device_id max17040_of_match[] = {
281
- { .compatible = "maxim,max17040" },
282
- { .compatible = "maxim,max77836-battery" },
283
- { },
617
+ { .compatible = "maxim,max17040", .data = (void *) ID_MAX17040 },
618
+ { .compatible = "maxim,max17041", .data = (void *) ID_MAX17041 },
619
+ { .compatible = "maxim,max17043", .data = (void *) ID_MAX17043 },
620
+ { .compatible = "maxim,max77836-battery", .data = (void *) ID_MAX17043 },
621
+ { .compatible = "maxim,max17044", .data = (void *) ID_MAX17044 },
622
+ { .compatible = "maxim,max17048", .data = (void *) ID_MAX17048 },
623
+ { .compatible = "maxim,max17049", .data = (void *) ID_MAX17049 },
624
+ { .compatible = "maxim,max17058", .data = (void *) ID_MAX17058 },
625
+ { .compatible = "maxim,max17059", .data = (void *) ID_MAX17059 },
626
+ { /* sentinel */ },
284627 };
285628 MODULE_DEVICE_TABLE(of, max17040_of_match);
286629
....@@ -291,7 +634,6 @@
291634 .pm = MAX17040_PM_OPS,
292635 },
293636 .probe = max17040_probe,
294
- .remove = max17040_remove,
295637 .id_table = max17040_id,
296638 };
297639 module_i2c_driver(max17040_i2c_driver);