sunxi: axp221: Add axp223 support
authorHans de Goede <hdegoede@redhat.com>
Sat, 29 Nov 2014 22:54:25 +0000 (23:54 +0100)
committerHans de Goede <hdegoede@redhat.com>
Wed, 14 Jan 2015 13:56:36 +0000 (14:56 +0100)
The axp223 appears to be the same as the axp221, except that it uses the
rsb to communicate rather then the p2wi. At least all the registers we use
are 100% the same.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Ian Campbell <ijc@hellion.org.uk>
arch/arm/cpu/armv7/sunxi/cpu_info.c
drivers/power/Kconfig
drivers/power/axp221.c
include/axp221.h

index 7a3a4ca81bf6b048adaeb7157fcb4f9271269aaa..b6cb9dea6434e4941527bb2fb363a84feb0f48f4 100644 (file)
@@ -76,7 +76,7 @@ int print_cpuinfo(void)
 
 int sunxi_get_sid(unsigned int *sid)
 {
-#ifdef CONFIG_MACH_SUN6I
+#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I
 #ifdef CONFIG_AXP221_POWER
        return axp221_get_sid(sid);
 #else
index 1ec7c0e59ae0e2c28e0fa045fc1d76d40859385a..7373a793e2552295d56a5e914c6d997a6cf7ba8a 100644 (file)
@@ -1,10 +1,10 @@
 config AXP221_POWER
-       boolean "axp221 pmic support"
-       depends on MACH_SUN6I
+       boolean "axp221 / axp223 pmic support"
+       depends on MACH_SUN6I || MACH_SUN8I
        default y
        ---help---
-       Say y here to enable support for the axp221 pmic found on most sun6i
-       (A31) boards.
+       Say y here to enable support for the axp221 / axp223 pmic found on most
+       sun6i (A31) / sun8i (A23) boards.
 
 config AXP221_DLDO1_VOLT
        int "axp221 dldo1 voltage"
index 826567a836b2284d9185533cc242659fb3e6be47..4667579c9158a99aa0b7caf5c5c217223107e1fd 100644 (file)
@@ -1,4 +1,10 @@
 /*
+ * AXP221 and AXP223 driver
+ *
+ * IMPORTANT when making changes to this file check that the registers
+ * used are the same for the axp221 and axp223.
+ *
+ * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com>
  * (C) Copyright 2013 Oliver Schinagl <oliver@schinagl.nl>
  *
  * SPDX-License-Identifier:    GPL-2.0+
@@ -7,8 +13,50 @@
 #include <common.h>
 #include <errno.h>
 #include <asm/arch/p2wi.h>
+#include <asm/arch/rsb.h>
 #include <axp221.h>
 
+/*
+ * The axp221 uses the p2wi bus, the axp223 is identical (for all registers
+ * used sofar) but uses the rsb bus. These functions abstract this.
+ */
+static int pmic_bus_init(void)
+{
+#ifdef CONFIG_MACH_SUN6I
+       p2wi_init();
+       return p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR, AXP221_CTRL_ADDR,
+                                       AXP221_INIT_DATA);
+#else
+       int ret;
+
+       rsb_init();
+
+       ret = rsb_set_device_mode(AXP223_DEVICE_MODE_DATA);
+       if (ret)
+               return ret;
+
+       return rsb_set_device_address(AXP223_DEVICE_ADDR, AXP223_RUNTIME_ADDR);
+#endif
+}
+
+static int pmic_bus_read(const u8 addr, u8 *data)
+{
+#ifdef CONFIG_MACH_SUN6I
+       return p2wi_read(addr, data);
+#else
+       return rsb_read(AXP223_RUNTIME_ADDR, addr, data);
+#endif
+}
+
+static int pmic_bus_write(const u8 addr, u8 data)
+{
+#ifdef CONFIG_MACH_SUN6I
+       return p2wi_write(addr, data);
+#else
+       return rsb_write(AXP223_RUNTIME_ADDR, addr, data);
+#endif
+}
+
 static u8 axp221_mvolt_to_cfg(int mvolt, int min, int max, int div)
 {
        if (mvolt < min)
@@ -24,12 +72,12 @@ static int axp221_setbits(u8 reg, u8 bits)
        int ret;
        u8 val;
 
-       ret = p2wi_read(reg, &val);
+       ret = pmic_bus_read(reg, &val);
        if (ret)
                return ret;
 
        val |= bits;
-       return p2wi_write(reg, val);
+       return pmic_bus_write(reg, val);
 }
 
 int axp221_set_dcdc1(unsigned int mvolt)
@@ -37,7 +85,7 @@ int axp221_set_dcdc1(unsigned int mvolt)
        int ret;
        u8 cfg = axp221_mvolt_to_cfg(mvolt, 1600, 3400, 100);
 
-       ret = p2wi_write(AXP221_DCDC1_CTRL, cfg);
+       ret = pmic_bus_write(AXP221_DCDC1_CTRL, cfg);
        if (ret)
                return ret;
 
@@ -49,28 +97,28 @@ int axp221_set_dcdc2(unsigned int mvolt)
 {
        u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1540, 20);
 
-       return p2wi_write(AXP221_DCDC2_CTRL, cfg);
+       return pmic_bus_write(AXP221_DCDC2_CTRL, cfg);
 }
 
 int axp221_set_dcdc3(unsigned int mvolt)
 {
        u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1860, 20);
 
