1 /* 2 * Copyright (C) 2012 Samsung Electronics 3 * Rajeshwari Shinde <rajeshwari.s@samsung.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <fdtdec.h> 10 #include <i2c.h> 11 #include <power/pmic.h> 12 #include <power/max77686_pmic.h> 13 #include <errno.h> 14 15 DECLARE_GLOBAL_DATA_PTR; 16 17 static const char max77686_buck_addr[] = { 18 0xff, 0x10, 0x12, 0x1c, 0x26, 0x30, 0x32, 0x34, 0x36, 0x38 19 }; 20 21 static unsigned int max77686_ldo_volt2hex(int ldo, ulong uV) 22 { 23 unsigned int hex = 0; 24 25 switch (ldo) { 26 case 1: 27 case 2: 28 case 6: 29 case 7: 30 case 8: 31 case 15: 32 hex = (uV - 800000) / 25000; 33 break; 34 default: 35 hex = (uV - 800000) / 50000; 36 } 37 38 if (hex >= 0 && hex <= MAX77686_LDO_VOLT_MAX_HEX) 39 return hex; 40 41 debug("%s: %ld is wrong voltage value for LDO%d\n", __func__, uV, ldo); 42 return 0; 43 } 44 45 int max77686_set_ldo_voltage(struct pmic *p, int ldo, ulong uV) 46 { 47 unsigned int val, ret, hex, adr; 48 49 if (ldo < 1 && ldo > 26) { 50 printf("%s: %d is wrong ldo number\n", __func__, ldo); 51 return -1; 52 } 53 54 adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1; 55 hex = max77686_ldo_volt2hex(ldo, uV); 56 57 if (!hex) 58 return -1; 59 60 ret = pmic_reg_read(p, adr, &val); 61 if (ret) 62 return ret; 63 64 val &= ~MAX77686_LDO_VOLT_MASK; 65 val |= hex; 66 ret |= pmic_reg_write(p, adr, val); 67 68 return ret; 69 } 70 71 int max77686_set_ldo_mode(struct pmic *p, int ldo, char opmode) 72 { 73 unsigned int val, ret, adr, mode; 74 75 if (ldo < 1 && 26 < ldo) { 76 printf("%s: %d is wrong ldo number\n", __func__, ldo); 77 return -1; 78 } 79 80 adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1; 81 82 /* mode */ 83 switch (opmode) { 84 case OPMODE_OFF: 85 mode = MAX77686_LDO_MODE_OFF; 86 break; 87 case OPMODE_STANDBY: 88 switch (ldo) { 89 case 2: 90 case 6: 91 case 7: 92 case 8: 93 case 10: 94 case 11: 95 case 12: 96 case 14: 97 case 15: 98 case 16: 99 mode = MAX77686_LDO_MODE_STANDBY; 100 break; 101 default: 102 mode = 0xff; 103 } 104 break; 105 case OPMODE_LPM: 106 mode = MAX77686_LDO_MODE_LPM; 107 break; 108 case OPMODE_ON: 109 mode = MAX77686_LDO_MODE_ON; 110 break; 111 default: 112 mode = 0xff; 113 } 114 115 if (mode == 0xff) { 116 printf("%s: %d is not supported on LDO%d\n", 117 __func__, opmode, ldo); 118 return -1; 119 } 120 121 ret = pmic_reg_read(p, adr, &val); 122 if (ret) 123 return ret; 124 125 val &= ~MAX77686_LDO_MODE_MASK; 126 val |= mode; 127 ret |= pmic_reg_write(p, adr, val); 128 129 return ret; 130 } 131 132 int max77686_set_buck_mode(struct pmic *p, int buck, char opmode) 133 { 134 unsigned int val, ret, mask, adr, size, mode, mode_shift; 135 136 size = ARRAY_SIZE(max77686_buck_addr); 137 if (buck >= size) { 138 printf("%s: %d is wrong buck number\n", __func__, buck); 139 return -1; 140 } 141 142 adr = max77686_buck_addr[buck]; 143 144 /* mask */ 145 switch (buck) { 146 case 2: 147 case 3: 148 case 4: 149 mode_shift = MAX77686_BUCK_MODE_SHIFT_2; 150 break; 151 default: 152 mode_shift = MAX77686_BUCK_MODE_SHIFT_1; 153 } 154 155 mask = MAX77686_BUCK_MODE_MASK << mode_shift; 156 157 /* mode */ 158 switch (opmode) { 159 case OPMODE_OFF: 160 mode = MAX77686_BUCK_MODE_OFF; 161 break; 162 case OPMODE_STANDBY: 163 switch (buck) { 164 case 1: 165 case 2: 166 case 3: 167 case 4: 168 mode = MAX77686_BUCK_MODE_STANDBY << mode_shift; 169 break; 170 default: 171 mode = 0xff; 172 } 173 break; 174 case OPMODE_LPM: 175 switch (buck) { 176 case 2: 177 case 3: 178 case 4: 179 mode = MAX77686_BUCK_MODE_LPM << mode_shift; 180 break; 181 default: 182 mode = 0xff; 183 } 184 break; 185 case OPMODE_ON: 186 mode = MAX77686_BUCK_MODE_ON << mode_shift; 187 break; 188 default: 189 mode = 0xff; 190 } 191 192 if (mode == 0xff) { 193 printf("%s: %d is not supported on BUCK%d\n", 194 __func__, opmode, buck); 195 return -1; 196 } 197 198 ret = pmic_reg_read(p, adr, &val); 199 if (ret) 200 return ret; 201 202 val &= ~mask; 203 val |= mode; 204 ret |= pmic_reg_write(p, adr, val); 205 206 return ret; 207 } 208 209 int pmic_init(unsigned char bus) 210 { 211 static const char name[] = "MAX77686_PMIC"; 212 struct pmic *p = pmic_alloc(); 213 #ifdef CONFIG_OF_CONTROL 214 const void *blob = gd->fdt_blob; 215 int node, parent, tmp; 216 #endif 217 218 if (!p) { 219 printf("%s: POWER allocation error!\n", __func__); 220 return -ENOMEM; 221 } 222 223 #ifdef CONFIG_OF_CONTROL 224 node = fdtdec_next_compatible(blob, 0, COMPAT_MAXIM_MAX77686_PMIC); 225 if (node < 0) { 226 debug("PMIC: No node for PMIC Chip in device tree\n"); 227 debug("node = %d\n", node); 228 return -1; 229 } 230 231 parent = fdt_parent_offset(blob, node); 232 if (parent < 0) { 233 debug("%s: Cannot find node parent\n", __func__); 234 return -1; 235 } 236 237 /* tmp since p->bus is unsigned */ 238 tmp = i2c_get_bus_num_fdt(parent); 239 if (tmp < 0) { 240 debug("%s: Cannot find I2C bus\n", __func__); 241 return -1; 242 } 243 p->bus = tmp; 244 p->hw.i2c.addr = fdtdec_get_int(blob, node, "reg", 9); 245 #else 246 p->bus = bus; 247 p->hw.i2c.addr = MAX77686_I2C_ADDR; 248 #endif 249 250 p->name = name; 251 p->interface = PMIC_I2C; 252 p->number_of_regs = PMIC_NUM_OF_REGS; 253 p->hw.i2c.tx_num = 1; 254 255 puts("Board PMIC init\n"); 256 257 return 0; 258 } 259