blob: a7865a5d4d20e7b2348c04cda02078c7f7656782 [file] [log] [blame]
Icenowy Zheng7508bef2018-07-21 20:41:12 +08001/*
Samuel Hollandf95b3682019-10-20 15:12:20 -05002 * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
Icenowy Zheng7508bef2018-07-21 20:41:12 +08003 * Copyright (c) 2018, Icenowy Zheng <icenowy@aosc.io>
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
Icenowy Zheng8d769822018-07-22 21:30:14 +08008#include <errno.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00009
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000010#include <common/debug.h>
Samuel Holland1dad2652019-10-20 21:34:38 -050011#include <drivers/allwinner/axp.h>
Samuel Hollandcb093f22020-12-13 22:34:10 -060012#include <drivers/allwinner/sunxi_rsb.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000013
Andre Przywara67537762018-10-14 22:13:53 +010014#include <sunxi_def.h>
Icenowy Zheng8d769822018-07-22 21:30:14 +080015#include <sunxi_mmap.h>
Andre Przywara456208a2018-10-14 12:02:02 +010016#include <sunxi_private.h>
Icenowy Zheng8d769822018-07-22 21:30:14 +080017
Samuel Hollandcb093f22020-12-13 22:34:10 -060018#define AXP805_HW_ADDR 0x745
19#define AXP805_RT_ADDR 0x3a
Icenowy Zheng8d769822018-07-22 21:30:14 +080020
Samuel Hollandf95b3682019-10-20 15:12:20 -050021static enum pmic_type {
22 UNKNOWN,
Icenowy Zheng8d769822018-07-22 21:30:14 +080023 AXP805,
Samuel Hollandf95b3682019-10-20 15:12:20 -050024} pmic;
Icenowy Zheng8d769822018-07-22 21:30:14 +080025
Samuel Holland1dad2652019-10-20 21:34:38 -050026int axp_read(uint8_t reg)
Icenowy Zheng8d769822018-07-22 21:30:14 +080027{
Samuel Hollandcb093f22020-12-13 22:34:10 -060028 return rsb_read(AXP805_RT_ADDR, reg);
Icenowy Zheng8d769822018-07-22 21:30:14 +080029}
30
Samuel Holland1dad2652019-10-20 21:34:38 -050031int axp_write(uint8_t reg, uint8_t val)
Icenowy Zheng8d769822018-07-22 21:30:14 +080032{
Samuel Hollandcb093f22020-12-13 22:34:10 -060033 return rsb_write(AXP805_RT_ADDR, reg, val);
Icenowy Zheng8d769822018-07-22 21:30:14 +080034}
35
Samuel Hollandcb093f22020-12-13 22:34:10 -060036static int rsb_init(void)
Icenowy Zheng8d769822018-07-22 21:30:14 +080037{
38 int ret;
Icenowy Zheng8d769822018-07-22 21:30:14 +080039
Samuel Hollandcb093f22020-12-13 22:34:10 -060040 ret = rsb_init_controller();
Samuel Hollandf39fd862019-10-20 15:28:14 -050041 if (ret)
42 return ret;
Icenowy Zheng8d769822018-07-22 21:30:14 +080043
Samuel Hollandcb093f22020-12-13 22:34:10 -060044 /* Switch to the recommended 3 MHz bus clock. */
45 ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 3000000);
Samuel Hollandf39fd862019-10-20 15:28:14 -050046 if (ret)
47 return ret;
Icenowy Zheng8d769822018-07-22 21:30:14 +080048
Samuel Hollandcb093f22020-12-13 22:34:10 -060049 /* Initiate an I2C transaction to switch the PMIC to RSB mode. */
50 ret = rsb_set_device_mode(AXP20X_MODE_RSB << 16 | AXP20X_MODE_REG << 8);
51 if (ret)
52 return ret;
53
54 /* Associate the 8-bit runtime address with the 12-bit bus address. */
55 ret = rsb_assign_runtime_address(AXP805_HW_ADDR, AXP805_RT_ADDR);
56 if (ret)
57 return ret;
58
59 return axp_check_id();
Icenowy Zheng8d769822018-07-22 21:30:14 +080060}
Icenowy Zheng7508bef2018-07-21 20:41:12 +080061
Andre Przywara4e4b1e62018-09-08 19:18:37 +010062int sunxi_pmic_setup(uint16_t socid, const void *fdt)
Icenowy Zheng7508bef2018-07-21 20:41:12 +080063{
Icenowy Zheng8d769822018-07-22 21:30:14 +080064 int ret;
65
Samuel Hollandcb093f22020-12-13 22:34:10 -060066 INFO("PMIC: Probing AXP805 on RSB\n");
Samuel Hollandf39fd862019-10-20 15:28:14 -050067
Samuel Hollandcb093f22020-12-13 22:34:10 -060068 ret = sunxi_init_platform_r_twi(socid, true);
Samuel Hollandf39fd862019-10-20 15:28:14 -050069 if (ret)
70 return ret;
71
Samuel Hollandcb093f22020-12-13 22:34:10 -060072 ret = rsb_init();
73 if (ret)
74 return ret;
Icenowy Zheng8d769822018-07-22 21:30:14 +080075
Samuel Hollandcb093f22020-12-13 22:34:10 -060076 /* Switch the AXP805 to master/single-PMIC mode. */
77 ret = axp_write(0xff, 0x0);
Icenowy Zheng8d769822018-07-22 21:30:14 +080078 if (ret)
Samuel Hollandf95b3682019-10-20 15:12:20 -050079 return ret;
80
81 pmic = AXP805;
Samuel Holland1dad2652019-10-20 21:34:38 -050082 axp_setup_regulators(fdt);
Icenowy Zheng7508bef2018-07-21 20:41:12 +080083
Samuel Hollandcb093f22020-12-13 22:34:10 -060084 /* Switch the PMIC back to I2C mode. */
85 ret = axp_write(AXP20X_MODE_REG, AXP20X_MODE_I2C);
86 if (ret)
87 return ret;
88
Icenowy Zheng7508bef2018-07-21 20:41:12 +080089 return 0;
90}
Icenowy Zhengbd57eb52018-07-22 21:52:50 +080091
Samuel Hollandfa4d9352019-10-20 15:06:57 -050092void sunxi_power_down(void)
Icenowy Zhengbd57eb52018-07-22 21:52:50 +080093{
Icenowy Zhengbd57eb52018-07-22 21:52:50 +080094 switch (pmic) {
95 case AXP805:
Samuel Hollandcb093f22020-12-13 22:34:10 -060096 /* (Re-)init RSB in case the rich OS has disabled it. */
97 sunxi_init_platform_r_twi(SUNXI_SOC_H6, true);
98 rsb_init();
Samuel Holland1dad2652019-10-20 21:34:38 -050099 axp_power_off();
Icenowy Zhengbd57eb52018-07-22 21:52:50 +0800100 break;
101 default:
102 break;
103 }
Icenowy Zhengbd57eb52018-07-22 21:52:50 +0800104}