blob: 68938898302d7d8bb3bd6e45ac1985e75a2b587f [file] [log] [blame]
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +08001/*
2 * Copyright (C) 2014-2018 Amlogic, Inc. All rights reserved.
3 *
4 * All information contained herein is Amlogic confidential.
5 *
6 * This software is provided to you pursuant to Software License Agreement
7 * (SLA) with Amlogic Inc ("Amlogic"). This software may be used
8 * only in accordance with the terms of this agreement.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification is strictly prohibited without prior written permission from
12 * Amlogic.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "bd71837.h"
28#include "meson_i2c.h"
29#include "uart.h"
30#include "myprintf.h"
31#include "gpio.h"
32
33static const struct regulator_linear_range bd718xx_dvs_buck_volts[] = {
34 REGULATOR_LINEAR_RANGE(700000, 0x00, 0x3C, 10000),
35 REGULATOR_LINEAR_RANGE(1300000, 0x3D, 0x3F, 0),
36};
37
38static const struct regulator_linear_range bd71837_buck5_volts[] = {
39 /* Ranges when VOLT_SEL bit is 0 */
40 REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000),
41 REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000),
42 REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000),
43};
44
45static const struct regulator_linear_range bd71837_buck6_volts[] = {
46 REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
47};
48
49static const unsigned int bd71837_buck7_volts[] = {
50 1605000, 1695000, 1755000, 1800000, 1845000, 1905000, 1950000, 1995000
51};
52
53static const struct regulator_linear_range bd71837_buck8_volts[] = {
54 REGULATOR_LINEAR_RANGE(680000, 0x00, 0x3C, 11500),
55 REGULATOR_LINEAR_RANGE(1370000, 0x3C, 0x3F, 0),
56 };
57
58static const struct regulator_linear_range bd718xx_ldo1_volts[] = {
59 REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000),
60};
61
62static const unsigned int ldo_2_volts[] = {
63 900000, 800000
64};
65
66static const struct regulator_linear_range bd718xx_ldo3_volts[] = {
67 REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
68};
69
70static const struct regulator_linear_range bd718xx_ldo4_volts[] = {
71 REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000),
72 REGULATOR_LINEAR_RANGE(1800000, 0xa, 0xf, 0),
73};
74
75static const struct regulator_linear_range bd71837_ldo5_volts[] = {
76 REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
77};
78
79static const struct regulator_linear_range bd718xx_ldo6_volts[] = {
80 REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000),
81 REGULATOR_LINEAR_RANGE(1800000, 0xA, 0xF, 0),
82};
83
84static const struct regulator_linear_range bd71837_ldo7_volts[] = {
85 REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
86};
87
88static int find_index(const unsigned int *p,unsigned int len,unsigned int sel)
89{
90 for (unsigned int i = 0; i < len; i++)
91 {
92 if (sel == p[i])
93 return i;
94 }
95 return -1;
96
97}
98
99static int find_index_struct(struct regulator_desc *rdev,unsigned int sel, int id)
100{
101 int b = 0;
102 unsigned int min_sel1 = 0;
103 unsigned int step = 0;
104 min_sel1 = (rdev->linear_ranges)[id].min_sel;
105 step = (rdev->linear_ranges)[id].uV_step;
106 b = sel - (rdev->linear_ranges)[id].min_uV;
107 b = b/step;
108 b = min_sel1 + b;
109 return b;
110
111}
112
113static void set_pmic_bd71837_pinmux(struct pmic_i2c *bd71837_i2c_config1)
114{
115 // set pinmux
116 iprintf("set %s pinmux\n",bd71837_i2c_config1->name);
117 xPinmuxSet(bd71837_i2c_config1->scl, bd71837_i2c_config1->scl_value);
118 xPinmuxSet(bd71837_i2c_config1->sda, bd71837_i2c_config1->sda_value);
119 //set ds and pull up
120 xPinconfSet(bd71837_i2c_config1->scl, PINF_CONFIG_BIAS_PULL_UP | PINF_CONFIG_DRV_STRENGTH_3);
121 xPinconfSet(bd71837_i2c_config1->sda, PINF_CONFIG_BIAS_PULL_UP | PINF_CONFIG_DRV_STRENGTH_3);
122}
123
124static void BD71837_PMIC_I2C_INIT(struct pmic_i2c *bd71837_i2c_config) {
125 set_pmic_bd71837_pinmux(bd71837_i2c_config);
126 xI2cMesonPortInit(bd71837_i2c_config->port);
127}
128
129static int bd71837_regulator_ctrl(struct regulator_desc *rdev,int status)
130{
131 int ret = 0;
132 unsigned char ctrl_reg = 0x0;
133 if ((rdev->id)<= 7) {
134 ret = xI2cMesonRead(bd718x7_slave_address,rdev->enable_reg,&ctrl_reg,1);
135 if (ret < 0) {
136 printf("i2c buck read failed\n");
137 return ret;
138 }
139 ctrl_reg &= (~(rdev->enable_mask));
140 if (status) {
141 ctrl_reg |= rdev->enable_val;
142 } else {
143 ctrl_reg |= rdev->disable_val;
144 }
145 ret = xI2cMesonWrite(bd718x7_slave_address,rdev->enable_reg,&ctrl_reg,1);
146 if (ret < 0) {
147 printf("i2c buck write failed\n");
148 return ret;
149 }
150
151 } else {
152 ret = xI2cMesonRead(bd718x7_slave_address,rdev->ldo_reg,&ctrl_reg,1);
153 if (ret < 0) {
154 printf("i2c ldo read failed\n");
155 return ret;
156 }
157 ctrl_reg &= (~(rdev->ldo_mask_ctrl));
158 if (status) {
159 ctrl_reg |= rdev->ldo_val_ctrl;
160 } else {
161 ctrl_reg |= rdev->ldo_val_ctrl_disable;
162 }
163 ret = xI2cMesonWrite(bd718x7_slave_address,rdev->ldo_reg,&ctrl_reg,1);
164 if (ret < 0) {
165 printf("i2c ldo write failed\n");
166 return ret;
167 }
168
169 }
170 return ret;
171}
172
173static int bd71837_regulator_set_voltage(struct regulator_desc *rdev, unsigned int sel)
174{
175 int a = 0;
176 int ret = 0;
177 unsigned char ctrl_reg = 0;
178 if ((rdev->id)<= 3) { /* buck1-4 */
179 if (sel <= 1290000) {
180 a = find_index_struct(rdev,sel,0);
181 } else {
182 a = (rdev->linear_ranges)[1].min_sel;
183 }
184 } /* buck5 */
185 if ((rdev->id) == 4) {
186 if (sel <= 1000000) {
187 a = find_index_struct(rdev,sel,0);
188 } else if (1050000 <= sel && sel <= 1100000) {
189 a = find_index_struct(rdev,sel,1);
190 } else {
191 a = find_index_struct(rdev,sel,2);
192 }
193 } /* buck6 */
194 if ((rdev->id) == 5) {
195 a = find_index_struct(rdev,sel,0);
196 } /*buck7 */
197 if ((rdev->id) == 6) {
198 a = find_index(rdev->volt_table,rdev->n_voltages,sel);
199 } /*buck8*/
200 if ((rdev->id) == 7) {
201 if (sel <= 1358500) {
202 a = find_index_struct(rdev,sel,0);
203 } else {
204 a = (rdev->linear_ranges)[1].min_sel;
205 }
206 } /* ldo1 */
207 if ((rdev->id) == 8) {
208 a = find_index_struct(rdev,sel,0);
209 } /* ldo2 */
210 if ((rdev->id) == 9) {
211 a = find_index(rdev->volt_table,rdev->n_voltages,sel);
212 a = a << 5;
213 } /* ldo3 */
214 if ((rdev->id) == 10) {
215 a = find_index_struct(rdev,sel,0);
216 } /* ldo4 */
217 if ((rdev->id) == 11) {
218 if (sel <= 1700000) {
219 a = find_index_struct(rdev,sel,0);
220 } else {
221 a = (rdev->linear_ranges)[1].min_sel;
222 }
223 } /* ldo5 */
224 if ((rdev->id) == 12) {
225 a = find_index_struct(rdev,sel,0);
226 } /* ldo6 */
227 if ((rdev->id) == 13) {
228 if (sel <= 1700000) {
229 a = find_index_struct(rdev,sel,0);
230 } else {
231 a = (rdev->linear_ranges)[1].min_sel;
232 }
233 } /* ldo7 */
234 if ((rdev->id) == 14) {
235 a = find_index_struct(rdev,sel,0);
236 }
237 if ((rdev->id) <= 7) {
238 ret = xI2cMesonRead(bd718x7_slave_address,rdev->vsel_reg,&ctrl_reg,1);
239 if (ret < 0) {
240 printf("i2c buck read failed\n");
241 return ret;
242 }
243 ctrl_reg &= (~(rdev->vsel_mask));
244 ctrl_reg |= (a<<0);
245 ret = xI2cMesonWrite(bd718x7_slave_address,rdev->vsel_reg,&ctrl_reg,1);
246 if (ret < 0) {
247 printf("i2c buck write failed\n");
248 return ret;
249 }
250 }
251 if ((rdev->id) > 7) {
252 ret = xI2cMesonRead(bd718x7_slave_address,rdev->ldo_reg,&ctrl_reg,1);
253 if (ret < 0) {
254 printf("i2c ldo read failed\n");
255 return ret;
256 }
257 ctrl_reg &= (~(rdev->ldo_out_mask));
258 ctrl_reg |= a;
259 ret = xI2cMesonWrite(bd718x7_slave_address,rdev->ldo_reg,&ctrl_reg,1);
260 if (ret < 0) {
261 printf("i2c ldo write failed\n");
262 return ret;
263 }
264 }
265
266 return ret;
267}
268
269static void bd71837_osc_ctrl(int status)
270{
271 unsigned char ctrl_reg = 0;
272 int ret = 0;
273 ret = xI2cMesonRead(bd718x7_slave_address,BD718XX_REG_OUT32K,&ctrl_reg,1);
274 if (ret < 0) {
275 printf("i2c osc read failed\n");
276 return;
277 }
278 if (status) {
279 ctrl_reg &= (~0x1);
280 ctrl_reg |= 0x1;
281 } else {
282 ctrl_reg &= (~0x1);
283 ctrl_reg |= 0x0;
284 }
285 ret = xI2cMesonWrite(bd718x7_slave_address,BD718XX_REG_OUT32K,&ctrl_reg,1);
286 if (ret < 0) {
287 printf("i2c osc write failed\n");
288 return;
289 }
290 return;
291}
292
293static const struct regulator_ops bd718xx_dvs_buck_regulator_ops = {
294 .ctrl = bd71837_regulator_ctrl,
295 .set_voltage = bd71837_regulator_set_voltage,
296};
297
298struct regulator_desc bd71837_desc[15] = {
299 {
300 .name = "buck1",
301 .id = BD718XX_BUCK1,
302 .ops = &bd718xx_dvs_buck_regulator_ops,
303 .linear_ranges = bd718xx_dvs_buck_volts,
304 .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts),
305 .enable_reg = BD718XX_REG_BUCK1_CTRL,
306 .enable_mask = 0x3, //bit0 = 1, bit1 = 1
307 .enable_val = 0x3,
308 .disable_val = 0x2, //bitt = 0 ,bit1 = 1
309 .vsel_reg = BD718XX_REG_BUCK1_VOLT_RUN,
310 .vsel_mask = 0x3f,
311 },
312 {
313 .name = "buck2",
314 .id = BD718XX_BUCK2,
315 .ops = &bd718xx_dvs_buck_regulator_ops,
316 .linear_ranges = bd718xx_dvs_buck_volts,
317 .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts),
318 .enable_reg = BD718XX_REG_BUCK2_CTRL,
319 .enable_mask = 0x3, //bit0 =1 ,bit1 = 1;
320 .enable_val = 0x3,
321 .disable_val = 0x2, //bitt = 0 ,bit1 = 1
322 .vsel_reg = BD718XX_REG_BUCK2_VOLT_RUN,
323 .vsel_mask = 0x3f,
324 },
325 {
326 .name = "buck3",
327 .id = BD718XX_BUCK3,
328 .ops = &bd718xx_dvs_buck_regulator_ops,
329 .linear_ranges = bd718xx_dvs_buck_volts,
330 .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts),
331 .enable_reg = BD71837_REG_BUCK3_CTRL,
332 .enable_mask = 0x7, //bit0 =1 ,bit1 = 1 , bit2 = 1;
333 .enable_val = 0x7,
334 .disable_val = 0x2, //bitt = 0 ,bit1 = 1
335 .vsel_reg = BD71837_REG_BUCK3_VOLT_RUN,
336 .vsel_mask = 0x3f,
337 },
338 {
339 .name = "buck4",
340 .id = BD718XX_BUCK4,
341 .ops = &bd718xx_dvs_buck_regulator_ops,
342 .linear_ranges = bd718xx_dvs_buck_volts,
343 .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts),
344 .enable_reg = BD71837_REG_BUCK4_CTRL,
345 .enable_mask = 0x7, //bit0 =1 ,bit1 = 1 , bit2 = 1;
346 .enable_val = 0x7,
347 .disable_val = 0x2, //bitt = 0 ,bit1 = 1
348 .vsel_reg = BD71837_REG_BUCK4_VOLT_RUN,
349 .vsel_mask = 0x3f,
350 },
351 {
352 .name = "buck5",
353 .id = BD718XX_BUCK5,
354 .ops = &bd718xx_dvs_buck_regulator_ops,
355 .linear_ranges = bd71837_buck5_volts,
356 .n_linear_ranges =
357 ARRAY_SIZE(bd71837_buck5_volts),
358 .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
359 .enable_mask = 0x3, //bit0 =1 ,bit1 = 1
360 .enable_val = 0x3,
361 .disable_val = 0x2, //bit0 = 0 ,bit1 = 1
362 .vsel_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
363 .vsel_mask = 0x7, // 某认bit7 = 0
364
365 },
366 {
367 .name = "buck6",
368 .id = BD718XX_BUCK6,
369 .ops = &bd718xx_dvs_buck_regulator_ops,
370 .linear_ranges = bd71837_buck6_volts,
371 .n_linear_ranges =
372 ARRAY_SIZE(bd71837_buck6_volts),
373 .enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL,
374 .enable_mask = 0x3, //bit0 =1 ,bit1 = 1,
375 .enable_val = 0x3,
376 .disable_val = 0x2, //bit0 = 0 ,bit1 = 1
377 .vsel_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT,
378 .vsel_mask = 0x3,
379 },
380 {
381 .name = "buck7",
382 .id = BD718XX_BUCK7,
383 .ops = &bd718xx_dvs_buck_regulator_ops,
384 .volt_table = &bd71837_buck7_volts[0],
385 .n_voltages = sizeof(bd71837_buck7_volts),
386 .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL,
387 .enable_mask = 0x3, //bit0 =1 ,bit1 = 1,
388 .enable_val = 0x3,
389 .disable_val = 0x2, //bit0 = 0 ,bit1 = 1
390 .vsel_reg = BD718XX_REG_3RD_NODVS_BUCK_VOLT,
391 .vsel_mask = 0x7,
392 },
393 {
394 .name = "buck8",
395 .id = BD718XX_BUCK8,
396 .ops = &bd718xx_dvs_buck_regulator_ops,
397 .linear_ranges = bd71837_buck8_volts,
398 .n_linear_ranges =
399 ARRAY_SIZE(bd71837_buck8_volts),
400 .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL,
401 .enable_mask = 0x3, //bit0 =1 ,bit1 = 1,
402 .enable_val = 0x3,
403 .disable_val = 0x2, //bit0 = 0 ,bit1 = 1
404 .vsel_reg = BD718XX_REG_4TH_NODVS_BUCK_VOLT,
405 .vsel_mask = 0x3f,
406 },
407 {
408 .name = "ldo1",
409 .id = BD718XX_LDO1,
410 .ops = &bd718xx_dvs_buck_regulator_ops,
411 .linear_ranges = bd718xx_ldo1_volts,
412 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo1_volts),
413 .ldo_reg = BD718XX_REG_LDO1_VOLT,
414 .ldo_mask_ctrl = 0xe0, //bit5 = 1,bit6 =1,bit7 =1
415 .ldo_val_ctrl = 0xe0,
416 .ldo_val_ctrl_disable = 0x80, //bit6 =0 ,bit7 = 1
417 .ldo_out_mask = 0x3, //bit0-bit1 = 1
418
419 },
420 {
421 .name = "ldo2",
422 .id = BD718XX_LDO2,
423 .ops = &bd718xx_dvs_buck_regulator_ops,
424 .volt_table = &ldo_2_volts[0],
425 .n_voltages =
426 ARRAY_SIZE(bd71837_buck8_volts),
427 .ldo_reg = BD718XX_REG_LDO2_VOLT,
428 .ldo_mask_ctrl = 0xc0, //bit6 =1,bit7 =1
429 .ldo_val_ctrl = 0xc0,
430 .ldo_val_ctrl_disable = 0x80, //bit6 =0 ,bit7 = 1
431 .ldo_out_mask = 0x20, //bit5 = 1
432 },
433 {
434 .name = "ldo3",
435 .id = BD718XX_LDO3,
436 .ops = &bd718xx_dvs_buck_regulator_ops,
437 .linear_ranges = bd718xx_ldo3_volts,
438 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo3_volts),
439 .ldo_reg = BD718XX_REG_LDO3_VOLT,
440 .ldo_mask_ctrl = 0xc0, //bit6=1,bi7=1
441 .ldo_val_ctrl = 0xc0,
442 .ldo_val_ctrl_disable = 0x80, //bit6 =0 ,bit7 = 1
443 .ldo_out_mask = 0xf, //bit0-bit3 = 1
444 },
445 {
446 .name = "ldo4",
447 .id = BD718XX_LDO4,
448 .ops = &bd718xx_dvs_buck_regulator_ops,
449 .linear_ranges = bd718xx_ldo4_volts,
450 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo4_volts),
451 .ldo_reg = BD718XX_REG_LDO4_VOLT,
452 .ldo_mask_ctrl = 0xc0, //bit6=1,bi7=1,
453 .ldo_val_ctrl = 0xc0,
454 .ldo_val_ctrl_disable = 0x80, //bit6 =0 ,bit7 = 1
455 .ldo_out_mask = 0xf, //bit0-bit3 = 1
456 },
457 {
458 .name = "ldo5",
459 .id = BD718XX_LDO5,
460 .ops = &bd718xx_dvs_buck_regulator_ops,
461 .linear_ranges = bd71837_ldo5_volts,
462 .n_linear_ranges = ARRAY_SIZE(bd71837_ldo5_volts),
463 .ldo_reg = BD718XX_REG_LDO5_VOLT,
464 .ldo_mask_ctrl = 0xc0, //bit6=1,bi7=1,
465 .ldo_val_ctrl = 0xc0,
466 .ldo_val_ctrl_disable = 0x80, //bit6 =0 ,bit7 = 1
467 .ldo_out_mask = 0xf, //bit0-bit3 = 1
468 },
469 {
470 .name = "ldo6",
471 .id = BD718XX_LDO6,
472 .ops = &bd718xx_dvs_buck_regulator_ops,
473 .linear_ranges = bd718xx_ldo6_volts,
474 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo6_volts),
475 .ldo_reg = BD718XX_REG_LDO6_VOLT,
476 .ldo_mask_ctrl = 0xc0, //bit6=1,bi7=1,
477 .ldo_val_ctrl = 0xc0,
478 .ldo_val_ctrl_disable = 0x80, //bit6 =0 ,bit7 = 1
479 .ldo_out_mask = 0xf, //bit0-bit3 = 1
480 },
481 {
482 .name = "ldo7",
483 .id = BD718XX_LDO7,
484 .ops = &bd718xx_dvs_buck_regulator_ops,
485 .linear_ranges = bd71837_ldo7_volts,
486 .n_linear_ranges = ARRAY_SIZE(bd71837_ldo7_volts),
487
488 .ldo_reg = BD71837_REG_LDO7_VOLT,
489 .ldo_mask_ctrl = 0xc0, //bit6=1,bi7=1,
490 .ldo_val_ctrl = 0xc0,
491 .ldo_val_ctrl_disable = 0x80, //bit6 =0 ,bit7 = 1
492 .ldo_out_mask = 0xf, //bit0-bit3 = 1
493 },
494
495};
496
497struct pmic_regulator BD71837_PMIC = {
498 .pmic_i2c_config = BD71837_PMIC_I2C_INIT,
499 .osc_ctrl = bd71837_osc_ctrl,
500 .rdev = bd71837_desc,
501 .num = ARRAY_SIZE(bd71837_desc),
502};
503
504
505
506