hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/power/supply/bq25700_charger.c
....@@ -1,18 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * TI BQ257000 charger driver
4
+
5
+ * Copyright (c) 2021 Rockchip Electronics Co. Ltd.
36 *
4
- * Copyright (C) 2016 Rockchip Corporation
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
15
- *
7
+ * Author: shengfeixu <xsf@rock-chips.com>
168 */
179
1810 #include <linux/power/bq25700-charge.h>
....@@ -22,6 +14,7 @@
2214 #include <linux/mfd/core.h>
2315 #include <linux/module.h>
2416 #include <linux/regmap.h>
17
+#include <linux/regulator/driver.h>
2518 #include <linux/of_device.h>
2619 #include <linux/delay.h>
2720 #include <linux/usb/phy.h>
....@@ -54,6 +47,7 @@
5447 #define MAX_CHARGEVOLTAGE 16800000
5548 #define MAX_CHARGECURRETNT 8128000
5649 #define MAX_OTGVOLTAGE 20800000
50
+#define MIN_OTGVOLTAGE 4280000
5751 #define MAX_OTGCURRENT 6350000
5852
5953 enum bq25700_fields {
....@@ -168,27 +162,24 @@
168162 bool charger_health_valid;
169163 bool battery_health_valid;
170164 bool battery_status_valid;
171
-
165
+ int automode;
166
+ struct notifier_block nb;
167
+ struct bq2570x_platform_data plat_data;
168
+ struct device_node *notify_node;
172169 struct workqueue_struct *usb_charger_wq;
173170 struct workqueue_struct *dc_charger_wq;
174171 struct workqueue_struct *finish_sig_wq;
175172 struct delayed_work usb_work;
176
- struct delayed_work pd_work;
177173 struct delayed_work host_work;
178174 struct delayed_work discnt_work;
179175 struct delayed_work usb_work1;
180
- struct delayed_work pd_work1;
181176 struct delayed_work host_work1;
182177 struct delayed_work discnt_work1;
183178 struct delayed_work irq_work;
184179 struct notifier_block cable_cg_nb;
185
- struct notifier_block cable_pd_nb;
186180 struct notifier_block cable_host_nb;
187
- struct notifier_block cable_discnt_nb;
188181 struct notifier_block cable_cg_nb1;
189
- struct notifier_block cable_pd_nb1;
190182 struct notifier_block cable_host_nb1;
191
- struct notifier_block cable_discnt_nb1;
192183 struct extcon_dev *cable_edev;
193184 struct extcon_dev *cable_edev_1;
194185 int typec0_status;
....@@ -199,6 +190,7 @@
199190 struct gpio_desc *typec1_discharge_io;
200191 struct gpio_desc *otg_mode_en_io;
201192
193
+ struct regulator_dev *otg_vbus_reg;
202194 struct regmap *regmap;
203195 struct regmap_field *rmap_fields[F_MAX_FIELDS];
204196 int chip_id;
....@@ -515,7 +507,13 @@
515507 u32 size;
516508 };
517509
518
-static const union {
510
+static const struct bq25700_range sc8886_otg_range = {
511
+ .min = 1280000,
512
+ .max = 20800000,
513
+ .step = 128000,
514
+};
515
+
516
+static union {
519517 struct bq25700_range rt;
520518 struct bq25700_lookup lt;
521519 } bq25700_tables[] = {
....@@ -816,7 +814,7 @@
816814 return 0;
817815 }
818816
819
-ssize_t bq25700_charge_info_show(struct device *dev,
817
+static ssize_t bq25700_charge_info_show(struct device *dev,
820818 struct device_attribute *attr, char *buf)
821819 {
822820 struct bq25700_device *charger = dev_get_drvdata(dev);
....@@ -944,12 +942,25 @@
944942 dev_err(charger->dev, "ti,input-current is error\n");
945943 return -ENODEV;
946944 }
947
- if ((props[i].tbl_id == TBL_OTGVOL) &&
948
- (property > MAX_OTGVOLTAGE)) {
949
- dev_err(charger->dev, "ti,ti,otg-voltage is error\n");
950
- return -ENODEV;
945
+ if (props[i].tbl_id == TBL_OTGVOL) {
946
+ if (of_device_is_compatible(charger->dev->of_node,
947
+ "southchip,sc8886")) {
948
+ bq25700_tables[TBL_OTGVOL].rt = sc8886_otg_range;
949
+
950
+ if (property < MIN_OTGVOLTAGE) {
951
+ dev_err(charger->dev,
952
+ "ti,otg-voltage is error");
953
+ return -ENODEV;
954
+ }
955
+ }
956
+
957
+ if (property > MAX_OTGVOLTAGE) {
958
+ dev_err(charger->dev, "ti,otg-voltage is error\n");
959
+ return -ENODEV;
960
+ };
951961 }
952
- if ((props[i].tbl_id == TBL_OTGVOL) &&
962
+
963
+ if ((props[i].tbl_id == TBL_OTGCUR) &&
953964 (property > MAX_OTGCURRENT)) {
954965 dev_err(charger->dev, "ti,otg-current is error\n");
955966 return -ENODEV;
....@@ -1231,6 +1242,7 @@
12311242
12321243 psy_cfg.supplied_to = bq25700_charger_supplied_to;
12331244 psy_cfg.num_supplicants = ARRAY_SIZE(bq25700_charger_supplied_to);
1245
+ psy_cfg.of_node = charger->dev->of_node;
12341246
12351247 charger->supply_charger =
12361248 power_supply_register(charger->dev,
....@@ -1238,6 +1250,71 @@
12381250 &psy_cfg);
12391251
12401252 return PTR_ERR_OR_ZERO(charger->supply_charger);
1253
+}
1254
+
1255
+static void bq25700_discnt(struct bq25700_device *charger, enum tpyec_port_t port);
1256
+
1257
+static int bq2570x_pd_notifier_call(struct notifier_block *nb,
1258
+ unsigned long val, void *v)
1259
+{
1260
+ struct bq25700_device *bq =
1261
+ container_of(nb, struct bq25700_device, nb);
1262
+ struct power_supply *psy = v;
1263
+ union power_supply_propval prop;
1264
+ struct bq25700_state state;
1265
+ int ret;
1266
+ int vol_idx, cur_idx, chr_idx;
1267
+
1268
+ if (val != PSY_EVENT_PROP_CHANGED)
1269
+ return NOTIFY_OK;
1270
+
1271
+ /* Ignore event if it was not send by notify_node/notify_device */
1272
+ if (bq->notify_node) {
1273
+ if (!psy->dev.parent ||
1274
+ psy->dev.parent->of_node != bq->notify_node)
1275
+ return NOTIFY_OK;
1276
+ } else if (bq->plat_data.notify_device) {
1277
+ if (strcmp(psy->desc->name, bq->plat_data.notify_device) != 0)
1278
+ return NOTIFY_OK;
1279
+ }
1280
+
1281
+ ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_ONLINE, &prop);
1282
+ if (ret != 0)
1283
+ return NOTIFY_OK;
1284
+ /* online=0: USB out */
1285
+ if (prop.intval == 0) {
1286
+ queue_delayed_work(bq->usb_charger_wq, &bq->discnt_work,
1287
+ msecs_to_jiffies(10));
1288
+ return NOTIFY_OK;
1289
+ }
1290
+
1291
+ ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_CURRENT_NOW, &prop);
1292
+ if (ret != 0)
1293
+ return NOTIFY_OK;
1294
+ if (prop.intval > 0) {
1295
+ cur_idx = bq25700_find_idx(prop.intval, TBL_INPUTCUR);
1296
+ ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_VOLTAGE_NOW,
1297
+ &prop);
1298
+ if (ret != 0)
1299
+ return NOTIFY_OK;
1300
+ vol_idx = bq25700_find_idx((prop.intval - 1280000 - 3200000), TBL_INPUTVOL);
1301
+ ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_CURRENT_NOW,
1302
+ &prop);
1303
+ if (ret != 0)
1304
+ return NOTIFY_OK;
1305
+ chr_idx = bq25700_find_idx(prop.intval, TBL_ICHG);
1306
+
1307
+ bq25700_field_write(bq, INPUT_CURRENT, cur_idx);
1308
+ bq25700_field_write(bq, INPUT_VOLTAGE, vol_idx);
1309
+ bq25700_field_write(bq, CHARGE_CURRENT, chr_idx);
1310
+ dev_info(bq->dev, "INPUT_CURRENT:%d, INPUT_VOLTAGE:%d, CHARGE_CURRENT:%d\n",
1311
+ cur_idx, vol_idx, chr_idx);
1312
+
1313
+ bq25700_get_chip_state(bq, &state);
1314
+ bq->state = state;
1315
+ power_supply_changed(bq->supply_charger);
1316
+ }
1317
+ return NOTIFY_OK;
12411318 }
12421319
12431320 static irqreturn_t bq25700_irq_handler_thread(int irq, void *private)
....@@ -1304,101 +1381,6 @@
13041381 msleep(20);
13051382 if (!IS_ERR_OR_NULL(charger->typec1_discharge_io))
13061383 gpiod_direction_output(charger->typec1_discharge_io, 0);
1307
-}
1308
-
1309
-static void bq25700_pd_connect(struct bq25700_device *charger,
1310
- struct extcon_dev *edev,
1311
- enum tpyec_port_t port)
1312
-{
1313
- union extcon_property_value prop_val;
1314
- struct bq25700_state state;
1315
- int ret;
1316
- int vol, cur;
1317
- int vol_idx, cur_idx;
1318
- int i;
1319
-
1320
- if (charger->typec0_status == USB_STATUS_PD ||
1321
- charger->typec1_status == USB_STATUS_PD)
1322
- return;
1323
-
1324
- if (extcon_get_state(edev, EXTCON_CHG_USB_FAST) > 0) {
1325
- ret = extcon_get_property(edev, EXTCON_CHG_USB_FAST,
1326
- EXTCON_PROP_USB_TYPEC_POLARITY,
1327
- &prop_val);
1328
- DBG("usb pd charge...\n");
1329
- vol = prop_val.intval & 0xffff;
1330
- cur = prop_val.intval >> 15;
1331
- if (ret == 0) {
1332
- if (port == USB_TYPEC_0) {
1333
- charger->typec0_status = USB_STATUS_PD;
1334
- bq25700_enable_typec0(charger);
1335
- } else {
1336
- charger->typec1_status = USB_STATUS_PD;
1337
- bq25700_enable_typec1(charger);
1338
- }
1339
-
1340
- i = 0;
1341
- while (!bq25700_field_read(charger, AC_STAT) && i < 5) {
1342
- msleep(1000);
1343
- i++;
1344
- }
1345
- vol_idx = bq25700_find_idx((vol - 1280) * 1000,
1346
- TBL_INPUTVOL);
1347
- cur_idx = bq25700_find_idx(cur * 1000, TBL_INPUTCUR);
1348
- bq25700_field_write(charger, INPUT_VOLTAGE, vol_idx);
1349
- bq25700_field_write(charger, INPUT_CURRENT, cur_idx);
1350
- bq25700_field_write(charger, CHARGE_CURRENT,
1351
- charger->init_data.ichg);
1352
- }
1353
-
1354
- bq25700_get_chip_state(charger, &state);
1355
- charger->state = state;
1356
- power_supply_changed(charger->supply_charger);
1357
- }
1358
-}
1359
-
1360
-static void bq25700_pd_evt_worker(struct work_struct *work)
1361
-{
1362
- struct bq25700_device *charger = container_of(work,
1363
- struct bq25700_device, pd_work.work);
1364
- struct extcon_dev *edev = charger->cable_edev;
1365
-
1366
- bq25700_pd_connect(charger, edev, USB_TYPEC_0);
1367
-}
1368
-
1369
-static void bq25700_pd_evt_worker1(struct work_struct *work)
1370
-{
1371
- struct bq25700_device *charger = container_of(work,
1372
- struct bq25700_device, pd_work1.work);
1373
- struct extcon_dev *edev = charger->cable_edev_1;
1374
-
1375
- bq25700_pd_connect(charger, edev, USB_TYPEC_1);
1376
-}
1377
-
1378
-static int bq25700_pd_evt_notifier(struct notifier_block *nb,
1379
- unsigned long event,
1380
- void *ptr)
1381
-{
1382
- struct bq25700_device *charger =
1383
- container_of(nb, struct bq25700_device, cable_pd_nb);
1384
-
1385
- queue_delayed_work(charger->usb_charger_wq, &charger->pd_work,
1386
- msecs_to_jiffies(10));
1387
-
1388
- return NOTIFY_DONE;
1389
-}
1390
-
1391
-static int bq25700_pd_evt_notifier1(struct notifier_block *nb,
1392
- unsigned long event,
1393
- void *ptr)
1394
-{
1395
- struct bq25700_device *charger =
1396
- container_of(nb, struct bq25700_device, cable_pd_nb1);
1397
-
1398
- queue_delayed_work(charger->usb_charger_wq, &charger->pd_work1,
1399
- msecs_to_jiffies(10));
1400
-
1401
- return NOTIFY_DONE;
14021384 }
14031385
14041386 static void bq25700_charger_evt_handel(struct bq25700_device *charger,
....@@ -1481,6 +1463,7 @@
14811463 struct bq25700_device *charger = container_of(work,
14821464 struct bq25700_device, usb_work.work);
14831465 struct extcon_dev *edev = charger->cable_edev;
1466
+
14841467 if (charger->usb_bc == 0)
14851468 bq25700_charger_evt_handel(charger, edev, USB_TYPEC_0);
14861469 else
....@@ -1522,24 +1505,25 @@
15221505 return NOTIFY_DONE;
15231506 }
15241507
1508
+static void bq25700_set_otg_vbus(struct bq25700_device *charger, bool enable)
1509
+{
1510
+ DBG("OTG %s\n", enable ? "enable" : "disable");
1511
+
1512
+ if (!IS_ERR_OR_NULL(charger->otg_mode_en_io))
1513
+ gpiod_direction_output(charger->otg_mode_en_io, enable);
1514
+ bq25700_field_write(charger, EN_OTG, enable);
1515
+}
1516
+
15251517 static void bq25700_host_evt_worker(struct work_struct *work)
15261518 {
15271519 struct bq25700_device *charger =
15281520 container_of(work, struct bq25700_device, host_work.work);
15291521 struct extcon_dev *edev = charger->cable_edev;
15301522
1531
- /* Determine charger type */
1532
- if (extcon_get_state(edev, EXTCON_USB_VBUS_EN) > 0) {
1533
- if (!IS_ERR_OR_NULL(charger->otg_mode_en_io))
1534
- gpiod_direction_output(charger->otg_mode_en_io, 1);
1535
- bq25700_field_write(charger, EN_OTG, 1);
1536
- DBG("OTG enable\n");
1537
- } else if (extcon_get_state(edev, EXTCON_USB_VBUS_EN) == 0) {
1538
- if (!IS_ERR_OR_NULL(charger->otg_mode_en_io))
1539
- gpiod_direction_output(charger->otg_mode_en_io, 0);
1540
- bq25700_field_write(charger, EN_OTG, 0);
1541
- DBG("OTG disable\n");
1542
- }
1523
+ if (extcon_get_state(edev, EXTCON_USB_VBUS_EN) > 0)
1524
+ bq25700_set_otg_vbus(charger, true);
1525
+ else if (extcon_get_state(edev, EXTCON_USB_VBUS_EN) == 0)
1526
+ bq25700_set_otg_vbus(charger, false);
15431527 }
15441528
15451529 static void bq25700_host_evt_worker1(struct work_struct *work)
....@@ -1548,18 +1532,10 @@
15481532 container_of(work, struct bq25700_device, host_work1.work);
15491533 struct extcon_dev *edev = charger->cable_edev_1;
15501534
1551
- /* Determine charger type */
1552
- if (extcon_get_state(edev, EXTCON_USB_VBUS_EN) > 0) {
1553
- if (!IS_ERR_OR_NULL(charger->otg_mode_en_io))
1554
- gpiod_direction_output(charger->otg_mode_en_io, 1);
1555
- bq25700_field_write(charger, EN_OTG, 1);
1556
- DBG("OTG enable\n");
1557
- } else if (extcon_get_state(edev, EXTCON_USB_VBUS_EN) == 0) {
1558
- if (!IS_ERR_OR_NULL(charger->otg_mode_en_io))
1559
- gpiod_direction_output(charger->otg_mode_en_io, 0);
1560
- bq25700_field_write(charger, EN_OTG, 0);
1561
- DBG("OTG disable\n");
1562
- }
1535
+ if (extcon_get_state(edev, EXTCON_USB_VBUS_EN) > 0)
1536
+ bq25700_set_otg_vbus(charger, true);
1537
+ else if (extcon_get_state(edev, EXTCON_USB_VBUS_EN) == 0)
1538
+ bq25700_set_otg_vbus(charger, false);
15631539 }
15641540
15651541 static int bq25700_host_evt_notifier(struct notifier_block *nb,
....@@ -1619,42 +1595,6 @@
16191595 discnt_work.work);
16201596
16211597 bq25700_discnt(charger, USB_TYPEC_0);
1622
-}
1623
-
1624
-static void bq25700_discnt_evt_worker1(struct work_struct *work)
1625
-{
1626
- struct bq25700_device *charger = container_of(work,
1627
- struct bq25700_device,
1628
- discnt_work1.work);
1629
- bq25700_discnt(charger, USB_TYPEC_1);
1630
-}
1631
-
1632
-static int bq25700_discnt_evt_notfier(struct notifier_block *nb,
1633
- unsigned long event,
1634
- void *ptr)
1635
-{
1636
- struct bq25700_device *charger =
1637
- container_of(nb, struct bq25700_device, cable_discnt_nb);
1638
-
1639
- queue_delayed_work(charger->usb_charger_wq,
1640
- &charger->discnt_work,
1641
- msecs_to_jiffies(0));
1642
-
1643
- return NOTIFY_DONE;
1644
-}
1645
-
1646
-static int bq25700_discnt_evt_notfier1(struct notifier_block *nb,
1647
- unsigned long event,
1648
- void *ptr)
1649
-{
1650
- struct bq25700_device *charger =
1651
- container_of(nb, struct bq25700_device, cable_discnt_nb1);
1652
-
1653
- queue_delayed_work(charger->usb_charger_wq,
1654
- &charger->discnt_work1,
1655
- msecs_to_jiffies(0));
1656
-
1657
- return NOTIFY_DONE;
16581598 }
16591599
16601600 static int bq25700_register_cg_extcon(struct bq25700_device *charger,
....@@ -1731,60 +1671,61 @@
17311671 return 0;
17321672 }
17331673
1734
-static int bq25700_register_discnt_nb(struct bq25700_device *charger)
1735
-{
1736
- int ret;
1737
-
1738
- /* Register discnt usb */
1739
- if (charger->cable_edev) {
1740
- INIT_DELAYED_WORK(&charger->discnt_work,
1741
- bq25700_discnt_evt_worker);
1742
- charger->cable_discnt_nb.notifier_call =
1743
- bq25700_discnt_evt_notfier;
1744
- ret = extcon_register_notifier(charger->cable_edev,
1745
- EXTCON_USB,
1746
- &charger->cable_discnt_nb);
1747
- if (ret < 0) {
1748
- dev_err(charger->dev,
1749
- "failed to register notifier for HOST\n");
1750
- return ret;
1751
- }
1752
- }
1753
-
1754
- if (charger->cable_edev_1) {
1755
- INIT_DELAYED_WORK(&charger->discnt_work1,
1756
- bq25700_discnt_evt_worker1);
1757
- charger->cable_discnt_nb1.notifier_call =
1758
- bq25700_discnt_evt_notfier1;
1759
- ret = extcon_register_notifier(charger->cable_edev_1,
1760
- EXTCON_USB,
1761
- &charger->cable_discnt_nb1);
1762
- if (ret < 0) {
1763
- dev_err(charger->dev,
1764
- "failed to register notifier for HOST\n");
1765
- return ret;
1766
- }
1767
- }
1768
-
1769
- return 0;
1770
-}
1771
-
17721674 static int bq25700_register_pd_nb(struct bq25700_device *charger)
17731675 {
1774
- if (charger->cable_edev) {
1775
- INIT_DELAYED_WORK(&charger->pd_work, bq25700_pd_evt_worker);
1776
- charger->cable_pd_nb.notifier_call = bq25700_pd_evt_notifier;
1777
- extcon_register_notifier(charger->cable_edev,
1778
- EXTCON_CHG_USB_FAST,
1779
- &charger->cable_pd_nb);
1676
+ struct power_supply *notify_psy = NULL;
1677
+ int vol_idx, cur_idx;
1678
+ int ret;
1679
+ union power_supply_propval prop;
1680
+
1681
+ if (charger->notify_node || charger->plat_data.notify_device) {
1682
+ INIT_DELAYED_WORK(&charger->discnt_work,
1683
+ bq25700_discnt_evt_worker);
1684
+ charger->nb.notifier_call = bq2570x_pd_notifier_call;
1685
+ ret = power_supply_reg_notifier(&charger->nb);
1686
+ if (ret) {
1687
+ dev_err(charger->dev, "failed to reg notifier: %d\n", ret);
1688
+ return ret;
1689
+ }
1690
+ charger->automode = 1;
1691
+ dev_info(charger->dev, "automode supported, waiting for events\n");
1692
+ } else {
1693
+ charger->automode = -1;
1694
+ dev_info(charger->dev, "automode not supported\n");
17801695 }
17811696
1782
- if (charger->cable_edev_1) {
1783
- INIT_DELAYED_WORK(&charger->pd_work1, bq25700_pd_evt_worker1);
1784
- charger->cable_pd_nb1.notifier_call = bq25700_pd_evt_notifier1;
1785
- extcon_register_notifier(charger->cable_edev_1,
1786
- EXTCON_CHG_USB_FAST,
1787
- &charger->cable_pd_nb1);
1697
+ if (charger->nb.notifier_call) {
1698
+ if (charger->dev->of_node) {
1699
+ notify_psy = power_supply_get_by_phandle(charger->dev->of_node,
1700
+ "ti,usb-charger-detection");
1701
+ if (IS_ERR_OR_NULL(notify_psy)) {
1702
+ dev_info(charger->dev, "bq25700 notify_psy is error\n");
1703
+ notify_psy = NULL;
1704
+ }
1705
+ } else if (charger->plat_data.notify_device) {
1706
+ notify_psy = power_supply_get_by_name(
1707
+ charger->plat_data.notify_device);
1708
+ }
1709
+ }
1710
+
1711
+ if (notify_psy) {
1712
+ ret = power_supply_get_property(notify_psy,
1713
+ POWER_SUPPLY_PROP_CURRENT_MAX, &prop);
1714
+ if (ret != 0)
1715
+ return ret;
1716
+ ret = power_supply_get_property(notify_psy,
1717
+ POWER_SUPPLY_PROP_VOLTAGE_MAX, &prop);
1718
+ if (ret != 0)
1719
+ return ret;
1720
+
1721
+ cur_idx = bq25700_find_idx(prop.intval, TBL_INPUTCUR);
1722
+ vol_idx = bq25700_find_idx((prop.intval - 1280000 - 3200000), TBL_INPUTVOL);
1723
+ bq25700_field_write(charger, INPUT_CURRENT, cur_idx);
1724
+ bq25700_field_write(charger, INPUT_VOLTAGE, vol_idx);
1725
+ bq25700_field_write(charger, CHARGE_CURRENT,
1726
+ charger->init_data.ichg);
1727
+ dev_info(charger->dev, "INPUT_CURRENT:%d, INPUT_VOLTAGE:%d, CHARGE_CURRENT:%d\n",
1728
+ cur_idx, vol_idx, charger->init_data.ichg);
17881729 }
17891730
17901731 return 0;
....@@ -1800,7 +1741,7 @@
18001741 charger->cable_host_nb.notifier_call =
18011742 bq25700_host_evt_notifier;
18021743 ret = extcon_register_notifier(charger->cable_edev,
1803
- EXTCON_USB_HOST,
1744
+ EXTCON_USB_VBUS_EN,
18041745 &charger->cable_host_nb);
18051746 if (ret < 0) {
18061747 dev_err(charger->dev,
....@@ -1815,7 +1756,7 @@
18151756 charger->cable_host_nb1.notifier_call =
18161757 bq25700_host_evt_notifier1;
18171758 ret = extcon_register_notifier(charger->cable_edev_1,
1818
- EXTCON_USB_HOST,
1759
+ EXTCON_USB_VBUS_EN,
18191760 &charger->cable_host_nb1);
18201761 if (ret < 0) {
18211762 dev_err(charger->dev,
....@@ -1823,6 +1764,77 @@
18231764 return -1;
18241765 }
18251766 }
1767
+
1768
+ return 0;
1769
+}
1770
+
1771
+static int bq25700_otg_vbus_enable(struct regulator_dev *dev)
1772
+{
1773
+ struct bq25700_device *charger = rdev_get_drvdata(dev);
1774
+
1775
+ bq25700_set_otg_vbus(charger, true);
1776
+
1777
+ return 0;
1778
+}
1779
+
1780
+static int bq25700_otg_vbus_disable(struct regulator_dev *dev)
1781
+{
1782
+ struct bq25700_device *charger = rdev_get_drvdata(dev);
1783
+
1784
+ bq25700_set_otg_vbus(charger, false);
1785
+
1786
+ return 0;
1787
+}
1788
+
1789
+static int bq25700_otg_vbus_is_enabled(struct regulator_dev *dev)
1790
+{
1791
+ struct bq25700_device *charger = rdev_get_drvdata(dev);
1792
+ u8 val;
1793
+ int gpio_status = 1;
1794
+
1795
+ val = bq25700_field_read(charger, EN_OTG);
1796
+ if (!IS_ERR_OR_NULL(charger->otg_mode_en_io))
1797
+ gpio_status = gpiod_get_value(charger->otg_mode_en_io);
1798
+
1799
+ return val && gpio_status ? 1 : 0;
1800
+}
1801
+
1802
+static const struct regulator_ops bq25700_otg_vbus_ops = {
1803
+ .enable = bq25700_otg_vbus_enable,
1804
+ .disable = bq25700_otg_vbus_disable,
1805
+ .is_enabled = bq25700_otg_vbus_is_enabled,
1806
+};
1807
+
1808
+static const struct regulator_desc bq25700_otg_vbus_desc = {
1809
+ .name = "otg-vbus",
1810
+ .of_match = "otg-vbus",
1811
+ .regulators_node = of_match_ptr("regulators"),
1812
+ .owner = THIS_MODULE,
1813
+ .ops = &bq25700_otg_vbus_ops,
1814
+ .type = REGULATOR_VOLTAGE,
1815
+ .fixed_uV = 5000000,
1816
+ .n_voltages = 1,
1817
+};
1818
+
1819
+static int bq25700_register_otg_vbus_regulator(struct bq25700_device *charger)
1820
+{
1821
+ struct device_node *np;
1822
+ struct regulator_config config = { };
1823
+
1824
+ np = of_get_child_by_name(charger->dev->of_node, "regulators");
1825
+ if (!np) {
1826
+ dev_warn(charger->dev, "cannot find regulators node\n");
1827
+ return -ENXIO;
1828
+ }
1829
+
1830
+ config.dev = charger->dev;
1831
+ config.driver_data = charger;
1832
+
1833
+ charger->otg_vbus_reg = devm_regulator_register(charger->dev,
1834
+ &bq25700_otg_vbus_desc,
1835
+ &config);
1836
+ if (IS_ERR(charger->otg_vbus_reg))
1837
+ return PTR_ERR(charger->otg_vbus_reg);
18261838
18271839 return 0;
18281840 }
....@@ -1854,21 +1866,31 @@
18541866 } else {
18551867 charger->cable_edev_1 = edev1;
18561868 }
1869
+ /*set power_on input current*/
1870
+ bq25700_field_write(charger, INPUT_CURRENT,
1871
+ charger->init_data.input_current_sdp);
1872
+
18571873 if (!charger->pd_charge_only)
18581874 bq25700_register_cg_nb(charger);
1859
- bq25700_register_host_nb(charger);
1860
- bq25700_register_discnt_nb(charger);
1875
+
1876
+ if (bq25700_register_otg_vbus_regulator(charger) < 0) {
1877
+ dev_warn(charger->dev,
1878
+ "Cannot register otg vbus regulator\n");
1879
+ charger->otg_vbus_reg = NULL;
1880
+ bq25700_register_host_nb(charger);
1881
+ }
1882
+
18611883 bq25700_register_pd_nb(charger);
18621884
18631885 if (charger->cable_edev) {
1864
- schedule_delayed_work(&charger->host_work, 0);
1865
- schedule_delayed_work(&charger->pd_work, 0);
1886
+ if (!charger->otg_vbus_reg)
1887
+ schedule_delayed_work(&charger->host_work, 0);
18661888 if (!charger->pd_charge_only)
18671889 schedule_delayed_work(&charger->usb_work, 0);
18681890 }
18691891 if (charger->cable_edev_1) {
1870
- schedule_delayed_work(&charger->host_work1, 0);
1871
- schedule_delayed_work(&charger->pd_work1, 0);
1892
+ if (!charger->otg_vbus_reg)
1893
+ schedule_delayed_work(&charger->host_work1, 0);
18721894 if (!charger->pd_charge_only)
18731895 schedule_delayed_work(&charger->usb_work1, 0);
18741896 }
....@@ -1918,7 +1940,11 @@
19181940 charger->usb_bc = 0;
19191941 else
19201942 charger->usb_bc = 1;
1943
+ of_node_put(temp_np);
19211944
1945
+ if (np)
1946
+ charger->notify_node = of_parse_phandle(np,
1947
+ "ti,usb-charger-detection", 0);
19221948 return 0;
19231949 }
19241950
....@@ -1944,6 +1970,8 @@
19441970 charger->dev = dev;
19451971
19461972 charger_np = of_find_compatible_node(NULL, NULL, "ti,bq25700");
1973
+ if (!charger_np)
1974
+ charger_np = of_find_compatible_node(NULL, NULL, "southchip,sc8885");
19471975 if (charger_np) {
19481976 charger->regmap = devm_regmap_init_i2c(client,
19491977 &bq25700_regmap_config);
....@@ -2006,6 +2034,20 @@
20062034 return -ENODEV;
20072035 }
20082036
2037
+ /*
2038
+ * Make sure battery online, otherwise, writing INPUT_CURRENT and
2039
+ * CHARGE_CURRENT would make system power off
2040
+ */
2041
+ if (of_parse_phandle(charger->dev->of_node, "ti,battery", 0)) {
2042
+ if (IS_ERR_OR_NULL(power_supply_get_by_phandle(
2043
+ charger->dev->of_node,
2044
+ "ti,battery"))) {
2045
+ dev_info(charger->dev, "No battery found\n");
2046
+ return -EPROBE_DEFER;
2047
+ }
2048
+ dev_info(charger->dev, "Battery found\n");
2049
+ }
2050
+
20092051 ret = bq25700_hw_init(charger);
20102052 if (ret < 0) {
20112053 dev_err(dev, "Cannot initialize the chip.\n");
....@@ -2044,7 +2086,7 @@
20442086 return ret;
20452087 }
20462088
2047
-void bq25700_shutdown(struct i2c_client *client)
2089
+static void bq25700_shutdown(struct i2c_client *client)
20482090 {
20492091 int vol_idx;
20502092 struct bq25700_device *charger = i2c_get_clientdata(client);
....@@ -2053,16 +2095,28 @@
20532095 bq25700_field_write(charger, INPUT_VOLTAGE, vol_idx);
20542096 bq25700_field_write(charger, INPUT_CURRENT,
20552097 charger->init_data.input_current_sdp);
2098
+
2099
+ if (!bq25700_field_read(charger, AC_STAT))
2100
+ bq25700_field_write(charger, EN_LWPWR, 1);
20562101 }
20572102
20582103 #ifdef CONFIG_PM_SLEEP
20592104 static int bq25700_pm_suspend(struct device *dev)
20602105 {
2106
+ struct bq25700_device *charger = dev_get_drvdata(dev);
2107
+
2108
+ if (!bq25700_field_read(charger, AC_STAT))
2109
+ bq25700_field_write(charger, EN_LWPWR, 1);
2110
+
20612111 return 0;
20622112 }
20632113
20642114 static int bq25700_pm_resume(struct device *dev)
20652115 {
2116
+ struct bq25700_device *charger = dev_get_drvdata(dev);
2117
+
2118
+ bq25700_field_write(charger, EN_LWPWR, 0);
2119
+
20662120 return 0;
20672121 }
20682122 #endif
....@@ -2079,6 +2133,8 @@
20792133 static const struct of_device_id bq25700_of_match[] = {
20802134 { .compatible = "ti,bq25700", },
20812135 { .compatible = "ti,bq25703", },
2136
+ { .compatible = "southchip,sc8885", },
2137
+ { .compatible = "southchip,sc8886", },
20822138 { },
20832139 };
20842140 MODULE_DEVICE_TABLE(of, bq25700_of_match);