Add register dump interface for WL2864C..

Add register dump interface to monitor PMIC when camera exception observed.
2 different ways can observe the WL2864C register dump from kernel log:
- Call kernel regulator API: regulator_get_error_flags()
- ADB command:
  adb shell "cat /sys/class/regulator/regulator.90/status"

The regulator name regulator.90 shall be replaced acording to different products.
We may execute:
adb shell "cat /sys/class/regulator/regulator.*/name"
to observe the regulator name and find out the correct number for your debugging regulator.

Change-Id: Idc33fcbab7ae108d579d934d0f4139476da38967
Signed-off-by: chenglong1 <chenglong1@lenovo.com>
Reviewed-on: https://gerrit.mot.com/1863819
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Wang Liu <liuwang2@lenovo.com>
Reviewed-by: Long Cheng <chengl1@motorola.com>
Reviewed-by: Jian Zhang <zhangjo@motorola.com>
Reviewed-by: Zhenxin Xi <xizx@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
chenglong1 2021-01-28 14:16:58 +08:00 • committed by Wang Liu
commit b218791597
2 changed files with 45 additions and 16 deletions

View file

@ -37,7 +37,6 @@ struct wl2864c {
struct regmap *regmap;
struct regulator_desc *rdesc[WL2864C_MAX_REGULATORS];
struct regulator_dev *rdev[WL2864C_MAX_REGULATORS];
int chip_irq;
int chip_cs_pin;
};
@ -48,7 +47,10 @@ struct wl2864c_evt_sta {
static const struct wl2864c_evt_sta wl2864c_status_reg = { WL2864C_LDO_EN };
static const struct regmap_range wl2864c_writeable_ranges[] = {
regmap_reg_range(WL2864C_CURRENT_LIMITSEL, WL2864C_SEQ_STATUS),
/* Do not let useless register writeable */
regmap_reg_range(WL2864C_CURRENT_LIMITSEL, WL2864C_CURRENT_LIMITSEL),
regmap_reg_range(WL2864C_LDO1_VOUT, WL2864C_LDO7_VOUT),
regmap_reg_range(WL2864C_LDO_EN, WL2864C_LDO_EN),
};
static const struct regmap_range wl2864c_readable_ranges[] = {
@ -83,6 +85,33 @@ static const struct regmap_config wl2864c_regmap_config = {
.volatile_table = &wl2864c_volatile_table,
};
static int wl2864c_get_error_flags(struct regulator_dev *rdev, unsigned int *flags)
{
struct wl2864c *chip = rdev_get_drvdata(rdev);
uint8_t reg_dump[WL2864C_REG_NUM];
uint8_t reg_idx;
unsigned int val = 0;
dev_err(chip->dev, "************ start dump wl2864c register ************\n");
dev_err(chip->dev, "register 0x00: chip version\n");
dev_err(chip->dev, "register 0x01: LDO CL\n");
dev_err(chip->dev, "register 0x03~0x09: LDO1~LDO7 OUT Voltage\n");
dev_err(chip->dev, "register 0x0e: Bit[6:0] LDO7~LDO1 EN\n");
for (reg_idx = 0; reg_idx < WL2864C_REG_NUM; reg_idx++) {
regmap_read(chip->regmap, reg_idx, &val);
reg_dump[reg_idx] = val;
dev_err(chip->dev, "Reg[0x%02x] = 0x%x", reg_idx, reg_dump[reg_idx]);
}
dev_err(chip->dev, "************ end dump wl2864c register ************\n");
if (flags != NULL) {
*flags = 0;
}
return 0;
}
static int wl2864c_get_status(struct regulator_dev *rdev)
{
struct wl2864c *chip = rdev_get_drvdata(rdev);
@ -99,6 +128,8 @@ static int wl2864c_get_status(struct regulator_dev *rdev)
if (!ret)
return REGULATOR_STATUS_OFF;
wl2864c_get_error_flags(rdev, NULL);
ret = regmap_read(chip->regmap, wl2864c_status_reg.sreg, &status);
if (ret < 0) {
dev_err(chip->dev, "Failed to read status register(%d)\n",
@ -122,6 +153,7 @@ static const struct regulator_ops wl2864c_regl_ops = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_status = wl2864c_get_status,
.get_error_flags = wl2864c_get_error_flags,
};
static int wl2864c_of_parse_cb(struct device_node *np,
@ -174,7 +206,7 @@ static int wl2864c_regulator_init(struct wl2864c *chip)
struct regulator_desc *rdesc;
u8 vsel_range[1];
int id, ret = 0;
const unsigned int min_regs[WL2864C_MAX_REGULATORS] = {
const unsigned int ldo_regs[WL2864C_MAX_REGULATORS] = {
WL2864C_LDO1_VOUT,
WL2864C_LDO2_VOUT,
WL2864C_LDO3_VOUT,
@ -209,22 +241,22 @@ static int wl2864c_regulator_init(struct wl2864c *chip)
config.dev = chip->dev;
config.driver_data = chip;
ret = regmap_bulk_read(chip->regmap, min_regs[id],
ret = regmap_bulk_read(chip->regmap, ldo_regs[id],
vsel_range, 1);
pr_err("wl2864c_regulator_init: LDO%d, min:%d", id, vsel_range[0]);
pr_err("wl2864c_regulator_init: LDO%d, default value:0x%x", (id+1), vsel_range[0]);
if (ret < 0) {
dev_err(chip->dev,
"Failed to read the MIN register\n");
"Failed to read the ldo register\n");
return ret;
}
ret = regmap_write(chip->regmap, min_regs[id], initial_voltage[id]);
ret = regmap_write(chip->regmap, ldo_regs[id], initial_voltage[id]);
if (ret < 0) {
dev_err(chip->dev,
"Failed to write inital voltage register\n");
return ret;
}
pr_err("wl2864c_regulator_init: LDO%d, default:%d", id, initial_voltage[id]);
pr_err("wl2864c_regulator_init: LDO%d, initial value:0x%x", (id+1), initial_voltage[id]);
chip->rdev[id] = devm_regulator_register(chip->dev, rdesc,
&config);
@ -245,7 +277,7 @@ static int wl2864c_i2c_probe(struct i2c_client *client,
{
struct device *dev = &client->dev;
struct wl2864c *chip;
int error, cs_gpio, ret, chip_rev, current_limit;
int error, cs_gpio, ret, current_limit;
chip = devm_kzalloc(dev, sizeof(struct wl2864c), GFP_KERNEL);
if (!chip) {
@ -278,7 +310,6 @@ static int wl2864c_i2c_probe(struct i2c_client *client,
mdelay(10);
i2c_set_clientdata(client, chip);
chip->chip_irq = client->irq;
chip->dev = dev;
chip->regmap = devm_regmap_init_i2c(client, &wl2864c_regmap_config);
if (IS_ERR(chip->regmap)) {
@ -288,9 +319,6 @@ static int wl2864c_i2c_probe(struct i2c_client *client,
return error;
}
ret = regmap_bulk_read(chip->regmap, WL2864C_CHIP_REV, &chip_rev, 1);
dev_err(chip->dev, "wl2864c chip rev: %02x\n", chip_rev);
ret = regmap_bulk_read(chip->regmap, WL2864C_CURRENT_LIMITSEL, &current_limit, 1);
dev_err(chip->dev, "default current limit is 0x%x\n", current_limit);
@ -300,14 +328,14 @@ static int wl2864c_i2c_probe(struct i2c_client *client,
dev_err(chip->dev,"Failed to write current limit register\n");
}
ret = regmap_bulk_read(chip->regmap, WL2864C_CURRENT_LIMITSEL, &current_limit, 1);
dev_err(chip->dev, "modify current limit to 0x%x\n", current_limit);
ret = wl2864c_regulator_init(chip);
if (ret < 0) {
dev_err(chip->dev, "Failed to init regulator(%d)\n", ret);
return ret;
}
wl2864c_get_error_flags(chip->rdev[0], NULL);
dev_info(chip->dev, "wl2864c_i2c_probe Exit...\n");
return ret;

View file

@ -10,6 +10,7 @@
#define __WL2864C_REGISTERS_H__
/* Registers */
#define WL2864C_REG_NUM (WL2864C_SEQ_STATUS-WL2864C_CHIP_REV+1)
#define WL2864C_CHIP_REV 0x00
#define WL2864C_CURRENT_LIMITSEL 0x01