0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/of.h>
0014 #include <linux/of_platform.h>
0015 #include <linux/slab.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/delay.h>
0018 #include <linux/power_supply.h>
0019 #include <linux/list.h>
0020 #include <asm/div64.h>
0021 #include <linux/mfd/da9150/core.h>
0022 #include <linux/mfd/da9150/registers.h>
0023 #include <linux/devm-helpers.h>
0024
0025
0026 #define DA9150_QIF_READ (0x0 << 7)
0027 #define DA9150_QIF_WRITE (0x1 << 7)
0028 #define DA9150_QIF_CODE_MASK 0x7F
0029
0030 #define DA9150_QIF_BYTE_SIZE 8
0031 #define DA9150_QIF_BYTE_MASK 0xFF
0032 #define DA9150_QIF_SHORT_SIZE 2
0033 #define DA9150_QIF_LONG_SIZE 4
0034
0035
0036 #define DA9150_QIF_UAVG 6
0037 #define DA9150_QIF_UAVG_SIZE DA9150_QIF_LONG_SIZE
0038 #define DA9150_QIF_IAVG 8
0039 #define DA9150_QIF_IAVG_SIZE DA9150_QIF_LONG_SIZE
0040 #define DA9150_QIF_NTCAVG 12
0041 #define DA9150_QIF_NTCAVG_SIZE DA9150_QIF_LONG_SIZE
0042 #define DA9150_QIF_SHUNT_VAL 36
0043 #define DA9150_QIF_SHUNT_VAL_SIZE DA9150_QIF_SHORT_SIZE
0044 #define DA9150_QIF_SD_GAIN 38
0045 #define DA9150_QIF_SD_GAIN_SIZE DA9150_QIF_LONG_SIZE
0046 #define DA9150_QIF_FCC_MAH 40
0047 #define DA9150_QIF_FCC_MAH_SIZE DA9150_QIF_SHORT_SIZE
0048 #define DA9150_QIF_SOC_PCT 43
0049 #define DA9150_QIF_SOC_PCT_SIZE DA9150_QIF_SHORT_SIZE
0050 #define DA9150_QIF_CHARGE_LIMIT 44
0051 #define DA9150_QIF_CHARGE_LIMIT_SIZE DA9150_QIF_SHORT_SIZE
0052 #define DA9150_QIF_DISCHARGE_LIMIT 45
0053 #define DA9150_QIF_DISCHARGE_LIMIT_SIZE DA9150_QIF_SHORT_SIZE
0054 #define DA9150_QIF_FW_MAIN_VER 118
0055 #define DA9150_QIF_FW_MAIN_VER_SIZE DA9150_QIF_SHORT_SIZE
0056 #define DA9150_QIF_E_FG_STATUS 126
0057 #define DA9150_QIF_E_FG_STATUS_SIZE DA9150_QIF_SHORT_SIZE
0058 #define DA9150_QIF_SYNC 127
0059 #define DA9150_QIF_SYNC_SIZE DA9150_QIF_SHORT_SIZE
0060 #define DA9150_QIF_MAX_CODES 128
0061
0062
0063 #define DA9150_QIF_SYNC_TIMEOUT 1000
0064 #define DA9150_QIF_SYNC_RETRIES 10
0065
0066
0067 #define DA9150_FG_IRQ_LOW_SOC_MASK (1 << 0)
0068 #define DA9150_FG_IRQ_HIGH_SOC_MASK (1 << 1)
0069 #define DA9150_FG_IRQ_SOC_MASK \
0070 (DA9150_FG_IRQ_LOW_SOC_MASK | DA9150_FG_IRQ_HIGH_SOC_MASK)
0071
0072
0073 struct da9150_fg {
0074 struct da9150 *da9150;
0075 struct device *dev;
0076
0077 struct mutex io_lock;
0078
0079 struct power_supply *battery;
0080 struct delayed_work work;
0081 u32 interval;
0082
0083 int warn_soc;
0084 int crit_soc;
0085 int soc;
0086 };
0087
0088
0089 static u32 da9150_fg_read_attr(struct da9150_fg *fg, u8 code, u8 size)
0090
0091 {
0092 u8 buf[DA9150_QIF_LONG_SIZE];
0093 u8 read_addr;
0094 u32 res = 0;
0095 int i;
0096
0097
0098 read_addr = (code & DA9150_QIF_CODE_MASK) | DA9150_QIF_READ;
0099
0100 da9150_read_qif(fg->da9150, read_addr, size, buf);
0101 for (i = 0; i < size; ++i)
0102 res |= (buf[i] << (i * DA9150_QIF_BYTE_SIZE));
0103
0104 return res;
0105 }
0106
0107 static void da9150_fg_write_attr(struct da9150_fg *fg, u8 code, u8 size,
0108 u32 val)
0109
0110 {
0111 u8 buf[DA9150_QIF_LONG_SIZE];
0112 u8 write_addr;
0113 int i;
0114
0115
0116 write_addr = (code & DA9150_QIF_CODE_MASK) | DA9150_QIF_WRITE;
0117
0118 for (i = 0; i < size; ++i) {
0119 buf[i] = (val >> (i * DA9150_QIF_BYTE_SIZE)) &
0120 DA9150_QIF_BYTE_MASK;
0121 }
0122 da9150_write_qif(fg->da9150, write_addr, size, buf);
0123 }
0124
0125
0126 static void da9150_fg_read_sync_start(struct da9150_fg *fg)
0127 {
0128 int i = 0;
0129 u32 res = 0;
0130
0131 mutex_lock(&fg->io_lock);
0132
0133
0134 res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC,
0135 DA9150_QIF_SYNC_SIZE);
0136 if (res > 0)
0137 da9150_fg_write_attr(fg, DA9150_QIF_SYNC,
0138 DA9150_QIF_SYNC_SIZE, 0);
0139
0140
0141 res = 0;
0142 while ((res == 0) && (i++ < DA9150_QIF_SYNC_RETRIES)) {
0143 usleep_range(DA9150_QIF_SYNC_TIMEOUT,
0144 DA9150_QIF_SYNC_TIMEOUT * 2);
0145 res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC,
0146 DA9150_QIF_SYNC_SIZE);
0147 }
0148
0149
0150 if (res == 0)
0151 dev_err(fg->dev, "Failed to perform QIF read sync!\n");
0152 }
0153
0154
0155
0156
0157
0158 static inline void da9150_fg_read_sync_end(struct da9150_fg *fg)
0159 {
0160 mutex_unlock(&fg->io_lock);
0161 }
0162
0163
0164 static u32 da9150_fg_read_attr_sync(struct da9150_fg *fg, u8 code, u8 size)
0165 {
0166 u32 val;
0167
0168 da9150_fg_read_sync_start(fg);
0169 val = da9150_fg_read_attr(fg, code, size);
0170 da9150_fg_read_sync_end(fg);
0171
0172 return val;
0173 }
0174
0175
0176 static void da9150_fg_write_attr_sync(struct da9150_fg *fg, u8 code, u8 size,
0177 u32 val)
0178 {
0179 int i = 0;
0180 u32 res = 0, sync_val;
0181
0182 mutex_lock(&fg->io_lock);
0183
0184
0185 res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC,
0186 DA9150_QIF_SYNC_SIZE);
0187
0188
0189 while ((res == 0) && (i++ < DA9150_QIF_SYNC_RETRIES)) {
0190 usleep_range(DA9150_QIF_SYNC_TIMEOUT,
0191 DA9150_QIF_SYNC_TIMEOUT * 2);
0192 res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC,
0193 DA9150_QIF_SYNC_SIZE);
0194 }
0195
0196 if (res == 0) {
0197 dev_err(fg->dev, "Timeout waiting for existing QIF sync!\n");
0198 mutex_unlock(&fg->io_lock);
0199 return;
0200 }
0201
0202
0203 da9150_fg_write_attr(fg, code, size, val);
0204
0205
0206 i = 0;
0207 sync_val = res;
0208 while ((res == sync_val) && (i++ < DA9150_QIF_SYNC_RETRIES)) {
0209 usleep_range(DA9150_QIF_SYNC_TIMEOUT,
0210 DA9150_QIF_SYNC_TIMEOUT * 2);
0211 res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC,
0212 DA9150_QIF_SYNC_SIZE);
0213 }
0214
0215 mutex_unlock(&fg->io_lock);
0216
0217
0218 if (res != (sync_val + 1))
0219 dev_err(fg->dev, "Error performing QIF sync write for code %d\n",
0220 code);
0221 }
0222
0223
0224 static int da9150_fg_capacity(struct da9150_fg *fg,
0225 union power_supply_propval *val)
0226 {
0227 val->intval = da9150_fg_read_attr_sync(fg, DA9150_QIF_SOC_PCT,
0228 DA9150_QIF_SOC_PCT_SIZE);
0229
0230 if (val->intval > 100)
0231 val->intval = 100;
0232
0233 return 0;
0234 }
0235
0236 static int da9150_fg_current_avg(struct da9150_fg *fg,
0237 union power_supply_propval *val)
0238 {
0239 u32 iavg, sd_gain, shunt_val;
0240 u64 div, res;
0241
0242 da9150_fg_read_sync_start(fg);
0243 iavg = da9150_fg_read_attr(fg, DA9150_QIF_IAVG,
0244 DA9150_QIF_IAVG_SIZE);
0245 shunt_val = da9150_fg_read_attr(fg, DA9150_QIF_SHUNT_VAL,
0246 DA9150_QIF_SHUNT_VAL_SIZE);
0247 sd_gain = da9150_fg_read_attr(fg, DA9150_QIF_SD_GAIN,
0248 DA9150_QIF_SD_GAIN_SIZE);
0249 da9150_fg_read_sync_end(fg);
0250
0251 div = (u64) (sd_gain * shunt_val * 65536ULL);
0252 do_div(div, 1000000);
0253 res = (u64) (iavg * 1000000ULL);
0254 do_div(res, div);
0255
0256 val->intval = (int) res;
0257
0258 return 0;
0259 }
0260
0261 static int da9150_fg_voltage_avg(struct da9150_fg *fg,
0262 union power_supply_propval *val)
0263 {
0264 u64 res;
0265
0266 val->intval = da9150_fg_read_attr_sync(fg, DA9150_QIF_UAVG,
0267 DA9150_QIF_UAVG_SIZE);
0268
0269 res = (u64) (val->intval * 186ULL);
0270 do_div(res, 10000);
0271 val->intval = (int) res;
0272
0273 return 0;
0274 }
0275
0276 static int da9150_fg_charge_full(struct da9150_fg *fg,
0277 union power_supply_propval *val)
0278 {
0279 val->intval = da9150_fg_read_attr_sync(fg, DA9150_QIF_FCC_MAH,
0280 DA9150_QIF_FCC_MAH_SIZE);
0281
0282 val->intval = val->intval * 1000;
0283
0284 return 0;
0285 }
0286
0287
0288
0289
0290
0291 static int da9150_fg_temp(struct da9150_fg *fg,
0292 union power_supply_propval *val)
0293 {
0294 val->intval = da9150_fg_read_attr_sync(fg, DA9150_QIF_NTCAVG,
0295 DA9150_QIF_NTCAVG_SIZE);
0296
0297 val->intval = (val->intval * 10) / 1048576;
0298
0299 return 0;
0300 }
0301
0302 static enum power_supply_property da9150_fg_props[] = {
0303 POWER_SUPPLY_PROP_CAPACITY,
0304 POWER_SUPPLY_PROP_CURRENT_AVG,
0305 POWER_SUPPLY_PROP_VOLTAGE_AVG,
0306 POWER_SUPPLY_PROP_CHARGE_FULL,
0307 POWER_SUPPLY_PROP_TEMP,
0308 };
0309
0310 static int da9150_fg_get_prop(struct power_supply *psy,
0311 enum power_supply_property psp,
0312 union power_supply_propval *val)
0313 {
0314 struct da9150_fg *fg = dev_get_drvdata(psy->dev.parent);
0315 int ret;
0316
0317 switch (psp) {
0318 case POWER_SUPPLY_PROP_CAPACITY:
0319 ret = da9150_fg_capacity(fg, val);
0320 break;
0321 case POWER_SUPPLY_PROP_CURRENT_AVG:
0322 ret = da9150_fg_current_avg(fg, val);
0323 break;
0324 case POWER_SUPPLY_PROP_VOLTAGE_AVG:
0325 ret = da9150_fg_voltage_avg(fg, val);
0326 break;
0327 case POWER_SUPPLY_PROP_CHARGE_FULL:
0328 ret = da9150_fg_charge_full(fg, val);
0329 break;
0330 case POWER_SUPPLY_PROP_TEMP:
0331 ret = da9150_fg_temp(fg, val);
0332 break;
0333 default:
0334 ret = -EINVAL;
0335 break;
0336 }
0337
0338 return ret;
0339 }
0340
0341
0342 static bool da9150_fg_soc_changed(struct da9150_fg *fg)
0343 {
0344 union power_supply_propval val;
0345
0346 da9150_fg_capacity(fg, &val);
0347 if (val.intval != fg->soc) {
0348 fg->soc = val.intval;
0349 return true;
0350 }
0351
0352 return false;
0353 }
0354
0355 static void da9150_fg_work(struct work_struct *work)
0356 {
0357 struct da9150_fg *fg = container_of(work, struct da9150_fg, work.work);
0358
0359
0360 if (da9150_fg_soc_changed(fg))
0361 power_supply_changed(fg->battery);
0362
0363 schedule_delayed_work(&fg->work, msecs_to_jiffies(fg->interval));
0364 }
0365
0366
0367 static void da9150_fg_soc_event_config(struct da9150_fg *fg)
0368 {
0369 int soc;
0370
0371 soc = da9150_fg_read_attr_sync(fg, DA9150_QIF_SOC_PCT,
0372 DA9150_QIF_SOC_PCT_SIZE);
0373
0374 if (soc > fg->warn_soc) {
0375
0376 da9150_fg_write_attr_sync(fg, DA9150_QIF_DISCHARGE_LIMIT,
0377 DA9150_QIF_DISCHARGE_LIMIT_SIZE,
0378 fg->warn_soc + 1);
0379 } else if ((soc <= fg->warn_soc) && (soc > fg->crit_soc)) {
0380
0381
0382
0383
0384 da9150_fg_write_attr_sync(fg, DA9150_QIF_DISCHARGE_LIMIT,
0385 DA9150_QIF_DISCHARGE_LIMIT_SIZE,
0386 fg->crit_soc + 1);
0387
0388 da9150_fg_write_attr_sync(fg, DA9150_QIF_CHARGE_LIMIT,
0389 DA9150_QIF_CHARGE_LIMIT_SIZE,
0390 fg->warn_soc);
0391 } else if (soc <= fg->crit_soc) {
0392
0393 da9150_fg_write_attr_sync(fg, DA9150_QIF_CHARGE_LIMIT,
0394 DA9150_QIF_CHARGE_LIMIT_SIZE,
0395 fg->crit_soc);
0396 }
0397 }
0398
0399 static irqreturn_t da9150_fg_irq(int irq, void *data)
0400 {
0401 struct da9150_fg *fg = data;
0402 u32 e_fg_status;
0403
0404
0405 e_fg_status = da9150_fg_read_attr(fg, DA9150_QIF_E_FG_STATUS,
0406 DA9150_QIF_E_FG_STATUS_SIZE);
0407
0408
0409 if (e_fg_status & DA9150_FG_IRQ_SOC_MASK)
0410 da9150_fg_soc_event_config(fg);
0411
0412
0413 da9150_fg_write_attr(fg, DA9150_QIF_E_FG_STATUS,
0414 DA9150_QIF_E_FG_STATUS_SIZE, e_fg_status);
0415
0416 return IRQ_HANDLED;
0417 }
0418
0419 static struct da9150_fg_pdata *da9150_fg_dt_pdata(struct device *dev)
0420 {
0421 struct device_node *fg_node = dev->of_node;
0422 struct da9150_fg_pdata *pdata;
0423
0424 pdata = devm_kzalloc(dev, sizeof(struct da9150_fg_pdata), GFP_KERNEL);
0425 if (!pdata)
0426 return NULL;
0427
0428 of_property_read_u32(fg_node, "dlg,update-interval",
0429 &pdata->update_interval);
0430 of_property_read_u8(fg_node, "dlg,warn-soc-level",
0431 &pdata->warn_soc_lvl);
0432 of_property_read_u8(fg_node, "dlg,crit-soc-level",
0433 &pdata->crit_soc_lvl);
0434
0435 return pdata;
0436 }
0437
0438 static const struct power_supply_desc fg_desc = {
0439 .name = "da9150-fg",
0440 .type = POWER_SUPPLY_TYPE_BATTERY,
0441 .properties = da9150_fg_props,
0442 .num_properties = ARRAY_SIZE(da9150_fg_props),
0443 .get_property = da9150_fg_get_prop,
0444 };
0445
0446 static int da9150_fg_probe(struct platform_device *pdev)
0447 {
0448 struct device *dev = &pdev->dev;
0449 struct da9150 *da9150 = dev_get_drvdata(dev->parent);
0450 struct da9150_fg_pdata *fg_pdata = dev_get_platdata(dev);
0451 struct da9150_fg *fg;
0452 int ver, irq, ret = 0;
0453
0454 fg = devm_kzalloc(dev, sizeof(*fg), GFP_KERNEL);
0455 if (fg == NULL)
0456 return -ENOMEM;
0457
0458 platform_set_drvdata(pdev, fg);
0459 fg->da9150 = da9150;
0460 fg->dev = dev;
0461
0462 mutex_init(&fg->io_lock);
0463
0464
0465 da9150_set_bits(da9150, DA9150_CORE2WIRE_CTRL_A, DA9150_FG_QIF_EN_MASK,
0466 DA9150_FG_QIF_EN_MASK);
0467
0468 fg->battery = devm_power_supply_register(dev, &fg_desc, NULL);
0469 if (IS_ERR(fg->battery)) {
0470 ret = PTR_ERR(fg->battery);
0471 return ret;
0472 }
0473
0474 ver = da9150_fg_read_attr(fg, DA9150_QIF_FW_MAIN_VER,
0475 DA9150_QIF_FW_MAIN_VER_SIZE);
0476 dev_info(dev, "Version: 0x%x\n", ver);
0477
0478
0479 if (dev->of_node) {
0480 fg_pdata = da9150_fg_dt_pdata(dev);
0481 dev->platform_data = fg_pdata;
0482 }
0483
0484
0485 if (fg_pdata) {
0486 fg->interval = fg_pdata->update_interval;
0487
0488 if (fg_pdata->warn_soc_lvl > 100)
0489 dev_warn(dev, "Invalid SOC warning level provided, Ignoring");
0490 else
0491 fg->warn_soc = fg_pdata->warn_soc_lvl;
0492
0493 if ((fg_pdata->crit_soc_lvl > 100) ||
0494 (fg_pdata->crit_soc_lvl >= fg_pdata->warn_soc_lvl))
0495 dev_warn(dev, "Invalid SOC critical level provided, Ignoring");
0496 else
0497 fg->crit_soc = fg_pdata->crit_soc_lvl;
0498
0499
0500 }
0501
0502
0503 da9150_fg_soc_event_config(fg);
0504
0505
0506
0507
0508
0509 if (fg->interval) {
0510 ret = devm_delayed_work_autocancel(dev, &fg->work,
0511 da9150_fg_work);
0512 if (ret) {
0513 dev_err(dev, "Failed to init work\n");
0514 return ret;
0515 }
0516
0517 schedule_delayed_work(&fg->work,
0518 msecs_to_jiffies(fg->interval));
0519 }
0520
0521
0522 irq = platform_get_irq_byname(pdev, "FG");
0523 if (irq < 0)
0524 return irq;
0525
0526 ret = devm_request_threaded_irq(dev, irq, NULL, da9150_fg_irq,
0527 IRQF_ONESHOT, "FG", fg);
0528 if (ret) {
0529 dev_err(dev, "Failed to request IRQ %d: %d\n", irq, ret);
0530 return ret;
0531 }
0532
0533 return 0;
0534 }
0535
0536 static int da9150_fg_resume(struct platform_device *pdev)
0537 {
0538 struct da9150_fg *fg = platform_get_drvdata(pdev);
0539
0540
0541
0542
0543
0544 if (fg->interval)
0545 flush_delayed_work(&fg->work);
0546
0547 return 0;
0548 }
0549
0550 static struct platform_driver da9150_fg_driver = {
0551 .driver = {
0552 .name = "da9150-fuel-gauge",
0553 },
0554 .probe = da9150_fg_probe,
0555 .resume = da9150_fg_resume,
0556 };
0557
0558 module_platform_driver(da9150_fg_driver);
0559
0560 MODULE_DESCRIPTION("Fuel-Gauge Driver for DA9150");
0561 MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");
0562 MODULE_LICENSE("GPL");