| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * axp288_charger.c - X-power AXP288 PMIC Charger driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2016-2017 Hans de Goede <hdegoede@redhat.com> |
|---|
| 5 | 6 | * Copyright (C) 2014 Intel Corporation |
|---|
| 6 | 7 | * Author: Ramakrishna Pallala <ramakrishna.pallala@intel.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 | | - * |
|---|
| 12 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 13 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 14 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 15 | | - * GNU General Public License for more details. |
|---|
| 16 | 8 | */ |
|---|
| 17 | 9 | |
|---|
| 18 | 10 | #include <linux/acpi.h> |
|---|
| 11 | +#include <linux/bitops.h> |
|---|
| 19 | 12 | #include <linux/module.h> |
|---|
| 20 | 13 | #include <linux/device.h> |
|---|
| 21 | 14 | #include <linux/regmap.h> |
|---|
| .. | .. |
|---|
| 30 | 23 | #include <linux/extcon.h> |
|---|
| 31 | 24 | #include <linux/dmi.h> |
|---|
| 32 | 25 | |
|---|
| 33 | | -#define PS_STAT_VBUS_TRIGGER (1 << 0) |
|---|
| 34 | | -#define PS_STAT_BAT_CHRG_DIR (1 << 2) |
|---|
| 35 | | -#define PS_STAT_VBAT_ABOVE_VHOLD (1 << 3) |
|---|
| 36 | | -#define PS_STAT_VBUS_VALID (1 << 4) |
|---|
| 37 | | -#define PS_STAT_VBUS_PRESENT (1 << 5) |
|---|
| 26 | +#define PS_STAT_VBUS_TRIGGER BIT(0) |
|---|
| 27 | +#define PS_STAT_BAT_CHRG_DIR BIT(2) |
|---|
| 28 | +#define PS_STAT_VBAT_ABOVE_VHOLD BIT(3) |
|---|
| 29 | +#define PS_STAT_VBUS_VALID BIT(4) |
|---|
| 30 | +#define PS_STAT_VBUS_PRESENT BIT(5) |
|---|
| 38 | 31 | |
|---|
| 39 | | -#define CHRG_STAT_BAT_SAFE_MODE (1 << 3) |
|---|
| 40 | | -#define CHRG_STAT_BAT_VALID (1 << 4) |
|---|
| 41 | | -#define CHRG_STAT_BAT_PRESENT (1 << 5) |
|---|
| 42 | | -#define CHRG_STAT_CHARGING (1 << 6) |
|---|
| 43 | | -#define CHRG_STAT_PMIC_OTP (1 << 7) |
|---|
| 32 | +#define CHRG_STAT_BAT_SAFE_MODE BIT(3) |
|---|
| 33 | +#define CHRG_STAT_BAT_VALID BIT(4) |
|---|
| 34 | +#define CHRG_STAT_BAT_PRESENT BIT(5) |
|---|
| 35 | +#define CHRG_STAT_CHARGING BIT(6) |
|---|
| 36 | +#define CHRG_STAT_PMIC_OTP BIT(7) |
|---|
| 44 | 37 | |
|---|
| 45 | 38 | #define VBUS_ISPOUT_CUR_LIM_MASK 0x03 |
|---|
| 46 | 39 | #define VBUS_ISPOUT_CUR_LIM_BIT_POS 0 |
|---|
| .. | .. |
|---|
| 48 | 41 | #define VBUS_ISPOUT_CUR_LIM_1500MA 0x1 /* 1500mA */ |
|---|
| 49 | 42 | #define VBUS_ISPOUT_CUR_LIM_2000MA 0x2 /* 2000mA */ |
|---|
| 50 | 43 | #define VBUS_ISPOUT_CUR_NO_LIM 0x3 /* 2500mA */ |
|---|
| 51 | | -#define VBUS_ISPOUT_VHOLD_SET_MASK 0x31 |
|---|
| 44 | +#define VBUS_ISPOUT_VHOLD_SET_MASK 0x38 |
|---|
| 52 | 45 | #define VBUS_ISPOUT_VHOLD_SET_BIT_POS 0x3 |
|---|
| 53 | 46 | #define VBUS_ISPOUT_VHOLD_SET_OFFSET 4000 /* 4000mV */ |
|---|
| 54 | 47 | #define VBUS_ISPOUT_VHOLD_SET_LSB_RES 100 /* 100mV */ |
|---|
| 55 | | -#define VBUS_ISPOUT_VHOLD_SET_4300MV 0x3 /* 4300mV */ |
|---|
| 56 | | -#define VBUS_ISPOUT_VBUS_PATH_DIS (1 << 7) |
|---|
| 48 | +#define VBUS_ISPOUT_VHOLD_SET_4400MV 0x4 /* 4400mV */ |
|---|
| 49 | +#define VBUS_ISPOUT_VBUS_PATH_DIS BIT(7) |
|---|
| 57 | 50 | |
|---|
| 58 | 51 | #define CHRG_CCCV_CC_MASK 0xf /* 4 bits */ |
|---|
| 59 | 52 | #define CHRG_CCCV_CC_BIT_POS 0 |
|---|
| 60 | 53 | #define CHRG_CCCV_CC_OFFSET 200 /* 200mA */ |
|---|
| 61 | 54 | #define CHRG_CCCV_CC_LSB_RES 200 /* 200mA */ |
|---|
| 62 | | -#define CHRG_CCCV_ITERM_20P (1 << 4) /* 20% of CC */ |
|---|
| 55 | +#define CHRG_CCCV_ITERM_20P BIT(4) /* 20% of CC */ |
|---|
| 63 | 56 | #define CHRG_CCCV_CV_MASK 0x60 /* 2 bits */ |
|---|
| 64 | 57 | #define CHRG_CCCV_CV_BIT_POS 5 |
|---|
| 65 | 58 | #define CHRG_CCCV_CV_4100MV 0x0 /* 4.10V */ |
|---|
| 66 | 59 | #define CHRG_CCCV_CV_4150MV 0x1 /* 4.15V */ |
|---|
| 67 | 60 | #define CHRG_CCCV_CV_4200MV 0x2 /* 4.20V */ |
|---|
| 68 | 61 | #define CHRG_CCCV_CV_4350MV 0x3 /* 4.35V */ |
|---|
| 69 | | -#define CHRG_CCCV_CHG_EN (1 << 7) |
|---|
| 62 | +#define CHRG_CCCV_CHG_EN BIT(7) |
|---|
| 70 | 63 | |
|---|
| 71 | 64 | #define CNTL2_CC_TIMEOUT_MASK 0x3 /* 2 bits */ |
|---|
| 72 | 65 | #define CNTL2_CC_TIMEOUT_OFFSET 6 /* 6 Hrs */ |
|---|
| 73 | 66 | #define CNTL2_CC_TIMEOUT_LSB_RES 2 /* 2 Hrs */ |
|---|
| 74 | 67 | #define CNTL2_CC_TIMEOUT_12HRS 0x3 /* 12 Hrs */ |
|---|
| 75 | | -#define CNTL2_CHGLED_TYPEB (1 << 4) |
|---|
| 76 | | -#define CNTL2_CHG_OUT_TURNON (1 << 5) |
|---|
| 68 | +#define CNTL2_CHGLED_TYPEB BIT(4) |
|---|
| 69 | +#define CNTL2_CHG_OUT_TURNON BIT(5) |
|---|
| 77 | 70 | #define CNTL2_PC_TIMEOUT_MASK 0xC0 |
|---|
| 78 | 71 | #define CNTL2_PC_TIMEOUT_OFFSET 40 /* 40 mins */ |
|---|
| 79 | 72 | #define CNTL2_PC_TIMEOUT_LSB_RES 10 /* 10 mins */ |
|---|
| 80 | 73 | #define CNTL2_PC_TIMEOUT_70MINS 0x3 |
|---|
| 81 | 74 | |
|---|
| 82 | | -#define CHRG_ILIM_TEMP_LOOP_EN (1 << 3) |
|---|
| 75 | +#define CHRG_ILIM_TEMP_LOOP_EN BIT(3) |
|---|
| 83 | 76 | #define CHRG_VBUS_ILIM_MASK 0xf0 |
|---|
| 84 | 77 | #define CHRG_VBUS_ILIM_BIT_POS 4 |
|---|
| 85 | 78 | #define CHRG_VBUS_ILIM_100MA 0x0 /* 100mA */ |
|---|
| .. | .. |
|---|
| 95 | 88 | #define CHRG_VLTFC_0C 0xA5 /* 0 DegC */ |
|---|
| 96 | 89 | #define CHRG_VHTFC_45C 0x1F /* 45 DegC */ |
|---|
| 97 | 90 | |
|---|
| 98 | | -#define FG_CNTL_OCV_ADJ_EN (1 << 3) |
|---|
| 91 | +#define FG_CNTL_OCV_ADJ_EN BIT(3) |
|---|
| 99 | 92 | |
|---|
| 100 | 93 | #define CV_4100MV 4100 /* 4100mV */ |
|---|
| 101 | 94 | #define CV_4150MV 4150 /* 4150mV */ |
|---|
| .. | .. |
|---|
| 751 | 744 | ret = axp288_charger_vbus_path_select(info, true); |
|---|
| 752 | 745 | if (ret < 0) |
|---|
| 753 | 746 | return ret; |
|---|
| 747 | + } else { |
|---|
| 748 | + /* Set Vhold to the factory default / recommended 4.4V */ |
|---|
| 749 | + val = VBUS_ISPOUT_VHOLD_SET_4400MV << VBUS_ISPOUT_VHOLD_SET_BIT_POS; |
|---|
| 750 | + ret = regmap_update_bits(info->regmap, AXP20X_VBUS_IPSOUT_MGMT, |
|---|
| 751 | + VBUS_ISPOUT_VHOLD_SET_MASK, val); |
|---|
| 752 | + if (ret < 0) { |
|---|
| 753 | + dev_err(&info->pdev->dev, "register(%x) write error(%d)\n", |
|---|
| 754 | + AXP20X_VBUS_IPSOUT_MGMT, ret); |
|---|
| 755 | + return ret; |
|---|
| 756 | + } |
|---|
| 754 | 757 | } |
|---|
| 755 | 758 | |
|---|
| 756 | 759 | /* Read current charge voltage and current limit */ |
|---|
| .. | .. |
|---|
| 893 | 896 | /* Register charger interrupts */ |
|---|
| 894 | 897 | for (i = 0; i < CHRG_INTR_END; i++) { |
|---|
| 895 | 898 | pirq = platform_get_irq(info->pdev, i); |
|---|
| 896 | | - if (pirq < 0) { |
|---|
| 897 | | - dev_err(&pdev->dev, "Failed to get IRQ: %d\n", pirq); |
|---|
| 899 | + if (pirq < 0) |
|---|
| 898 | 900 | return pirq; |
|---|
| 899 | | - } |
|---|
| 901 | + |
|---|
| 900 | 902 | info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq); |
|---|
| 901 | 903 | if (info->irq[i] < 0) { |
|---|
| 902 | 904 | dev_warn(&info->pdev->dev, |
|---|