qcom-charger: expose RRADC charger temp and usbin readings

Read the charger die temperature and its threshold from RR_ADC,
and expose to the userspace through battery PSY.

Read USBIN current and voltage from RR_ADC, and expose to the
userspace through USB PSY.

CRs-Fixed: 1050042
Change-Id: I452a050298a6ab081f64aa2dcf295d2d257bcb32
Signed-off-by: Harry Yang <harryy@codeaurora.org>
This commit is contained in:
Harry Yang 2016-08-19 14:17:01 -07:00
parent 26745af012
commit e67aba2720
5 changed files with 184 additions and 26 deletions

View file

@ -80,6 +80,22 @@ Charger specific properties:
offset of charging current in uA, from -3100000 to 3200000.
If the array is not present, step charging is disabled.
- io-channels
Usage: optional
Value type: List of <phandle u32>
Definition: List of phandle and IIO specifier pairs, one pair
for each IIO input to the device. Note: if the
IIO provider specifies '0' for #io-channel-cells,
then only the phandle portion of the pair will appear.
- io-channel-names
Usage: optional
Value type: List of <string>
Definition: List of IIO input name strings sorted in the same
order as the io-channels property. Consumer drivers
will use io-channel-names to match IIO input names
with IIO specifiers.
=============================================
Second Level Nodes - SMB2 Charger Peripherals
=============================================
@ -110,6 +126,9 @@ pmicobalt_charger: qcom,qpnp-smb2 {
#address-cells = <1>;
#size-cells = <1>;
io-channels = <&pmic_rradc 0>;
io-channel-names = "rradc_batt_id";
qcom,suspend-input;
dpdm-supply = <&qusb_phy0>;

View file

@ -145,6 +145,15 @@
qcom,pmic-revid = <&pmicobalt_revid>;
io-channels = <&pmicobalt_rradc 8>,
<&pmicobalt_rradc 10>,
<&pmicobalt_rradc 3>,
<&pmicobalt_rradc 4>;
io-channel-names = "charger_temp",
"charger_temp_max",
"usbin_i",
"usbin_v";
dpdm-supply = <&qusb_phy0>;
qcom,thermal-mitigation

View file

@ -324,6 +324,7 @@ static enum power_supply_property smb2_usb_props[] = {
POWER_SUPPLY_PROP_PD_ALLOWED,
POWER_SUPPLY_PROP_PD_ACTIVE,
POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED,
POWER_SUPPLY_PROP_INPUT_CURRENT_NOW,
};
static int smb2_usb_get_prop(struct power_supply *psy,
@ -383,6 +384,9 @@ static int smb2_usb_get_prop(struct power_supply *psy,
case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED:
rc = smblib_get_prop_input_current_settled(chg, val);
break;
case POWER_SUPPLY_PROP_INPUT_CURRENT_NOW:
rc = smblib_get_prop_usb_current_now(chg, val);
break;
default:
pr_err("get prop %d is not supported\n", psp);
rc = -EINVAL;
@ -582,42 +586,51 @@ static enum power_supply_property smb2_batt_props[] = {
POWER_SUPPLY_PROP_CHARGE_TYPE,
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL,
POWER_SUPPLY_PROP_CHARGER_TEMP,
POWER_SUPPLY_PROP_CHARGER_TEMP_MAX,
};
static int smb2_batt_get_prop(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
int rc;
struct smb_charger *chg = power_supply_get_drvdata(psy);
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
smblib_get_prop_batt_status(chg, val);
rc = smblib_get_prop_batt_status(chg, val);
break;
case POWER_SUPPLY_PROP_HEALTH:
smblib_get_prop_batt_health(chg, val);
rc = smblib_get_prop_batt_health(chg, val);
break;
case POWER_SUPPLY_PROP_PRESENT:
smblib_get_prop_batt_present(chg, val);
rc = smblib_get_prop_batt_present(chg, val);
break;
case POWER_SUPPLY_PROP_INPUT_SUSPEND:
smblib_get_prop_input_suspend(chg, val);
rc = smblib_get_prop_input_suspend(chg, val);
break;
case POWER_SUPPLY_PROP_CHARGE_TYPE:
smblib_get_prop_batt_charge_type(chg, val);
rc = smblib_get_prop_batt_charge_type(chg, val);
break;
case POWER_SUPPLY_PROP_CAPACITY:
smblib_get_prop_batt_capacity(chg, val);
rc = smblib_get_prop_batt_capacity(chg, val);
break;
case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
smblib_get_prop_system_temp_level(chg, val);
rc = smblib_get_prop_system_temp_level(chg, val);
break;
case POWER_SUPPLY_PROP_CHARGER_TEMP:
rc = smblib_get_prop_charger_temp(chg, val);
break;
case POWER_SUPPLY_PROP_CHARGER_TEMP_MAX:
rc = smblib_get_prop_charger_temp_max(chg, val);
break;
default:
pr_err("batt power supply prop %d not supported\n", psp);
return -EINVAL;
}
return 0;
return rc;
}
static int smb2_batt_set_prop(struct power_supply *psy,
@ -1219,7 +1232,11 @@ static int smb2_probe(struct platform_device *pdev)
return -EINVAL;
}
smblib_init(chg);
rc = smblib_init(chg);
if (rc < 0) {
pr_err("Smblib_init failed rc=%d\n", rc);
goto cleanup;
}
rc = smb2_parse_dt(chip);
if (rc < 0) {

View file

@ -12,6 +12,7 @@
#include <linux/device.h>
#include <linux/regmap.h>
#include <linux/iio/consumer.h>
#include <linux/power_supply.h>
#include <linux/regulator/driver.h>
#include <linux/irq.h>
@ -1172,12 +1173,20 @@ int smblib_get_prop_usb_online(struct smb_charger *chg,
int smblib_get_prop_usb_voltage_now(struct smb_charger *chg,
union power_supply_propval *val)
{
if (chg->vbus_present)
val->intval = MICRO_5V;
else
val->intval = 0;
int rc = 0;
return 0;
rc = smblib_get_prop_usb_present(chg, val);
if (rc < 0 || !val->intval)
return rc;
if (!chg->iio.usbin_v_chan ||
PTR_ERR(chg->iio.usbin_v_chan) == -EPROBE_DEFER)
chg->iio.usbin_v_chan = iio_channel_get(chg->dev, "usbin_v");
if (IS_ERR(chg->iio.usbin_v_chan))
return PTR_ERR(chg->iio.usbin_v_chan);
return iio_read_channel_processed(chg->iio.usbin_v_chan, &val->intval);
}
int smblib_get_prop_usb_current_max(struct smb_charger *chg,
@ -1187,6 +1196,59 @@ int smblib_get_prop_usb_current_max(struct smb_charger *chg,
return 0;
}
int smblib_get_prop_usb_current_now(struct smb_charger *chg,
union power_supply_propval *val)
{
int rc = 0;
rc = smblib_get_prop_usb_present(chg, val);
if (rc < 0 || !val->intval)
return rc;
if (!chg->iio.usbin_i_chan ||
PTR_ERR(chg->iio.usbin_i_chan) == -EPROBE_DEFER)
chg->iio.usbin_i_chan = iio_channel_get(chg->dev, "usbin_i");
if (IS_ERR(chg->iio.usbin_i_chan))
return PTR_ERR(chg->iio.usbin_i_chan);
return iio_read_channel_processed(chg->iio.usbin_i_chan, &val->intval);
}
int smblib_get_prop_charger_temp(struct smb_charger *chg,
union power_supply_propval *val)
{
int rc;
if (!chg->iio.temp_chan ||
PTR_ERR(chg->iio.temp_chan) == -EPROBE_DEFER)
chg->iio.temp_chan = iio_channel_get(chg->dev, "charger_temp");
if (IS_ERR(chg->iio.temp_chan))
return PTR_ERR(chg->iio.temp_chan);
rc = iio_read_channel_processed(chg->iio.temp_chan, &val->intval);
val->intval /= 100;
return rc;
}
int smblib_get_prop_charger_temp_max(struct smb_charger *chg,
union power_supply_propval *val)
{
int rc;
if (!chg->iio.temp_max_chan ||
PTR_ERR(chg->iio.temp_max_chan) == -EPROBE_DEFER)
chg->iio.temp_max_chan = iio_channel_get(chg->dev,
"charger_temp_max");
if (IS_ERR(chg->iio.temp_max_chan))
return PTR_ERR(chg->iio.temp_max_chan);
rc = iio_read_channel_processed(chg->iio.temp_max_chan, &val->intval);
val->intval /= 100;
return rc;
}
int smblib_get_prop_typec_cc_orientation(struct smb_charger *chg,
union power_supply_propval *val)
{
@ -1992,7 +2054,7 @@ done:
vote(chg->awake_votable, PL_VOTER, false, 0);
}
int smblib_create_votables(struct smb_charger *chg)
static int smblib_create_votables(struct smb_charger *chg)
{
int rc = 0;
@ -2086,6 +2148,42 @@ int smblib_create_votables(struct smb_charger *chg)
return rc;
}
static void smblib_destroy_votables(struct smb_charger *chg)
{
if (chg->usb_suspend_votable)
destroy_votable(chg->usb_suspend_votable);
if (chg->dc_suspend_votable)
destroy_votable(chg->dc_suspend_votable);
if (chg->fcc_max_votable)
destroy_votable(chg->fcc_max_votable);
if (chg->fcc_votable)
destroy_votable(chg->fcc_votable);
if (chg->fv_votable)
destroy_votable(chg->fv_votable);
if (chg->usb_icl_votable)
destroy_votable(chg->usb_icl_votable);
if (chg->dc_icl_votable)
destroy_votable(chg->dc_icl_votable);
if (chg->pd_allowed_votable)
destroy_votable(chg->pd_allowed_votable);
if (chg->awake_votable)
destroy_votable(chg->awake_votable);
if (chg->pl_disable_votable)
destroy_votable(chg->pl_disable_votable);
}
static void smblib_iio_deinit(struct smb_charger *chg)
{
if (!IS_ERR_OR_NULL(chg->iio.temp_chan))
iio_channel_release(chg->iio.temp_chan);
if (!IS_ERR_OR_NULL(chg->iio.temp_max_chan))
iio_channel_release(chg->iio.temp_max_chan);
if (!IS_ERR_OR_NULL(chg->iio.usbin_i_chan))
iio_channel_release(chg->iio.usbin_i_chan);
if (!IS_ERR_OR_NULL(chg->iio.usbin_v_chan))
iio_channel_release(chg->iio.usbin_v_chan);
}
int smblib_init(struct smb_charger *chg)
{
int rc = 0;
@ -2130,18 +2228,19 @@ int smblib_init(struct smb_charger *chg)
int smblib_deinit(struct smb_charger *chg)
{
destroy_votable(chg->usb_suspend_votable);
destroy_votable(chg->dc_suspend_votable);
destroy_votable(chg->fcc_max_votable);
destroy_votable(chg->fcc_votable);
destroy_votable(chg->fv_votable);
destroy_votable(chg->usb_icl_votable);
destroy_votable(chg->dc_icl_votable);
destroy_votable(chg->pd_allowed_votable);
destroy_votable(chg->awake_votable);
destroy_votable(chg->pl_disable_votable);
switch (chg->mode) {
case PARALLEL_MASTER:
power_supply_unreg_notifier(&chg->nb);
smblib_destroy_votables(chg);
break;
case PARALLEL_SLAVE:
break;
default:
dev_err(chg->dev, "Unsupported mode %d\n", chg->mode);
return -EINVAL;
}
power_supply_unreg_notifier(&chg->nb);
smblib_iio_deinit(chg);
return 0;
}

View file

@ -88,10 +88,18 @@ struct parallel_params {
int slave_fcc;
};
struct smb_iio {
struct iio_channel *temp_chan;
struct iio_channel *temp_max_chan;
struct iio_channel *usbin_i_chan;
struct iio_channel *usbin_v_chan;
};
struct smb_charger {
struct device *dev;
struct regmap *regmap;
struct smb_params param;
struct smb_iio iio;
int *debug_mask;
enum smb_mode mode;
@ -236,6 +244,8 @@ int smblib_get_prop_usb_voltage_now(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_usb_current_max(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_usb_current_now(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_typec_cc_orientation(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_typec_mode(struct smb_charger *chg,
@ -246,6 +256,10 @@ int smblib_get_prop_pd_allowed(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_input_current_settled(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_charger_temp(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_charger_temp_max(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_set_prop_usb_current_max(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_set_prop_usb_voltage_min(struct smb_charger *chg,