1d4e6f98dSHope Wang /*
2d4e6f98dSHope Wang * Copyright (c) 2025, Mediatek Inc. All rights reserved.
3d4e6f98dSHope Wang *
4d4e6f98dSHope Wang * SPDX-License-Identifier: BSD-3-Clause
5d4e6f98dSHope Wang */
6d4e6f98dSHope Wang
7d4e6f98dSHope Wang #ifndef PMIC_SET_LOWPOWER_H
8d4e6f98dSHope Wang #define PMIC_SET_LOWPOWER_H
9d4e6f98dSHope Wang
10d4e6f98dSHope Wang #include <stdint.h>
11d4e6f98dSHope Wang
12d4e6f98dSHope Wang #include <drivers/spmi_api.h>
13d4e6f98dSHope Wang
14d4e6f98dSHope Wang #include "mt6316_lowpower_reg.h"
15*868b2d60SZhigang Qin #include "mt6319_lowpower_reg.h"
16d4e6f98dSHope Wang #include "mt6363_lowpower_reg.h"
17d4e6f98dSHope Wang #include "mt6373_lowpower_reg.h"
18d4e6f98dSHope Wang
19d4e6f98dSHope Wang #define OP_MODE_MU 0
20d4e6f98dSHope Wang #define OP_MODE_LP 1
21d4e6f98dSHope Wang
22d4e6f98dSHope Wang #define HW_OFF 0
23d4e6f98dSHope Wang #define HW_ON 0
24d4e6f98dSHope Wang #define HW_LP 1
25d4e6f98dSHope Wang #define HW_ONLV (0x10 | 1)
26d4e6f98dSHope Wang #define NORMAL_OP_CFG 0x10
27d4e6f98dSHope Wang
28d4e6f98dSHope Wang enum {
29d4e6f98dSHope Wang RC0 = 0,
30d4e6f98dSHope Wang RC1,
31d4e6f98dSHope Wang RC2,
32d4e6f98dSHope Wang RC3,
33d4e6f98dSHope Wang RC4,
34d4e6f98dSHope Wang RC5,
35d4e6f98dSHope Wang RC6,
36d4e6f98dSHope Wang RC7,
37d4e6f98dSHope Wang RC8 = 0,
38d4e6f98dSHope Wang RC9,
39d4e6f98dSHope Wang RC10,
40d4e6f98dSHope Wang RC11,
41d4e6f98dSHope Wang RC12,
42d4e6f98dSHope Wang RC13,
43d4e6f98dSHope Wang HW0 = 0,
44d4e6f98dSHope Wang HW1,
45d4e6f98dSHope Wang HW2,
46d4e6f98dSHope Wang HW3,
47d4e6f98dSHope Wang HW4,
48d4e6f98dSHope Wang HW5,
49d4e6f98dSHope Wang HW6,
50d4e6f98dSHope Wang HW7,
51d4e6f98dSHope Wang HW8 = 0,
52d4e6f98dSHope Wang HW9,
53d4e6f98dSHope Wang HW10,
54d4e6f98dSHope Wang HW11,
55d4e6f98dSHope Wang HW12,
56d4e6f98dSHope Wang HW13,
57d4e6f98dSHope Wang };
58d4e6f98dSHope Wang
59d4e6f98dSHope Wang #define VOTER_EN_SET 1
60d4e6f98dSHope Wang #define VOTER_EN_CLR 2
61d4e6f98dSHope Wang
62d4e6f98dSHope Wang enum {
63d4e6f98dSHope Wang VOTER_EN_LO_BIT0 = 0,
64d4e6f98dSHope Wang VOTER_EN_LO_BIT1,
65d4e6f98dSHope Wang VOTER_EN_LO_BIT2,
66d4e6f98dSHope Wang VOTER_EN_LO_BIT3,
67d4e6f98dSHope Wang VOTER_EN_LO_BIT4,
68d4e6f98dSHope Wang VOTER_EN_LO_BIT5,
69d4e6f98dSHope Wang VOTER_EN_LO_BIT6,
70d4e6f98dSHope Wang VOTER_EN_LO_BIT7,
71d4e6f98dSHope Wang VOTER_EN_HI_BIT0 = 0,
72d4e6f98dSHope Wang VOTER_EN_HI_BIT1,
73d4e6f98dSHope Wang VOTER_EN_HI_BIT2,
74d4e6f98dSHope Wang VOTER_EN_HI_BIT3,
75d4e6f98dSHope Wang };
76d4e6f98dSHope Wang
77d4e6f98dSHope Wang enum {
78d4e6f98dSHope Wang MT6363_SLAVE = SPMI_SLAVE_4,
79d4e6f98dSHope Wang MT6368_SLAVE = SPMI_SLAVE_5,
80d4e6f98dSHope Wang MT6369_SLAVE = SPMI_SLAVE_5,
81d4e6f98dSHope Wang MT6373_SLAVE = SPMI_SLAVE_5,
82d4e6f98dSHope Wang MT6316_S6_SLAVE = SPMI_SLAVE_6,
83d4e6f98dSHope Wang MT6316_S7_SLAVE = SPMI_SLAVE_7,
84d4e6f98dSHope Wang MT6316_S8_SLAVE = SPMI_SLAVE_8,
85d4e6f98dSHope Wang MT6316_S15_SLAVE = SPMI_SLAVE_15,
86d4e6f98dSHope Wang MT6319_S6_SLAVE = SPMI_SLAVE_6,
87d4e6f98dSHope Wang MT6319_S7_SLAVE = SPMI_SLAVE_7,
88d4e6f98dSHope Wang MT6319_S8_SLAVE = SPMI_SLAVE_8,
89d4e6f98dSHope Wang MT6319_S15_SLAVE = SPMI_SLAVE_15,
90d4e6f98dSHope Wang };
91d4e6f98dSHope Wang
92d4e6f98dSHope Wang extern struct spmi_device *lowpower_sdev[SPMI_MAX_SLAVE_ID];
93d4e6f98dSHope Wang
94d4e6f98dSHope Wang #define PMIC_BUCK_SET_LP(_chip, _name, _user, _en, _mode, _cfg) \
95d4e6f98dSHope Wang { \
96d4e6f98dSHope Wang uint8_t val = 0; \
97d4e6f98dSHope Wang struct spmi_device *sdev = lowpower_sdev[_chip##_SLAVE]; \
98d4e6f98dSHope Wang if (sdev && \
99d4e6f98dSHope Wang !spmi_ext_register_readl(sdev, _chip##_RG_BUCK_##_name##_HW0_OP_CFG_ADDR, &val, 1) && \
100d4e6f98dSHope Wang !(val & NORMAL_OP_CFG)) {\
101d4e6f98dSHope Wang if ((_cfg) == HW_ONLV) { \
102d4e6f98dSHope Wang pmic_spmi_update_bits(sdev, \
103d4e6f98dSHope Wang _chip##_RG_BUCK_##_name##_ONLV_EN_ADDR, \
104d4e6f98dSHope Wang (1 << _chip##_RG_BUCK_##_name##_ONLV_EN_SHIFT), \
105d4e6f98dSHope Wang (1 << _chip##_RG_BUCK_##_name##_ONLV_EN_SHIFT)); \
106d4e6f98dSHope Wang } else if ((_cfg) == HW_LP) { \
107d4e6f98dSHope Wang pmic_spmi_update_bits(sdev, \
108d4e6f98dSHope Wang _chip##_RG_BUCK_##_name##_ONLV_EN_ADDR, \
109d4e6f98dSHope Wang (1 << _chip##_RG_BUCK_##_name##_ONLV_EN_SHIFT), \
110d4e6f98dSHope Wang 0); \
111d4e6f98dSHope Wang } \
112d4e6f98dSHope Wang pmic_spmi_update_bits(sdev, \
113d4e6f98dSHope Wang _chip##_RG_BUCK_##_name##_##_user##_OP_CFG_ADDR, \
114d4e6f98dSHope Wang 1 << (_user), \
115d4e6f98dSHope Wang ((_cfg) & 0x1) ? 1 << (_user) : 0); \
116d4e6f98dSHope Wang pmic_spmi_update_bits(sdev, \
117d4e6f98dSHope Wang _chip##_RG_BUCK_##_name##_##_user##_OP_MODE_ADDR, \
118d4e6f98dSHope Wang 1 << (_user), \
119d4e6f98dSHope Wang (_mode) ? 1 << (_user) : 0); \
120d4e6f98dSHope Wang pmic_spmi_update_bits(sdev, \
121d4e6f98dSHope Wang _chip##_RG_BUCK_##_name##_##_user##_OP_EN_ADDR, \
122d4e6f98dSHope Wang 1 << (_user), \
123d4e6f98dSHope Wang (_en) ? 1 << (_user) : 0); \
124d4e6f98dSHope Wang } \
125d4e6f98dSHope Wang }
126d4e6f98dSHope Wang
127d4e6f98dSHope Wang #define PMIC_LDO_SET_LP(_chip, _name, _user, _en, _mode, _cfg) \
128d4e6f98dSHope Wang { \
129d4e6f98dSHope Wang uint8_t val = 0; \
130d4e6f98dSHope Wang struct spmi_device *sdev = lowpower_sdev[_chip##_SLAVE]; \
131d4e6f98dSHope Wang if (sdev && \
132d4e6f98dSHope Wang !spmi_ext_register_readl(sdev, _chip##_RG_LDO_##_name##_HW0_OP_CFG_ADDR, &val, 1) && \
133d4e6f98dSHope Wang !(val & NORMAL_OP_CFG)) {\
134d4e6f98dSHope Wang if ((_cfg) == HW_ONLV) { \
135d4e6f98dSHope Wang pmic_spmi_update_bits(sdev, \
136d4e6f98dSHope Wang _chip##_RG_LDO_##_name##_ONLV_EN_ADDR, \
137d4e6f98dSHope Wang (1 << _chip##_RG_LDO_##_name##_ONLV_EN_SHIFT), \
138d4e6f98dSHope Wang (1 << _chip##_RG_LDO_##_name##_ONLV_EN_SHIFT)); \
139d4e6f98dSHope Wang } else { \
140d4e6f98dSHope Wang pmic_spmi_update_bits(sdev, \
141d4e6f98dSHope Wang _chip##_RG_LDO_##_name##_ONLV_EN_ADDR, \
142d4e6f98dSHope Wang (1 << _chip##_RG_LDO_##_name##_ONLV_EN_SHIFT), \
143d4e6f98dSHope Wang 0); \
144d4e6f98dSHope Wang } \
145d4e6f98dSHope Wang pmic_spmi_update_bits(sdev, \
146d4e6f98dSHope Wang _chip##_RG_LDO_##_name##_##_user##_OP_CFG_ADDR, \
147d4e6f98dSHope Wang 1 << (_user), \
148d4e6f98dSHope Wang ((_cfg) & 0x1) ? 1 << (_user) : 0); \
149d4e6f98dSHope Wang pmic_spmi_update_bits(sdev, \
150d4e6f98dSHope Wang _chip##_RG_LDO_##_name##_##_user##_OP_MODE_ADDR, \
151d4e6f98dSHope Wang 1 << (_user), \
152d4e6f98dSHope Wang (_mode) ? 1 << (_user) : 0); \
153d4e6f98dSHope Wang pmic_spmi_update_bits(sdev, \
154d4e6f98dSHope Wang _chip##_RG_LDO_##_name##_##_user##_OP_EN_ADDR, \
155d4e6f98dSHope Wang 1 << (_user), \
156d4e6f98dSHope Wang (_en) ? 1 << (_user) : 0); \
157d4e6f98dSHope Wang } \
158d4e6f98dSHope Wang }
159d4e6f98dSHope Wang
160d4e6f98dSHope Wang #define PMIC_SLVID_BUCK_SET_LP(_chip, _slvid, _name, _user, _en, _mode, _cfg) \
161d4e6f98dSHope Wang { \
162d4e6f98dSHope Wang struct spmi_device *sdev = lowpower_sdev[_chip##_##_slvid##_SLAVE]; \
163d4e6f98dSHope Wang if (sdev) {\
164d4e6f98dSHope Wang pmic_spmi_update_bits(sdev, \
165d4e6f98dSHope Wang _chip##_RG_BUCK_##_name##_##_user##_OP_CFG_ADDR, \
166d4e6f98dSHope Wang 1 << (_user), \
167d4e6f98dSHope Wang (_cfg) ? 1 << (_user) : 0); \
168d4e6f98dSHope Wang pmic_spmi_update_bits(sdev, \
169d4e6f98dSHope Wang _chip##_RG_BUCK_##_name##_##_user##_OP_MODE_ADDR, \
170d4e6f98dSHope Wang 1 << (_user), \
171d4e6f98dSHope Wang (_mode) ? 1 << (_user) : 0); \
172d4e6f98dSHope Wang pmic_spmi_update_bits(sdev, \
173d4e6f98dSHope Wang _chip##_RG_BUCK_##_name##_##_user##_OP_EN_ADDR, \
174d4e6f98dSHope Wang 1 << (_user), \
175d4e6f98dSHope Wang (_en) ? 1 << (_user) : 0); \
176d4e6f98dSHope Wang } \
177d4e6f98dSHope Wang }
178d4e6f98dSHope Wang
179d4e6f98dSHope Wang #define PMIC_BUCK_VOTER_EN(_chip, _name, _user, _cfg) \
180d4e6f98dSHope Wang { \
181d4e6f98dSHope Wang struct spmi_device *sdev = lowpower_sdev[_chip##_SLAVE]; \
182d4e6f98dSHope Wang if (sdev) {\
183d4e6f98dSHope Wang pmic_spmi_update_bits(sdev, \
184d4e6f98dSHope Wang _chip##_RG_BUCK_##_name##_##_user##_ADDR + (_cfg), \
185d4e6f98dSHope Wang 1 << (_user), \
186d4e6f98dSHope Wang 1 << (_user)); \
187d4e6f98dSHope Wang } \
188d4e6f98dSHope Wang }
189d4e6f98dSHope Wang
pmic_spmi_update_bits(struct spmi_device * sdev,uint16_t reg,uint8_t mask,uint8_t val)190d4e6f98dSHope Wang static inline int pmic_spmi_update_bits(struct spmi_device *sdev, uint16_t reg,
191d4e6f98dSHope Wang uint8_t mask, uint8_t val)
192d4e6f98dSHope Wang {
193d4e6f98dSHope Wang uint8_t org = 0;
194d4e6f98dSHope Wang int ret = 0;
195d4e6f98dSHope Wang
196d4e6f98dSHope Wang ret = spmi_ext_register_readl(sdev, reg, &org, 1);
197d4e6f98dSHope Wang if (ret < 0)
198d4e6f98dSHope Wang return ret;
199d4e6f98dSHope Wang
200d4e6f98dSHope Wang org &= ~mask;
201d4e6f98dSHope Wang org |= val & mask;
202d4e6f98dSHope Wang
203d4e6f98dSHope Wang ret = spmi_ext_register_writel(sdev, reg, &org, 1);
204d4e6f98dSHope Wang return ret;
205d4e6f98dSHope Wang }
206d4e6f98dSHope Wang
207d4e6f98dSHope Wang #endif /* PMIC_SET_LOWPOWER_H */
208