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