]>
Commit | Line | Data |
---|---|---|
1d624a4f HG |
1 | /* |
2 | * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com> | |
3 | * | |
4 | * Sunxi PMIC bus access helpers | |
5 | * | |
6 | * The axp152 & axp209 use an i2c bus, the axp221 uses the p2wi bus and the | |
7 | * axp223 uses the rsb bus, these functions abstract this. | |
8 | * | |
9 | * SPDX-License-Identifier: GPL-2.0+ | |
10 | */ | |
11 | ||
12 | #include <common.h> | |
13 | #include <asm/arch/p2wi.h> | |
14 | #include <asm/arch/rsb.h> | |
a536077d | 15 | #include <i2c.h> |
1d624a4f HG |
16 | #include <asm/arch/pmic_bus.h> |
17 | ||
a536077d HG |
18 | #define AXP152_I2C_ADDR 0x30 |
19 | ||
20 | #define AXP209_I2C_ADDR 0x34 | |
21 | ||
1d624a4f HG |
22 | #define AXP221_CHIP_ADDR 0x68 |
23 | #define AXP221_CTRL_ADDR 0x3e | |
24 | #define AXP221_INIT_DATA 0x3e | |
25 | ||
95ab8fee | 26 | /* AXP818 device and runtime addresses are same as AXP223 */ |
1d624a4f HG |
27 | #define AXP223_DEVICE_ADDR 0x3a3 |
28 | #define AXP223_RUNTIME_ADDR 0x2d | |
29 | ||
30 | int pmic_bus_init(void) | |
31 | { | |
32 | /* This cannot be 0 because it is used in SPL before BSS is ready */ | |
33 | static int needs_init = 1; | |
a536077d | 34 | __maybe_unused int ret; |
1d624a4f HG |
35 | |
36 | if (!needs_init) | |
37 | return 0; | |
38 | ||
95ab8fee | 39 | #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER |
a536077d | 40 | # ifdef CONFIG_MACH_SUN6I |
1d624a4f HG |
41 | p2wi_init(); |
42 | ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR, AXP221_CTRL_ADDR, | |
43 | AXP221_INIT_DATA); | |
a536077d | 44 | # else |
1d624a4f HG |
45 | ret = rsb_init(); |
46 | if (ret) | |
47 | return ret; | |
48 | ||
49 | ret = rsb_set_device_address(AXP223_DEVICE_ADDR, AXP223_RUNTIME_ADDR); | |
a536077d | 50 | # endif |
1d624a4f HG |
51 | if (ret) |
52 | return ret; | |
a536077d | 53 | #endif |
1d624a4f HG |
54 | |
55 | needs_init = 0; | |
56 | return 0; | |
57 | } | |
58 | ||
59 | int pmic_bus_read(u8 reg, u8 *data) | |
60 | { | |
a536077d HG |
61 | #ifdef CONFIG_AXP152_POWER |
62 | return i2c_read(AXP152_I2C_ADDR, reg, 1, data, 1); | |
63 | #elif defined CONFIG_AXP209_POWER | |
64 | return i2c_read(AXP209_I2C_ADDR, reg, 1, data, 1); | |
95ab8fee | 65 | #elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER |
a536077d | 66 | # ifdef CONFIG_MACH_SUN6I |
1d624a4f | 67 | return p2wi_read(reg, data); |
a536077d | 68 | # else |
1d624a4f | 69 | return rsb_read(AXP223_RUNTIME_ADDR, reg, data); |
a536077d | 70 | # endif |
1d624a4f HG |
71 | #endif |
72 | } | |
73 | ||
74 | int pmic_bus_write(u8 reg, u8 data) | |
75 | { | |
a536077d HG |
76 | #ifdef CONFIG_AXP152_POWER |
77 | return i2c_write(AXP152_I2C_ADDR, reg, 1, &data, 1); | |
78 | #elif defined CONFIG_AXP209_POWER | |
79 | return i2c_write(AXP209_I2C_ADDR, reg, 1, &data, 1); | |
95ab8fee | 80 | #elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER |
a536077d | 81 | # ifdef CONFIG_MACH_SUN6I |
1d624a4f | 82 | return p2wi_write(reg, data); |
a536077d | 83 | # else |
1d624a4f | 84 | return rsb_write(AXP223_RUNTIME_ADDR, reg, data); |
a536077d | 85 | # endif |
1d624a4f HG |
86 | #endif |
87 | } | |
88 | ||
89 | int pmic_bus_setbits(u8 reg, u8 bits) | |
90 | { | |
91 | int ret; | |
92 | u8 val; | |
93 | ||
94 | ret = pmic_bus_read(reg, &val); | |
95 | if (ret) | |
96 | return ret; | |
97 | ||
98 | val |= bits; | |
99 | return pmic_bus_write(reg, val); | |
100 | } | |
101 | ||
102 | int pmic_bus_clrbits(u8 reg, u8 bits) | |
103 | { | |
104 | int ret; | |
105 | u8 val; | |
106 | ||
107 | ret = pmic_bus_read(reg, &val); | |
108 | if (ret) | |
109 | return ret; | |
110 | ||
111 | val &= ~bits; | |
112 | return pmic_bus_write(reg, val); | |
113 | } |