1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2016 Freescale Semiconductor, Inc. 4 * Hou Zhiqiang <Zhiqiang.Hou@freescale.com> 5 */ 6 7 #include <common.h> 8 #include <errno.h> 9 #include <i2c.h> 10 #include <power/pmic.h> 11 #include <power/mc34vr500_pmic.h> 12 13 static uint8_t swxvolt_addr[4] = { MC34VR500_SW1VOLT, 14 MC34VR500_SW2VOLT, 15 MC34VR500_SW3VOLT, 16 MC34VR500_SW4VOLT }; 17 18 static uint8_t swx_set_point_base[4] = { 13, 9, 9, 9 }; 19 20 int mc34vr500_get_sw_volt(uint8_t sw) 21 { 22 struct pmic *p; 23 u32 swxvolt; 24 uint8_t spb; 25 int sw_volt; 26 int ret; 27 28 debug("%s: Get SW%u volt from swxvolt_addr = 0x%x\n", 29 __func__, sw + 1, swxvolt_addr[sw]); 30 if (sw > SW4) { 31 printf("%s: Unsupported SW(sw%d)\n", __func__, sw + 1); 32 return -EINVAL; 33 } 34 35 p = pmic_get("MC34VR500"); 36 if (!p) { 37 printf("%s: Did NOT find PMIC MC34VR500\n", __func__); 38 return -ENODEV; 39 } 40 41 ret = pmic_probe(p); 42 if (ret) 43 return ret; 44 45 ret = pmic_reg_read(p, swxvolt_addr[sw], &swxvolt); 46 if (ret) { 47 printf("%s: Failed to get SW%u volt\n", __func__, sw + 1); 48 return ret; 49 } 50 51 debug("%s: SW%d step point swxvolt = %u\n", __func__, sw + 1, swxvolt); 52 spb = swx_set_point_base[sw]; 53 /* The base of SW volt is 625mV and increase by step 25mV */ 54 sw_volt = 625 + (swxvolt - spb) * 25; 55 56 debug("%s: SW%u volt = %dmV\n", __func__, sw + 1, sw_volt); 57 return sw_volt; 58 } 59 60 int mc34vr500_set_sw_volt(uint8_t sw, int sw_volt) 61 { 62 struct pmic *p; 63 u32 swxvolt; 64 uint8_t spb; 65 int ret; 66 67 debug("%s: Set SW%u volt to %dmV\n", __func__, sw + 1, sw_volt); 68 /* The least SW volt is 625mV, and only 4 SW outputs */ 69 if (sw > SW4 || sw_volt < 625) 70 return -EINVAL; 71 72 p = pmic_get("MC34VR500"); 73 if (!p) { 74 printf("%s: Did NOT find PMIC MC34VR500\n", __func__); 75 return -ENODEV; 76 } 77 78 ret = pmic_probe(p); 79 if (ret) 80 return ret; 81 82 spb = swx_set_point_base[sw]; 83 /* The base of SW volt is 625mV and increase by step 25mV */ 84 swxvolt = (sw_volt - 625) / 25 + spb; 85 debug("%s: SW%d step point swxvolt = %u\n", __func__, sw + 1, swxvolt); 86 if (swxvolt > 63) 87 return -EINVAL; 88 89 ret = pmic_reg_write(p, swxvolt_addr[sw], swxvolt); 90 if (ret) 91 return ret; 92 93 return 0; 94 } 95