Hi,
I am currently using L4T 27.1 in TX2 which has device tree node as below in the file hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-quill-spmic-p3310-1000-a00-00.dtsi
backup-battery {
maxim,backup-battery-charging-current = <100>;
maxim,backup-battery-charging-voltage = <3000000>;
maxim,backup-battery-output-resister = <100>;
status = "disabled";
};
In this node status is disabled.
But in the link you have shared, They have used L4T 24.1 and their has device tree node as below.
backup-battery {
maxim,backup-battery-charging-current = <100>;
maxim,backup-battery-charging-voltage = <3000000>;
maxim,backup-battery-output-resister = <100>;
};
In this node status is not disabled.
In 27.1 , kernel/kernel-4.4/drivers/mfd/max77620.c has probe function as below, it does not initialize any backup battery charging.
static int max77620_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
const struct regmap_config *rmap_config;
struct max77620_chip *chip;
struct mfd_cell *mfd_cells;
int n_mfd_cells;
int ret;
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;
i2c_set_clientdata(client, chip);
chip->dev = &client->dev;
chip->irq_base = -1;
chip->chip_irq = client->irq;
chip->chip_id = (enum max77620_chip_id)id->driver_data;
switch (chip->chip_id) {
case MAX77620:
mfd_cells = max77620_children;
n_mfd_cells = ARRAY_SIZE(max77620_children);
rmap_config = &max77620_regmap_config;
break;
case MAX20024:
mfd_cells = max20024_children;
n_mfd_cells = ARRAY_SIZE(max20024_children);
rmap_config = &max20024_regmap_config;
break;
default:
dev_err(chip->dev, "ChipID is invalid %d\n", chip->chip_id);
return -EINVAL;
}
chip->rmap = devm_regmap_init_i2c(client, rmap_config);
if (IS_ERR(chip->rmap)) {
ret = PTR_ERR(chip->rmap);
dev_err(chip->dev, "Failed to regmap init: %d\n", ret);
return ret;
}
ret = max77620_read_es_version(chip);
if (ret < 0)
return ret;
max77620_top_irq_chip.pre_post_irq_data = chip;
ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq,
IRQF_ONESHOT | IRQF_SHARED,
chip->irq_base, &max77620_top_irq_chip,
&chip->top_irq_data);
if (ret < 0) {
dev_err(chip->dev, "Failed to add regmap irq: %d\n", ret);
return ret;
}
ret = max77620_initialise_fps(chip);
if (ret < 0)
return ret;
ret = mfd_add_devices(chip->dev, PLATFORM_DEVID_NONE,
mfd_cells, n_mfd_cells, NULL, 0,
regmap_irq_get_domain(chip->top_irq_data));
if (ret < 0) {
dev_err(chip->dev, "Failed to add sub devices: %d\n", ret);
return ret;
}
dev_info(chip->dev, "max77620 probe successful");
return 0;
}
But in 24.1, drivers/mfd/max77620-core.c has probe function and backup battery initalization as below,
static int max77620_init_backup_battery_charging(struct max77620_chip *chip,
struct device *dev)
{
struct device_node *np;
u32 pval;
u8 config;
int charging_current;
int charging_voltage;
int resistor;
int ret;
np = of_get_child_by_name(dev->of_node, "backup-battery");
if (!np) {
dev_info(dev, "Backup battery charging support disabled\n");
max77620_reg_update(chip->dev, MAX77620_PWR_SLAVE,
MAX77620_REG_CNFGBBC, MAX77620_CNFGBBC_ENABLE, 0);
return 0;
}
ret = of_property_read_u32(np,
"maxim,backup-battery-charging-current", &pval);
charging_current = (!ret) ? pval : 50;
ret = of_property_read_u32(np,
"maxim,backup-battery-charging-voltage", &pval);
charging_voltage = (!ret) ? pval : 2500000;
charging_voltage /= 1000;
ret = of_property_read_u32(np,
"maxim,backup-battery-output-resister", &pval);
resistor = (!ret) ? pval : 1000;
config = MAX77620_CNFGBBC_ENABLE;
if (charging_current <= 50)
config |= 0 << MAX77620_CNFGBBC_CURRENT_SHIFT;
else if (charging_current <= 100)
config |= 3 << MAX77620_CNFGBBC_CURRENT_SHIFT;
else if (charging_current <= 200)
config |= 0 << MAX77620_CNFGBBC_CURRENT_SHIFT;
else if (charging_current <= 400)
config |= 3 << MAX77620_CNFGBBC_CURRENT_SHIFT;
else if (charging_current <= 600)
config |= 1 << MAX77620_CNFGBBC_CURRENT_SHIFT;
else
config |= 2 << MAX77620_CNFGBBC_CURRENT_SHIFT;
if (charging_current > 100)
config |= MAX77620_CNFGBBC_LOW_CURRENT_ENABLE;
if (charging_voltage <= 2500)
config |= 0 << MAX77620_CNFGBBC_VOLTAGE_SHIFT;
else if (charging_voltage <= 3000)
config |= 1 << MAX77620_CNFGBBC_VOLTAGE_SHIFT;
else if (charging_voltage <= 3300)
config |= 2 << MAX77620_CNFGBBC_VOLTAGE_SHIFT;
else
config |= 3 << MAX77620_CNFGBBC_VOLTAGE_SHIFT;
if (resistor <= 100)
config |= 0 << MAX77620_CNFGBBC_RESISTOR_SHIFT;
else if (resistor <= 1000)
config |= 1 << MAX77620_CNFGBBC_RESISTOR_SHIFT;
else if (resistor <= 3000)
config |= 2 << MAX77620_CNFGBBC_RESISTOR_SHIFT;
else if (resistor <= 6000)
config |= 3 << MAX77620_CNFGBBC_RESISTOR_SHIFT;
ret = max77620_reg_write(dev, MAX77620_PWR_SLAVE,
MAX77620_REG_CNFGBBC, config);
if (ret < 0) {
dev_err(dev, "Reg 0x%02x write failed, %d\n",
MAX77620_REG_CNFGBBC, ret);
return ret;
}
return 0;
}
static int max77620_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device_node *node = client->dev.of_node;
const struct max77620_sub_modules *children;
struct max77620_chip *chip;
int i = 0;
int ret = 0;
if (!node) {
dev_err(&client->dev, "Device is not from DT\n");
return -ENODEV;
}
children = of_get_match_device_data(max77620_of_match, &client->dev);
if (!children)
return -ENODEV;
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
dev_err(&client->dev, "Memory alloc for chip failed\n");
return -ENOMEM;
}
i2c_set_clientdata(client, chip);
chip->dev = &client->dev;
chip->irq_base = -1;
chip->chip_irq = client->irq;
if (node)
chip->avoid_rtc_bulk_write = of_property_read_bool(node,
"maxim,avoid-rtc-bulk-register-write");
mutex_init(&chip->mutex_config);
for (i = 0; i < MAX77620_NUM_SLAVES; i++) {
if (max77620_slave_address[i] == client->addr)
chip->clients[i] = client;
else
chip->clients[i] = i2c_new_dummy(client->adapter,
max77620_slave_address[i]);
if (!chip->clients[i]) {
dev_err(&client->dev, "can't attach client %d\n", i);
ret = -ENOMEM;
goto fail_client_reg;
}
chip->clients[i]->dev.of_node = node;
i2c_set_clientdata(chip->clients[i], chip);
max77620_regmap_config[i].lock_arg = chip;
chip->rmap[i] = devm_regmap_init_i2c(chip->clients[i],
(const struct regmap_config *)&max77620_regmap_config[i]);
if (IS_ERR(chip->rmap[i])) {
ret = PTR_ERR(chip->rmap[i]);
dev_err(&client->dev,
"regmap %d init failed, err %d\n", i, ret);
goto fail_client_reg;
}
}
ret = max77620_read_es_version(chip);
if (ret < 0) {
dev_err(chip->dev, "Chip revision init failed: %d\n", ret);
goto fail_client_reg;
}
ret = max77620_initialise_chip(chip, &client->dev);
if (ret < 0) {
dev_err(&client->dev, "Chip initialisation failed, %d\n", ret);
goto fail_client_reg;
}
max77620_top_irq_chip.pre_post_irq_data = chip;
ret = regmap_add_irq_chip(chip->rmap[MAX77620_PWR_SLAVE],
chip->chip_irq, IRQF_ONESHOT | IRQF_SHARED, chip->irq_base,
&max77620_top_irq_chip, &chip->top_irq_data);
if (ret < 0) {
dev_err(chip->dev, "Failed to add top irq_chip %d\n", ret);
goto fail_client_reg;
}
ret = max77620_initialise_fps(chip, &client->dev);
if (ret < 0) {
dev_err(&client->dev, "FPS initialisation failed, %d\n", ret);
goto fail_free_irq;
}
ret = max77620_init_backup_battery_charging(chip, &client->dev);
if (ret < 0) {
dev_err(&client->dev,
"Backup battery charging init failed, %d\n", ret);
goto fail_free_irq;
}
ret = max77620_init_low_battery_monitor(chip, &client->dev);
if (ret < 0) {
dev_err(&client->dev, "Low battery monitor init failed, %d\n",
ret);
goto fail_free_irq;
}
ret = mfd_add_devices(&client->dev, -1, children->cells,
children->ncells, NULL, 0,
regmap_irq_get_domain(chip->top_irq_data));
if (ret < 0) {
dev_err(&client->dev, "mfd add dev fail %d\n", ret);
goto fail_free_irq;
}
chip->irq_mbattlow = max77620_irq_get_virq(chip->dev,
MAX77620_IRQ_LBT_MBATLOW);
if (chip->irq_mbattlow) {
ret = devm_request_threaded_irq(chip->dev, chip->irq_mbattlow,
NULL, max77620_mbattlow_irq,
IRQF_ONESHOT, dev_name(chip->dev),
chip);
if (ret < 0)
dev_err(&client->dev, "request irq %d failed: %d\n",
chip->irq_mbattlow, ret);
}
dev_info(&client->dev, "max77620 probe successfully\n");
return 0;
fail_free_irq:
regmap_del_irq_chip(chip->chip_irq, chip->top_irq_data);
fail_client_reg:
for (i = 0; i < MAX77620_NUM_SLAVES; i++) {
if (!chip->clients[i] || chip->clients[i] == client)
continue;
i2c_unregister_device(chip->clients[i]);
}
return ret;
}
Do you have any suggestion on this?