1 /*
2  * Copyright (c) 2020 Allwinner Technology Co., Ltd. ALL rights reserved.
3  */
4 
5 #ifndef __SUNXI_HAL_REGULATOR_H__
6 #define __SUNXI_HAL_REGULATOR_H__
7 #include <hal_debug.h>
8 #include <hal_log.h>
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 struct regulator_dev;
14 
15 struct regulator_ops{
16     int (*enable) (struct regulator_dev *);
17     int (*disable) (struct regulator_dev *);
18     int (*set_voltage) (struct regulator_dev *, int target_uV);
19     int (*get_voltage) (struct regulator_dev *, int *vol_uV);
20 };
21 
22 struct regulator_dev{
23     unsigned int flag;
24     struct regulator_ops *ops;
25     void *private;
26 };
27 
28 struct regulator_linear_range {
29     unsigned int min_uV;
30     unsigned int min_sel;
31     unsigned int max_sel;
32     unsigned int uV_step;
33 };
34 
35 struct regulator_desc {
36     int min_uv;
37     int max_uv;
38     int step1_uv;
39     int vol_reg;
40     int vol_mask;
41     int enable_reg;
42     int enable_mask;
43     int enable_val;
44     int disable_val;
45     const struct regulator_linear_range *linear_ranges;
46     int n_linear_ranges;
47     int *vtable;
48 };
49 
50 #define AXP_DESC(min, max, step1, vreg, vmask, ereg, emask)\
51 {                                             \
52     .min_uv       = (min) * 1000,             \
53     .max_uv       = (max) * 1000,             \
54     .step1_uv     = (step1) * 1000,           \
55     .vol_reg      = vreg,                     \
56     .vol_mask    = (vmask),                  \
57     .enable_reg   = ereg,                     \
58     .enable_mask  = (emask),                  \
59 }
60 
61 #define AXP_DESC_FIXED(volt)\
62 {                                             \
63     .min_uv       = (volt) * 1000,             \
64     .max_uv       = (volt) * 1000,             \
65 }
66 
67 #define AXP_IO(min, max, step1, vreg, vmask, ereg, emask, eval, disval)\
68 {                                             \
69     .min_uv       = (min) * 1000,             \
70     .max_uv       = (max) * 1000,             \
71     .step1_uv     = (step1) * 1000,           \
72     .vol_reg      = vreg,                     \
73     .vol_mask    = (vmask),                  \
74     .enable_reg   = ereg,                     \
75     .enable_mask  = (emask),                  \
76     .enable_val   = eval,                     \
77     .disable_val  = disval,                   \
78 }
79 
80 #define AXP_DESC_RANGES(_ranges, vreg, vmask, ereg, emask)\
81 {                                             \
82     .vol_reg      = vreg,                     \
83     .vol_mask    = (vmask),                  \
84     .enable_reg   = ereg,                     \
85     .enable_mask  = (emask),                  \
86     .linear_ranges  = (_ranges),              \
87     .n_linear_ranges = ARRAY_SIZE(_ranges),   \
88 }
89 
90 #define AXP_SW(ereg, emask)\
91 {                                             \
92     .enable_reg   = ereg,                     \
93     .enable_mask  = (emask),                  \
94 }
95 
96 #define AXP_SEL(min, max, vreg, vmask, ereg, emask, table_name)\
97 {                                                    \
98     .min_uv      = (min) * 1000,                     \
99     .max_uv      = (max) * 1000,                     \
100     .vol_reg     = vreg,                             \
101     .vol_mask   = (vmask),                          \
102     .enable_reg  = ereg,                             \
103     .enable_mask = (emask),                          \
104     .vtable      = (int *)&table_name##_table,       \
105 }
106 
107 /* Initialize struct regulator_linear_range */
108 #define REGULATOR_LINEAR_RANGE(_min_uV, _min_sel, _max_sel, _step_uV)   \
109 {                                                                       \
110     .min_uV         = _min_uV,                                      \
111     .min_sel        = _min_sel,                                     \
112     .max_sel        = _max_sel,                                     \
113     .uV_step        = _step_uV,                                     \
114 }
115 
116 /* for request_flag */
117 #define TWI_PORT_SHIFT      8
118 #define AXP_ADDR_SHIFT      12
119 #define REGULATOR_TYPE_SHIFT    28
120 
121 #define REGULATOR_ID(x)     ((x) & AXP_ID_MASK)
122 #define TWI_PORT(x)     (((x) & TWI_PORT_MASK) >> TWI_PORT_SHIFT)
123 #define AXP_ADDR(x)     (((x) & AXP_ADDR_MASK) >> AXP_ADDR_SHIFT)
124 #define REGULATOR_TYPE(x)   ((x) >> REGULATOR_TYPE_SHIFT)
125 
126 #define AXP_ID_MASK     0x000ff
127 #define TWI_PORT_MASK       0x00f00
128 #define AXP_ADDR_MASK       0xff000
129 
130 #define REGULATOR_GET(x, y) (((x) << REGULATOR_TYPE_SHIFT) | (y))
131 
132 enum REGULATOR_TYPE_ENUM{
133     AXP2101_REGULATOR,
134     PWM_REGULATOR,
135     GPIO_REGULATOR,
136 };
137 
138 /*
139  *         +---> regulator type
140  *         |
141  *         |                --->Rsv
142  *         |               /             --->pmu addr
143  *         |              /             /        --->twi port
144  *         |             /             /        /           --->regulator id
145  *         |            /             /        /           /
146  *      +--------------------------------------------------------+
147  *      |31   28|27             20|19     12|11    8|7          0|
148  *      +--------------------------------------------------------+
149  */
150 
151 //FIXME
152 /*
153 typedef short           s16;
154 typedef long long int       s64;
155 
156 typedef unsigned char       u8;
157 typedef unsigned short      u16;
158 typedef unsigned long long int  u64;
159 */
hal_regulator_get_voltage(struct regulator_dev * rdev,int * vol_uV)160 static inline int hal_regulator_get_voltage(struct regulator_dev *rdev,
161                          int *vol_uV)
162 {
163         if(rdev && rdev->ops && rdev->ops->get_voltage)
164     {
165         return rdev->ops->get_voltage(rdev, vol_uV);
166     }
167     else
168     {
169         hal_soft_break();
170         hal_log_err("fatal error.");
171     }
172     return 0;
173 }
174 
hal_regulator_set_voltage(struct regulator_dev * rdev,int target_uV)175 static inline int hal_regulator_set_voltage(struct regulator_dev *rdev,
176                          int target_uV)
177 {
178         if(rdev && rdev->ops && rdev->ops->set_voltage)
179     {
180         return rdev->ops->set_voltage(rdev, target_uV);
181     }
182     else
183     {
184         hal_soft_break();
185         hal_log_err("fatal error.");
186     }
187     return 0;
188 }
189 
hal_regulator_enable(struct regulator_dev * rdev)190 static inline int hal_regulator_enable(struct regulator_dev *rdev)
191 {
192         if(rdev && rdev->ops && rdev->ops->enable)
193     {
194         return rdev->ops->enable(rdev);
195     }
196     else
197     {
198         hal_soft_break();
199         hal_log_err("fatal error.");
200     }
201     return 0;
202 }
203 
hal_regulator_disable(struct regulator_dev * rdev)204 static inline int hal_regulator_disable(struct regulator_dev *rdev)
205 {
206         if(rdev && rdev->ops && rdev->ops->disable)
207     {
208         return rdev->ops->disable(rdev);
209     }
210     else
211     {
212         hal_soft_break();
213         hal_log_err("fatal error.");
214     }
215 
216     return 0;
217 }
218 int hal_regulator_get(unsigned int request_flag, struct regulator_dev *rdev);
219 /* TODO fix void type */
220 /* TODO fix void type */
221 
222 enum REGULATOR_ID_ENUM {
223     AXP2101_ID_DCDC1 = 0,
224     AXP2101_ID_DCDC2,
225     AXP2101_ID_DCDC3,
226     AXP2101_ID_DCDC4,
227     AXP2101_ID_DCDC5,
228     AXP2101_ID_ALDO1,
229     AXP2101_ID_ALDO2,
230     AXP2101_ID_ALDO3,
231     AXP2101_ID_ALDO4,
232     AXP2101_ID_BLDO1,
233     AXP2101_ID_BLDO2,
234     AXP2101_ID_DLDO1,
235     AXP2101_ID_DLDO2,
236     AXP2101_ID_CPUSLDO,
237     AXP2101_ID_MAX,
238 };
239 extern const struct regulator_desc axp2101_regulators[];
240 
241 int hal_axp_twi_init(struct regulator_dev *rdev);
242 /*int hal_axp_byte_read(struct regulator_dev *rdev, u8 reg, u8 *reg_val);
243 int hal_axp_byte_write(struct regulator_dev *rdev, u8 reg, u8 reg_val);
244 int hal_axp_byte_update(struct regulator_dev *rdev, u8 reg, u8 val, u8 mask);
245 */
246 #ifdef __cplusplus
247 }
248 #endif
249 
250 #endif /* __SUNXI_HAL_REGULATOR_H__ */
251