15c7f10fdSOliver Schinagl /* 2bdcdf846SHans de Goede * AXP221 and AXP223 driver 3bdcdf846SHans de Goede * 4bdcdf846SHans de Goede * IMPORTANT when making changes to this file check that the registers 5bdcdf846SHans de Goede * used are the same for the axp221 and axp223. 6bdcdf846SHans de Goede * 7bdcdf846SHans de Goede * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com> 85c7f10fdSOliver Schinagl * (C) Copyright 2013 Oliver Schinagl <oliver@schinagl.nl> 95c7f10fdSOliver Schinagl * 105c7f10fdSOliver Schinagl * SPDX-License-Identifier: GPL-2.0+ 115c7f10fdSOliver Schinagl */ 125c7f10fdSOliver Schinagl 135c7f10fdSOliver Schinagl #include <common.h> 145c7f10fdSOliver Schinagl #include <errno.h> 155c7f10fdSOliver Schinagl #include <asm/arch/p2wi.h> 16bdcdf846SHans de Goede #include <asm/arch/rsb.h> 175c7f10fdSOliver Schinagl #include <axp221.h> 185c7f10fdSOliver Schinagl 19bdcdf846SHans de Goede /* 20bdcdf846SHans de Goede * The axp221 uses the p2wi bus, the axp223 is identical (for all registers 21bdcdf846SHans de Goede * used sofar) but uses the rsb bus. These functions abstract this. 22bdcdf846SHans de Goede */ 23bdcdf846SHans de Goede static int pmic_bus_init(void) 24bdcdf846SHans de Goede { 25bdcdf846SHans de Goede #ifdef CONFIG_MACH_SUN6I 26bdcdf846SHans de Goede p2wi_init(); 27bdcdf846SHans de Goede return p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR, AXP221_CTRL_ADDR, 28bdcdf846SHans de Goede AXP221_INIT_DATA); 29bdcdf846SHans de Goede #else 30bdcdf846SHans de Goede int ret; 31bdcdf846SHans de Goede 32bdcdf846SHans de Goede rsb_init(); 33bdcdf846SHans de Goede 34bdcdf846SHans de Goede ret = rsb_set_device_mode(AXP223_DEVICE_MODE_DATA); 35bdcdf846SHans de Goede if (ret) 36bdcdf846SHans de Goede return ret; 37bdcdf846SHans de Goede 38bdcdf846SHans de Goede return rsb_set_device_address(AXP223_DEVICE_ADDR, AXP223_RUNTIME_ADDR); 39bdcdf846SHans de Goede #endif 40bdcdf846SHans de Goede } 41bdcdf846SHans de Goede 42bdcdf846SHans de Goede static int pmic_bus_read(const u8 addr, u8 *data) 43bdcdf846SHans de Goede { 44bdcdf846SHans de Goede #ifdef CONFIG_MACH_SUN6I 45bdcdf846SHans de Goede return p2wi_read(addr, data); 46bdcdf846SHans de Goede #else 47bdcdf846SHans de Goede return rsb_read(AXP223_RUNTIME_ADDR, addr, data); 48bdcdf846SHans de Goede #endif 49bdcdf846SHans de Goede } 50bdcdf846SHans de Goede 51bdcdf846SHans de Goede static int pmic_bus_write(const u8 addr, u8 data) 52bdcdf846SHans de Goede { 53bdcdf846SHans de Goede #ifdef CONFIG_MACH_SUN6I 54bdcdf846SHans de Goede return p2wi_write(addr, data); 55bdcdf846SHans de Goede #else 56bdcdf846SHans de Goede return rsb_write(AXP223_RUNTIME_ADDR, addr, data); 57bdcdf846SHans de Goede #endif 58bdcdf846SHans de Goede } 59bdcdf846SHans de Goede 605c7f10fdSOliver Schinagl static u8 axp221_mvolt_to_cfg(int mvolt, int min, int max, int div) 615c7f10fdSOliver Schinagl { 625c7f10fdSOliver Schinagl if (mvolt < min) 635c7f10fdSOliver Schinagl mvolt = min; 645c7f10fdSOliver Schinagl else if (mvolt > max) 655c7f10fdSOliver Schinagl mvolt = max; 665c7f10fdSOliver Schinagl 675c7f10fdSOliver Schinagl return (mvolt - min) / div; 685c7f10fdSOliver Schinagl } 695c7f10fdSOliver Schinagl 705c7f10fdSOliver Schinagl static int axp221_setbits(u8 reg, u8 bits) 715c7f10fdSOliver Schinagl { 725c7f10fdSOliver Schinagl int ret; 735c7f10fdSOliver Schinagl u8 val; 745c7f10fdSOliver Schinagl 75bdcdf846SHans de Goede ret = pmic_bus_read(reg, &val); 765c7f10fdSOliver Schinagl if (ret) 775c7f10fdSOliver Schinagl return ret; 785c7f10fdSOliver Schinagl 795c7f10fdSOliver Schinagl val |= bits; 80bdcdf846SHans de Goede return pmic_bus_write(reg, val); 815c7f10fdSOliver Schinagl } 825c7f10fdSOliver Schinagl 8350e0d5e6SHans de Goede static int axp221_clrbits(u8 reg, u8 bits) 8450e0d5e6SHans de Goede { 8550e0d5e6SHans de Goede int ret; 8650e0d5e6SHans de Goede u8 val; 8750e0d5e6SHans de Goede 8850e0d5e6SHans de Goede ret = pmic_bus_read(reg, &val); 8950e0d5e6SHans de Goede if (ret) 9050e0d5e6SHans de Goede return ret; 9150e0d5e6SHans de Goede 9250e0d5e6SHans de Goede val &= ~bits; 9350e0d5e6SHans de Goede return pmic_bus_write(reg, val); 9450e0d5e6SHans de Goede } 9550e0d5e6SHans de Goede 965c7f10fdSOliver Schinagl int axp221_set_dcdc1(unsigned int mvolt) 975c7f10fdSOliver Schinagl { 985c7f10fdSOliver Schinagl int ret; 995c7f10fdSOliver Schinagl u8 cfg = axp221_mvolt_to_cfg(mvolt, 1600, 3400, 100); 1005c7f10fdSOliver Schinagl 10150e0d5e6SHans de Goede if (mvolt == 0) 10250e0d5e6SHans de Goede return axp221_clrbits(AXP221_OUTPUT_CTRL1, 10350e0d5e6SHans de Goede AXP221_OUTPUT_CTRL1_DCDC1_EN); 10450e0d5e6SHans de Goede 105bdcdf846SHans de Goede ret = pmic_bus_write(AXP221_DCDC1_CTRL, cfg); 1065c7f10fdSOliver Schinagl if (ret) 1075c7f10fdSOliver Schinagl return ret; 1085c7f10fdSOliver Schinagl 10950e0d5e6SHans de Goede ret = axp221_setbits(AXP221_OUTPUT_CTRL2, 11050e0d5e6SHans de Goede AXP221_OUTPUT_CTRL2_DCDC1SW_EN); 11150e0d5e6SHans de Goede if (ret) 11250e0d5e6SHans de Goede return ret; 11350e0d5e6SHans de Goede 11450e0d5e6SHans de Goede return axp221_setbits(AXP221_OUTPUT_CTRL1, 11550e0d5e6SHans de Goede AXP221_OUTPUT_CTRL1_DCDC1_EN); 1165c7f10fdSOliver Schinagl } 1175c7f10fdSOliver Schinagl 1185c7f10fdSOliver Schinagl int axp221_set_dcdc2(unsigned int mvolt) 1195c7f10fdSOliver Schinagl { 12050e0d5e6SHans de Goede int ret; 1215c7f10fdSOliver Schinagl u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1540, 20); 1225c7f10fdSOliver Schinagl 12350e0d5e6SHans de Goede if (mvolt == 0) 12450e0d5e6SHans de Goede return axp221_clrbits(AXP221_OUTPUT_CTRL1, 12550e0d5e6SHans de Goede AXP221_OUTPUT_CTRL1_DCDC2_EN); 12650e0d5e6SHans de Goede 12750e0d5e6SHans de Goede ret = pmic_bus_write(AXP221_DCDC2_CTRL, cfg); 12850e0d5e6SHans de Goede if (ret) 12950e0d5e6SHans de Goede return ret; 13050e0d5e6SHans de Goede 13150e0d5e6SHans de Goede return axp221_setbits(AXP221_OUTPUT_CTRL1, 13250e0d5e6SHans de Goede AXP221_OUTPUT_CTRL1_DCDC2_EN); 1335c7f10fdSOliver Schinagl } 1345c7f10fdSOliver Schinagl 1355c7f10fdSOliver Schinagl int axp221_set_dcdc3(unsigned int mvolt) 1365c7f10fdSOliver Schinagl { 13750e0d5e6SHans de Goede int ret; 1385c7f10fdSOliver Schinagl u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1860, 20); 1395c7f10fdSOliver Schinagl 14050e0d5e6SHans de Goede if (mvolt == 0) 14150e0d5e6SHans de Goede return axp221_clrbits(AXP221_OUTPUT_CTRL1, 14250e0d5e6SHans de Goede AXP221_OUTPUT_CTRL1_DCDC3_EN); 14350e0d5e6SHans de Goede 14450e0d5e6SHans de Goede ret = pmic_bus_write(AXP221_DCDC3_CTRL, cfg); 14550e0d5e6SHans de Goede if (ret) 14650e0d5e6SHans de Goede return ret; 14750e0d5e6SHans de Goede 14850e0d5e6SHans de Goede return axp221_setbits(AXP221_OUTPUT_CTRL1, 14950e0d5e6SHans de Goede AXP221_OUTPUT_CTRL1_DCDC3_EN); 1505c7f10fdSOliver Schinagl } 1515c7f10fdSOliver Schinagl 1525c7f10fdSOliver Schinagl int axp221_set_dcdc4(unsigned int mvolt) 1535c7f10fdSOliver Schinagl { 15450e0d5e6SHans de Goede int ret; 1555c7f10fdSOliver Schinagl u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1540, 20); 1565c7f10fdSOliver Schinagl 15750e0d5e6SHans de Goede if (mvolt == 0) 15850e0d5e6SHans de Goede return axp221_clrbits(AXP221_OUTPUT_CTRL1, 15950e0d5e6SHans de Goede AXP221_OUTPUT_CTRL1_DCDC4_EN); 16050e0d5e6SHans de Goede 16150e0d5e6SHans de Goede ret = pmic_bus_write(AXP221_DCDC4_CTRL, cfg); 16250e0d5e6SHans de Goede if (ret) 16350e0d5e6SHans de Goede return ret; 16450e0d5e6SHans de Goede 16550e0d5e6SHans de Goede return axp221_setbits(AXP221_OUTPUT_CTRL1, 16650e0d5e6SHans de Goede AXP221_OUTPUT_CTRL1_DCDC4_EN); 1675c7f10fdSOliver Schinagl } 1685c7f10fdSOliver Schinagl 1695c7f10fdSOliver Schinagl int axp221_set_dcdc5(unsigned int mvolt) 1705c7f10fdSOliver Schinagl { 17150e0d5e6SHans de Goede int ret; 1725c7f10fdSOliver Schinagl u8 cfg = axp221_mvolt_to_cfg(mvolt, 1000, 2550, 50); 1735c7f10fdSOliver Schinagl 17450e0d5e6SHans de Goede if (mvolt == 0) 17550e0d5e6SHans de Goede return axp221_clrbits(AXP221_OUTPUT_CTRL1, 17650e0d5e6SHans de Goede AXP221_OUTPUT_CTRL1_DCDC5_EN); 17750e0d5e6SHans de Goede 17850e0d5e6SHans de Goede ret = pmic_bus_write(AXP221_DCDC5_CTRL, cfg); 17950e0d5e6SHans de Goede if (ret) 18050e0d5e6SHans de Goede return ret; 18150e0d5e6SHans de Goede 18250e0d5e6SHans de Goede return axp221_setbits(AXP221_OUTPUT_CTRL1, 18350e0d5e6SHans de Goede AXP221_OUTPUT_CTRL1_DCDC5_EN); 1845c7f10fdSOliver Schinagl } 1855c7f10fdSOliver Schinagl 1865c7f10fdSOliver Schinagl int axp221_set_dldo1(unsigned int mvolt) 1875c7f10fdSOliver Schinagl { 1885c7f10fdSOliver Schinagl int ret; 1895c7f10fdSOliver Schinagl u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100); 1905c7f10fdSOliver Schinagl 19150e0d5e6SHans de Goede if (mvolt == 0) 19250e0d5e6SHans de Goede return axp221_clrbits(AXP221_OUTPUT_CTRL2, 19350e0d5e6SHans de Goede AXP221_OUTPUT_CTRL2_DLDO1_EN); 19450e0d5e6SHans de Goede 195bdcdf846SHans de Goede ret = pmic_bus_write(AXP221_DLDO1_CTRL, cfg); 1965c7f10fdSOliver Schinagl if (ret) 1975c7f10fdSOliver Schinagl return ret; 1985c7f10fdSOliver Schinagl 1995c7f10fdSOliver Schinagl return axp221_setbits(AXP221_OUTPUT_CTRL2, 2005c7f10fdSOliver Schinagl AXP221_OUTPUT_CTRL2_DLDO1_EN); 2015c7f10fdSOliver Schinagl } 2025c7f10fdSOliver Schinagl 2035c7f10fdSOliver Schinagl int axp221_set_dldo2(unsigned int mvolt) 2045c7f10fdSOliver Schinagl { 2055c7f10fdSOliver Schinagl int ret; 2065c7f10fdSOliver Schinagl u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100); 2075c7f10fdSOliver Schinagl 20850e0d5e6SHans de Goede if (mvolt == 0) 20950e0d5e6SHans de Goede return axp221_clrbits(AXP221_OUTPUT_CTRL2, 21050e0d5e6SHans de Goede AXP221_OUTPUT_CTRL2_DLDO2_EN); 21150e0d5e6SHans de Goede 212bdcdf846SHans de Goede ret = pmic_bus_write(AXP221_DLDO2_CTRL, cfg); 2135c7f10fdSOliver Schinagl if (ret) 2145c7f10fdSOliver Schinagl return ret; 2155c7f10fdSOliver Schinagl 2165c7f10fdSOliver Schinagl return axp221_setbits(AXP221_OUTPUT_CTRL2, 2175c7f10fdSOliver Schinagl AXP221_OUTPUT_CTRL2_DLDO2_EN); 2185c7f10fdSOliver Schinagl } 2195c7f10fdSOliver Schinagl 2205c7f10fdSOliver Schinagl int axp221_set_dldo3(unsigned int mvolt) 2215c7f10fdSOliver Schinagl { 2225c7f10fdSOliver Schinagl int ret; 2235c7f10fdSOliver Schinagl u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100); 2245c7f10fdSOliver Schinagl 22550e0d5e6SHans de Goede if (mvolt == 0) 22650e0d5e6SHans de Goede return axp221_clrbits(AXP221_OUTPUT_CTRL2, 22750e0d5e6SHans de Goede AXP221_OUTPUT_CTRL2_DLDO3_EN); 22850e0d5e6SHans de Goede 229bdcdf846SHans de Goede ret = pmic_bus_write(AXP221_DLDO3_CTRL, cfg); 2305c7f10fdSOliver Schinagl if (ret) 2315c7f10fdSOliver Schinagl return ret; 2325c7f10fdSOliver Schinagl 2335c7f10fdSOliver Schinagl return axp221_setbits(AXP221_OUTPUT_CTRL2, 2345c7f10fdSOliver Schinagl AXP221_OUTPUT_CTRL2_DLDO3_EN); 2355c7f10fdSOliver Schinagl } 2365c7f10fdSOliver Schinagl 2375c7f10fdSOliver Schinagl int axp221_set_dldo4(unsigned int mvolt) 2385c7f10fdSOliver Schinagl { 2395c7f10fdSOliver Schinagl int ret; 2405c7f10fdSOliver Schinagl u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100); 2415c7f10fdSOliver Schinagl 24250e0d5e6SHans de Goede if (mvolt == 0) 24350e0d5e6SHans de Goede return axp221_clrbits(AXP221_OUTPUT_CTRL2, 24450e0d5e6SHans de Goede AXP221_OUTPUT_CTRL2_DLDO4_EN); 24550e0d5e6SHans de Goede 246bdcdf846SHans de Goede ret = pmic_bus_write(AXP221_DLDO4_CTRL, cfg); 2475c7f10fdSOliver Schinagl if (ret) 2485c7f10fdSOliver Schinagl return ret; 2495c7f10fdSOliver Schinagl 2505c7f10fdSOliver Schinagl return axp221_setbits(AXP221_OUTPUT_CTRL2, 2515c7f10fdSOliver Schinagl AXP221_OUTPUT_CTRL2_DLDO4_EN); 2525c7f10fdSOliver Schinagl } 2535c7f10fdSOliver Schinagl 2545c7f10fdSOliver Schinagl int axp221_set_aldo1(unsigned int mvolt) 2555c7f10fdSOliver Schinagl { 2565c7f10fdSOliver Schinagl int ret; 2575c7f10fdSOliver Schinagl u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100); 2585c7f10fdSOliver Schinagl 25950e0d5e6SHans de Goede if (mvolt == 0) 26050e0d5e6SHans de Goede return axp221_clrbits(AXP221_OUTPUT_CTRL1, 26150e0d5e6SHans de Goede AXP221_OUTPUT_CTRL1_ALDO1_EN); 26250e0d5e6SHans de Goede 263bdcdf846SHans de Goede ret = pmic_bus_write(AXP221_ALDO1_CTRL, cfg); 2645c7f10fdSOliver Schinagl if (ret) 2655c7f10fdSOliver Schinagl return ret; 2665c7f10fdSOliver Schinagl 2675c7f10fdSOliver Schinagl return axp221_setbits(AXP221_OUTPUT_CTRL1, 2685c7f10fdSOliver Schinagl AXP221_OUTPUT_CTRL1_ALDO1_EN); 2695c7f10fdSOliver Schinagl } 2705c7f10fdSOliver Schinagl 2715c7f10fdSOliver Schinagl int axp221_set_aldo2(unsigned int mvolt) 2725c7f10fdSOliver Schinagl { 2735c7f10fdSOliver Schinagl int ret; 2745c7f10fdSOliver Schinagl u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100); 2755c7f10fdSOliver Schinagl 27650e0d5e6SHans de Goede if (mvolt == 0) 27750e0d5e6SHans de Goede return axp221_clrbits(AXP221_OUTPUT_CTRL1, 27850e0d5e6SHans de Goede AXP221_OUTPUT_CTRL1_ALDO2_EN); 27950e0d5e6SHans de Goede 280bdcdf846SHans de Goede ret = pmic_bus_write(AXP221_ALDO2_CTRL, cfg); 2815c7f10fdSOliver Schinagl if (ret) 2825c7f10fdSOliver Schinagl return ret; 2835c7f10fdSOliver Schinagl 2845c7f10fdSOliver Schinagl return axp221_setbits(AXP221_OUTPUT_CTRL1, 2855c7f10fdSOliver Schinagl AXP221_OUTPUT_CTRL1_ALDO2_EN); 2865c7f10fdSOliver Schinagl } 2875c7f10fdSOliver Schinagl 2885c7f10fdSOliver Schinagl int axp221_set_aldo3(unsigned int mvolt) 2895c7f10fdSOliver Schinagl { 2905c7f10fdSOliver Schinagl int ret; 2915c7f10fdSOliver Schinagl u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100); 2925c7f10fdSOliver Schinagl 29350e0d5e6SHans de Goede if (mvolt == 0) 29450e0d5e6SHans de Goede return axp221_clrbits(AXP221_OUTPUT_CTRL3, 29550e0d5e6SHans de Goede AXP221_OUTPUT_CTRL3_ALDO3_EN); 29650e0d5e6SHans de Goede 297bdcdf846SHans de Goede ret = pmic_bus_write(AXP221_ALDO3_CTRL, cfg); 2985c7f10fdSOliver Schinagl if (ret) 2995c7f10fdSOliver Schinagl return ret; 3005c7f10fdSOliver Schinagl 3015c7f10fdSOliver Schinagl return axp221_setbits(AXP221_OUTPUT_CTRL3, 3025c7f10fdSOliver Schinagl AXP221_OUTPUT_CTRL3_ALDO3_EN); 3035c7f10fdSOliver Schinagl } 3045c7f10fdSOliver Schinagl 305*6906df1aSSiarhei Siamashka int axp221_set_eldo(int eldo_num, unsigned int mvolt) 306*6906df1aSSiarhei Siamashka { 307*6906df1aSSiarhei Siamashka int ret; 308*6906df1aSSiarhei Siamashka u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100); 309*6906df1aSSiarhei Siamashka u8 addr, bits; 310*6906df1aSSiarhei Siamashka 311*6906df1aSSiarhei Siamashka switch (eldo_num) { 312*6906df1aSSiarhei Siamashka case 3: 313*6906df1aSSiarhei Siamashka addr = AXP221_ELDO3_CTRL; 314*6906df1aSSiarhei Siamashka bits = AXP221_OUTPUT_CTRL2_ELDO3_EN; 315*6906df1aSSiarhei Siamashka break; 316*6906df1aSSiarhei Siamashka case 2: 317*6906df1aSSiarhei Siamashka addr = AXP221_ELDO2_CTRL; 318*6906df1aSSiarhei Siamashka bits = AXP221_OUTPUT_CTRL2_ELDO2_EN; 319*6906df1aSSiarhei Siamashka break; 320*6906df1aSSiarhei Siamashka case 1: 321*6906df1aSSiarhei Siamashka addr = AXP221_ELDO1_CTRL; 322*6906df1aSSiarhei Siamashka bits = AXP221_OUTPUT_CTRL2_ELDO1_EN; 323*6906df1aSSiarhei Siamashka break; 324*6906df1aSSiarhei Siamashka default: 325*6906df1aSSiarhei Siamashka return -EINVAL; 326*6906df1aSSiarhei Siamashka } 327*6906df1aSSiarhei Siamashka 328*6906df1aSSiarhei Siamashka if (mvolt == 0) 329*6906df1aSSiarhei Siamashka return axp221_clrbits(AXP221_OUTPUT_CTRL2, bits); 330*6906df1aSSiarhei Siamashka 331*6906df1aSSiarhei Siamashka ret = pmic_bus_write(addr, cfg); 332*6906df1aSSiarhei Siamashka if (ret) 333*6906df1aSSiarhei Siamashka return ret; 334*6906df1aSSiarhei Siamashka 335*6906df1aSSiarhei Siamashka return axp221_setbits(AXP221_OUTPUT_CTRL2, bits); 336*6906df1aSSiarhei Siamashka } 337*6906df1aSSiarhei Siamashka 3385c7f10fdSOliver Schinagl int axp221_init(void) 3395c7f10fdSOliver Schinagl { 3403c781190SHans de Goede /* This cannot be 0 because it is used in SPL before BSS is ready */ 3413c781190SHans de Goede static int needs_init = 1; 3425c7f10fdSOliver Schinagl u8 axp_chip_id; 3435c7f10fdSOliver Schinagl int ret; 3445c7f10fdSOliver Schinagl 3453c781190SHans de Goede if (!needs_init) 3463c781190SHans de Goede return 0; 3473c781190SHans de Goede 348bdcdf846SHans de Goede ret = pmic_bus_init(); 3495c7f10fdSOliver Schinagl if (ret) 3505c7f10fdSOliver Schinagl return ret; 3515c7f10fdSOliver Schinagl 352bdcdf846SHans de Goede ret = pmic_bus_read(AXP221_CHIP_ID, &axp_chip_id); 3535c7f10fdSOliver Schinagl if (ret) 3545c7f10fdSOliver Schinagl return ret; 3555c7f10fdSOliver Schinagl 3565c7f10fdSOliver Schinagl if (!(axp_chip_id == 0x6 || axp_chip_id == 0x7 || axp_chip_id == 0x17)) 3575c7f10fdSOliver Schinagl return -ENODEV; 3585c7f10fdSOliver Schinagl 3593c781190SHans de Goede needs_init = 0; 3605c7f10fdSOliver Schinagl return 0; 3615c7f10fdSOliver Schinagl } 362f3fba566SHans de Goede 363f3fba566SHans de Goede int axp221_get_sid(unsigned int *sid) 364f3fba566SHans de Goede { 365f3fba566SHans de Goede u8 *dest = (u8 *)sid; 366f3fba566SHans de Goede int i, ret; 367f3fba566SHans de Goede 368f3fba566SHans de Goede ret = axp221_init(); 369f3fba566SHans de Goede if (ret) 370f3fba566SHans de Goede return ret; 371f3fba566SHans de Goede 372bdcdf846SHans de Goede ret = pmic_bus_write(AXP221_PAGE, 1); 373f3fba566SHans de Goede if (ret) 374f3fba566SHans de Goede return ret; 375f3fba566SHans de Goede 376f3fba566SHans de Goede for (i = 0; i < 16; i++) { 377bdcdf846SHans de Goede ret = pmic_bus_read(AXP221_SID + i, &dest[i]); 378f3fba566SHans de Goede if (ret) 379f3fba566SHans de Goede return ret; 380f3fba566SHans de Goede } 381f3fba566SHans de Goede 382bdcdf846SHans de Goede pmic_bus_write(AXP221_PAGE, 0); 383f3fba566SHans de Goede 384f3fba566SHans de Goede for (i = 0; i < 4; i++) 385f3fba566SHans de Goede sid[i] = be32_to_cpu(sid[i]); 386f3fba566SHans de Goede 387f3fba566SHans de Goede return 0; 388f3fba566SHans de Goede } 3892abac621SHans de Goede 3902abac621SHans de Goede static int axp_drivebus_setup(void) 3912abac621SHans de Goede { 3922abac621SHans de Goede int ret; 3932abac621SHans de Goede 3942abac621SHans de Goede ret = axp221_init(); 3952abac621SHans de Goede if (ret) 3962abac621SHans de Goede return ret; 3972abac621SHans de Goede 3982abac621SHans de Goede /* Set N_VBUSEN pin to output / DRIVEBUS function */ 3992abac621SHans de Goede return axp221_clrbits(AXP221_MISC_CTRL, AXP221_MISC_CTRL_N_VBUSEN_FUNC); 4002abac621SHans de Goede } 4012abac621SHans de Goede 4022abac621SHans de Goede int axp_drivebus_enable(void) 4032abac621SHans de Goede { 4042abac621SHans de Goede int ret; 4052abac621SHans de Goede 4062abac621SHans de Goede ret = axp_drivebus_setup(); 4072abac621SHans de Goede if (ret) 4082abac621SHans de Goede return ret; 4092abac621SHans de Goede 4102abac621SHans de Goede /* Set DRIVEBUS high */ 4112abac621SHans de Goede return axp221_setbits(AXP221_VBUS_IPSOUT, AXP221_VBUS_IPSOUT_DRIVEBUS); 4122abac621SHans de Goede } 4132abac621SHans de Goede 4142abac621SHans de Goede int axp_drivebus_disable(void) 4152abac621SHans de Goede { 4162abac621SHans de Goede int ret; 4172abac621SHans de Goede 4182abac621SHans de Goede ret = axp_drivebus_setup(); 4192abac621SHans de Goede if (ret) 4202abac621SHans de Goede return ret; 4212abac621SHans de Goede 4222abac621SHans de Goede /* Set DRIVEBUS low */ 4232abac621SHans de Goede return axp221_clrbits(AXP221_VBUS_IPSOUT, AXP221_VBUS_IPSOUT_DRIVEBUS); 4242abac621SHans de Goede } 425