blob: 443015bacfae16a05dbfd7982d8069580c7ee98a [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>
Icenowy Zheng8d769822018-07-22 21:30:14 +08009#include <string.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000010
11#include <arch_helpers.h>
12#include <common/debug.h>
Samuel Holland1dad2652019-10-20 21:34:38 -050013#include <drivers/allwinner/axp.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000014#include <drivers/delay_timer.h>
15#include <drivers/mentor/mi2cv.h>
16#include <lib/mmio.h>
17
Andre Przywara67537762018-10-14 22:13:53 +010018#include <sunxi_def.h>
Icenowy Zheng8d769822018-07-22 21:30:14 +080019#include <sunxi_mmap.h>
Andre Przywara456208a2018-10-14 12:02:02 +010020#include <sunxi_private.h>
Icenowy Zheng8d769822018-07-22 21:30:14 +080021
22#define AXP805_ADDR 0x36
Icenowy Zheng8d769822018-07-22 21:30:14 +080023
Samuel Hollandf95b3682019-10-20 15:12:20 -050024static enum pmic_type {
25 UNKNOWN,
Icenowy Zheng8d769822018-07-22 21:30:14 +080026 AXP805,
Samuel Hollandf95b3682019-10-20 15:12:20 -050027} pmic;
Icenowy Zheng8d769822018-07-22 21:30:14 +080028
Samuel Holland1dad2652019-10-20 21:34:38 -050029int axp_read(uint8_t reg)
Icenowy Zheng8d769822018-07-22 21:30:14 +080030{
Samuel Holland1dad2652019-10-20 21:34:38 -050031 uint8_t val;
Icenowy Zheng8d769822018-07-22 21:30:14 +080032 int ret;
33
Samuel Holland1dad2652019-10-20 21:34:38 -050034 ret = i2c_write(AXP805_ADDR, 0, 0, &reg, 1);
Samuel Hollandf39fd862019-10-20 15:28:14 -050035 if (ret == 0)
Samuel Holland1dad2652019-10-20 21:34:38 -050036 ret = i2c_read(AXP805_ADDR, 0, 0, &val, 1);
37 if (ret) {
Samuel Hollandf39fd862019-10-20 15:28:14 -050038 ERROR("PMIC: Cannot read AXP805 register %02x\n", reg);
Samuel Holland1dad2652019-10-20 21:34:38 -050039 return ret;
40 }
Icenowy Zheng8d769822018-07-22 21:30:14 +080041
Samuel Holland1dad2652019-10-20 21:34:38 -050042 return val;
Icenowy Zheng8d769822018-07-22 21:30:14 +080043}
44
Samuel Holland1dad2652019-10-20 21:34:38 -050045int axp_write(uint8_t reg, uint8_t val)
Icenowy Zheng8d769822018-07-22 21:30:14 +080046{
Samuel Hollandf39fd862019-10-20 15:28:14 -050047 int ret;
48
Samuel Holland1dad2652019-10-20 21:34:38 -050049 ret = i2c_write(AXP805_ADDR, reg, 1, &val, 1);
Samuel Hollandf39fd862019-10-20 15:28:14 -050050 if (ret)
51 ERROR("PMIC: Cannot write AXP805 register %02x\n", reg);
52
53 return ret;
Icenowy Zheng8d769822018-07-22 21:30:14 +080054}
55
56static int axp805_probe(void)
57{
58 int ret;
Icenowy Zheng8d769822018-07-22 21:30:14 +080059
Samuel Hollandf39fd862019-10-20 15:28:14 -050060 /* Switch the AXP805 to master/single-PMIC mode. */
Samuel Holland1dad2652019-10-20 21:34:38 -050061 ret = axp_write(0xff, 0x0);
Samuel Hollandf39fd862019-10-20 15:28:14 -050062 if (ret)
63 return ret;
Icenowy Zheng8d769822018-07-22 21:30:14 +080064
Samuel Holland1dad2652019-10-20 21:34:38 -050065 ret = axp_check_id();
Samuel Hollandf39fd862019-10-20 15:28:14 -050066 if (ret)
67 return ret;
Icenowy Zheng8d769822018-07-22 21:30:14 +080068
Icenowy Zheng8d769822018-07-22 21:30:14 +080069 return 0;
70}
Icenowy Zheng7508bef2018-07-21 20:41:12 +080071
Andre Przywara4e4b1e62018-09-08 19:18:37 +010072int sunxi_pmic_setup(uint16_t socid, const void *fdt)
Icenowy Zheng7508bef2018-07-21 20:41:12 +080073{
Icenowy Zheng8d769822018-07-22 21:30:14 +080074 int ret;
75
Samuel Hollandf39fd862019-10-20 15:28:14 -050076 INFO("PMIC: Probing AXP805 on I2C\n");
77
78 ret = sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
79 if (ret)
80 return ret;
81
Andre Przywara67537762018-10-14 22:13:53 +010082 /* initialise mi2cv driver */
83 i2c_init((void *)SUNXI_R_I2C_BASE);
Icenowy Zheng8d769822018-07-22 21:30:14 +080084
Icenowy Zheng8d769822018-07-22 21:30:14 +080085 ret = axp805_probe();
86 if (ret)
Samuel Hollandf95b3682019-10-20 15:12:20 -050087 return ret;
88
89 pmic = AXP805;
Samuel Holland1dad2652019-10-20 21:34:38 -050090 axp_setup_regulators(fdt);
Icenowy Zheng7508bef2018-07-21 20:41:12 +080091
92 return 0;
93}
Icenowy Zhengbd57eb52018-07-22 21:52:50 +080094
Samuel Hollandfa4d9352019-10-20 15:06:57 -050095void sunxi_power_down(void)
Icenowy Zhengbd57eb52018-07-22 21:52:50 +080096{
Icenowy Zhengbd57eb52018-07-22 21:52:50 +080097 switch (pmic) {
98 case AXP805:
Andre Przywara67537762018-10-14 22:13:53 +010099 /* Re-initialise after rich OS might have used it. */
100 sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
101 /* initialise mi2cv driver */
102 i2c_init((void *)SUNXI_R_I2C_BASE);
Samuel Holland1dad2652019-10-20 21:34:38 -0500103 axp_power_off();
Icenowy Zhengbd57eb52018-07-22 21:52:50 +0800104 break;
105 default:
106 break;
107 }
Icenowy Zhengbd57eb52018-07-22 21:52:50 +0800108}