xref: /rk3399_rockchip-uboot/drivers/power/pmic/pmic_sy7636a.c (revision f222e09f7157041ec8eca58e1caa29785fc3abcd)
149fa68b0SChaoyi Chen // SPDX-License-Identifier: GPL-2.0
249fa68b0SChaoyi Chen /*
349fa68b0SChaoyi Chen  * Copyright (c) 2024 Rockchip Electronics Co., Ltd.
449fa68b0SChaoyi Chen  */
549fa68b0SChaoyi Chen 
649fa68b0SChaoyi Chen #include <common.h>
712e25d6dSChaoyi Chen #include <asm/gpio.h>
849fa68b0SChaoyi Chen #include <dm.h>
949fa68b0SChaoyi Chen #include <dm/lists.h>
1049fa68b0SChaoyi Chen #include <dm/device-internal.h>
1149fa68b0SChaoyi Chen #include <dm/of_access.h>
1249fa68b0SChaoyi Chen #include <dm/pinctrl.h>
1349fa68b0SChaoyi Chen #include <i2c.h>
1449fa68b0SChaoyi Chen #include <power/pmic.h>
1549fa68b0SChaoyi Chen #include <power/regulator.h>
1649fa68b0SChaoyi Chen #include <power/sy7636a.h>
1749fa68b0SChaoyi Chen 
1849fa68b0SChaoyi Chen DECLARE_GLOBAL_DATA_PTR;
1949fa68b0SChaoyi Chen 
2049fa68b0SChaoyi Chen static const struct pmic_child_info pmic_children_info[] = {
2149fa68b0SChaoyi Chen 	{ .prefix = "vcom", .driver = SY7636A_REGULATOR_DRIVER_NAME },
2249fa68b0SChaoyi Chen 	{ },
2349fa68b0SChaoyi Chen };
2449fa68b0SChaoyi Chen 
2549fa68b0SChaoyi Chen static const struct pmic_child_info thermal_child_info[] = {
2649fa68b0SChaoyi Chen 	{ .prefix = "sy7636a_thermal", .driver = SY7636A_THERMAL_COMTATIBLE_NAME },
2749fa68b0SChaoyi Chen 	{ },
2849fa68b0SChaoyi Chen };
2949fa68b0SChaoyi Chen 
sy7636a_reg_count(struct udevice * dev)3049fa68b0SChaoyi Chen static int sy7636a_reg_count(struct udevice *dev)
3149fa68b0SChaoyi Chen {
3249fa68b0SChaoyi Chen         return SY7636A_REG_MAX;
3349fa68b0SChaoyi Chen }
3449fa68b0SChaoyi Chen 
sy7636a_write(struct udevice * dev,uint reg,const uint8_t * buff,int len)3549fa68b0SChaoyi Chen static int sy7636a_write(struct udevice *dev, uint reg, const uint8_t *buff, int len)
3649fa68b0SChaoyi Chen {
3749fa68b0SChaoyi Chen 	int ret;
3849fa68b0SChaoyi Chen 
3949fa68b0SChaoyi Chen 	ret = dm_i2c_write(dev, reg, buff, len);
4049fa68b0SChaoyi Chen 	if (ret) {
4149fa68b0SChaoyi Chen 		pr_err("sy7636a failed to write register: %#x, ret:%d\n", reg, ret);
4249fa68b0SChaoyi Chen 		return ret;
4349fa68b0SChaoyi Chen 	}
4449fa68b0SChaoyi Chen 
4549fa68b0SChaoyi Chen 	return 0;
4649fa68b0SChaoyi Chen }
4749fa68b0SChaoyi Chen 
sy7636a_read(struct udevice * dev,uint reg,uint8_t * buff,int len)4849fa68b0SChaoyi Chen static int sy7636a_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
4949fa68b0SChaoyi Chen {
5049fa68b0SChaoyi Chen 	int ret;
5149fa68b0SChaoyi Chen 
5249fa68b0SChaoyi Chen 	ret = dm_i2c_read(dev, reg, buff, len);
5349fa68b0SChaoyi Chen 	if (ret) {
5449fa68b0SChaoyi Chen 		pr_err("sy7636a failed to write register: %#x, ret:%d\n", reg, ret);
5549fa68b0SChaoyi Chen 		return ret;
5649fa68b0SChaoyi Chen 	}
5749fa68b0SChaoyi Chen 
5849fa68b0SChaoyi Chen 	return 0;
5949fa68b0SChaoyi Chen }
6049fa68b0SChaoyi Chen 
pmic_sy7636a_probe(struct udevice * dev)6149fa68b0SChaoyi Chen static int pmic_sy7636a_probe(struct udevice *dev)
6249fa68b0SChaoyi Chen {
6312e25d6dSChaoyi Chen 	struct gpio_desc gpio_desc[8];
64*f222e09fSChaoyi Chen 	uint8_t data;
65*f222e09fSChaoyi Chen 	int num;
6612e25d6dSChaoyi Chen 	int ret;
6712e25d6dSChaoyi Chen 
68*f222e09fSChaoyi Chen 	num = gpio_request_list_by_name(dev, "enable-gpios", gpio_desc, 8,
6912e25d6dSChaoyi Chen 					GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
70*f222e09fSChaoyi Chen 	if (num < 0)
7112e25d6dSChaoyi Chen 		dev_warn(dev, "sy7636a failed to get enable gpios:%d\n", ret);
7212e25d6dSChaoyi Chen 
7312e25d6dSChaoyi Chen 	/* After enable, SY7636A requires 2.5ms delay time to enter active mode */
7449fa68b0SChaoyi Chen 	udelay(2500);
7549fa68b0SChaoyi Chen 
76*f222e09fSChaoyi Chen 	/* check is device i2c present */
77*f222e09fSChaoyi Chen 	ret = dm_i2c_read(dev, SY7636A_REG_OPERATION_MODE_CRL, &data, 1);
78*f222e09fSChaoyi Chen 	if (ret) {
79*f222e09fSChaoyi Chen 		dev_warn(dev, "sy7636a i2c not present: %d\n", ret);
80*f222e09fSChaoyi Chen 		goto fail;
81*f222e09fSChaoyi Chen 	}
82*f222e09fSChaoyi Chen 
8349fa68b0SChaoyi Chen 	return 0;
84*f222e09fSChaoyi Chen 
85*f222e09fSChaoyi Chen fail:
86*f222e09fSChaoyi Chen 	if (num > 0)
87*f222e09fSChaoyi Chen 		gpio_free_list(dev, gpio_desc, num);
88*f222e09fSChaoyi Chen 
89*f222e09fSChaoyi Chen 	return ret;
9049fa68b0SChaoyi Chen }
9149fa68b0SChaoyi Chen 
pmic_sy7636a_bind(struct udevice * dev)9249fa68b0SChaoyi Chen static int pmic_sy7636a_bind(struct udevice *dev)
9349fa68b0SChaoyi Chen {
9449fa68b0SChaoyi Chen 	ofnode regulators_node;
9549fa68b0SChaoyi Chen 	int children;
9649fa68b0SChaoyi Chen 
9749fa68b0SChaoyi Chen 	regulators_node = dev_read_subnode(dev, "regulators");
9849fa68b0SChaoyi Chen 	if (!ofnode_valid(regulators_node)) {
9949fa68b0SChaoyi Chen 		dev_err(dev, "Regulators subnode not found!");
10049fa68b0SChaoyi Chen 		return -ENXIO;
10149fa68b0SChaoyi Chen 	}
10249fa68b0SChaoyi Chen 
10349fa68b0SChaoyi Chen 	children = pmic_bind_children(dev, regulators_node, pmic_children_info);
10449fa68b0SChaoyi Chen 	if (!children)
10549fa68b0SChaoyi Chen 		dev_err(dev, "Failed to bind sy7636a regulator\n");
10649fa68b0SChaoyi Chen 
10749fa68b0SChaoyi Chen 	children = pmic_bind_children(dev, dev->node, thermal_child_info);
10849fa68b0SChaoyi Chen 	if (!children)
10949fa68b0SChaoyi Chen 		dev_err(dev, "Failed to bind sy7636a thermal\n");
11049fa68b0SChaoyi Chen 
11149fa68b0SChaoyi Chen         return 0;
11249fa68b0SChaoyi Chen }
11349fa68b0SChaoyi Chen 
11449fa68b0SChaoyi Chen static struct dm_pmic_ops sy7636a_ops = {
11549fa68b0SChaoyi Chen 	.reg_count = sy7636a_reg_count,
11649fa68b0SChaoyi Chen 	.read = sy7636a_read,
11749fa68b0SChaoyi Chen 	.write = sy7636a_write,
11849fa68b0SChaoyi Chen };
11949fa68b0SChaoyi Chen 
12049fa68b0SChaoyi Chen static const struct udevice_id pmic_sy7636a_of_match[] = {
12149fa68b0SChaoyi Chen 	{ .compatible = "silergy,sy7636a" },
12249fa68b0SChaoyi Chen 	{ .compatible = "silergy,sy7636a-pmic" },
12349fa68b0SChaoyi Chen 	{}
12449fa68b0SChaoyi Chen };
12549fa68b0SChaoyi Chen 
12649fa68b0SChaoyi Chen U_BOOT_DRIVER(pmic_sy7636a) = {
12749fa68b0SChaoyi Chen 	.name = "pmic_sy7636a",
12849fa68b0SChaoyi Chen 	.id = UCLASS_PMIC,
12949fa68b0SChaoyi Chen 	.of_match = pmic_sy7636a_of_match,
13049fa68b0SChaoyi Chen 	.probe = pmic_sy7636a_probe,
13149fa68b0SChaoyi Chen 	.ops = &sy7636a_ops,
13249fa68b0SChaoyi Chen 	.bind = pmic_sy7636a_bind,
13349fa68b0SChaoyi Chen };
134