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 uint8_t data; 65 int num; 66 int ret; 67 68 num = gpio_request_list_by_name(dev, "enable-gpios", gpio_desc, 8, 69 GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); 70 if (num < 0) 71 dev_warn(dev, "sy7636a failed to get enable gpios:%d\n", ret); 72 73 /* After enable, SY7636A requires 2.5ms delay time to enter active mode */ 74 udelay(2500); 75 76 /* check is device i2c present */ 77 ret = dm_i2c_read(dev, SY7636A_REG_OPERATION_MODE_CRL, &data, 1); 78 if (ret) { 79 dev_warn(dev, "sy7636a i2c not present: %d\n", ret); 80 goto fail; 81 } 82 83 return 0; 84 85 fail: 86 if (num > 0) 87 gpio_free_list(dev, gpio_desc, num); 88 89 return ret; 90 } 91 92 static int pmic_sy7636a_bind(struct udevice *dev) 93 { 94 ofnode regulators_node; 95 int children; 96 97 regulators_node = dev_read_subnode(dev, "regulators"); 98 if (!ofnode_valid(regulators_node)) { 99 dev_err(dev, "Regulators subnode not found!"); 100 return -ENXIO; 101 } 102 103 children = pmic_bind_children(dev, regulators_node, pmic_children_info); 104 if (!children) 105 dev_err(dev, "Failed to bind sy7636a regulator\n"); 106 107 children = pmic_bind_children(dev, dev->node, thermal_child_info); 108 if (!children) 109 dev_err(dev, "Failed to bind sy7636a thermal\n"); 110 111 return 0; 112 } 113 114 static struct dm_pmic_ops sy7636a_ops = { 115 .reg_count = sy7636a_reg_count, 116 .read = sy7636a_read, 117 .write = sy7636a_write, 118 }; 119 120 static const struct udevice_id pmic_sy7636a_of_match[] = { 121 { .compatible = "silergy,sy7636a" }, 122 { .compatible = "silergy,sy7636a-pmic" }, 123 {} 124 }; 125 126 U_BOOT_DRIVER(pmic_sy7636a) = { 127 .name = "pmic_sy7636a", 128 .id = UCLASS_PMIC, 129 .of_match = pmic_sy7636a_of_match, 130 .probe = pmic_sy7636a_probe, 131 .ops = &sy7636a_ops, 132 .bind = pmic_sy7636a_bind, 133 }; 134