1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2014 NVIDIA Corporation 4 */ 5 6 #define pr_fmt(fmt) "as3722: " fmt 7 8 #include <common.h> 9 #include <dm.h> 10 #include <errno.h> 11 #include <fdtdec.h> 12 #include <i2c.h> 13 #include <dm/lists.h> 14 #include <power/as3722.h> 15 #include <power/pmic.h> 16 17 #define AS3722_NUM_OF_REGS 0x92 18 19 static int as3722_read(struct udevice *dev, uint reg, uint8_t *buff, int len) 20 { 21 int ret; 22 23 ret = dm_i2c_read(dev, reg, buff, len); 24 if (ret < 0) 25 return ret; 26 27 return 0; 28 } 29 30 static int as3722_write(struct udevice *dev, uint reg, const uint8_t *buff, 31 int len) 32 { 33 int ret; 34 35 ret = dm_i2c_write(dev, reg, buff, len); 36 if (ret < 0) 37 return ret; 38 39 return 0; 40 } 41 42 static int as3722_read_id(struct udevice *dev, uint *idp, uint *revisionp) 43 { 44 int ret; 45 46 ret = pmic_reg_read(dev, AS3722_ASIC_ID1); 47 if (ret < 0) { 48 pr_err("failed to read ID1 register: %d", ret); 49 return ret; 50 } 51 *idp = ret; 52 53 ret = pmic_reg_read(dev, AS3722_ASIC_ID2); 54 if (ret < 0) { 55 pr_err("failed to read ID2 register: %d", ret); 56 return ret; 57 } 58 *revisionp = ret; 59 60 return 0; 61 } 62 63 /* TODO(treding@nvidia.com): Add proper regulator support to avoid this */ 64 int as3722_sd_set_voltage(struct udevice *dev, unsigned int sd, u8 value) 65 { 66 int ret; 67 68 if (sd > 6) 69 return -EINVAL; 70 71 ret = pmic_reg_write(dev, AS3722_SD_VOLTAGE(sd), value); 72 if (ret < 0) { 73 pr_err("failed to write SD%u voltage register: %d", sd, ret); 74 return ret; 75 } 76 77 return 0; 78 } 79 80 int as3722_ldo_set_voltage(struct udevice *dev, unsigned int ldo, u8 value) 81 { 82 int ret; 83 84 if (ldo > 11) 85 return -EINVAL; 86 87 ret = pmic_reg_write(dev, AS3722_LDO_VOLTAGE(ldo), value); 88 if (ret < 0) { 89 pr_err("failed to write LDO%u voltage register: %d", ldo, 90 ret); 91 return ret; 92 } 93 94 return 0; 95 } 96 97 static int as3722_probe(struct udevice *dev) 98 { 99 uint id, revision; 100 int ret; 101 102 ret = as3722_read_id(dev, &id, &revision); 103 if (ret < 0) { 104 pr_err("failed to read ID: %d", ret); 105 return ret; 106 } 107 108 if (id != AS3722_DEVICE_ID) { 109 pr_err("unknown device"); 110 return -ENOENT; 111 } 112 113 debug("AS3722 revision %#x found on I2C bus %s\n", revision, dev->name); 114 115 return 0; 116 } 117 118 #if CONFIG_IS_ENABLED(PMIC_CHILDREN) 119 static const struct pmic_child_info pmic_children_info[] = { 120 { .prefix = "sd", .driver = "as3722_stepdown"}, 121 { .prefix = "ldo", .driver = "as3722_ldo"}, 122 { }, 123 }; 124 125 static int as3722_bind(struct udevice *dev) 126 { 127 struct udevice *gpio_dev; 128 ofnode regulators_node; 129 int children; 130 int ret; 131 132 regulators_node = dev_read_subnode(dev, "regulators"); 133 if (!ofnode_valid(regulators_node)) { 134 debug("%s: %s regulators subnode not found\n", __func__, 135 dev->name); 136 return -ENXIO; 137 } 138 139 children = pmic_bind_children(dev, regulators_node, pmic_children_info); 140 if (!children) 141 debug("%s: %s - no child found\n", __func__, dev->name); 142 ret = device_bind_driver(dev, "gpio_as3722", "gpio_as3722", &gpio_dev); 143 if (ret) { 144 debug("%s: Cannot bind GPIOs (ret=%d)\n", __func__, ret); 145 return ret; 146 } 147 148 return 0; 149 } 150 #endif 151 152 static int as3722_reg_count(struct udevice *dev) 153 { 154 return AS3722_NUM_OF_REGS; 155 } 156 157 static struct dm_pmic_ops as3722_ops = { 158 .reg_count = as3722_reg_count, 159 .read = as3722_read, 160 .write = as3722_write, 161 }; 162 163 static const struct udevice_id as3722_ids[] = { 164 { .compatible = "ams,as3722" }, 165 { } 166 }; 167 168 U_BOOT_DRIVER(pmic_as3722) = { 169 .name = "as3722_pmic", 170 .id = UCLASS_PMIC, 171 .of_match = as3722_ids, 172 #if CONFIG_IS_ENABLED(PMIC_CHILDREN) 173 .bind = as3722_bind, 174 #endif 175 .probe = as3722_probe, 176 .ops = &as3722_ops, 177 }; 178