blob: 87df312725c4fb73d16a86254fabd741a92e78bd [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Hans de Goede1d624a42015-04-25 14:07:37 +02002/*
3 * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
4 *
5 * Sunxi PMIC bus access helpers
6 *
7 * The axp152 & axp209 use an i2c bus, the axp221 uses the p2wi bus and the
8 * axp223 uses the rsb bus, these functions abstract this.
Hans de Goede1d624a42015-04-25 14:07:37 +02009 */
10
Samuel Holland104950a2021-10-08 00:17:20 -050011#include <axp_pmic.h>
Samuel Holland8b0eacd2021-10-08 00:17:23 -050012#include <dm.h>
Hans de Goede1d624a42015-04-25 14:07:37 +020013#include <asm/arch/p2wi.h>
14#include <asm/arch/rsb.h>
Hans de Goedea5360772015-04-25 22:18:09 +020015#include <i2c.h>
Samuel Holland8b0eacd2021-10-08 00:17:23 -050016#include <power/pmic.h>
Hans de Goede1d624a42015-04-25 14:07:37 +020017#include <asm/arch/pmic_bus.h>
18
Hans de Goedea5360772015-04-25 22:18:09 +020019#define AXP152_I2C_ADDR 0x30
20
21#define AXP209_I2C_ADDR 0x34
22
Jernej Skrabecfbd37d82021-01-11 21:11:33 +010023#define AXP305_I2C_ADDR 0x36
Andre Przywarad17d0512023-07-30 01:11:01 +010024#define AXP313_I2C_ADDR 0x36
Jernej Skrabecfbd37d82021-01-11 21:11:33 +010025
Hans de Goede1d624a42015-04-25 14:07:37 +020026#define AXP221_CHIP_ADDR 0x68
Hans de Goede1d624a42015-04-25 14:07:37 +020027
Samuel Holland8b0eacd2021-10-08 00:17:23 -050028#if CONFIG_IS_ENABLED(PMIC_AXP)
29static struct udevice *pmic;
30#else
Samuel Hollandd3b02982021-10-08 00:17:22 -050031static int pmic_i2c_address(void)
32{
33 if (IS_ENABLED(CONFIG_AXP152_POWER))
34 return AXP152_I2C_ADDR;
35 if (IS_ENABLED(CONFIG_AXP305_POWER))
36 return AXP305_I2C_ADDR;
Andre Przywarad17d0512023-07-30 01:11:01 +010037 if (IS_ENABLED(CONFIG_AXP313_POWER))
38 return AXP313_I2C_ADDR;
Samuel Hollandd3b02982021-10-08 00:17:22 -050039
40 /* Other AXP2xx and AXP8xx variants */
41 return AXP209_I2C_ADDR;
42}
Samuel Holland8b0eacd2021-10-08 00:17:23 -050043#endif
Samuel Hollandd3b02982021-10-08 00:17:22 -050044
Hans de Goede1d624a42015-04-25 14:07:37 +020045int pmic_bus_init(void)
46{
47 /* This cannot be 0 because it is used in SPL before BSS is ready */
48 static int needs_init = 1;
Samuel Hollandd3b02982021-10-08 00:17:22 -050049 int ret = 0;
Hans de Goede1d624a42015-04-25 14:07:37 +020050
51 if (!needs_init)
52 return 0;
53
Samuel Holland8b0eacd2021-10-08 00:17:23 -050054#if CONFIG_IS_ENABLED(PMIC_AXP)
55 ret = uclass_get_device_by_driver(UCLASS_PMIC, DM_DRIVER_GET(axp_pmic),
56 &pmic);
57#else
Samuel Hollandd3b02982021-10-08 00:17:22 -050058 if (IS_ENABLED(CONFIG_SYS_I2C_SUN6I_P2WI)) {
59 p2wi_init();
60 ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR,
61 AXP_PMIC_MODE_REG,
62 AXP_PMIC_MODE_P2WI);
63 } else if (IS_ENABLED(CONFIG_SYS_I2C_SUN8I_RSB)) {
64 ret = rsb_init();
65 if (ret)
66 return ret;
Hans de Goede1d624a42015-04-25 14:07:37 +020067
Samuel Hollandd3b02982021-10-08 00:17:22 -050068 ret = rsb_set_device_address(AXP_PMIC_PRI_DEVICE_ADDR,
69 AXP_PMIC_PRI_RUNTIME_ADDR);
70 }
Samuel Holland8b0eacd2021-10-08 00:17:23 -050071#endif
Hans de Goede1d624a42015-04-25 14:07:37 +020072
Samuel Hollandd3b02982021-10-08 00:17:22 -050073 needs_init = ret;
74
75 return ret;
Hans de Goede1d624a42015-04-25 14:07:37 +020076}
77
78int pmic_bus_read(u8 reg, u8 *data)
79{
Samuel Holland8b0eacd2021-10-08 00:17:23 -050080#if CONFIG_IS_ENABLED(PMIC_AXP)
81 return pmic_read(pmic, reg, data, 1);
82#else
Samuel Hollandd3b02982021-10-08 00:17:22 -050083 if (IS_ENABLED(CONFIG_SYS_I2C_SUN6I_P2WI))
84 return p2wi_read(reg, data);
85 if (IS_ENABLED(CONFIG_SYS_I2C_SUN8I_RSB))
86 return rsb_read(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
87
88 return i2c_read(pmic_i2c_address(), reg, 1, data, 1);
Samuel Holland8b0eacd2021-10-08 00:17:23 -050089#endif
Hans de Goede1d624a42015-04-25 14:07:37 +020090}
91
92int pmic_bus_write(u8 reg, u8 data)
93{
Samuel Holland8b0eacd2021-10-08 00:17:23 -050094#if CONFIG_IS_ENABLED(PMIC_AXP)
95 return pmic_write(pmic, reg, &data, 1);
96#else
Samuel Hollandd3b02982021-10-08 00:17:22 -050097 if (IS_ENABLED(CONFIG_SYS_I2C_SUN6I_P2WI))
98 return p2wi_write(reg, data);
99 if (IS_ENABLED(CONFIG_SYS_I2C_SUN8I_RSB))
100 return rsb_write(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
101
102 return i2c_write(pmic_i2c_address(), reg, 1, &data, 1);
Samuel Holland8b0eacd2021-10-08 00:17:23 -0500103#endif
Hans de Goede1d624a42015-04-25 14:07:37 +0200104}
105
106int pmic_bus_setbits(u8 reg, u8 bits)
107{
108 int ret;
109 u8 val;
110
111 ret = pmic_bus_read(reg, &val);
112 if (ret)
113 return ret;
114
Olliver Schinaglc970e892018-11-21 20:05:26 +0200115 if ((val & bits) == bits)
116 return 0;
117
Hans de Goede1d624a42015-04-25 14:07:37 +0200118 val |= bits;
119 return pmic_bus_write(reg, val);
120}
121
122int pmic_bus_clrbits(u8 reg, u8 bits)
123{
124 int ret;
125 u8 val;
126
127 ret = pmic_bus_read(reg, &val);
128 if (ret)
129 return ret;
130
Olliver Schinaglc970e892018-11-21 20:05:26 +0200131 if (!(val & bits))
132 return 0;
133
Hans de Goede1d624a42015-04-25 14:07:37 +0200134 val &= ~bits;
135 return pmic_bus_write(reg, val);
136}