-       return p2wi_write(AXP221_DCDC3_CTRL, cfg);
+       return pmic_bus_write(AXP221_DCDC3_CTRL, cfg);
 }
 
 int axp221_set_dcdc4(unsigned int mvolt)
 {
        u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1540, 20);
 
-       return p2wi_write(AXP221_DCDC4_CTRL, cfg);
+       return pmic_bus_write(AXP221_DCDC4_CTRL, cfg);
 }
 
 int axp221_set_dcdc5(unsigned int mvolt)
 {
        u8 cfg = axp221_mvolt_to_cfg(mvolt, 1000, 2550, 50);
 
-       return p2wi_write(AXP221_DCDC5_CTRL, cfg);
+       return pmic_bus_write(AXP221_DCDC5_CTRL, cfg);
 }
 
 int axp221_set_dldo1(unsigned int mvolt)
@@ -78,7 +126,7 @@ int axp221_set_dldo1(unsigned int mvolt)
        int ret;
        u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
 
-       ret = p2wi_write(AXP221_DLDO1_CTRL, cfg);
+       ret = pmic_bus_write(AXP221_DLDO1_CTRL, cfg);
        if (ret)
                return ret;
 
@@ -91,7 +139,7 @@ int axp221_set_dldo2(unsigned int mvolt)
        int ret;
        u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
 
-       ret = p2wi_write(AXP221_DLDO2_CTRL, cfg);
+       ret = pmic_bus_write(AXP221_DLDO2_CTRL, cfg);
        if (ret)
                return ret;
 
@@ -104,7 +152,7 @@ int axp221_set_dldo3(unsigned int mvolt)
        int ret;
        u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
 
-       ret = p2wi_write(AXP221_DLDO3_CTRL, cfg);
+       ret = pmic_bus_write(AXP221_DLDO3_CTRL, cfg);
        if (ret)
                return ret;
 
@@ -117,7 +165,7 @@ int axp221_set_dldo4(unsigned int mvolt)
        int ret;
        u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
 
-       ret = p2wi_write(AXP221_DLDO4_CTRL, cfg);
+       ret = pmic_bus_write(AXP221_DLDO4_CTRL, cfg);
        if (ret)
                return ret;
 
@@ -130,7 +178,7 @@ int axp221_set_aldo1(unsigned int mvolt)
        int ret;
        u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
 
-       ret = p2wi_write(AXP221_ALDO1_CTRL, cfg);
+       ret = pmic_bus_write(AXP221_ALDO1_CTRL, cfg);
        if (ret)
                return ret;
 
@@ -143,7 +191,7 @@ int axp221_set_aldo2(unsigned int mvolt)
        int ret;
        u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
 
-       ret = p2wi_write(AXP221_ALDO2_CTRL, cfg);
+       ret = pmic_bus_write(AXP221_ALDO2_CTRL, cfg);
        if (ret)
                return ret;
 
@@ -156,7 +204,7 @@ int axp221_set_aldo3(unsigned int mvolt)
        int ret;
        u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
 
-       ret = p2wi_write(AXP221_ALDO3_CTRL, cfg);
+       ret = pmic_bus_write(AXP221_ALDO3_CTRL, cfg);
        if (ret)
                return ret;
 
@@ -169,13 +217,11 @@ int axp221_init(void)
        u8 axp_chip_id;
        int ret;
 
-       p2wi_init();
-       ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR, AXP221_CTRL_ADDR,
-                                      AXP221_INIT_DATA);
+       ret = pmic_bus_init();
        if (ret)
                return ret;
 
-       ret = p2wi_read(AXP221_CHIP_ID, &axp_chip_id);
+       ret = pmic_bus_read(AXP221_CHIP_ID, &axp_chip_id);
        if (ret)
                return ret;
 
@@ -194,17 +240,17 @@ int axp221_get_sid(unsigned int *sid)
        if (ret)
                return ret;
 
-       ret = p2wi_write(AXP221_PAGE, 1);
+       ret = pmic_bus_write(AXP221_PAGE, 1);
        if (ret)
                return ret;
 
        for (i = 0; i < 16; i++) {
-               ret = p2wi_read(AXP221_SID + i, &dest[i]);
+               ret = pmic_bus_read(AXP221_SID + i, &dest[i]);
                if (ret)
                        return ret;
        }
 
-       p2wi_write(AXP221_PAGE, 0);
+       pmic_bus_write(AXP221_PAGE, 0);
 
        for (i = 0; i < 4; i++)
                sid[i] = be32_to_cpu(sid[i]);
index ade906620774e584fddf869e6472c020eee3b116..8df811a3a4b5fde97047e9227860e9278db1a85d 100644 (file)
 #define AXP221_CTRL_ADDR 0x3e
 #define AXP221_INIT_DATA 0x3e
 
+#define AXP223_DEVICE_ADDR 0x3a3
+#define AXP223_RUNTIME_ADDR 0x2d
+#define AXP223_DEVICE_MODE_DATA 0x7c3e00
+
 /* Page 0 addresses */
 #define AXP221_CHIP_ID         0x03
 #define AXP221_OUTPUT_CTRL1    0x10