mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 05:39:54 -04:00
p938x_charger: read epp capabilities
Read EPP power capabilities. Provide this information in tx_capabilties sysfs file. Also use this information to set the dc current limit. A new sysfs entry has been provided at force_idc to override this. Change-Id: I27102a273ee14bc878a5026b99ebacb6fb23e430 Signed-off-by: Ryan Lattrel <ryanl@motorola.com> Reviewed-on: https://gerrit.mot.com/1461865 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Cesar Augusto Marcelino dos Santos <cmsantos@motorola.com> Reviewed-by: Ling Jin <lingjin@motorola.com> Submit-Approved: Jira Key
This commit is contained in:
parent
af55ab1653
commit
73ff838453
1 changed files with 151 additions and 0 deletions
|
|
@ -75,6 +75,9 @@
|
|||
#define SYS_MODE_REG 0x004a
|
||||
#define SYS_CMD_REG 0x004C
|
||||
|
||||
#define EPP_TX_GUARANTEED 0x0084
|
||||
#define EPP_TX_POTENTIAL 0x0085
|
||||
|
||||
#define ST_TX_FOD_FAULT BIT(15)
|
||||
#define ST_TX_CONFLICT BIT(14)
|
||||
#define ST_RX_CONN BIT(13)
|
||||
|
|
@ -108,8 +111,10 @@
|
|||
|
||||
#define BPP_MAX_VOUT 5000
|
||||
#define BPP_MAX_IOUT 1600
|
||||
#define BPP_MAX_IDC 1000
|
||||
#define EPP_MAX_VOUT 12000
|
||||
#define EPP_MAX_IOUT 1600
|
||||
#define EPP_MAX_IDC 1250
|
||||
|
||||
#define MIN_VOUT_SET 5000
|
||||
#define MAX_VOUT_SET 12000
|
||||
|
|
@ -225,6 +230,7 @@ struct p938x_charger {
|
|||
|
||||
u16 wls_vout_max;
|
||||
u16 wls_iout_max;
|
||||
int wls_idc_max;
|
||||
|
||||
u16 stat;
|
||||
u16 irq_stat;
|
||||
|
|
@ -247,6 +253,20 @@ struct p938x_charger {
|
|||
bool epp_mode;
|
||||
};
|
||||
|
||||
struct p938x_limits {
|
||||
unsigned int tx_capability_mw;
|
||||
unsigned long idc_max_ma;
|
||||
};
|
||||
|
||||
/* Lowest mW first, highest mW last */
|
||||
static struct p938x_limits p938x_epp_limits[] = {
|
||||
{10000, 850},
|
||||
{15000, 1250},
|
||||
};
|
||||
|
||||
static const int p938x_epp_limit_num =
|
||||
sizeof(p938x_epp_limits) / sizeof(struct p938x_limits);
|
||||
|
||||
#define WLS_FLAG_BOOST_ENABLED 0
|
||||
#define WLS_FLAG_TX_ATTACHED 1
|
||||
#define WLS_FLAG_KEEP_AWAKE 2
|
||||
|
|
@ -732,6 +752,20 @@ static int p938x_set_dc_en_override(struct p938x_charger *chip, int en)
|
|||
val);
|
||||
}
|
||||
|
||||
static int p938x_set_dc_max_icl_ma(struct p938x_charger *chip, unsigned int idc)
|
||||
{
|
||||
union power_supply_propval val;
|
||||
|
||||
p938x_dbg(chip, PR_MOTO, "Setting IDC to %u mA\n", idc);
|
||||
|
||||
idc *= 1000; /* Convert to uA */
|
||||
val.intval = idc;
|
||||
|
||||
return p938x_set_dc_psp_prop(chip,
|
||||
POWER_SUPPLY_PROP_CURRENT_MAX,
|
||||
val);
|
||||
}
|
||||
|
||||
static inline void p938x_set_tx_mode(struct p938x_charger *chip, int val)
|
||||
{
|
||||
u8 buf = 0;
|
||||
|
|
@ -1087,10 +1121,32 @@ release_fw:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int p938x_get_tx_capability(struct p938x_charger *chip, int *guaranteed,
|
||||
int *potential)
|
||||
{
|
||||
u8 tmp;
|
||||
|
||||
if (!p938x_read_reg(chip, EPP_TX_POTENTIAL, &tmp))
|
||||
*potential = 500 * tmp;
|
||||
else
|
||||
return 1;
|
||||
|
||||
if (!p938x_read_reg(chip, EPP_TX_GUARANTEED, &tmp))
|
||||
*guaranteed = 500 * tmp;
|
||||
else
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int p938x_check_system_mode(struct p938x_charger *chip)
|
||||
{
|
||||
int rc;
|
||||
int i;
|
||||
u8 mode = 0;
|
||||
int tx_guaranteed;
|
||||
int tx_potential;
|
||||
struct p938x_limits epp_limit = p938x_epp_limits[0];
|
||||
|
||||
rc = p938x_read_buffer(chip, SYS_MODE_REG, &mode, 1);
|
||||
if (rc < 0)
|
||||
|
|
@ -1107,10 +1163,34 @@ static int p938x_check_system_mode(struct p938x_charger *chip)
|
|||
if (mode & SYS_MODE_EXTENDED) {
|
||||
p938x_dbg(chip, PR_INTERRUPT, "MODE: SYS_MODE_EXTENDED\n");
|
||||
chip->epp_mode = true;
|
||||
|
||||
if (!p938x_get_tx_capability(chip, &tx_guaranteed, &tx_potential)) {
|
||||
p938x_dbg(chip, PR_INTERRUPT, "EPP GUARANTEED %dmW, POTENTIAL %dmW\n",
|
||||
tx_guaranteed, tx_potential);
|
||||
|
||||
/* Default value is the lowest setting, start at the highest setting
|
||||
* and go backwards, if we find one more appropriate use that one
|
||||
* instead
|
||||
*/
|
||||
for(i=p938x_epp_limit_num-1; i >= 0; i--) {
|
||||
if(tx_potential >= p938x_epp_limits[i].tx_capability_mw) {
|
||||
epp_limit = p938x_epp_limits[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
p938x_dbg(chip, PR_INTERRUPT, "EPP LIMIT is %d mW -> %lu mA\n",
|
||||
epp_limit.tx_capability_mw, epp_limit.idc_max_ma);
|
||||
|
||||
p938x_set_dc_max_icl_ma(chip, epp_limit.idc_max_ma);
|
||||
} else
|
||||
p938x_set_dc_max_icl_ma(chip, EPP_MAX_IDC);
|
||||
|
||||
p938x_set_rx_vout(chip, EPP_MAX_VOUT);
|
||||
p938x_set_rx_ocl(chip, EPP_MAX_IOUT);
|
||||
} else {
|
||||
chip->epp_mode = false;
|
||||
p938x_set_dc_max_icl_ma(chip, BPP_MAX_IDC);
|
||||
p938x_set_rx_vout(chip, BPP_MAX_VOUT);
|
||||
p938x_set_rx_ocl(chip, BPP_MAX_IOUT);
|
||||
}
|
||||
|
|
@ -1120,6 +1200,8 @@ static int p938x_check_system_mode(struct p938x_charger *chip)
|
|||
p938x_set_rx_vout(chip, chip->wls_vout_max);
|
||||
if(chip->wls_iout_max)
|
||||
p938x_set_rx_ocl(chip, chip->wls_iout_max);
|
||||
if(chip->wls_idc_max)
|
||||
p938x_set_dc_max_icl_ma(chip, chip->wls_idc_max);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -1358,6 +1440,46 @@ static ssize_t boost_show(struct device *dev,
|
|||
return scnprintf(buf, WLS_SHOW_MAX_SIZE, "%d\n",
|
||||
p938x_get_boost(chip));
|
||||
}
|
||||
|
||||
static ssize_t force_idc_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long r;
|
||||
unsigned long value;
|
||||
struct p938x_charger *chip = dev_get_drvdata(dev);
|
||||
|
||||
r = kstrtoul(buf, 0, &value);
|
||||
if (r) {
|
||||
p938x_err(chip, "Invalid idc value = %ld\n", value);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Store to persist change */
|
||||
chip->wls_idc_max = value;
|
||||
|
||||
p938x_set_dc_max_icl_ma(chip, value);
|
||||
|
||||
return r ? r : count;
|
||||
}
|
||||
|
||||
static ssize_t force_idc_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
int rc;
|
||||
union power_supply_propval prop = {0,};
|
||||
struct p938x_charger *chip = dev_get_drvdata(dev);
|
||||
|
||||
rc = power_supply_get_property(chip->dc_psy,
|
||||
POWER_SUPPLY_PROP_CURRENT_MAX, &prop);
|
||||
if (rc) {
|
||||
p938x_err(chip, "Couldn't read IDC prop, rc=%d\n", rc);
|
||||
return scnprintf(buf, WLS_SHOW_MAX_SIZE, "Unknown\n");
|
||||
}
|
||||
|
||||
return scnprintf(buf, WLS_SHOW_MAX_SIZE, "%d\n",
|
||||
prop.intval / 1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
static ssize_t tx_mode_store(struct device *dev,
|
||||
|
|
@ -1501,9 +1623,29 @@ static ssize_t program_fw_store(struct device *dev,
|
|||
return r ? r : count;
|
||||
}
|
||||
|
||||
static ssize_t tx_capability_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct p938x_charger *chip = dev_get_drvdata(dev);
|
||||
int tx_potential;
|
||||
int tx_guaranteed;
|
||||
|
||||
if (!test_bit(WLS_FLAG_TX_ATTACHED, &chip->flags))
|
||||
return scnprintf(buf, WLS_SHOW_MAX_SIZE, "No charger attached\n");
|
||||
|
||||
if (chip->epp_mode) {
|
||||
if (!p938x_get_tx_capability(chip, &tx_guaranteed, &tx_potential))
|
||||
return scnprintf(buf, WLS_SHOW_MAX_SIZE, "EPP %dmW\n", tx_potential);
|
||||
else
|
||||
return scnprintf(buf, WLS_SHOW_MAX_SIZE, "EPP Unknown\n");
|
||||
} else
|
||||
return scnprintf(buf, WLS_SHOW_MAX_SIZE, "BPP\n");
|
||||
}
|
||||
|
||||
#ifdef P938X_USER_DEBUG
|
||||
static DEVICE_ATTR(usb_keep_on, S_IRUGO|S_IWUSR, usb_keep_on_show, usb_keep_on_store);
|
||||
static DEVICE_ATTR(boost, S_IRUGO|S_IWUSR, boost_show, boost_store);
|
||||
static DEVICE_ATTR(force_idc, S_IRUGO|S_IWUSR, force_idc_show, force_idc_store);
|
||||
#endif
|
||||
static DEVICE_ATTR(tx_mode, S_IRUGO|S_IWUSR, tx_mode_show, tx_mode_store);
|
||||
static DEVICE_ATTR(chip_id, S_IRUGO, chip_id_show, NULL);
|
||||
|
|
@ -1514,11 +1656,13 @@ static DEVICE_ATTR(fw_ver, S_IRUGO, fw_ver_show, NULL);
|
|||
static DEVICE_ATTR(fw_name, S_IWUSR, NULL, fw_name_store);
|
||||
static DEVICE_ATTR(program_fw_stat, S_IRUGO, program_fw_stat_show, NULL);
|
||||
static DEVICE_ATTR(program_fw, S_IWUSR, NULL, program_fw_store);
|
||||
static DEVICE_ATTR(tx_capability, S_IRUGO, tx_capability_show, NULL);
|
||||
|
||||
static struct attribute *p938x_attrs[] = {
|
||||
#ifdef P938X_USER_DEBUG
|
||||
&dev_attr_usb_keep_on.attr,
|
||||
&dev_attr_boost.attr,
|
||||
&dev_attr_force_idc.attr,
|
||||
#endif
|
||||
&dev_attr_tx_mode.attr,
|
||||
&dev_attr_chip_id_max.attr,
|
||||
|
|
@ -1529,6 +1673,7 @@ static struct attribute *p938x_attrs[] = {
|
|||
&dev_attr_fw_name.attr,
|
||||
&dev_attr_program_fw_stat.attr,
|
||||
&dev_attr_program_fw.attr,
|
||||
&dev_attr_tx_capability.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -1598,6 +1743,10 @@ static int show_dump_regs(struct seq_file *m, void *data)
|
|||
seq_printf(m, "ILIMIT_SET: %dmA\n", buf[0] * 100 + 100);
|
||||
p938x_read_reg(chip, SYS_MODE_REG, &buf[0]);
|
||||
seq_printf(m, "SYS_MODE: 0x%02x\n", buf[0]);
|
||||
p938x_read_reg(chip, EPP_TX_GUARANTEED, &buf[0]);
|
||||
seq_printf(m, "EPP_TX_GUARANTEED: 0x%02x\n", buf[0]);
|
||||
p938x_read_reg(chip, EPP_TX_POTENTIAL, &buf[0]);
|
||||
seq_printf(m, "EPP_TX_POTENTIAL: 0x%02x\n", buf[0]);
|
||||
|
||||
show_dump_flags(m, chip);
|
||||
|
||||
|
|
@ -1834,8 +1983,10 @@ static int p938x_wls_prop_is_writeable(struct power_supply *psy,
|
|||
int rc;
|
||||
|
||||
switch (psp) {
|
||||
#ifdef P938X_USER_DEBUG
|
||||
case POWER_SUPPLY_PROP_CURRENT_MAX:
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
|
||||
#endif
|
||||
case POWER_SUPPLY_PROP_CHARGING_ENABLED:
|
||||
rc = 1;
|
||||
break;
|
||||
|
|
|
|||
Loading…
Reference in a new issue