blob: a7865a5d4d20e7b2348c04cda02078c7f7656782 [file] [log] [blame]
Icenowy Zheng7c26b6e2018-07-21 20:41:12 +08001/*
Samuel Hollandc0e109f2019-10-20 15:12:20 -05002 * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
Icenowy Zheng7c26b6e2018-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 Zheng6d372822018-07-22 21:30:14 +08008#include <errno.h>
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +00009
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +000010#include <common/debug.h>
Samuel Hollandfb23b102019-10-20 21:34:38 -050011#include <drivers/allwinner/axp.h>
Samuel Holland7060e0d2020-12-13 22:34:10 -060012#include <drivers/allwinner/sunxi_rsb.h>
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +000013
Andre Przywarad5ddf672018-10-14 22:13:53 +010014#include <sunxi_def.h>
Icenowy Zheng6d372822018-07-22 21:30:14 +080015#include <sunxi_mmap.h>
Andre Przywara4ec1a232018-10-14 12:02:02 +010016#include <sunxi_private.h>
Icenowy Zheng6d372822018-07-22 21:30:14 +080017
Samuel Holland7060e0d2020-12-13 22:34:10 -060018#define AXP805_HW_ADDR 0x745
19#define AXP805_RT_ADDR 0x3a
Icenowy Zheng6d372822018-07-22 21:30:14 +080020
Samuel Hollandc0e109f2019-10-20 15:12:20 -050021static enum pmic_type {
22 UNKNOWN,
Icenowy Zheng6d372822018-07-22 21:30:14 +080023 AXP805,
Samuel Hollandc0e109f2019-10-20 15:12:20 -050024} pmic;
Icenowy Zheng6d372822018-07-22 21:30:14 +080025
Samuel Hollandfb23b102019-10-20 21:34:38 -050026int axp_read(uint8_t reg)
Icenowy Zheng6d372822018-07-22 21:30:14 +080027{
Samuel Holland7060e0d2020-12-13 22:34:10 -060028 return rsb_read(AXP805_RT_ADDR, reg);
Icenowy Zheng6d372822018-07-22 21:30:14 +080029}
30
Samuel Hollandfb23b102019-10-20 21:34:38 -050031int axp_write(uint8_t reg, uint8_t val)
Icenowy Zheng6d372822018-07-22 21:30:14 +080032{
Samuel Holland7060e0d2020-12-13 22:34:10 -060033 return rsb_write(AXP805_RT_ADDR, reg, val);
Icenowy Zheng6d372822018-07-22 21:30:14 +080034}
35
Samuel Holland7060e0d2020-12-13 22:34:10 -060036static int rsb_init(void)
Icenowy Zheng6d372822018-07-22 21:30:14 +080037{
38 int ret;
Icenowy Zheng6d372822018-07-22 21:30:14 +080039
Samuel Holland7060e0d2020-12-13 22:34:10 -060040 ret = rsb_init_controller();
Samuel Holland4538c492019-10-20 15:28:14 -050041 if (ret)
42 return ret;
Icenowy Zheng6d372822018-07-22 21:30:14 +080043
Samuel Holland7060e0d2020-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 Holland4538c492019-10-20 15:28:14 -050046 if (ret)
47 return ret;
Icenowy Zheng6d372822018-07-22 21:30:14 +080048
Samuel Holland7060e0d2020-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 Zheng6d372822018-07-22 21:30:14 +080060}
Icenowy Zheng7c26b6e2018-07-21 20:41:12 +080061
Andre Przywaradf301602018-09-08 19:18:37 +010062int sunxi_pmic_setup(uint16_t socid, const void *fdt)
Icenowy Zheng7c26b6e2018-07-21 20:41:12 +080063{
Icenowy Zheng6d372822018-07-22 21:30:14 +080064 int ret;
65
Samuel Holland7060e0d2020-12-13 22:34:10 -060066 INFO("PMIC: Probing AXP805 on RSB\n");
Samuel Holland4538c492019-10-20 15:28:14 -050067
Samuel Holland7060e0d2020-12-13 22:34:10 -060068 ret = sunxi_init_platform_r_twi(socid, true);
Samuel Holland4538c492019-10-20 15:28:14 -050069 if (ret)
70 return ret;
71
Samuel Holland7060e0d2020-12-13 22:34:10 -060072 ret = rsb_init();
73 if (ret)
74 return ret;
Icenowy Zheng6d372822018-07-22 21:30:14 +080075
Samuel Holland7060e0d2020-12-13 22:34:10 -060076 /* Switch the AXP805 to master/single-PMIC mode. */
77 ret = axp_write(0xff, 0x0);
Icenowy Zheng6d372822018-07-22 21:30:14 +080078 if (ret)
Samuel Hollandc0e109f2019-10-20 15:12:20 -050079 return ret;
80
81 pmic = AXP805;
Samuel Hollandfb23b102019-10-20 21:34:38 -050082 axp_setup_regulators(fdt);
Icenowy Zheng7c26b6e2018-07-21 20:41:12 +080083
Samuel Holland7060e0d2020-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 Zheng7c26b6e2018-07-21 20:41:12 +080089 return 0;
90}
Icenowy Zheng5069c1c2018-07-22 21:52:50 +080091
Samuel Holland818e6732019-10-20 15:06:57 -050092void sunxi_power_down(void)
Icenowy Zheng5069c1c2018-07-22 21:52:50 +080093{
Icenowy Zheng5069c1c2018-07-22 21:52:50 +080094 switch (pmic) {
95 case AXP805:
Samuel Holland7060e0d2020-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 Hollandfb23b102019-10-20 21:34:38 -050099 axp_power_off();
Icenowy Zheng5069c1c2018-07-22 21:52:50 +0800100 break;
101 default:
102 break;
103 }
Icenowy Zheng5069c1c2018-07-22 21:52:50 +0800104}