Commit fff45ce7e753cece9e205d2d32ec7deb1db743b8

Authored by Keerthy
Committed by Lokesh Vutla
1 parent 6f3f23b509

power: pmic: tps65218: Fix tps65218_voltage_update function

commit 6183b29559107650cb38f905e069a93ff9da1d7d upstream

Currently while setting the vsel value for dcdc1 and dcdc2
the driver is wrongly masking the entire 8 bits in the process
clearing PFM (bit7) field as well. Hence describe an appropriate
mask for vsel field and modify only those bits in the vsel
mask.

Source: http://www.ti.com/lit/ds/symlink/tps65218.pdf

Signed-off-by: Keerthy <j-keerthy@ti.com>
Fixes: 86db550b38 ("power: Add support for the TPS65218 PMIC")
Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>

Showing 2 changed files with 3 additions and 1 deletions Inline Diff

drivers/power/pmic/pmic_tps65218.c
1 /* 1 /*
2 * (C) Copyright 2011-2013 2 * (C) Copyright 2011-2013
3 * Texas Instruments, <www.ti.com> 3 * Texas Instruments, <www.ti.com>
4 * 4 *
5 * SPDX-License-Identifier: GPL-2.0+ 5 * SPDX-License-Identifier: GPL-2.0+
6 */ 6 */
7 7
8 #include <common.h> 8 #include <common.h>
9 #include <i2c.h> 9 #include <i2c.h>
10 #include <linux/errno.h> 10 #include <linux/errno.h>
11 #include <power/pmic.h> 11 #include <power/pmic.h>
12 #include <power/tps65218.h> 12 #include <power/tps65218.h>
13 13
14 int tps65218_reg_read(uchar dest_reg, uchar *dest_val) 14 int tps65218_reg_read(uchar dest_reg, uchar *dest_val)
15 { 15 {
16 uchar read_val; 16 uchar read_val;
17 int ret; 17 int ret;
18 18
19 ret = i2c_read(TPS65218_CHIP_PM, dest_reg, 1, &read_val, 1); 19 ret = i2c_read(TPS65218_CHIP_PM, dest_reg, 1, &read_val, 1);
20 if (ret) 20 if (ret)
21 return ret; 21 return ret;
22 22
23 *dest_val = read_val; 23 *dest_val = read_val;
24 24
25 return 0; 25 return 0;
26 } 26 }
27 27
28 /** 28 /**
29 * tps65218_reg_write() - Generic function that can write a TPS65218 PMIC 29 * tps65218_reg_write() - Generic function that can write a TPS65218 PMIC
30 * register or bit field regardless of protection 30 * register or bit field regardless of protection
31 * level. 31 * level.
32 * 32 *
33 * @prot_level: Register password protection. Use 33 * @prot_level: Register password protection. Use
34 * TPS65218_PROT_LEVEL_NONE, 34 * TPS65218_PROT_LEVEL_NONE,
35 * TPS65218_PROT_LEVEL_1 or TPS65218_PROT_LEVEL_2 35 * TPS65218_PROT_LEVEL_1 or TPS65218_PROT_LEVEL_2
36 * @dest_reg: Register address to write. 36 * @dest_reg: Register address to write.
37 * @dest_val: Value to write. 37 * @dest_val: Value to write.
38 * @mask: Bit mask (8 bits) to be applied. Function will only 38 * @mask: Bit mask (8 bits) to be applied. Function will only
39 * change bits that are set in the bit mask. 39 * change bits that are set in the bit mask.
40 * 40 *
41 * @return: 0 for success, not 0 on failure, as per the i2c API 41 * @return: 0 for success, not 0 on failure, as per the i2c API
42 */ 42 */
43 int tps65218_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val, 43 int tps65218_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
44 uchar mask) 44 uchar mask)
45 { 45 {
46 uchar read_val; 46 uchar read_val;
47 uchar xor_reg; 47 uchar xor_reg;
48 int ret; 48 int ret;
49 49
50 /* 50 /*
51 * If we are affecting only a bit field, read dest_reg and apply the 51 * If we are affecting only a bit field, read dest_reg and apply the
52 * mask 52 * mask
53 */ 53 */
54 if (mask != TPS65218_MASK_ALL_BITS) { 54 if (mask != TPS65218_MASK_ALL_BITS) {
55 ret = i2c_read(TPS65218_CHIP_PM, dest_reg, 1, &read_val, 1); 55 ret = i2c_read(TPS65218_CHIP_PM, dest_reg, 1, &read_val, 1);
56 if (ret) 56 if (ret)
57 return ret; 57 return ret;
58 read_val &= (~mask); 58 read_val &= (~mask);
59 read_val |= (dest_val & mask); 59 read_val |= (dest_val & mask);
60 dest_val = read_val; 60 dest_val = read_val;
61 } 61 }
62 62
63 if (prot_level > 0) { 63 if (prot_level > 0) {
64 xor_reg = dest_reg ^ TPS65218_PASSWORD_UNLOCK; 64 xor_reg = dest_reg ^ TPS65218_PASSWORD_UNLOCK;
65 ret = i2c_write(TPS65218_CHIP_PM, TPS65218_PASSWORD, 1, 65 ret = i2c_write(TPS65218_CHIP_PM, TPS65218_PASSWORD, 1,
66 &xor_reg, 1); 66 &xor_reg, 1);
67 if (ret) 67 if (ret)
68 return ret; 68 return ret;
69 } 69 }
70 70
71 ret = i2c_write(TPS65218_CHIP_PM, dest_reg, 1, &dest_val, 1); 71 ret = i2c_write(TPS65218_CHIP_PM, dest_reg, 1, &dest_val, 1);
72 if (ret) 72 if (ret)
73 return ret; 73 return ret;
74 74
75 if (prot_level == TPS65218_PROT_LEVEL_2) { 75 if (prot_level == TPS65218_PROT_LEVEL_2) {
76 ret = i2c_write(TPS65218_CHIP_PM, TPS65218_PASSWORD, 1, 76 ret = i2c_write(TPS65218_CHIP_PM, TPS65218_PASSWORD, 1,
77 &xor_reg, 1); 77 &xor_reg, 1);
78 if (ret) 78 if (ret)
79 return ret; 79 return ret;
80 80
81 ret = i2c_write(TPS65218_CHIP_PM, dest_reg, 1, &dest_val, 1); 81 ret = i2c_write(TPS65218_CHIP_PM, dest_reg, 1, &dest_val, 1);
82 if (ret) 82 if (ret)
83 return ret; 83 return ret;
84 } 84 }
85 85
86 return 0; 86 return 0;
87 } 87 }
88 88
89 /** 89 /**
90 * tps65218_voltage_update() - Function to change a voltage level, as this 90 * tps65218_voltage_update() - Function to change a voltage level, as this
91 * is a multi-step process. 91 * is a multi-step process.
92 * @dc_cntrl_reg: DC voltage control register to change. 92 * @dc_cntrl_reg: DC voltage control register to change.
93 * @volt_sel: New value for the voltage register 93 * @volt_sel: New value for the voltage register
94 * @return: 0 for success, not 0 on failure. 94 * @return: 0 for success, not 0 on failure.
95 */ 95 */
96 int tps65218_voltage_update(uchar dc_cntrl_reg, uchar volt_sel) 96 int tps65218_voltage_update(uchar dc_cntrl_reg, uchar volt_sel)
97 { 97 {
98 if ((dc_cntrl_reg != TPS65218_DCDC1) && 98 if ((dc_cntrl_reg != TPS65218_DCDC1) &&
99 (dc_cntrl_reg != TPS65218_DCDC2) && 99 (dc_cntrl_reg != TPS65218_DCDC2) &&
100 (dc_cntrl_reg != TPS65218_DCDC3)) 100 (dc_cntrl_reg != TPS65218_DCDC3))
101 return 1; 101 return 1;
102 102
103 /* set voltage level */ 103 /* set voltage level */
104 if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, dc_cntrl_reg, volt_sel, 104 if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, dc_cntrl_reg, volt_sel,
105 TPS65218_MASK_ALL_BITS)) 105 TPS65218_DCDC_VSEL_MASK))
106 return 1; 106 return 1;
107 107
108 /* set GO bit to initiate voltage transition */ 108 /* set GO bit to initiate voltage transition */
109 if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, TPS65218_SLEW, 109 if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, TPS65218_SLEW,
110 TPS65218_DCDC_GO, TPS65218_DCDC_GO)) 110 TPS65218_DCDC_GO, TPS65218_DCDC_GO))
111 return 1; 111 return 1;
112 112
113 return 0; 113 return 0;
114 } 114 }
115 115
116 /** 116 /**
117 * tps65218_toggle_fseal() - Perform the sequence that toggles the FSEAL bit. 117 * tps65218_toggle_fseal() - Perform the sequence that toggles the FSEAL bit.
118 * 118 *
119 * @return: 0 on success, -EBADE if the sequence was broken 119 * @return: 0 on success, -EBADE if the sequence was broken
120 */ 120 */
121 int tps65218_toggle_fseal(void) 121 int tps65218_toggle_fseal(void)
122 { 122 {
123 if (tps65218_reg_write(TPS65218_PROT_LEVEL_NONE, TPS65218_PASSWORD, 123 if (tps65218_reg_write(TPS65218_PROT_LEVEL_NONE, TPS65218_PASSWORD,
124 0xb1, TPS65218_MASK_ALL_BITS)) 124 0xb1, TPS65218_MASK_ALL_BITS))
125 return -EBADE; 125 return -EBADE;
126 126
127 if (tps65218_reg_write(TPS65218_PROT_LEVEL_NONE, TPS65218_PASSWORD, 127 if (tps65218_reg_write(TPS65218_PROT_LEVEL_NONE, TPS65218_PASSWORD,
128 0xfe, TPS65218_MASK_ALL_BITS)) 128 0xfe, TPS65218_MASK_ALL_BITS))
129 return -EBADE; 129 return -EBADE;
130 130
131 if (tps65218_reg_write(TPS65218_PROT_LEVEL_NONE, TPS65218_PASSWORD, 131 if (tps65218_reg_write(TPS65218_PROT_LEVEL_NONE, TPS65218_PASSWORD,
132 0xa3, TPS65218_MASK_ALL_BITS)) 132 0xa3, TPS65218_MASK_ALL_BITS))
133 return -EBADE; 133 return -EBADE;
134 134
135 return 0; 135 return 0;
136 } 136 }
137 137
138 /** 138 /**
139 * tps65218_lock_fseal() - Perform the sequence that locks the FSEAL bit to 1. 139 * tps65218_lock_fseal() - Perform the sequence that locks the FSEAL bit to 1.
140 * 140 *
141 * The FSEAL bit prevents the PMIC from turning off DCDC5 and DCDC6. It can be 141 * The FSEAL bit prevents the PMIC from turning off DCDC5 and DCDC6. It can be
142 * toggled at most 3 times: 0->1, 1->0, and finally 0->1. After the third switch 142 * toggled at most 3 times: 0->1, 1->0, and finally 0->1. After the third switch
143 * its value is locked and can only be reset by powering off the PMIC entirely. 143 * its value is locked and can only be reset by powering off the PMIC entirely.
144 * 144 *
145 * @return: 0 on success, -EBADE if the sequence was broken 145 * @return: 0 on success, -EBADE if the sequence was broken
146 */ 146 */
147 int tps65218_lock_fseal(void) 147 int tps65218_lock_fseal(void)
148 { 148 {
149 int i; 149 int i;
150 150
151 for (i = 0; i < 3; i++) 151 for (i = 0; i < 3; i++)
152 if (tps65218_toggle_fseal()) 152 if (tps65218_toggle_fseal())
153 return -EBADE; 153 return -EBADE;
154 154
155 return 0; 155 return 0;
156 } 156 }
157 157
158 int power_tps65218_init(unsigned char bus) 158 int power_tps65218_init(unsigned char bus)
159 { 159 {
160 static const char name[] = "TPS65218_PMIC"; 160 static const char name[] = "TPS65218_PMIC";
161 struct pmic *p = pmic_alloc(); 161 struct pmic *p = pmic_alloc();
162 162
163 if (!p) { 163 if (!p) {
164 printf("%s: POWER allocation error!\n", __func__); 164 printf("%s: POWER allocation error!\n", __func__);
165 return -ENOMEM; 165 return -ENOMEM;
166 } 166 }
167 167
168 p->name = name; 168 p->name = name;
169 p->interface = PMIC_I2C; 169 p->interface = PMIC_I2C;
170 p->number_of_regs = TPS65218_PMIC_NUM_OF_REGS; 170 p->number_of_regs = TPS65218_PMIC_NUM_OF_REGS;
171 p->hw.i2c.addr = TPS65218_CHIP_PM; 171 p->hw.i2c.addr = TPS65218_CHIP_PM;
172 p->hw.i2c.tx_num = 1; 172 p->hw.i2c.tx_num = 1;
173 p->bus = bus; 173 p->bus = bus;
174 174
175 return 0; 175 return 0;
176 } 176 }
177 177
include/power/tps65218.h
1 /* 1 /*
2 * (C) Copyright 2014 2 * (C) Copyright 2014
3 * Texas Instruments, <www.ti.com> 3 * Texas Instruments, <www.ti.com>
4 * 4 *
5 * SPDX-License-Identifier: GPL-2.0+ 5 * SPDX-License-Identifier: GPL-2.0+
6 */ 6 */
7 7
8 #ifndef __POWER_TPS65218_H__ 8 #ifndef __POWER_TPS65218_H__
9 #define __POWER_TPS65218_H__ 9 #define __POWER_TPS65218_H__
10 10
11 #include <linux/bitops.h> 11 #include <linux/bitops.h>
12 12
13 /* I2C chip address */ 13 /* I2C chip address */
14 #define TPS65218_CHIP_PM 0x24 14 #define TPS65218_CHIP_PM 0x24
15 15
16 /* Registers */ 16 /* Registers */
17 enum { 17 enum {
18 TPS65218_CHIPID = 0x00, 18 TPS65218_CHIPID = 0x00,
19 TPS65218_INT1, 19 TPS65218_INT1,
20 TPS65218_INT2, 20 TPS65218_INT2,
21 TPS65218_INT_MASK1, 21 TPS65218_INT_MASK1,
22 TPS65218_INT_MASK2, 22 TPS65218_INT_MASK2,
23 TPS65218_STATUS, 23 TPS65218_STATUS,
24 TPS65218_CONTROL, 24 TPS65218_CONTROL,
25 TPS65218_FLAG, 25 TPS65218_FLAG,
26 TPS65218_PASSWORD = 0x10, 26 TPS65218_PASSWORD = 0x10,
27 TPS65218_ENABLE1, 27 TPS65218_ENABLE1,
28 TPS65218_ENABLE2, 28 TPS65218_ENABLE2,
29 TPS65218_CONFIG1, 29 TPS65218_CONFIG1,
30 TPS65218_CONFIG2, 30 TPS65218_CONFIG2,
31 TPS65218_CONFIG3, 31 TPS65218_CONFIG3,
32 TPS65218_DCDC1, 32 TPS65218_DCDC1,
33 TPS65218_DCDC2, 33 TPS65218_DCDC2,
34 TPS65218_DCDC3, 34 TPS65218_DCDC3,
35 TPS65218_DCDC4, 35 TPS65218_DCDC4,
36 TPS65218_SLEW, 36 TPS65218_SLEW,
37 TPS65218_LDO1, 37 TPS65218_LDO1,
38 TPS65218_SEQ1 = 0x20, 38 TPS65218_SEQ1 = 0x20,
39 TPS65218_SEQ2, 39 TPS65218_SEQ2,
40 TPS65218_SEQ3, 40 TPS65218_SEQ3,
41 TPS65218_SEQ4, 41 TPS65218_SEQ4,
42 TPS65218_SEQ5, 42 TPS65218_SEQ5,
43 TPS65218_SEQ6, 43 TPS65218_SEQ6,
44 TPS65218_SEQ7, 44 TPS65218_SEQ7,
45 TPS65218_PMIC_NUM_OF_REGS, 45 TPS65218_PMIC_NUM_OF_REGS,
46 }; 46 };
47 47
48 #define TPS65218_PROT_LEVEL_NONE 0x00 48 #define TPS65218_PROT_LEVEL_NONE 0x00
49 #define TPS65218_PROT_LEVEL_1 0x01 49 #define TPS65218_PROT_LEVEL_1 0x01
50 #define TPS65218_PROT_LEVEL_2 0x02 50 #define TPS65218_PROT_LEVEL_2 0x02
51 51
52 #define TPS65218_PASSWORD_LOCK_FOR_WRITE 0x00 52 #define TPS65218_PASSWORD_LOCK_FOR_WRITE 0x00
53 #define TPS65218_PASSWORD_UNLOCK 0x7D 53 #define TPS65218_PASSWORD_UNLOCK 0x7D
54 54
55 #define TPS65218_DCDC_GO 0x80 55 #define TPS65218_DCDC_GO 0x80
56 56
57 #define TPS65218_MASK_ALL_BITS 0xFF 57 #define TPS65218_MASK_ALL_BITS 0xFF
58 58
59 #define TPS65218_DCDC_VSEL_MASK 0x3F
60
59 #define TPS65218_DCDC_VOLT_SEL_0950MV 0x0a 61 #define TPS65218_DCDC_VOLT_SEL_0950MV 0x0a
60 #define TPS65218_DCDC_VOLT_SEL_1100MV 0x19 62 #define TPS65218_DCDC_VOLT_SEL_1100MV 0x19
61 #define TPS65218_DCDC_VOLT_SEL_1200MV 0x23 63 #define TPS65218_DCDC_VOLT_SEL_1200MV 0x23
62 #define TPS65218_DCDC_VOLT_SEL_1260MV 0x29 64 #define TPS65218_DCDC_VOLT_SEL_1260MV 0x29
63 #define TPS65218_DCDC_VOLT_SEL_1330MV 0x30 65 #define TPS65218_DCDC_VOLT_SEL_1330MV 0x30
64 #define TPS65218_DCDC3_VOLT_SEL_1350MV 0x12 66 #define TPS65218_DCDC3_VOLT_SEL_1350MV 0x12
65 67
66 #define TPS65218_CC_STAT (BIT(0) | BIT(1)) 68 #define TPS65218_CC_STAT (BIT(0) | BIT(1))
67 #define TPS65218_STATE (BIT(2) | BIT(3)) 69 #define TPS65218_STATE (BIT(2) | BIT(3))
68 #define TPS65218_PB_STATE BIT(4) 70 #define TPS65218_PB_STATE BIT(4)
69 #define TPS65218_AC_STATE BIT(5) 71 #define TPS65218_AC_STATE BIT(5)
70 #define TPS65218_EE BIT(6) 72 #define TPS65218_EE BIT(6)
71 #define TPS65218_FSEAL BIT(7) 73 #define TPS65218_FSEAL BIT(7)
72 74
73 int tps65218_reg_read(uchar dest_reg, uchar *dest_val); 75 int tps65218_reg_read(uchar dest_reg, uchar *dest_val);
74 int tps65218_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val, 76 int tps65218_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
75 uchar mask); 77 uchar mask);
76 int tps65218_voltage_update(uchar dc_cntrl_reg, uchar volt_sel); 78 int tps65218_voltage_update(uchar dc_cntrl_reg, uchar volt_sel);
77 int tps65218_toggle_fseal(void); 79 int tps65218_toggle_fseal(void);
78 int tps65218_lock_fseal(void); 80 int tps65218_lock_fseal(void);
79 int power_tps65218_init(unsigned char bus); 81 int power_tps65218_init(unsigned char bus);
80 #endif /* __POWER_TPS65218_H__ */ 82 #endif /* __POWER_TPS65218_H__ */
81 83