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