blob: 9e0512725b470cb3f736b70fdeffbb44aee5f2d0 [file] [log] [blame]
Hans de Goedebb930c32015-04-25 14:07:37 +02001/*
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>
Hans de Goede858b6db2015-04-25 22:18:09 +020015#include <i2c.h>
Hans de Goedebb930c32015-04-25 14:07:37 +020016#include <asm/arch/pmic_bus.h>
17
Hans de Goede858b6db2015-04-25 22:18:09 +020018#define AXP152_I2C_ADDR 0x30
19
20#define AXP209_I2C_ADDR 0x34
21
Hans de Goedebb930c32015-04-25 14:07:37 +020022#define AXP221_CHIP_ADDR 0x68
23#define AXP221_CTRL_ADDR 0x3e
24#define AXP221_INIT_DATA 0x3e
25
26#define AXP223_DEVICE_ADDR 0x3a3
27#define AXP223_RUNTIME_ADDR 0x2d
28
29int pmic_bus_init(void)
30{
31 /* This cannot be 0 because it is used in SPL before BSS is ready */
32 static int needs_init = 1;
Hans de Goede858b6db2015-04-25 22:18:09 +020033 __maybe_unused int ret;
Hans de Goedebb930c32015-04-25 14:07:37 +020034
35 if (!needs_init)
36 return 0;
37
Hans de Goede858b6db2015-04-25 22:18:09 +020038#ifdef CONFIG_AXP221_POWER
39# ifdef CONFIG_MACH_SUN6I
Hans de Goedebb930c32015-04-25 14:07:37 +020040 p2wi_init();
41 ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR, AXP221_CTRL_ADDR,
42 AXP221_INIT_DATA);
Hans de Goede858b6db2015-04-25 22:18:09 +020043# else
Hans de Goedebb930c32015-04-25 14:07:37 +020044 ret = rsb_init();
45 if (ret)
46 return ret;
47
48 ret = rsb_set_device_address(AXP223_DEVICE_ADDR, AXP223_RUNTIME_ADDR);
Hans de Goede858b6db2015-04-25 22:18:09 +020049# endif
Hans de Goedebb930c32015-04-25 14:07:37 +020050 if (ret)
51 return ret;
Hans de Goede858b6db2015-04-25 22:18:09 +020052#endif
Hans de Goedebb930c32015-04-25 14:07:37 +020053
54 needs_init = 0;
55 return 0;
56}
57
58int pmic_bus_read(u8 reg, u8 *data)
59{
Hans de Goede858b6db2015-04-25 22:18:09 +020060#ifdef CONFIG_AXP152_POWER
61 return i2c_read(AXP152_I2C_ADDR, reg, 1, data, 1);
62#elif defined CONFIG_AXP209_POWER
63 return i2c_read(AXP209_I2C_ADDR, reg, 1, data, 1);
64#elif defined CONFIG_AXP221_POWER
65# ifdef CONFIG_MACH_SUN6I
Hans de Goedebb930c32015-04-25 14:07:37 +020066 return p2wi_read(reg, data);
Hans de Goede858b6db2015-04-25 22:18:09 +020067# else
Hans de Goedebb930c32015-04-25 14:07:37 +020068 return rsb_read(AXP223_RUNTIME_ADDR, reg, data);
Hans de Goede858b6db2015-04-25 22:18:09 +020069# endif
Hans de Goedebb930c32015-04-25 14:07:37 +020070#endif
71}
72
73int pmic_bus_write(u8 reg, u8 data)
74{
Hans de Goede858b6db2015-04-25 22:18:09 +020075#ifdef CONFIG_AXP152_POWER
76 return i2c_write(AXP152_I2C_ADDR, reg, 1, &data, 1);
77#elif defined CONFIG_AXP209_POWER
78 return i2c_write(AXP209_I2C_ADDR, reg, 1, &data, 1);
79#elif defined CONFIG_AXP221_POWER
80# ifdef CONFIG_MACH_SUN6I
Hans de Goedebb930c32015-04-25 14:07:37 +020081 return p2wi_write(reg, data);
Hans de Goede858b6db2015-04-25 22:18:09 +020082# else
Hans de Goedebb930c32015-04-25 14:07:37 +020083 return rsb_write(AXP223_RUNTIME_ADDR, reg, data);
Hans de Goede858b6db2015-04-25 22:18:09 +020084# endif
Hans de Goedebb930c32015-04-25 14:07:37 +020085#endif
86}
87
88int pmic_bus_setbits(u8 reg, u8 bits)
89{
90 int ret;
91 u8 val;
92
93 ret = pmic_bus_read(reg, &val);
94 if (ret)
95 return ret;
96
97 val |= bits;
98 return pmic_bus_write(reg, val);
99}
100
101int pmic_bus_clrbits(u8 reg, u8 bits)
102{
103 int ret;
104 u8 val;
105
106 ret = pmic_bus_read(reg, &val);
107 if (ret)
108 return ret;
109
110 val &= ~bits;
111 return pmic_bus_write(reg, val);
112}