REG: SUPER CAP VOLTAGE RATING FOR TX2

hi,
The super cap part used in TX2 carrier board is XH414HG IV01E, which is NRND part. The part has rated voltage of 3.3V. So i have planned to use another super cap which is an ACTIVE part, so can you please let me know the rated voltage to choose the super cap? 3.3V to 5V rated super cap will suite TX2?

thanks

Hi, please refer to module datasheet for backup cell selection:

Backup cells must provide a voltage in the range 2.5V to
3.5V. These will be charged with a constant current (CC), constant voltage (CV) charger that can be configured
between 2.5V and 3.5V CV output and 50uA to 800uA CC. The following backup cells may be attached to this pin:
 Super Capacitor (gold cap, double layer electrolytic)
 Standard capacitors (tantalum)
 Rechargeable Lithium Manganese cells

thanks for the reply, what will be the default charge voltage and current from the TX2 module?

Please refer to this link, it is same for TX1 and TX2: [url]Jetson TX1/FAQ - eLinux.org

Hi,
I have seen default charging voltage and current in pmic dtsi in TX2 as below,

maxim,backup-battery-charging-current = <100>;

maxim,backup-battery-charging-voltage = <3000000>;

By changing the above device tree entry, can i change the default charging voltage and current for backup cell?

The voltage and current can only be set to several fix values as below:

Current : 50uA, 100uA, 200uA, 400uA, 600uA, 800uA
Voltage : 2.5V, 3.0V, 3.3V, 3.5V

Hi,
Thanks a lot for the reply.

maxim,backup-battery-charging-current = <100>;

maxim,backup-battery-charging-voltage = <3000000>;

I have checked whether the above device tree property is used any where in the driver. But i could not find one. is it sure that by changing the voltage and current value in the above device tree entry as u suggested will work?

Sure.

You can refer to this site: [url]Jetson TX1/FAQ - eLinux.org

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?

I saw the max77620_init_backup_battery_charging in r28.2
You may reference to 28.2 port back to 27.1 or update to 28.2