qpnp-fg-gen3: add algorithm flags debugfs file
The fuel gauge has several algorithm flags which are useful for debugging. Add a debugfs file called alg_flags to expose them. Change-Id: Ibeeea88e2e0745e98e8bfdfa3e086263d82e7bac Signed-off-by: Nicholas Troast <ntroast@codeaurora.org>
This commit is contained in:
parent
46692be6dd
commit
a3946ad93e
3 changed files with 188 additions and 27 deletions
|
@ -114,6 +114,7 @@ enum fg_sram_param_id {
|
|||
FG_SRAM_VOLTAGE_PRED,
|
||||
FG_SRAM_OCV,
|
||||
FG_SRAM_RSLOW,
|
||||
FG_SRAM_ALG_FLAGS,
|
||||
/* Entries below here are configurable during initialization */
|
||||
FG_SRAM_CUTOFF_VOLT,
|
||||
FG_SRAM_EMPTY_VOLT,
|
||||
|
@ -143,6 +144,23 @@ struct fg_sram_param {
|
|||
int val);
|
||||
};
|
||||
|
||||
enum fg_alg_flag_id {
|
||||
ALG_FLAG_SOC_LT_OTG_MIN = 0,
|
||||
ALG_FLAG_SOC_LT_RECHARGE,
|
||||
ALG_FLAG_IBATT_LT_ITERM,
|
||||
ALG_FLAG_IBATT_GT_HPM,
|
||||
ALG_FLAG_IBATT_GT_UPM,
|
||||
ALG_FLAG_VBATT_LT_RECHARGE,
|
||||
ALG_FLAG_VBATT_GT_VFLOAT,
|
||||
ALG_FLAG_MAX,
|
||||
};
|
||||
|
||||
struct fg_alg_flag {
|
||||
char *name;
|
||||
u8 bit;
|
||||
bool invalid;
|
||||
};
|
||||
|
||||
/* DT parameters for FG device */
|
||||
struct fg_dt_props {
|
||||
int cutoff_volt_mv;
|
||||
|
@ -179,7 +197,7 @@ struct fg_chip {
|
|||
struct device *dev;
|
||||
struct pmic_revid_data *pmic_rev_id;
|
||||
struct regmap *regmap;
|
||||
struct dentry *dentry;
|
||||
struct dentry *dfs_root;
|
||||
struct power_supply *fg_psy;
|
||||
struct power_supply *batt_psy;
|
||||
struct iio_channel *batt_id_chan;
|
||||
|
@ -205,6 +223,7 @@ struct fg_chip {
|
|||
struct completion soc_ready;
|
||||
struct delayed_work profile_load_work;
|
||||
struct work_struct status_change_work;
|
||||
struct fg_alg_flag *alg_flags;
|
||||
};
|
||||
|
||||
/* Debugfs data structures are below */
|
||||
|
@ -249,7 +268,7 @@ extern int fg_read(struct fg_chip *chip, int addr, u8 *val, int len);
|
|||
extern int fg_write(struct fg_chip *chip, int addr, u8 *val, int len);
|
||||
extern int fg_masked_write(struct fg_chip *chip, int addr, u8 mask, u8 val);
|
||||
extern int fg_ima_init(struct fg_chip *chip);
|
||||
extern int fg_sram_debugfs_create(struct fg_chip *chip);
|
||||
extern int fg_debugfs_create(struct fg_chip *chip);
|
||||
extern void fill_string(char *str, size_t str_len, u8 *buf, int buf_len);
|
||||
extern int64_t twos_compliment_extend(int64_t val, int s_bit_pos);
|
||||
extern s64 fg_float_decode(u16 val);
|
||||
|
|
|
@ -611,27 +611,23 @@ static const struct file_operations fg_sram_dfs_reg_fops = {
|
|||
* fg_debugfs_create: adds new fg_sram debugfs entry
|
||||
* @return zero on success
|
||||
*/
|
||||
int fg_sram_debugfs_create(struct fg_chip *chip)
|
||||
static int fg_sram_debugfs_create(struct fg_chip *chip)
|
||||
{
|
||||
struct dentry *root;
|
||||
struct dentry *dfs_sram;
|
||||
struct dentry *file;
|
||||
mode_t dfs_mode = S_IRUSR | S_IWUSR;
|
||||
|
||||
pr_debug("Creating FG_SRAM debugfs file-system\n");
|
||||
root = debugfs_create_dir("fg_sram", NULL);
|
||||
if (IS_ERR_OR_NULL(root)) {
|
||||
pr_err("Error creating top level directory err:%ld",
|
||||
(long)root);
|
||||
if (PTR_ERR(root) == -ENODEV)
|
||||
pr_err("debugfs is not enabled in the kernel");
|
||||
return -ENODEV;
|
||||
dfs_sram = debugfs_create_dir("sram", chip->dfs_root);
|
||||
if (!dfs_sram) {
|
||||
pr_err("error creating fg sram dfs rc=%ld\n",
|
||||
(long)dfs_sram);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!root)
|
||||
return -ENOENT;
|
||||
|
||||
dbgfs_data.help_msg.size = strlen(dbgfs_data.help_msg.data);
|
||||
file = debugfs_create_blob("help", S_IRUGO, root, &dbgfs_data.help_msg);
|
||||
file = debugfs_create_blob("help", S_IRUGO, dfs_sram,
|
||||
&dbgfs_data.help_msg);
|
||||
if (!file) {
|
||||
pr_err("error creating help entry\n");
|
||||
goto err_remove_fs;
|
||||
|
@ -639,30 +635,106 @@ int fg_sram_debugfs_create(struct fg_chip *chip)
|
|||
|
||||
dbgfs_data.chip = chip;
|
||||
|
||||
file = debugfs_create_u32("count", dfs_mode, root, &(dbgfs_data.cnt));
|
||||
file = debugfs_create_u32("count", dfs_mode, dfs_sram,
|
||||
&(dbgfs_data.cnt));
|
||||
if (!file) {
|
||||
pr_err("error creating 'count' entry\n");
|
||||
goto err_remove_fs;
|
||||
}
|
||||
|
||||
file = debugfs_create_x32("address", dfs_mode,
|
||||
root, &(dbgfs_data.addr));
|
||||
file = debugfs_create_x32("address", dfs_mode, dfs_sram,
|
||||
&(dbgfs_data.addr));
|
||||
if (!file) {
|
||||
pr_err("error creating 'address' entry\n");
|
||||
goto err_remove_fs;
|
||||
}
|
||||
|
||||
file = debugfs_create_file("data", dfs_mode, root, &dbgfs_data,
|
||||
&fg_sram_dfs_reg_fops);
|
||||
file = debugfs_create_file("data", dfs_mode, dfs_sram, &dbgfs_data,
|
||||
&fg_sram_dfs_reg_fops);
|
||||
if (!file) {
|
||||
pr_err("error creating 'data' entry\n");
|
||||
goto err_remove_fs;
|
||||
}
|
||||
|
||||
chip->dentry = root;
|
||||
return 0;
|
||||
|
||||
err_remove_fs:
|
||||
debugfs_remove_recursive(root);
|
||||
debugfs_remove_recursive(dfs_sram);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int fg_alg_flags_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
file->private_data = inode->i_private;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t fg_alg_flags_read(struct file *file, char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct fg_chip *chip = file->private_data;
|
||||
char buf[512];
|
||||
u8 alg_flags = 0;
|
||||
int rc, i, len;
|
||||
|
||||
rc = fg_sram_read(chip, chip->sp[FG_SRAM_ALG_FLAGS].addr_word,
|
||||
chip->sp[FG_SRAM_ALG_FLAGS].addr_byte, &alg_flags, 1,
|
||||
FG_IMA_DEFAULT);
|
||||
if (rc < 0) {
|
||||
pr_err("failed to read algorithm flags rc=%d\n", rc);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
len = 0;
|
||||
for (i = 0; i < ALG_FLAG_MAX; ++i) {
|
||||
if (len > ARRAY_SIZE(buf) - 1)
|
||||
return -EFAULT;
|
||||
if (chip->alg_flags[i].invalid)
|
||||
continue;
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - sizeof(*buf) * len,
|
||||
"%s = %d\n", chip->alg_flags[i].name,
|
||||
(bool)(alg_flags & chip->alg_flags[i].bit));
|
||||
}
|
||||
|
||||
return simple_read_from_buffer(userbuf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
static const struct file_operations fg_alg_flags_fops = {
|
||||
.open = fg_alg_flags_open,
|
||||
.read = fg_alg_flags_read,
|
||||
};
|
||||
|
||||
int fg_debugfs_create(struct fg_chip *chip)
|
||||
{
|
||||
int rc;
|
||||
|
||||
pr_debug("Creating debugfs file-system\n");
|
||||
chip->dfs_root = debugfs_create_dir("fg", NULL);
|
||||
if (IS_ERR_OR_NULL(chip->dfs_root)) {
|
||||
if (PTR_ERR(chip->dfs_root) == -ENODEV)
|
||||
pr_err("debugfs is not enabled in the kernel\n");
|
||||
else
|
||||
pr_err("error creating fg dfs root rc=%ld\n",
|
||||
(long)chip->dfs_root);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
rc = fg_sram_debugfs_create(chip);
|
||||
if (rc < 0) {
|
||||
pr_err("failed to create sram dfs rc=%d\n", rc);
|
||||
goto err_remove_fs;
|
||||
}
|
||||
|
||||
if (!debugfs_create_file("alg_flags", S_IRUSR, chip->dfs_root, chip,
|
||||
&fg_alg_flags_fops)) {
|
||||
pr_err("failed to create alg_flags file\n");
|
||||
goto err_remove_fs;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_remove_fs:
|
||||
debugfs_remove_recursive(chip->dfs_root);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
|
@ -73,6 +73,8 @@
|
|||
#define LAST_BATT_SOC_OFFSET 0
|
||||
#define LAST_MONOTONIC_SOC_WORD 119
|
||||
#define LAST_MONOTONIC_SOC_OFFSET 2
|
||||
#define ALG_FLAGS_WORD 120
|
||||
#define ALG_FLAGS_OFFSET 1
|
||||
|
||||
/* v2 SRAM address and offset in ascending order */
|
||||
#define DELTA_SOC_THR_v2_WORD 13
|
||||
|
@ -119,6 +121,8 @@ static struct fg_sram_param pmicobalt_v1_sram_params[] = {
|
|||
fg_decode_value_16b),
|
||||
PARAM(RSLOW, RSLOW_WORD, RSLOW_OFFSET, 2, 244141, 1000, 0, NULL,
|
||||
fg_decode_value_16b),
|
||||
PARAM(ALG_FLAGS, ALG_FLAGS_WORD, ALG_FLAGS_OFFSET, 1, 1, 1, 0, NULL,
|
||||
fg_decode_default),
|
||||
/* Entries below here are configurable during initialization */
|
||||
PARAM(CUTOFF_VOLT, CUTOFF_VOLT_WORD, CUTOFF_VOLT_OFFSET, 2, 1000000,
|
||||
244141, 0, fg_encode_voltage, NULL),
|
||||
|
@ -155,6 +159,8 @@ static struct fg_sram_param pmicobalt_v2_sram_params[] = {
|
|||
fg_decode_value_16b),
|
||||
PARAM(RSLOW, RSLOW_WORD, RSLOW_OFFSET, 2, 244141, 1000, 0, NULL,
|
||||
fg_decode_value_16b),
|
||||
PARAM(ALG_FLAGS, ALG_FLAGS_WORD, ALG_FLAGS_OFFSET, 1, 1, 1, 0, NULL,
|
||||
fg_decode_default),
|
||||
/* Entries below here are configurable during initialization */
|
||||
PARAM(CUTOFF_VOLT, CUTOFF_VOLT_WORD, CUTOFF_VOLT_OFFSET, 2, 1000000,
|
||||
244141, 0, fg_encode_voltage, NULL),
|
||||
|
@ -183,6 +189,67 @@ static struct fg_sram_param pmicobalt_v2_sram_params[] = {
|
|||
ESR_TIMER_CHG_INIT_OFFSET, 2, 1, 1, 0, fg_encode_default, NULL),
|
||||
};
|
||||
|
||||
static struct fg_alg_flag pmicobalt_v1_alg_flags[] = {
|
||||
[ALG_FLAG_SOC_LT_OTG_MIN] = {
|
||||
.name = "SOC_LT_OTG_MIN",
|
||||
.bit = BIT(0),
|
||||
},
|
||||
[ALG_FLAG_SOC_LT_RECHARGE] = {
|
||||
.name = "SOC_LT_RECHARGE",
|
||||
.bit = BIT(1),
|
||||
},
|
||||
[ALG_FLAG_IBATT_LT_ITERM] = {
|
||||
.name = "IBATT_LT_ITERM",
|
||||
.bit = BIT(2),
|
||||
},
|
||||
[ALG_FLAG_IBATT_GT_HPM] = {
|
||||
.name = "IBATT_GT_HPM",
|
||||
.bit = BIT(3),
|
||||
},
|
||||
[ALG_FLAG_IBATT_GT_UPM] = {
|
||||
.name = "IBATT_GT_UPM",
|
||||
.bit = BIT(4),
|
||||
},
|
||||
[ALG_FLAG_VBATT_LT_RECHARGE] = {
|
||||
.name = "VBATT_LT_RECHARGE",
|
||||
.bit = BIT(5),
|
||||
},
|
||||
[ALG_FLAG_VBATT_GT_VFLOAT] = {
|
||||
.invalid = true,
|
||||
},
|
||||
};
|
||||
|
||||
static struct fg_alg_flag pmicobalt_v2_alg_flags[] = {
|
||||
[ALG_FLAG_SOC_LT_OTG_MIN] = {
|
||||
.name = "SOC_LT_OTG_MIN",
|
||||
.bit = BIT(0),
|
||||
},
|
||||
[ALG_FLAG_SOC_LT_RECHARGE] = {
|
||||
.name = "SOC_LT_RECHARGE",
|
||||
.bit = BIT(1),
|
||||
},
|
||||
[ALG_FLAG_IBATT_LT_ITERM] = {
|
||||
.name = "IBATT_LT_ITERM",
|
||||
.bit = BIT(2),
|
||||
},
|
||||
[ALG_FLAG_IBATT_GT_HPM] = {
|
||||
.name = "IBATT_GT_HPM",
|
||||
.bit = BIT(4),
|
||||
},
|
||||
[ALG_FLAG_IBATT_GT_UPM] = {
|
||||
.name = "IBATT_GT_UPM",
|
||||
.bit = BIT(5),
|
||||
},
|
||||
[ALG_FLAG_VBATT_LT_RECHARGE] = {
|
||||
.name = "VBATT_LT_RECHARGE",
|
||||
.bit = BIT(6),
|
||||
},
|
||||
[ALG_FLAG_VBATT_GT_VFLOAT] = {
|
||||
.name = "VBATT_GT_VFLOAT",
|
||||
.bit = BIT(7),
|
||||
},
|
||||
};
|
||||
|
||||
static int fg_gen3_debug_mask;
|
||||
module_param_named(
|
||||
debug_mask, fg_gen3_debug_mask, int, S_IRUSR | S_IWUSR
|
||||
|
@ -1318,12 +1385,15 @@ static int fg_parse_dt(struct fg_chip *chip)
|
|||
|
||||
switch (chip->pmic_rev_id->pmic_subtype) {
|
||||
case PMICOBALT_SUBTYPE:
|
||||
if (chip->pmic_rev_id->rev4 < PMICOBALT_V2P0_REV4)
|
||||
if (chip->pmic_rev_id->rev4 < PMICOBALT_V2P0_REV4) {
|
||||
chip->sp = pmicobalt_v1_sram_params;
|
||||
else if (chip->pmic_rev_id->rev4 == PMICOBALT_V2P0_REV4)
|
||||
chip->alg_flags = pmicobalt_v1_alg_flags;
|
||||
} else if (chip->pmic_rev_id->rev4 == PMICOBALT_V2P0_REV4) {
|
||||
chip->sp = pmicobalt_v2_sram_params;
|
||||
else
|
||||
chip->alg_flags = pmicobalt_v2_alg_flags;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
@ -1465,7 +1535,7 @@ static int fg_parse_dt(struct fg_chip *chip)
|
|||
static void fg_cleanup(struct fg_chip *chip)
|
||||
{
|
||||
power_supply_unreg_notifier(&chip->nb);
|
||||
debugfs_remove_recursive(chip->dentry);
|
||||
debugfs_remove_recursive(chip->dfs_root);
|
||||
if (chip->awake_votable)
|
||||
destroy_votable(chip->awake_votable);
|
||||
|
||||
|
@ -1562,7 +1632,7 @@ static int fg_gen3_probe(struct platform_device *pdev)
|
|||
if (fg_irqs[SOC_UPDATE_IRQ].irq)
|
||||
disable_irq_nosync(fg_irqs[SOC_UPDATE_IRQ].irq);
|
||||
|
||||
rc = fg_sram_debugfs_create(chip);
|
||||
rc = fg_debugfs_create(chip);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "Error in creating debugfs entries, rc:%d\n",
|
||||
rc);
|
||||
|
|
Loading…
Add table
Reference in a new issue