summaryrefslogtreecommitdiff
path: root/driver
diff options
context:
space:
mode:
authorAseda Aboagye <aaboagye@google.com>2017-11-29 23:26:36 -0800
committerchrome-bot <chrome-bot@chromium.org>2017-12-06 01:08:24 -0800
commitfb32b6d30cf55408f4bdb36b729c99452f6e8e11 (patch)
tree8506ce54893a0cf9953ea7bcaaf29d96eb1b0df9 /driver
parentfb43b2f4869182e9337c031a4d516ce820fe78d1 (diff)
downloadchrome-ec-fb32b6d30cf55408f4bdb36b729c99452f6e8e11.tar.gz
ppc: Create generic PPC driver framework.
This commit introduces a driver framework for power path controllers. It provides some common PPC APIs as well as allowing a board to use multiple different PPCs drivers/parts. This should make it easier to add PPC drivers in the future. BUG=None BRANCH=None TEST=`make -j buildall` TEST=Flash zoombini; verify PPC works as expected. TEST=Flash meowth; verify PPC works as expected. Change-Id: Icfb99f384610590b431456cfd28d4aff18442cb2 Signed-off-by: Aseda Aboagye <aaboagye@google.com> Reviewed-on: https://chromium-review.googlesource.com/807630 Commit-Ready: Aseda Aboagye <aaboagye@chromium.org> Tested-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Edward Hill <ecgh@chromium.org> Reviewed-by: Shawn N <shawnn@chromium.org>
Diffstat (limited to 'driver')
-rw-r--r--driver/ppc/sn5s330.c115
-rw-r--r--driver/ppc/sn5s330.h22
2 files changed, 46 insertions, 91 deletions
diff --git a/driver/ppc/sn5s330.c b/driver/ppc/sn5s330.c
index 05cb9eac14..136861aac6 100644
--- a/driver/ppc/sn5s330.c
+++ b/driver/ppc/sn5s330.c
@@ -17,54 +17,38 @@
#include "i2c.h"
#include "system.h"
#include "timer.h"
+#include "usbc_ppc.h"
#include "util.h"
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
-static int read_reg(uint8_t chip_idx, int reg, int *regval)
+static int read_reg(uint8_t port, int reg, int *regval)
{
- if (chip_idx >= sn5s330_cnt)
- return EC_ERROR_INVAL;
-
- return i2c_read8(sn5s330_chips[chip_idx].i2c_port,
- sn5s330_chips[chip_idx].i2c_addr,
- reg,
- regval);
+ return i2c_read8(ppc_chips[port].i2c_port,
+ ppc_chips[port].i2c_addr,
+ reg,
+ regval);
}
-static int write_reg(uint8_t chip_idx, int reg, int regval)
+static int write_reg(uint8_t port, int reg, int regval)
{
- if (chip_idx >= sn5s330_cnt)
- return EC_ERROR_INVAL;
-
- return i2c_write8(sn5s330_chips[chip_idx].i2c_port,
- sn5s330_chips[chip_idx].i2c_addr,
+ return i2c_write8(ppc_chips[port].i2c_port,
+ ppc_chips[port].i2c_addr,
reg,
regval);
}
#ifdef CONFIG_CMD_PPC_DUMP
-static int command_sn5s330_dump(int argc, char **argv)
+static int sn5s330_dump(int port)
{
int i;
int data;
- int chip_idx;
- int port;
- int addr;
-
- if (argc < 2)
- return EC_ERROR_PARAM_COUNT;
-
- chip_idx = atoi(argv[1]);
- if (chip_idx >= sn5s330_cnt)
- return EC_ERROR_PARAM1;
-
- port = sn5s330_chips[chip_idx].i2c_port;
- addr = sn5s330_chips[chip_idx].i2c_addr;
+ const int i2c_port = ppc_chips[port].i2c_port;
+ const int i2c_addr = ppc_chips[port].i2c_addr;
for (i = SN5S330_FUNC_SET1; i <= SN5S330_FUNC_SET12; i++) {
- i2c_read8(port, addr, i, &data);
+ i2c_read8(i2c_port, i2c_addr, i, &data);
ccprintf("FUNC_SET%d [%02Xh] = 0x%02x\n",
i - SN5S330_FUNC_SET1 + 1,
i,
@@ -72,7 +56,7 @@ static int command_sn5s330_dump(int argc, char **argv)
}
for (i = SN5S330_INT_STATUS_REG1; i <= SN5S330_INT_STATUS_REG4; i++) {
- i2c_read8(port, addr, i, &data);
+ i2c_read8(i2c_port, i2c_addr, i, &data);
ccprintf("INT_STATUS_REG%d [%02Xh] = 0x%02x\n",
i - SN5S330_INT_STATUS_REG1 + 1,
i,
@@ -81,7 +65,7 @@ static int command_sn5s330_dump(int argc, char **argv)
for (i = SN5S330_INT_TRIP_RISE_REG1; i <= SN5S330_INT_TRIP_RISE_REG3;
i++) {
- i2c_read8(port, addr, i, &data);
+ i2c_read8(i2c_port, i2c_addr, i, &data);
ccprintf("INT_TRIP_RISE_REG%d [%02Xh] = 0x%02x\n",
i - SN5S330_INT_TRIP_RISE_REG1 + 1,
i,
@@ -90,7 +74,7 @@ static int command_sn5s330_dump(int argc, char **argv)
for (i = SN5S330_INT_TRIP_FALL_REG1; i <= SN5S330_INT_TRIP_FALL_REG3;
i++) {
- i2c_read8(port, addr, i, &data);
+ i2c_read8(i2c_port, i2c_addr, i, &data);
ccprintf("INT_TRIP_FALL_REG%d [%02Xh] = 0x%02x\n",
i - SN5S330_INT_TRIP_FALL_REG1 + 1,
i,
@@ -99,7 +83,7 @@ static int command_sn5s330_dump(int argc, char **argv)
for (i = SN5S330_INT_MASK_RISE_REG1; i <= SN5S330_INT_MASK_RISE_REG3;
i++) {
- i2c_read8(port, addr, i, &data);
+ i2c_read8(i2c_port, i2c_addr, i, &data);
ccprintf("INT_MASK_RISE_REG%d [%02Xh] = 0x%02x\n",
i - SN5S330_INT_MASK_RISE_REG1 + 1,
i,
@@ -108,7 +92,7 @@ static int command_sn5s330_dump(int argc, char **argv)
for (i = SN5S330_INT_MASK_FALL_REG1; i <= SN5S330_INT_MASK_FALL_REG3;
i++) {
- i2c_read8(port, addr, i, &data);
+ i2c_read8(i2c_port, i2c_addr, i, &data);
ccprintf("INT_MASK_FALL_REG%d [%02Xh] = 0x%02x\n",
i - SN5S330_INT_MASK_FALL_REG1 + 1,
i,
@@ -117,22 +101,20 @@ static int command_sn5s330_dump(int argc, char **argv)
return EC_SUCCESS;
}
-DECLARE_CONSOLE_COMMAND(ppc_dump, command_sn5s330_dump,
- "<Type-C port>", "dump the SN5S330 regs");
#endif /* defined(CONFIG_CMD_PPC_DUMP) */
-static int get_func_set3(uint8_t chip_idx, int *regval)
+static int get_func_set3(uint8_t port, int *regval)
{
int status;
- status = read_reg(chip_idx, SN5S330_FUNC_SET3, regval);
+ status = read_reg(port, SN5S330_FUNC_SET3, regval);
if (status)
CPRINTS("Failed to read FUNC_SET3!");
return status;
}
-int sn5s330_is_pp_fet_enabled(uint8_t chip_idx, enum sn5s330_pp_idx pp,
+static int sn5s330_is_pp_fet_enabled(uint8_t port, enum sn5s330_pp_idx pp,
int *is_enabled)
{
int pp_bit;
@@ -148,7 +130,7 @@ int sn5s330_is_pp_fet_enabled(uint8_t chip_idx, enum sn5s330_pp_idx pp,
return EC_ERROR_INVAL;
}
- status = get_func_set3(chip_idx, &regval);
+ status = get_func_set3(port, &regval);
if (status)
return status;
@@ -157,7 +139,8 @@ int sn5s330_is_pp_fet_enabled(uint8_t chip_idx, enum sn5s330_pp_idx pp,
return EC_SUCCESS;
}
-int sn5s330_pp_fet_enable(uint8_t chip_idx, enum sn5s330_pp_idx pp, int enable)
+static int sn5s330_pp_fet_enable(uint8_t port, enum sn5s330_pp_idx pp,
+ int enable)
{
int regval;
int status;
@@ -170,7 +153,7 @@ int sn5s330_pp_fet_enable(uint8_t chip_idx, enum sn5s330_pp_idx pp, int enable)
else
return EC_ERROR_INVAL;
- status = get_func_set3(chip_idx, &regval);
+ status = get_func_set3(port, &regval);
if (status)
return status;
@@ -179,7 +162,7 @@ int sn5s330_pp_fet_enable(uint8_t chip_idx, enum sn5s330_pp_idx pp, int enable)
else
regval &= ~pp_bit;
- status = write_reg(chip_idx, SN5S330_FUNC_SET3, regval);
+ status = write_reg(port, SN5S330_FUNC_SET3, regval);
if (status) {
CPRINTS("Failed to set FUNC_SET3!");
return status;
@@ -188,17 +171,14 @@ int sn5s330_pp_fet_enable(uint8_t chip_idx, enum sn5s330_pp_idx pp, int enable)
return EC_SUCCESS;
}
-static int init_sn5s330(int idx)
+static int sn5s330_init(int port)
{
int regval;
int status;
int retries;
- int i2c_port;
- int i2c_addr;
int reg;
-
- i2c_port = sn5s330_chips[idx].i2c_port;
- i2c_addr = sn5s330_chips[idx].i2c_addr;
+ const int i2c_port = ppc_chips[port].i2c_port;
+ const int i2c_addr = ppc_chips[port].i2c_addr;
/* Set the sourcing current limit value. */
#if defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT) && \
@@ -306,7 +286,7 @@ static int init_sn5s330(int idx)
}
/* Turn off PP1 FET. */
- status = sn5s330_pp_fet_enable(idx, SN5S330_PP1, 0);
+ status = sn5s330_pp_fet_enable(port, SN5S330_PP1, 0);
if (status) {
CPRINTS("Failed to turn off PP1 FET!");
}
@@ -415,7 +395,7 @@ static int init_sn5s330(int idx)
SN5S330_DB_BOOT);
/* Turn on PP2 FET. */
- status = sn5s330_pp_fet_enable(idx, SN5S330_PP2, 1);
+ status = sn5s330_pp_fet_enable(port, SN5S330_PP2, 1);
if (status) {
CPRINTS("Failed to turn on PP2 FET!");
return status;
@@ -425,24 +405,9 @@ static int init_sn5s330(int idx)
return EC_SUCCESS;
}
-static void sn5s330_init(void)
-{
- int i;
- int rv;
-
- for (i = 0; i < sn5s330_cnt; i++) {
- rv = init_sn5s330(i);
- if (!rv)
- CPRINTS("C%d: SN5S330 init done.", i);
- else
- CPRINTS("C%d: SN5S330 init failed! (%d)", i, rv);
- }
-}
-DECLARE_HOOK(HOOK_INIT, sn5s330_init, HOOK_PRIO_INIT_I2C + 1);
-
-int ppc_is_sourcing_vbus(int port)
+static int sn5s330_is_sourcing_vbus(int port)
{
- int is_sourcing_vbus;
+ int is_sourcing_vbus = 0;
int rv;
rv = sn5s330_is_pp_fet_enabled(port, SN5S330_PP1, &is_sourcing_vbus);
@@ -455,12 +420,22 @@ int ppc_is_sourcing_vbus(int port)
return is_sourcing_vbus;
}
-int ppc_vbus_sink_enable(int port, int enable)
+static int sn5s330_vbus_sink_enable(int port, int enable)
{
return sn5s330_pp_fet_enable(port, SN5S330_PP2, !!enable);
}
-int ppc_vbus_source_enable(int port, int enable)
+static int sn5s330_vbus_source_enable(int port, int enable)
{
return sn5s330_pp_fet_enable(port, SN5S330_PP1, !!enable);
}
+
+const struct ppc_drv sn5s330_drv = {
+ .init = &sn5s330_init,
+ .is_sourcing_vbus = &sn5s330_is_sourcing_vbus,
+ .vbus_sink_enable = &sn5s330_vbus_sink_enable,
+ .vbus_source_enable = &sn5s330_vbus_source_enable,
+#ifdef CONFIG_CMD_PPC_DUMP
+ .reg_dump = &sn5s330_dump,
+#endif /* defined(CONFIG_CMD_PPC_DUMP) */
+};
diff --git a/driver/ppc/sn5s330.h b/driver/ppc/sn5s330.h
index f1bea3da46..059df14a30 100644
--- a/driver/ppc/sn5s330.h
+++ b/driver/ppc/sn5s330.h
@@ -116,26 +116,6 @@ enum sn5s330_pp_idx {
*/
#define SN5S330_ILIM_PP1_MASK (1 << 4)
-/**
- * Determine if a PP FET is enabled or not.
- *
- * @param chip_idx: The index into the sn5s330_chips[] table.
- * @param pp: The power path index (PP1 or PP2).
- * @param is_enabled: 1 to turn on the FET, 0 to turn off.
- * @return EC_SUCCESS if i2c access worked, otherwise an error.
- */
-int sn5s330_is_pp_fet_enabled(uint8_t chip_idx, enum sn5s330_pp_idx pp,
- int *is_enabled);
-
-/**
- * Turn on/off the PP1 or PP2 FET.
- *
- * @param chip_idx: The index into the sn5s330_chips[] table.
- * @param pp: The power path index (PP1 or PP2).
- * @param enable: 1 to turn on the FET, 0 to turn off.
- * @return EC_SUCCESS on success,
- * otherwise if failed to enable the FET.
- */
-int sn5s330_pp_fet_enable(uint8_t chip_idx, enum sn5s330_pp_idx pp, int enable);
+extern const struct ppc_drv sn5s330_drv;
#endif /* defined(__CROS_EC_SN5S330_H) */