fcd0a654a889835d3f07aae84a3e0c99f9757b78
[platform/kernel/u-boot.git] / drivers / power / pmic / pmic_tps65910.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2011-2013
4  * Texas Instruments, <www.ti.com>
5  */
6
7 #include <common.h>
8 #include <i2c.h>
9 #include <power/tps65910.h>
10
11 struct udevice *tps65910_dev __section(".data") = NULL;
12
13 static inline int tps65910_read_reg(int addr, uchar *buf)
14 {
15 #if !CONFIG_IS_ENABLED(DM_I2C)
16         return i2c_read(TPS65910_CTRL_I2C_ADDR, addr, 1, buf, 1);
17 #else
18         int rc;
19
20         rc = dm_i2c_reg_read(tps65910_dev, addr);
21         if (rc < 0)
22                 return rc;
23         *buf = (uchar)rc;
24         return 0;
25 #endif
26 }
27
28 static inline int tps65910_write_reg(int addr, uchar *buf)
29 {
30 #if !CONFIG_IS_ENABLED(DM_I2C)
31         return i2c_write(TPS65910_CTRL_I2C_ADDR, addr, 1, buf, 1);
32 #else
33         return dm_i2c_reg_write(tps65910_dev, addr, *buf);
34 #endif
35 }
36
37 int power_tps65910_init(unsigned char bus)
38 {
39 #if CONFIG_IS_ENABLED(DM_I2C)
40         struct udevice *dev = NULL;
41         int rc;
42
43         rc = i2c_get_chip_for_busnum(bus, TPS65910_CTRL_I2C_ADDR, 1, &dev);
44
45         if (rc)
46                 return rc;
47         tps65910_dev = dev;
48 #endif
49         return 0;
50 }
51
52 /*
53  * tps65910_set_i2c_control() - Set the TPS65910 to be controlled via the I2C
54  *                              interface.
55  * @return:                    0 on success, not 0 on failure
56  */
57 int tps65910_set_i2c_control(void)
58 {
59         int ret;
60         uchar buf;
61
62         /* VDD1/2 voltage selection register access by control i/f */
63         ret = tps65910_read_reg(TPS65910_DEVCTRL_REG, &buf);
64
65         if (ret)
66                 return ret;
67
68         buf |= TPS65910_DEVCTRL_REG_SR_CTL_I2C_SEL_CTL_I2C;
69
70         return tps65910_write_reg(TPS65910_DEVCTRL_REG, &buf);
71 }
72
73 /*
74  * tps65910_voltage_update() - Voltage switching for MPU frequency switching.
75  * @module:                    mpu - 0, core - 1
76  * @vddx_op_vol_sel:           vdd voltage to set
77  * @return:                    0 on success, not 0 on failure
78  */
79 int tps65910_voltage_update(unsigned int module, unsigned char vddx_op_vol_sel)
80 {
81         uchar buf;
82         unsigned int reg_offset;
83         int ret;
84
85         if (module == MPU)
86                 reg_offset = TPS65910_VDD1_OP_REG;
87         else
88                 reg_offset = TPS65910_VDD2_OP_REG;
89
90         /* Select VDDx OP   */
91         ret = tps65910_read_reg(reg_offset, &buf);
92         if (ret)
93                 return ret;
94
95         buf &= ~TPS65910_OP_REG_CMD_MASK;
96
97         ret = tps65910_write_reg(reg_offset, &buf);
98         if (ret)
99                 return ret;
100
101         /* Configure VDDx OP  Voltage */
102         ret = tps65910_read_reg(reg_offset, &buf);
103         if (ret)
104                 return ret;
105
106         buf &= ~TPS65910_OP_REG_SEL_MASK;
107         buf |= vddx_op_vol_sel;
108
109         ret = tps65910_write_reg(reg_offset, &buf);
110         if (ret)
111                 return ret;
112
113         ret = tps65910_read_reg(reg_offset, &buf);
114         if (ret)
115                 return ret;
116
117         if ((buf & TPS65910_OP_REG_SEL_MASK) != vddx_op_vol_sel)
118                 return 1;
119
120         return 0;
121 }