1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2024 Rockchip Electronics Co., Ltd. 4 */ 5 6 #include <common.h> 7 #include <asm/gpio.h> 8 #include <dm.h> 9 #include <dm/lists.h> 10 #include <dm/device-internal.h> 11 #include <dm/of_access.h> 12 #include <dm/pinctrl.h> 13 #include <i2c.h> 14 #include <power/pmic.h> 15 #include <power/regulator.h> 16 #include <power/sy7636a.h> 17 18 DECLARE_GLOBAL_DATA_PTR; 19 20 static const struct pmic_child_info pmic_children_info[] = { 21 { .prefix = "vcom", .driver = SY7636A_REGULATOR_DRIVER_NAME }, 22 { }, 23 }; 24 25 static const struct pmic_child_info thermal_child_info[] = { 26 { .prefix = "sy7636a_thermal", .driver = SY7636A_THERMAL_COMTATIBLE_NAME }, 27 { }, 28 }; 29 30 static int sy7636a_reg_count(struct udevice *dev) 31 { 32 return SY7636A_REG_MAX; 33 } 34 35 static int sy7636a_write(struct udevice *dev, uint reg, const uint8_t *buff, int len) 36 { 37 int ret; 38 39 ret = dm_i2c_write(dev, reg, buff, len); 40 if (ret) { 41 pr_err("sy7636a failed to write register: %#x, ret:%d\n", reg, ret); 42 return ret; 43 } 44 45 return 0; 46 } 47 48 static int sy7636a_read(struct udevice *dev, uint reg, uint8_t *buff, int len) 49 { 50 int ret; 51 52 ret = dm_i2c_read(dev, reg, buff, len); 53 if (ret) { 54 pr_err("sy7636a failed to write register: %#x, ret:%d\n", reg, ret); 55 return ret; 56 } 57 58 return 0; 59 } 60 61 static int pmic_sy7636a_probe(struct udevice *dev) 62 { 63 struct gpio_desc gpio_desc[8]; 64 int ret; 65 66 ret = gpio_request_list_by_name(dev, "enable-gpios", gpio_desc, 8, 67 GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); 68 if (ret < 0) 69 dev_warn(dev, "sy7636a failed to get enable gpios:%d\n", ret); 70 71 /* After enable, SY7636A requires 2.5ms delay time to enter active mode */ 72 udelay(2500); 73 74 return 0; 75 } 76 77 static int pmic_sy7636a_bind(struct udevice *dev) 78 { 79 ofnode regulators_node; 80 int children; 81 82 regulators_node = dev_read_subnode(dev, "regulators"); 83 if (!ofnode_valid(regulators_node)) { 84 dev_err(dev, "Regulators subnode not found!"); 85 return -ENXIO; 86 } 87 88 children = pmic_bind_children(dev, regulators_node, pmic_children_info); 89 if (!children) 90 dev_err(dev, "Failed to bind sy7636a regulator\n"); 91 92 children = pmic_bind_children(dev, dev->node, thermal_child_info); 93 if (!children) 94 dev_err(dev, "Failed to bind sy7636a thermal\n"); 95 96 return 0; 97 } 98 99 static struct dm_pmic_ops sy7636a_ops = { 100 .reg_count = sy7636a_reg_count, 101 .read = sy7636a_read, 102 .write = sy7636a_write, 103 }; 104 105 static const struct udevice_id pmic_sy7636a_of_match[] = { 106 { .compatible = "silergy,sy7636a" }, 107 { .compatible = "silergy,sy7636a-pmic" }, 108 {} 109 }; 110 111 U_BOOT_DRIVER(pmic_sy7636a) = { 112 .name = "pmic_sy7636a", 113 .id = UCLASS_PMIC, 114 .of_match = pmic_sy7636a_of_match, 115 .probe = pmic_sy7636a_probe, 116 .ops = &sy7636a_ops, 117 .bind = pmic_sy7636a_bind, 118 }; 119