summaryrefslogtreecommitdiff
path: root/driver/wpc
diff options
context:
space:
mode:
Diffstat (limited to 'driver/wpc')
-rw-r--r--driver/wpc/cps8100.c278
-rw-r--r--driver/wpc/p9221.c808
-rw-r--r--driver/wpc/p9221.h394
3 files changed, 396 insertions, 1084 deletions
diff --git a/driver/wpc/cps8100.c b/driver/wpc/cps8100.c
index 78aa73fbfd..acfdc06a32 100644
--- a/driver/wpc/cps8100.c
+++ b/driver/wpc/cps8100.c
@@ -1,4 +1,4 @@
-/* Copyright 2022 The Chromium OS Authors. All rights reserved.
+/* Copyright 2022 The ChromiumOS Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
@@ -18,49 +18,61 @@
/* Print additional data */
#define CPS8100_DEBUG
-#define CPUTS(outstr) cputs(CC_PCHG, outstr)
-#define CPRINTS(fmt, args...) cprints(CC_PCHG, "CPS8100: " fmt, ##args)
-#define CPRINTFP(fmt, args...) cprintf(CC_PCHG, "CPS8100: " fmt, ##args)
-#define CPRINTF(fmt, args...) cprintf(CC_PCHG, fmt, ##args)
+#define CPUTS(outstr) cputs(CC_PCHG, outstr)
+#define CPRINTS(fmt, args...) cprints(CC_PCHG, "CPS8100: " fmt, ##args)
+#define CPRINTFP(fmt, args...) cprintf(CC_PCHG, "CPS8100: " fmt, ##args)
+#define CPRINTF(fmt, args...) cprintf(CC_PCHG, fmt, ##args)
/*
* Configuration
*/
-#define CPS8100_I2C_ADDR_H 0x31
-#define CPS8100_I2C_ADDR_L 0x30
+#define CPS8100_I2C_ADDR_H 0x31
+#define CPS8100_I2C_ADDR_L 0x30
+#define CPS8200_I2C_ADDR 0x30
/* High address registers (commands?) */
-#define CPS8100_REGH_PASSWORD 0xf500
-#define CPS8100_REGH_ACCESS_MODE 0xf505
-#define CPS8100_REGH_ADDRESS 0xf503
+#define CPS8100_REGH_PASSWORD 0xf500
+#define CPS8100_REGH_ACCESS_MODE 0xf505
+#define CPS8100_REGH_ADDRESS 0xf503
-#define CPS8100_ACCESS_MODE_8 0x00
-#define CPS8100_ACCESS_MODE_16 0x01
-#define CPS8100_ACCESS_MODE_32 0x02
+#define CPS8100_ACCESS_MODE_8 0x00
+#define CPS8100_ACCESS_MODE_16 0x01
+#define CPS8100_ACCESS_MODE_32 0x02
+#define CPS8100_PASSWORD 0x19e5
+#define CPS8100_CHIPID 0x8100
+#define CPS8200_CHIPID 0x8200
+
+#define CPS8200_I2C_ENABLE 0x0000000E
+#define CPS8200_PASSWORD 0x00001250
/* Registers */
-#define CPS8100_REG_IC_INFO 0x20000000
-#define CPS8100_REG_FW_INFO 0x20000004
-#define CPS8100_REG_FUNC_EN 0x2000003c
-#define CPS8100_REG_ALERT_INFO 0x20000158
-#define CPS8100_REG_INT_ENABLE 0x20000160
-#define CPS8100_REG_INT_FLAG 0x20000164
-
-#define CPS8100_STATUS_PROFILE(r) (((r) & GENMASK(5, 4)) >> 4)
-#define CPS8100_STATUS_CHARGE(r) ((r) & BIT(6))
-#define CPS8100_STATUS_DEVICE(r) ((r) & BIT(7))
-#define CPS8100_STATUS_BATTERY(r) (((r) & GENMASK(15, 8)) >> 8)
-#define CPS8100_IRQ_TYPE(r) (((r) & GENMASK(23, 20)) >> 20)
+#define CPS8100_REG_IC_INFO 0x20000000
+#define CPS8100_REG_FW_INFO 0x20000004
+#define CPS8100_REG_FUNC_EN 0x2000003c
+#define CPS8100_REG_ALERT_INFO 0x20000158
+#define CPS8100_REG_INT_ENABLE 0x20000160
+#define CPS8100_REG_INT_FLAG 0x20000164
+
+#define CPS8200_REG_I2C_ENABLE 0xFFFFFF00
+#define CPS8200_REG_PASSWORD 0x400140FC
+
+#define CPS8100_STATUS_PROFILE(r) (((r)&GENMASK(5, 4)) >> 4)
+#define CPS8100_STATUS_CHARGE(r) ((r)&BIT(6))
+#define CPS8100_STATUS_DEVICE(r) ((r)&BIT(7))
+#define CPS8100_STATUS_BATTERY(r) (((r)&GENMASK(15, 8)) >> 8)
+#define CPS8100_IRQ_TYPE(r) (((r)&GENMASK(23, 20)) >> 20)
/* Status flags in ALERT_INFO register */
-#define CPS8100_STATUS_FOD BIT(0)
-#define CPS8100_STATUS_OCP BIT(1)
-#define CPS8100_STATUS_OVP BIT(2)
-#define CPS8100_STATUS_OTP BIT(3)
-#define CPS8100_STATUS_UVP BIT(16)
+#define CPS8100_STATUS_FOD BIT(0)
+#define CPS8100_STATUS_OCP BIT(1)
+#define CPS8100_STATUS_OVP BIT(2)
+#define CPS8100_STATUS_OTP BIT(3)
+#define CPS8100_STATUS_UVP BIT(16)
/* Buffer size for i2c read & write */
-#define CPS8100_MESSAGE_BUFFER_SIZE 0x20
+#define CPS8100_MESSAGE_BUFFER_SIZE 0x20
+
+static uint32_t chip_id;
/* TODO: Check datasheet how to wake up and how long it takes to wake up. */
static const int cps8100_wake_up_delay_ms = 10;
@@ -81,22 +93,15 @@ struct cps8100_msg {
uint8_t data[2];
} __packed;
+static int (*cps8x00_read32)(int port, uint32_t reg, uint32_t *val);
+
/* This driver isn't compatible with big endian. */
-BUILD_ASSERT(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__);
-
-static const char * const cps8100_func_names[] = {
- [0] = "DPL",
- [1] = "OPP",
- [2] = "OTP",
- [3] = "OVPK",
- [4] = "OCP",
- [5] = "UVP",
- [6] = "OVP",
- [7] = "FOD",
- [8] = "SAMSUNG",
- [9] = "APPLE",
- [10] = "EPP",
- [11] = "HUAWEI",
+BUILD_ASSERT(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__);
+
+static const char *const cps8100_func_names[] = {
+ [0] = "DPL", [1] = "OPP", [2] = "OTP", [3] = "OVPK",
+ [4] = "OCP", [5] = "UVP", [6] = "OVP", [7] = "FOD",
+ [8] = "SAMSUNG", [9] = "APPLE", [10] = "EPP", [11] = "HUAWEI",
[12] = "CPS",
};
@@ -114,7 +119,7 @@ enum cps8100_irq_type {
CPS8100_IRQ_TYPE_COUNT
};
-static const char * const cps8100_irq_type_names[] = {
+static const char *const cps8100_irq_type_names[] = {
[CPS8100_IRQ_TYPE_FOD] = "FOD",
[CPS8100_IRQ_TYPE_OCP] = "OCP",
[CPS8100_IRQ_TYPE_OVP] = "OVP",
@@ -127,7 +132,7 @@ static const char * const cps8100_irq_type_names[] = {
[CPS8100_IRQ_TYPE_RESET] = "RESET",
};
-static const char * const cps8100_profile_names[] = {
+static const char *const cps8100_profile_names[] = {
[0] = "NONE",
[1] = "BPP",
[2] = "EPP",
@@ -211,14 +216,54 @@ static int cps8100_i2c_write(int port, int addr, const uint8_t *buf, size_t len)
static int cps8100_set_unlock(int port)
{
- uint8_t buf[4];
+ const uint8_t cps8100_unlock_cmd[] = {
+ /* Password register address */
+ (CPS8100_REGH_PASSWORD >> 8) & 0xff,
+ (CPS8100_REGH_PASSWORD >> 0) & 0xff,
+ /* Password */
+ (CPS8100_PASSWORD >> 0) & 0xff,
+ (CPS8100_PASSWORD >> 8) & 0xff,
+ };
+
+ return cps8100_i2c_write(port, CPS8100_I2C_ADDR_H, cps8100_unlock_cmd,
+ 4);
+}
- buf[0] = 0xf5;
- buf[1] = 0x00; /* Password register address */
- buf[2] = 0xe5;
- buf[3] = 0x19; /* Password */
+static int cps8200_set_unlock(int port)
+{
+ const uint8_t cps8200_unlock_cmd[] = {
+ /* Password register addr */
+ (CPS8200_REG_PASSWORD >> 24) & 0xff,
+ (CPS8200_REG_PASSWORD >> 16) & 0xff,
+ (CPS8200_REG_PASSWORD >> 8) & 0xff,
+ (CPS8200_REG_PASSWORD >> 0) & 0xff,
+ /* Password */
+ (CPS8200_PASSWORD >> 0) & 0xff,
+ (CPS8200_PASSWORD >> 8) & 0xff,
+ (CPS8200_PASSWORD >> 16) & 0xff,
+ (CPS8200_PASSWORD >> 24) & 0xff,
+ };
+
+ return cps8100_i2c_write(port, CPS8200_I2C_ADDR, cps8200_unlock_cmd, 8);
+}
- return cps8100_i2c_write(port, CPS8100_I2C_ADDR_H, buf, 4);
+static int cps8200_i2c_enable(int port)
+{
+ const uint8_t cps8200_i2c_enable_cmd[] = {
+ /* addr */
+ (CPS8200_REG_I2C_ENABLE >> 24) & 0xff,
+ (CPS8200_REG_I2C_ENABLE >> 16) & 0xff,
+ (CPS8200_REG_I2C_ENABLE >> 8) & 0xff,
+ (CPS8200_REG_I2C_ENABLE >> 0) & 0xff,
+ /* data */
+ (CPS8200_I2C_ENABLE >> 0) & 0xff,
+ (CPS8200_I2C_ENABLE >> 8) & 0xff,
+ (CPS8200_I2C_ENABLE >> 16) & 0xff,
+ (CPS8200_I2C_ENABLE >> 24) & 0xff,
+ };
+
+ return cps8100_i2c_write(port, CPS8200_I2C_ADDR, cps8200_i2c_enable_cmd,
+ 8);
}
static int cps8100_set_write_mode(int port, uint8_t mode)
@@ -249,17 +294,44 @@ static int cps8100_read32(int port, uint32_t reg, uint32_t *val)
{
uint8_t buf[CPS8100_MESSAGE_BUFFER_SIZE];
- if (cps8100_set_unlock(port) ||
- cps8100_set_write_mode(port, CPS8100_ACCESS_MODE_32) ||
- cps8100_set_high_address(port, reg))
+ if (cps8100_set_high_address(port, reg))
return EC_ERROR_UNKNOWN;
/* Set low 16 bits of register address and read a byte. */
buf[0] = (reg >> 8) & 0xff;
buf[1] = (reg >> 0) & 0xff;
- return i2c_xfer(port, CPS8100_I2C_ADDR_L, buf, 2,
- (void *)val, sizeof(*val));
+ return i2c_xfer(port, CPS8100_I2C_ADDR_L, buf, 2, (void *)val,
+ sizeof(*val));
+}
+
+static int cps8200_read32(int port, uint32_t reg, uint32_t *val)
+{
+ uint8_t buf[4];
+
+ buf[0] = (reg >> 24) & 0xff;
+ buf[1] = (reg >> 16) & 0xff;
+ buf[2] = (reg >> 8) & 0xff;
+ buf[3] = (reg >> 0) & 0xff;
+
+ return i2c_xfer(port, CPS8200_I2C_ADDR, buf, 4, (void *)val,
+ sizeof(*val));
+}
+
+static int cps8100_unlock(int port)
+{
+ int rv;
+
+ rv = cps8100_set_unlock(port);
+ return rv ? rv : cps8100_set_write_mode(port, CPS8100_ACCESS_MODE_32);
+}
+
+static int cps8200_unlock(int port)
+{
+ int rv;
+
+ rv = cps8200_i2c_enable(port);
+ return rv ? rv : cps8200_set_unlock(port);
}
static int cps8100_reset(struct pchg *ctx)
@@ -274,19 +346,15 @@ static int cps8100_reset(struct pchg *ctx)
static int cps8100_init(struct pchg *ctx)
{
- uint32_t u32;
int port = ctx->cfg->i2c_port;
- int rv;
- rv = cps8100_read32(port, CPS8100_REG_IC_INFO, &u32);
- if (!rv)
- CPRINTS("IC=0x%08x", u32);
-
- rv = cps8100_read32(port, CPS8100_REG_FW_INFO, &u32);
- if (!rv)
- CPRINTS("FW=0x%08x", u32);
-
- return EC_SUCCESS;
+ /* Enable I2C, unlock and set mode */;
+ if (chip_id == CPS8100_CHIPID)
+ return cps8100_unlock(port);
+ else if (chip_id == CPS8200_CHIPID)
+ return cps8200_unlock(port);
+ else
+ return EC_ERROR_UNKNOWN;
}
static int cps8100_enable(struct pchg *ctx, bool enable)
@@ -298,7 +366,7 @@ static int cps8100_get_alert_info(struct pchg *ctx, uint32_t *reg)
{
int rv;
- rv = cps8100_read32(ctx->cfg->i2c_port, CPS8100_REG_ALERT_INFO, reg);
+ rv = cps8x00_read32(ctx->cfg->i2c_port, CPS8100_REG_ALERT_INFO, reg);
if (rv) {
CPRINTS("Failed to get alert info (%d)", rv);
return rv;
@@ -307,6 +375,63 @@ static int cps8100_get_alert_info(struct pchg *ctx, uint32_t *reg)
return EC_SUCCESS;
}
+static int cps8100_get_chip_info(struct pchg *ctx)
+{
+ uint32_t u32;
+ int port = ctx->cfg->i2c_port;
+ int rv = EC_ERROR_UNKNOWN;
+
+ /*
+ * CPS8100 needs 100~120ms delay, CPS8200 needs 40~50ms delay
+ * between reset and the first access to I2C register.
+ */
+ if (chip_id == CPS8100_CHIPID) {
+ /*
+ * already probed but unlock again in case it's turned
+ * off.
+ */
+ msleep(120);
+ return cps8100_unlock(port);
+ } else if (chip_id == CPS8200_CHIPID) {
+ msleep(50);
+ return cps8200_unlock(port);
+ }
+
+ /* not probed yet, need to unlock blindly first. */
+ msleep(120);
+ if (!cps8100_unlock(port))
+ rv = cps8100_read32(port, CPS8100_REG_IC_INFO, &u32);
+ else if (!cps8200_unlock(port))
+ rv = cps8200_read32(port, CPS8100_REG_IC_INFO, &u32);
+
+ if (rv) {
+ CPRINTS("Failed to read IC info!");
+ return rv;
+ }
+
+ /* Probe */;
+ CPRINTS("IC=0x%08x", u32);
+ if ((u32 & 0xffff) == CPS8100_CHIPID) {
+ cps8x00_read32 = cps8100_read32;
+ chip_id = CPS8100_CHIPID;
+ } else if ((u32 & 0xffff) == CPS8200_CHIPID) {
+ cps8x00_read32 = cps8200_read32;
+ chip_id = CPS8200_CHIPID;
+ } else {
+ CPRINTS("Unknown chip!");
+ return EC_ERROR_UNKNOWN;
+ }
+
+ if (!cps8x00_read32(port, CPS8100_REG_FW_INFO, &u32)) {
+ CPRINTS("FW=0x%08x", u32);
+ } else {
+ CPRINTS("Failed to read FW info!");
+ return EC_ERROR_UNKNOWN;
+ }
+
+ return EC_SUCCESS;
+}
+
static void cps8100_print_alert_info(uint32_t reg)
{
cps8100_print_irq_type_names("IRQ_TYPE: ", reg);
@@ -315,7 +440,8 @@ static void cps8100_print_alert_info(uint32_t reg)
CPRINTFP("Profile: %s\n",
cps8100_profile_names[CPS8100_STATUS_PROFILE(reg)]);
CPRINTFP("%sCharging\n", CPS8100_STATUS_CHARGE(reg) ? "" : "Not ");
- CPRINTFP("Device %sPresent\n", CPS8100_STATUS_DEVICE(reg) ? "":"Not ");
+ CPRINTFP("Device %sPresent\n",
+ CPS8100_STATUS_DEVICE(reg) ? "" : "Not ");
CPRINTFP("Battery: %d%%\n", CPS8100_STATUS_BATTERY(reg));
}
@@ -386,6 +512,7 @@ const struct pchg_drv cps8100_drv = {
.reset = cps8100_reset,
.init = cps8100_init,
.enable = cps8100_enable,
+ .get_chip_info = cps8100_get_chip_info,
.get_event = cps8100_get_event,
.get_soc = cps8100_get_soc,
.update_open = cps8100_update_open,
@@ -398,7 +525,7 @@ static void cps8100_dump(struct pchg *ctx)
uint32_t val;
int rv;
- rv = cps8100_read32(ctx->cfg->i2c_port, CPS8100_REG_FUNC_EN, &val);
+ rv = cps8x00_read32(ctx->cfg->i2c_port, CPS8100_REG_FUNC_EN, &val);
if (rv == EC_SUCCESS)
cps8100_print_func_names("FEATURES: ", val);
@@ -407,7 +534,7 @@ static void cps8100_dump(struct pchg *ctx)
cps8100_print_alert_info(val);
}
-static int cc_cps8100(int argc, char **argv)
+static int cc_cps8100(int argc, const char **argv)
{
struct pchg *ctx;
char *end;
@@ -436,6 +563,5 @@ static int cc_cps8100(int argc, char **argv)
return EC_SUCCESS;
}
-DECLARE_CONSOLE_COMMAND(cps8100, cc_cps8100,
- "<port> [reset]",
+DECLARE_CONSOLE_COMMAND(cps8100, cc_cps8100, "<port> [reset]",
"Print status of or reset CPS8100");
diff --git a/driver/wpc/p9221.c b/driver/wpc/p9221.c
deleted file mode 100644
index 973d991240..0000000000
--- a/driver/wpc/p9221.c
+++ /dev/null
@@ -1,808 +0,0 @@
-/* Copyright 2019 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/*
- * IDT P9221-R7 Wireless Power Receiver driver.
- */
-
-#include "p9221.h"
-#include "charge_manager.h"
-#include "chipset.h"
-#include "common.h"
-#include "console.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "power.h"
-#include "tcpm/tcpm.h"
-#include "timer.h"
-#include "usb_charge.h"
-#include "usb_pd.h"
-#include "util.h"
-#include <stdbool.h>
-#include "printf.h"
-
-#define CPRINTS(format, args...) cprints(CC_USBPD, "WPC " format, ## args)
-
-#define P9221_TX_TIMEOUT_MS (20 * 1000*1000)
-#define P9221_DCIN_TIMEOUT_MS (2 * 1000*1000)
-#define P9221_VRECT_TIMEOUT_MS (2 * 1000*1000)
-#define P9221_NOTIFIER_DELAY_MS (80*1000)
-#define P9221R7_ILIM_MAX_UA (1600 * 1000)
-#define P9221R7_OVER_CHECK_NUM 3
-
-#define OVC_LIMIT 1
-#define OVC_THRESHOLD 1400000
-#define OVC_BACKOFF_LIMIT 900000
-#define OVC_BACKOFF_AMOUNT 100000
-
-/* P9221 parameters */
-static struct wpc_charger_info p9221_charger_info = {
- .online = false,
- .i2c_port = I2C_PORT_WPC,
- .pp_buf_valid = false,
-};
-
-static struct wpc_charger_info *wpc = &p9221_charger_info;
-
-static void p9221_set_offline(void);
-
-static const uint32_t p9221_ov_set_lut[] = {
- 17000000, 20000000, 15000000, 13000000,
- 11000000, 11000000, 11000000, 11000000
-};
-
-static int p9221_reg_is_8_bit(uint16_t reg)
-{
- switch (reg) {
- case P9221_CHIP_REVISION_REG:
- case P9221R7_VOUT_SET_REG:
- case P9221R7_ILIM_SET_REG:
- case P9221R7_CHARGE_STAT_REG:
- case P9221R7_EPT_REG:
- case P9221R7_SYSTEM_MODE_REG:
- case P9221R7_COM_CHAN_RESET_REG:
- case P9221R7_COM_CHAN_SEND_SIZE_REG:
- case P9221R7_COM_CHAN_SEND_IDX_REG:
- case P9221R7_COM_CHAN_RECV_SIZE_REG:
- case P9221R7_COM_CHAN_RECV_IDX_REG:
- case P9221R7_DEBUG_REG:
- case P9221R7_EPP_Q_FACTOR_REG:
- case P9221R7_EPP_TX_GUARANTEED_POWER_REG:
- case P9221R7_EPP_TX_POTENTIAL_POWER_REG:
- case P9221R7_EPP_TX_CAPABILITY_FLAGS_REG:
- case P9221R7_EPP_RENEGOTIATION_REG:
- case P9221R7_EPP_CUR_RPP_HEADER_REG:
- case P9221R7_EPP_CUR_NEGOTIATED_POWER_REG:
- case P9221R7_EPP_CUR_MAXIMUM_POWER_REG:
- case P9221R7_EPP_CUR_FSK_MODULATION_REG:
- case P9221R7_EPP_REQ_RPP_HEADER_REG:
- case P9221R7_EPP_REQ_NEGOTIATED_POWER_REG:
- case P9221R7_EPP_REQ_MAXIMUM_POWER_REG:
- case P9221R7_EPP_REQ_FSK_MODULATION_REG:
- case P9221R7_VRECT_TARGET_REG:
- case P9221R7_VRECT_KNEE_REG:
- case P9221R7_FOD_SECTION_REG:
- case P9221R7_VRECT_ADJ_REG:
- case P9221R7_ALIGN_X_ADC_REG:
- case P9221R7_ALIGN_Y_ADC_REG:
- case P9221R7_ASK_MODULATION_DEPTH_REG:
- case P9221R7_OVSET_REG:
- case P9221R7_EPP_TX_SPEC_REV_REG:
- return true;
- default:
- return false;
- }
-}
-
-static int p9221_read8(uint16_t reg, int *val)
-{
- return i2c_read_offset16(wpc->i2c_port, P9221_R7_ADDR_FLAGS,
- reg, val, 1);
-}
-
-static int p9221_write8(uint16_t reg, int val)
-{
- return i2c_write_offset16(wpc->i2c_port, P9221_R7_ADDR_FLAGS,
- reg, val, 1);
-}
-
-static int p9221_read16(uint16_t reg, int *val)
-{
- return i2c_read_offset16(wpc->i2c_port, P9221_R7_ADDR_FLAGS,
- reg, val, 2);
-}
-
-static int p9221_write16(uint16_t reg, int val)
-{
- return i2c_write_offset16(wpc->i2c_port, P9221_R7_ADDR_FLAGS,
- reg, val, 2);
-}
-
-static int p9221_block_read(uint16_t reg, uint8_t *data, int len)
-{
- return i2c_read_offset16_block(wpc->i2c_port, P9221_R7_ADDR_FLAGS,
- reg, data, len);
-}
-
-static int p9221_block_write(uint16_t reg, uint8_t *data, int len)
-{
- return i2c_write_offset16_block(wpc->i2c_port, P9221_R7_ADDR_FLAGS,
- reg, data, len);
-}
-
-static int p9221_set_cmd_reg(uint8_t cmd)
-{
- int cur_cmd;
- int retry;
- int ret;
-
- for (retry = 0; retry < P9221_COM_CHAN_RETRIES; retry++) {
- ret = p9221_read8(P9221_COM_REG, &cur_cmd);
- if (ret == EC_SUCCESS && cur_cmd == 0)
- break;
- msleep(25);
- }
-
- if (retry >= P9221_COM_CHAN_RETRIES) {
- CPRINTS("Failed to wait for cmd free %02x", cur_cmd);
- return EC_ERROR_TIMEOUT;
- }
-
- ret = p9221_write8(P9221_COM_REG, cmd);
- if (ret)
- CPRINTS("Failed to set cmd reg %02x: %d", cmd, ret);
-
- return ret;
-}
-
-/* Convert a register value to uV, Hz, or uA */
-static int p9221_convert_reg_r7(uint16_t reg, uint16_t raw_data, uint32_t *val)
-{
- switch (reg) {
- case P9221R7_ALIGN_X_ADC_REG: /* raw */
- case P9221R7_ALIGN_Y_ADC_REG: /* raw */
- *val = raw_data;
- break;
- case P9221R7_VOUT_ADC_REG: /* 12-bit ADC raw */
- case P9221R7_IOUT_ADC_REG: /* 12-bit ADC raw */
- case P9221R7_DIE_TEMP_ADC_REG: /* 12-bit ADC raw */
- case P9221R7_EXT_TEMP_REG:
- *val = raw_data & 0xFFF;
- break;
- case P9221R7_VOUT_SET_REG: /* 0.1V -> uV */
- *val = raw_data * 100 * 1000;
- break;
- case P9221R7_IOUT_REG: /* mA -> uA */
- case P9221R7_VRECT_REG: /* mV -> uV */
- case P9221R7_VOUT_REG: /* mV -> uV */
- case P9221R7_OP_FREQ_REG: /* kHz -> Hz */
- case P9221R7_TX_PINGFREQ_REG: /* kHz -> Hz */
- *val = raw_data * 1000;
- break;
- case P9221R7_ILIM_SET_REG: /* 100mA -> uA, 200mA offset */
- *val = ((raw_data * 100) + 200) * 1000;
- break;
- case P9221R7_OVSET_REG: /* uV */
- raw_data &= P9221R7_OVSET_MASK;
- *val = p9221_ov_set_lut[raw_data];
- break;
- default:
- return -2;
- }
-
- return 0;
-}
-
-static int p9221_reg_read_converted(uint16_t reg, uint32_t *val)
-{
- int ret;
- int data;
-
- if (p9221_reg_is_8_bit(reg))
- ret = p9221_read8(reg, &data);
- else
- ret = p9221_read16(reg, &data);
-
- if (ret)
- return ret;
-
- return p9221_convert_reg_r7(reg, data, val);
-}
-
-static int p9221_is_online(void)
-{
- int chip_id;
-
- if (p9221_read16(P9221_CHIP_ID_REG, &chip_id)
- || chip_id != P9221_CHIP_ID)
- return false;
- else
- return true;
-}
-
-int wpc_chip_is_online(void)
-{
- return p9221_is_online();
-}
-
-
-void p9221_interrupt(enum gpio_signal signal)
-{
- task_wake(TASK_ID_WPC);
-}
-
-static int p9221r7_clear_interrupts(uint16_t mask)
-{
- int ret;
-
- ret = p9221_write16(P9221R7_INT_CLEAR_REG, mask);
- if (ret) {
- CPRINTS("Failed to clear INT reg: %d", ret);
- return ret;
- }
-
- ret = p9221_set_cmd_reg(P9221_COM_CLEAR_INT_MASK);
- if (ret)
- CPRINTS("Failed to reset INT: %d", ret);
-
- return ret;
-}
-
-/*
- * Enable interrupts on the P9221 R7, note we don't really need to disable
- * interrupts since when the device goes out of field, the P9221 is reset.
- */
-static int p9221_enable_interrupts_r7(void)
-{
- uint16_t mask = 0;
- int ret;
-
- CPRINTS("Enable interrupts");
-
- mask = P9221R7_STAT_LIMIT_MASK | P9221R7_STAT_CC_MASK
- | P9221_STAT_VRECT;
-
- p9221r7_clear_interrupts(mask);
-
- ret = p9221_write8(P9221_INT_ENABLE_REG, mask);
- if (ret)
- CPRINTS("Failed to enable INTs: %d", ret);
- return ret;
-}
-
-static int p9221_send_csp(uint8_t status)
-{
- int ret;
-
- CPRINTS("Send CSP=%d", status);
- mutex_lock(&wpc->cmd_lock);
-
- ret = p9221_write8(P9221R7_CHARGE_STAT_REG, status);
- if (ret == EC_SUCCESS)
- ret = p9221_set_cmd_reg(P9221R7_COM_SENDCSP);
-
- mutex_unlock(&wpc->cmd_lock);
- return ret;
-}
-
-static int p9221_send_eop(uint8_t reason)
-{
- int rv;
-
- CPRINTS("Send EOP reason=%d", reason);
- mutex_lock(&wpc->cmd_lock);
-
- rv = p9221_write8(P9221R7_EPT_REG, reason);
- if (rv == EC_SUCCESS)
- rv = p9221_set_cmd_reg(P9221R7_COM_SENDEPT);
-
- mutex_unlock(&wpc->cmd_lock);
- return rv;
-}
-
-static void print_current_samples(uint32_t *iout_val, int count)
-{
- int i;
- char temp[P9221R7_OVER_CHECK_NUM * 9 + 1] = { 0 };
-
- for (i = 0; i < count ; i++)
- snprintf(temp + i * 9, sizeof(temp) - i * 9,
- "%08x ", iout_val[i]);
- CPRINTS("OVER IOUT_SAMPLES: %s", temp);
-}
-
-
-/*
- * Number of times to poll the status to see if the current limit condition
- * was transient or not.
- */
-static void p9221_limit_handler_r7(uint16_t orign_irq_src)
-{
- uint8_t reason;
- int i;
- int ret;
- int ovc_count = 0;
- uint32_t iout_val[P9221R7_OVER_CHECK_NUM] = { 0 };
- int irq_src = (int)orign_irq_src;
-
- CPRINTS("OVER INT: %02x", irq_src);
-
- if (irq_src & P9221R7_STAT_OVV) {
- reason = P9221_EOP_OVER_VOLT;
- goto send_eop;
- }
-
- if (irq_src & P9221R7_STAT_OVT) {
- reason = P9221_EOP_OVER_TEMP;
- goto send_eop;
- }
-
- if ((irq_src & P9221R7_STAT_UV) && !(irq_src & P9221R7_STAT_OVC))
- return;
-
- reason = P9221_EOP_OVER_CURRENT;
- for (i = 0; i < P9221R7_OVER_CHECK_NUM; i++) {
- ret = p9221r7_clear_interrupts(
- irq_src & P9221R7_STAT_LIMIT_MASK);
- msleep(50);
- if (ret)
- continue;
-
- ret = p9221_reg_read_converted(P9221R7_IOUT_REG, &iout_val[i]);
- if (ret) {
- CPRINTS("Failed to read IOUT[%d]: %d", i, ret);
- continue;
- } else if (iout_val[i] > OVC_THRESHOLD) {
- ovc_count++;
- }
-
- ret = p9221_read16(P9221_STATUS_REG, &irq_src);
- if (ret) {
- CPRINTS("Failed to read status: %d", ret);
- continue;
- }
-
- if ((irq_src & P9221R7_STAT_OVC) == 0) {
- print_current_samples(iout_val, i + 1);
- CPRINTS("OVER condition %04x cleared after %d tries",
- irq_src, i);
- return;
- }
-
- CPRINTS("OVER status is still %04x, retry", irq_src);
- }
-
- if (ovc_count < OVC_LIMIT) {
- print_current_samples(iout_val, P9221R7_OVER_CHECK_NUM);
- CPRINTS("ovc_threshold=%d, ovc_count=%d, ovc_limit=%d",
- OVC_THRESHOLD, ovc_count, OVC_LIMIT);
- return;
- }
-
-send_eop:
- CPRINTS("OVER is %04x, sending EOP %d", irq_src, reason);
-
- ret = p9221_send_eop(reason);
- if (ret)
- CPRINTS("Failed to send EOP %d: %d", reason, ret);
-}
-
-static void p9221_abort_transfers(void)
-{
- wpc->tx_busy = false;
- wpc->tx_done = true;
- wpc->rx_done = true;
- wpc->rx_len = 0;
-}
-
-/* Handler for r7 and R7 chips */
-static void p9221r7_irq_handler(uint16_t irq_src)
-{
- int res;
-
- if (irq_src & P9221R7_STAT_LIMIT_MASK)
- p9221_limit_handler_r7(irq_src);
-
- /* Receive complete */
- if (irq_src & P9221R7_STAT_CCDATARCVD) {
- int rxlen = 0;
-
- res = p9221_read8(P9221R7_COM_CHAN_RECV_SIZE_REG, &rxlen);
- if (res)
- CPRINTS("Failed to read len: %d", res);
-
- if (rxlen) {
- res = p9221_block_read(P9221R7_DATA_RECV_BUF_START,
- wpc->rx_buf, rxlen);
- if (res) {
- CPRINTS("Failed to read CC data: %d", res);
- rxlen = 0;
- }
-
- wpc->rx_len = rxlen;
- wpc->rx_done = true;
- }
- }
-
- /* Send complete */
- if (irq_src & P9221R7_STAT_CCSENDBUSY) {
- wpc->tx_busy = false;
- wpc->tx_done = true;
- }
-
- /* Proprietary packet */
- if (irq_src & P9221R7_STAT_PPRCVD) {
- res = p9221_block_read(P9221R7_DATA_RECV_BUF_START,
- wpc->pp_buf, sizeof(wpc->pp_buf));
- if (res) {
- CPRINTS("Failed to read PP: %d", res);
- wpc->pp_buf_valid = false;
- return;
- }
-
- /* We only care about PP which come with 0x4F header */
- wpc->pp_buf_valid = (wpc->pp_buf[0] == 0x4F);
-
- hexdump(wpc->pp_buf, sizeof(wpc->pp_buf));
- }
-
- /* CC Reset complete */
- if (irq_src & P9221R7_STAT_CCRESET)
- p9221_abort_transfers();
-}
-
-static int p9221_is_epp(void)
-{
- int ret, reg;
- uint32_t vout_uv;
-
- if (p9221_read8(P9221R7_SYSTEM_MODE_REG, &reg) == EC_SUCCESS)
- return reg & P9221R7_SYSTEM_MODE_EXTENDED_MASK;
-
- /* Check based on power supply voltage */
- ret = p9221_reg_read_converted(P9221R7_VOUT_ADC_REG, &vout_uv);
- if (ret) {
- CPRINTS("Failed to read VOUT_ADC: %d", ret);
- return false;
- }
-
- CPRINTS("Voltage is %duV", vout_uv);
- if (vout_uv > P9221_EPP_THRESHOLD_UV)
- return true;
-
- return false;
-}
-
-static void p9221_config_fod(void)
-{
-
- int epp;
- uint8_t *fod;
- int fod_len;
- int ret;
- int retries = 3;
-
- CPRINTS("Config FOD");
-
- epp = p9221_is_epp();
- fod_len = epp ? board_get_epp_fod(&fod) : board_get_fod(&fod);
- if (!fod_len || !fod) {
- CPRINTS("FOD data not found");
- return;
- }
-
- while (retries) {
- uint8_t fod_read[fod_len];
-
- CPRINTS("Writing %s FOD (n=%d try=%d)",
- epp ? "EPP" : "BPP", fod_len, retries);
-
- ret = p9221_block_write(P9221R7_FOD_REG, fod, fod_len);
- if (ret)
- goto no_fod;
-
- /* Verify the FOD has been written properly */
- ret = p9221_block_read(P9221R7_FOD_REG, fod_read, fod_len);
- if (ret)
- goto no_fod;
-
- if (memcmp(fod, fod_read, fod_len) == 0)
- return;
-
- hexdump(fod_read, fod_len);
-
- retries--;
- msleep(100);
- }
-
-no_fod:
- CPRINTS("Failed to set FOD. retries:%d ret:%d", retries, ret);
-}
-
-static void p9221_set_online(void)
-{
- int ret;
-
- CPRINTS("Set online");
-
- wpc->online = true;
-
- wpc->tx_busy = false;
- wpc->tx_done = true;
- wpc->rx_done = false;
- wpc->charge_supplier = CHARGE_SUPPLIER_WPC_BPP;
-
- ret = p9221_enable_interrupts_r7();
- if (ret)
- CPRINTS("Failed to enable INT: %d", ret);
-
- /* NOTE: depends on _is_epp() which is not valid until DC_IN */
- p9221_config_fod();
-}
-
-static void p9221_vbus_check_timeout(void)
-{
- CPRINTS("Timeout VBUS, online=%d", wpc->online);
- if (wpc->online)
- p9221_set_offline();
-
-}
-DECLARE_DEFERRED(p9221_vbus_check_timeout);
-
-static void p9221_set_offline(void)
-{
- CPRINTS("Set offline");
-
- wpc->online = false;
- /* Reset PP buf so we can get a new serial number next time around */
- wpc->pp_buf_valid = false;
-
- p9221_abort_transfers();
-
- hook_call_deferred(&p9221_vbus_check_timeout_data, -1);
-}
-
-/* P9221_NOTIFIER_DELAY_MS from VRECTON */
-static int p9221_notifier_check_det(void)
-{
- if (wpc->online)
- goto done;
-
- /* send out a FOD but is_epp() is still invalid */
- p9221_set_online();
-
- /* Give the vbus 2 seconds to come up. */
- CPRINTS("Waiting VBUS");
- hook_call_deferred(&p9221_vbus_check_timeout_data, -1);
- hook_call_deferred(&p9221_vbus_check_timeout_data,
- P9221_DCIN_TIMEOUT_MS);
-
-done:
- wpc->p9221_check_det = false;
- return 0;
-}
-
-static int p9221_get_charge_supplier(void)
-{
- if (!wpc->online)
- return EC_ERROR_UNKNOWN;
-
- if (p9221_is_epp()) {
- uint32_t tx_id;
- int txmf_id;
- int ret;
-
- wpc->charge_supplier = CHARGE_SUPPLIER_WPC_EPP;
-
- ret = p9221_read16(P9221R7_EPP_TX_MFG_CODE_REG, &txmf_id);
- if (ret || txmf_id != P9221_GPP_TX_MF_ID)
- return ret;
-
- ret = p9221_block_read(P9221R7_PROP_TX_ID_REG,
- (uint8_t *) &tx_id,
- P9221R7_PROP_TX_ID_SIZE);
- if (ret)
- return ret;
-
- if (tx_id & P9221R7_PROP_TX_ID_GPP_MASK)
- wpc->charge_supplier = CHARGE_SUPPLIER_WPC_GPP;
-
- CPRINTS("txmf_id=0x%04x tx_id=0x%08x supplier=%d",
- txmf_id, tx_id, wpc->charge_supplier);
- } else {
- wpc->charge_supplier = CHARGE_SUPPLIER_WPC_BPP;
- CPRINTS("supplier=%d", wpc->charge_supplier);
- }
-
- return EC_SUCCESS;
-}
-
-static int p9221_get_icl(int charge_supplier)
-{
- switch (charge_supplier) {
- case CHARGE_SUPPLIER_WPC_EPP:
- case CHARGE_SUPPLIER_WPC_GPP:
- return P9221_DC_ICL_EPP_MA;
- case CHARGE_SUPPLIER_WPC_BPP:
- default:
- return P9221_DC_ICL_BPP_MA;
- }
-}
-
-static int p9221_get_ivl(int charge_supplier)
-{
- switch (charge_supplier) {
- case CHARGE_SUPPLIER_WPC_EPP:
- case CHARGE_SUPPLIER_WPC_GPP:
- return P9221_DC_IVL_EPP_MV;
- case CHARGE_SUPPLIER_WPC_BPP:
- default:
- return P9221_DC_IVL_BPP_MV;
- }
-}
-
-static void p9221_update_charger(int type, struct charge_port_info *chg)
-{
- if (!chg)
- charge_manager_update_dualrole(0, CAP_UNKNOWN);
- else
- charge_manager_update_dualrole(0, CAP_DEDICATED);
-
- charge_manager_update_charge(type, 0, chg);
-}
-
-static int p9221_reg_write_converted_r7(uint16_t reg, uint32_t val)
-{
- int ret = 0;
- uint16_t data;
- int i;
- /* Do the appropriate conversion */
- switch (reg) {
- case P9221R7_ILIM_SET_REG:
- /* uA -> 0.1A, offset 0.2A */
- if ((val < 200000) || (val > 1600000))
- return -EC_ERROR_INVAL;
- data = (val / (100 * 1000)) - 2;
- break;
- case P9221R7_VOUT_SET_REG:
- /* uV -> 0.1V */
- val /= 1000;
- if (val < 3500 || val > 9000)
- return -EC_ERROR_INVAL;
- data = val / 100;
- break;
- case P9221R7_OVSET_REG:
- /* uV */
- for (i = 0; i < ARRAY_SIZE(p9221_ov_set_lut); i++) {
- if (val == p9221_ov_set_lut[i])
- break;
- }
- if (i == ARRAY_SIZE(p9221_ov_set_lut))
- return -EC_ERROR_INVAL;
- data = i;
- break;
- default:
- return -EC_ERROR_INVAL;
- }
- if (p9221_reg_is_8_bit(reg))
- ret = p9221_write8(reg, data);
- else
- ret = p9221_write16(reg, data);
- return ret;
-}
-
-static int p9221_set_dc_icl(void)
-{
- /* Increase the IOUT limit */
- if (p9221_reg_write_converted_r7(P9221R7_ILIM_SET_REG,
- P9221R7_ILIM_MAX_UA))
- CPRINTS("%s set rx_iout limit fail.", __func__);
-
- return EC_SUCCESS;
-}
-
-
-static void p9221_notifier_check_vbus(void)
-{
- struct charge_port_info chg;
-
- wpc->p9221_check_vbus = false;
-
- CPRINTS("%s online:%d vbus:%d", __func__, wpc->online,
- wpc->vbus_status);
-
- /*
- * We now have confirmation from DC_IN, kill the timer, p9221_online
- * will be set by this function.
- */
- hook_call_deferred(&p9221_vbus_check_timeout_data, -1);
-
- if (wpc->vbus_status) {
- /* WPC VBUS on ,Always write FOD, check dc_icl, send CSP */
- p9221_set_dc_icl();
- p9221_config_fod();
-
- p9221_send_csp(1);
-
- /* when wpc vbus attached after 2s, set wpc online */
- if (!wpc->online)
- p9221_set_online();
-
- /* WPC VBUS on , update charge voltage and current */
- p9221_get_charge_supplier();
- chg.voltage = p9221_get_ivl(wpc->charge_supplier);
- chg.current = p9221_get_icl(wpc->charge_supplier);
-
- p9221_update_charger(wpc->charge_supplier, &chg);
- } else {
- /*
- * Vbus detached, set wpc offline and update wpc charge voltage
- * and current to zero.
- */
- if (wpc->online) {
- p9221_set_offline();
- p9221_update_charger(wpc->charge_supplier, NULL);
- }
- }
-
- CPRINTS("check_vbus changed on:%d vbus:%d", wpc->online,
- wpc->vbus_status);
-
-}
-
-static void p9221_detect_work(void)
-{
-
- CPRINTS("%s online:%d check_vbus:%d check_det:%d vbus:%d", __func__,
- wpc->online, wpc->p9221_check_vbus, wpc->p9221_check_det,
- wpc->vbus_status);
-
- /* Step 1 */
- if (wpc->p9221_check_det)
- p9221_notifier_check_det();
-
- /* Step 2 */
- if (wpc->p9221_check_vbus)
- p9221_notifier_check_vbus();
-
-}
-DECLARE_DEFERRED(p9221_detect_work);
-
-void p9221_notify_vbus_change(int vbus)
-{
- wpc->p9221_check_vbus = true;
- wpc->vbus_status = vbus;
- hook_call_deferred(&p9221_detect_work_data, P9221_NOTIFIER_DELAY_MS);
-}
-
-void wireless_power_charger_task(void *u)
-{
- while (1) {
- int ret, irq_src;
- task_wait_event(-1);
-
- ret = p9221_read16(P9221_INT_REG, &irq_src);
- if (ret) {
- CPRINTS("Failed to read INT REG");
- continue;
- }
-
- CPRINTS("INT SRC 0x%04x", irq_src);
-
- if (p9221r7_clear_interrupts(irq_src))
- continue;
-
- if (irq_src & P9221_STAT_VRECT) {
- CPRINTS("VRECTON, online=%d", wpc->online);
- if (!wpc->online) {
- wpc->p9221_check_det = true;
- hook_call_deferred(&p9221_detect_work_data,
- P9221_NOTIFIER_DELAY_MS);
- }
- }
-
- p9221r7_irq_handler(irq_src);
- }
-}
diff --git a/driver/wpc/p9221.h b/driver/wpc/p9221.h
index 0bb0571b38..53dcc57aa7 100644
--- a/driver/wpc/p9221.h
+++ b/driver/wpc/p9221.h
@@ -1,9 +1,8 @@
-/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+/* Copyright 2018 The ChromiumOS Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
-
/*
* IDT P9221-R7 Wireless Power Receiver driver definitions.
*/
@@ -16,248 +15,243 @@
#include "charge_manager.h"
#include "task.h"
-
/* ========== Variant-specific configuration ============ */
-#define P9221_R7_ADDR_FLAGS 0x61
+#define P9221_R7_ADDR_FLAGS 0x61
/*
* P9221 common registers
*/
-#define P9221_CHIP_ID_REG 0x00
-#define P9221_CHIP_ID 0x9220
-#define P9221_CHIP_REVISION_REG 0x02
-#define P9221_CUSTOMER_ID_REG 0x03
-#define P9221R7_CUSTOMER_ID_VAL 0x05
-#define P9221_OTP_FW_MAJOR_REV_REG 0x04
-#define P9221_OTP_FW_MINOR_REV_REG 0x06
-#define P9221_OTP_FW_DATE_REG 0x08
-#define P9221_OTP_FW_DATE_SIZE 12
-#define P9221_OTP_FW_TIME_REG 0x14
-#define P9221_OTP_FW_TIME_SIZE 8
-#define P9221_SRAM_FW_MAJOR_REV_REG 0x1C
-#define P9221_SRAM_FW_MINOR_REV_REG 0x1E
-#define P9221_SRAM_FW_DATE_REG 0x20
-#define P9221_SRAM_FW_DATE_SIZE 12
-#define P9221_SRAM_FW_TIME_REG 0x2C
-#define P9221_SRAM_FW_TIME_SIZE 8
-#define P9221_STATUS_REG 0x34
-#define P9221_INT_REG 0x36
-#define P9221_INT_MASK 0xF7
-#define P9221_INT_ENABLE_REG 0x38
-#define P9221_GPP_TX_MF_ID 0x0072
+#define P9221_CHIP_ID_REG 0x00
+#define P9221_CHIP_ID 0x9220
+#define P9221_CHIP_REVISION_REG 0x02
+#define P9221_CUSTOMER_ID_REG 0x03
+#define P9221R7_CUSTOMER_ID_VAL 0x05
+#define P9221_OTP_FW_MAJOR_REV_REG 0x04
+#define P9221_OTP_FW_MINOR_REV_REG 0x06
+#define P9221_OTP_FW_DATE_REG 0x08
+#define P9221_OTP_FW_DATE_SIZE 12
+#define P9221_OTP_FW_TIME_REG 0x14
+#define P9221_OTP_FW_TIME_SIZE 8
+#define P9221_SRAM_FW_MAJOR_REV_REG 0x1C
+#define P9221_SRAM_FW_MINOR_REV_REG 0x1E
+#define P9221_SRAM_FW_DATE_REG 0x20
+#define P9221_SRAM_FW_DATE_SIZE 12
+#define P9221_SRAM_FW_TIME_REG 0x2C
+#define P9221_SRAM_FW_TIME_SIZE 8
+#define P9221_STATUS_REG 0x34
+#define P9221_INT_REG 0x36
+#define P9221_INT_MASK 0xF7
+#define P9221_INT_ENABLE_REG 0x38
+#define P9221_GPP_TX_MF_ID 0x0072
/*
* P9221 Rx registers (x != 5)
*/
-#define P9221_CHARGE_STAT_REG 0x3A
-#define P9221_EPT_REG 0x3B
-#define P9221_VOUT_ADC_REG 0x3C
-#define P9221_VOUT_ADC_MASK 0x0FFF
-#define P9221_VOUT_SET_REG 0x3E
-#define P9221_MAX_VOUT_SET_MV_DEFAULT 9000
-#define P9221_VRECT_ADC_REG 0x40
-#define P9221_VRECT_ADC_MASK 0x0FFF
-#define P9221_OVSET_REG 0x42
-#define P9221_OVSET_MASK 0x70
-#define P9221_OVSET_SHIFT 4
-#define P9221_RX_IOUT_REG 0x44
-#define P9221_DIE_TEMP_ADC_REG 0x46
-#define P9221_DIE_TEMP_ADC_MASK 0x0FFF
-#define P9221_OP_FREQ_REG 0x48
-#define P9221_ILIM_SET_REG 0x4A
-#define P9221_ALIGN_X_ADC_REG 0x4B
-#define P9221_ALIGN_Y_ADC_REG 0x4C
-#define P9221_OP_MODE_REG 0x4D
-#define P9221_COM_REG 0x4E
-#define P9221_FW_SWITCH_KEY_REG 0x4F
-#define P9221_INT_CLEAR_REG 0x56
-#define P9221_RXID_REG 0x5C
-#define P9221_RXID_LEN 6
-#define P9221_MPREQ_REG 0x5C
-#define P9221_MPREQ_LEN 6
-#define P9221_FOD_REG 0x68
-#define P9221_NUM_FOD 16
-#define P9221_RX_RAWIOUT_REG 0x7A
-#define P9221_RX_RAWIOUT_MASK 0xFFF
-#define P9221_PMA_AD_REG 0x7C
-#define P9221_RX_PINGFREQ_REG 0xFC
-#define P9221_RX_PINGFREQ_MASK 0xFFF
-#define P9221_LAST_REG 0xFF
+#define P9221_CHARGE_STAT_REG 0x3A
+#define P9221_EPT_REG 0x3B
+#define P9221_VOUT_ADC_REG 0x3C
+#define P9221_VOUT_ADC_MASK 0x0FFF
+#define P9221_VOUT_SET_REG 0x3E
+#define P9221_MAX_VOUT_SET_MV_DEFAULT 9000
+#define P9221_VRECT_ADC_REG 0x40
+#define P9221_VRECT_ADC_MASK 0x0FFF
+#define P9221_OVSET_REG 0x42
+#define P9221_OVSET_MASK 0x70
+#define P9221_OVSET_SHIFT 4
+#define P9221_RX_IOUT_REG 0x44
+#define P9221_DIE_TEMP_ADC_REG 0x46
+#define P9221_DIE_TEMP_ADC_MASK 0x0FFF
+#define P9221_OP_FREQ_REG 0x48
+#define P9221_ILIM_SET_REG 0x4A
+#define P9221_ALIGN_X_ADC_REG 0x4B
+#define P9221_ALIGN_Y_ADC_REG 0x4C
+#define P9221_OP_MODE_REG 0x4D
+#define P9221_COM_REG 0x4E
+#define P9221_FW_SWITCH_KEY_REG 0x4F
+#define P9221_INT_CLEAR_REG 0x56
+#define P9221_RXID_REG 0x5C
+#define P9221_RXID_LEN 6
+#define P9221_MPREQ_REG 0x5C
+#define P9221_MPREQ_LEN 6
+#define P9221_FOD_REG 0x68
+#define P9221_NUM_FOD 16
+#define P9221_RX_RAWIOUT_REG 0x7A
+#define P9221_RX_RAWIOUT_MASK 0xFFF
+#define P9221_PMA_AD_REG 0x7C
+#define P9221_RX_PINGFREQ_REG 0xFC
+#define P9221_RX_PINGFREQ_MASK 0xFFF
+#define P9221_LAST_REG 0xFF
/*
* P9221R7 unique registers
*/
-#define P9221R7_INT_CLEAR_REG 0x3A
-#define P9221R7_VOUT_SET_REG 0x3C
-#define P9221R7_ILIM_SET_REG 0x3D
-#define P9221R7_ILIM_SET_MAX 0x0E /* 0x0E = 1.6A */
-#define P9221R7_CHARGE_STAT_REG 0x3E
-#define P9221R7_EPT_REG 0x3F
-#define P9221R7_VRECT_REG 0x40
-#define P9221R7_VOUT_REG 0x42
-#define P9221R7_IOUT_REG 0x44
-#define P9221R7_OP_FREQ_REG 0x48
-#define P9221R7_SYSTEM_MODE_REG 0x4C
-#define P9221R7_COM_CHAN_RESET_REG 0x50
-#define P9221R7_COM_CHAN_SEND_SIZE_REG 0x58
-#define P9221R7_COM_CHAN_SEND_IDX_REG 0x59
-#define P9221R7_COM_CHAN_RECV_SIZE_REG 0x5A
-#define P9221R7_COM_CHAN_RECV_IDX_REG 0x5B
-#define P9221R7_VRECT_ADC_REG 0x60
-#define P9221R7_VOUT_ADC_REG 0x62
-#define P9221R7_VOUT_ADC_MASK 0xFFF
-#define P9221R7_IOUT_ADC_REG 0x64
-#define P9221R7_IOUT_ADC_MASK 0xFFF
-#define P9221R7_DIE_TEMP_ADC_REG 0x66
-#define P9221R7_DIE_TEMP_ADC_MASK 0xFFF
-#define P9221R7_AC_PERIOD_REG 0x68
-#define P9221R7_TX_PINGFREQ_REG 0x6A
-#define P9221R7_EXT_TEMP_REG 0x6C
-#define P9221R7_EXT_TEMP_MASK 0xFFF
-#define P9221R7_FOD_REG 0x70
-#define P9221R7_NUM_FOD 16
-#define P9221R7_DEBUG_REG 0x80
-#define P9221R7_EPP_Q_FACTOR_REG 0x83
-#define P9221R7_EPP_TX_GUARANTEED_POWER_REG 0x84
-#define P9221R7_EPP_TX_POTENTIAL_POWER_REG 0x85
-#define P9221R7_EPP_TX_CAPABILITY_FLAGS_REG 0x86
-#define P9221R7_EPP_RENEGOTIATION_REG 0x87
-#define P9221R7_EPP_CUR_RPP_HEADER_REG 0x88
-#define P9221R7_EPP_CUR_NEGOTIATED_POWER_REG 0x89
-#define P9221R7_EPP_CUR_MAXIMUM_POWER_REG 0x8A
-#define P9221R7_EPP_CUR_FSK_MODULATION_REG 0x8B
-#define P9221R7_EPP_REQ_RPP_HEADER_REG 0x8C
-#define P9221R7_EPP_REQ_NEGOTIATED_POWER_REG 0x8D
-#define P9221R7_EPP_REQ_MAXIMUM_POWER_REG 0x8E
-#define P9221R7_EPP_REQ_FSK_MODULATION_REG 0x8F
-#define P9221R7_VRECT_TARGET_REG 0x90
-#define P9221R7_VRECT_KNEE_REG 0x92
-#define P9221R7_VRECT_CORRECTION_FACTOR_REG 0x93
-#define P9221R7_VRECT_MAX_CORRECTION_FACTOR_REG 0x94
-#define P9221R7_VRECT_MIN_CORRECTION_FACTOR_REG 0x96
-#define P9221R7_FOD_SECTION_REG 0x99
-#define P9221R7_VRECT_ADJ_REG 0x9E
-#define P9221R7_ALIGN_X_ADC_REG 0xA0
-#define P9221R7_ALIGN_Y_ADC_REG 0xA1
-#define P9221R7_ASK_MODULATION_DEPTH_REG 0xA2
-#define P9221R7_OVSET_REG 0xA3
-#define P9221R7_OVSET_MASK 0x7
-#define P9221R7_EPP_TX_SPEC_REV_REG 0xA9
-#define P9221R7_EPP_TX_MFG_CODE_REG 0xAA
-#define P9221R7_GP0_RESET_VOLT_REG 0xAC
-#define P9221R7_GP1_RESET_VOLT_REG 0xAE
-#define P9221R7_GP2_RESET_VOLT_REG 0xB0
-#define P9221R7_GP3_RESET_VOLT_REG 0xB2
-#define P9221R7_PROP_TX_ID_REG 0xB4
-#define P9221R7_PROP_TX_ID_SIZE 4
-#define P9221R7_DATA_SEND_BUF_START 0x100
-#define P9221R7_DATA_SEND_BUF_SIZE 0x80
-#define P9221R7_DATA_RECV_BUF_START 0x180
-#define P9221R7_DATA_RECV_BUF_SIZE 0x80
-#define P9221R7_MAX_PP_BUF_SIZE 16
-#define P9221R7_LAST_REG 0x1FF
+#define P9221R7_INT_CLEAR_REG 0x3A
+#define P9221R7_VOUT_SET_REG 0x3C
+#define P9221R7_ILIM_SET_REG 0x3D
+#define P9221R7_ILIM_SET_MAX 0x0E /* 0x0E = 1.6A */
+#define P9221R7_CHARGE_STAT_REG 0x3E
+#define P9221R7_EPT_REG 0x3F
+#define P9221R7_VRECT_REG 0x40
+#define P9221R7_VOUT_REG 0x42
+#define P9221R7_IOUT_REG 0x44
+#define P9221R7_OP_FREQ_REG 0x48
+#define P9221R7_SYSTEM_MODE_REG 0x4C
+#define P9221R7_COM_CHAN_RESET_REG 0x50
+#define P9221R7_COM_CHAN_SEND_SIZE_REG 0x58
+#define P9221R7_COM_CHAN_SEND_IDX_REG 0x59
+#define P9221R7_COM_CHAN_RECV_SIZE_REG 0x5A
+#define P9221R7_COM_CHAN_RECV_IDX_REG 0x5B
+#define P9221R7_VRECT_ADC_REG 0x60
+#define P9221R7_VOUT_ADC_REG 0x62
+#define P9221R7_VOUT_ADC_MASK 0xFFF
+#define P9221R7_IOUT_ADC_REG 0x64
+#define P9221R7_IOUT_ADC_MASK 0xFFF
+#define P9221R7_DIE_TEMP_ADC_REG 0x66
+#define P9221R7_DIE_TEMP_ADC_MASK 0xFFF
+#define P9221R7_AC_PERIOD_REG 0x68
+#define P9221R7_TX_PINGFREQ_REG 0x6A
+#define P9221R7_EXT_TEMP_REG 0x6C
+#define P9221R7_EXT_TEMP_MASK 0xFFF
+#define P9221R7_FOD_REG 0x70
+#define P9221R7_NUM_FOD 16
+#define P9221R7_DEBUG_REG 0x80
+#define P9221R7_EPP_Q_FACTOR_REG 0x83
+#define P9221R7_EPP_TX_GUARANTEED_POWER_REG 0x84
+#define P9221R7_EPP_TX_POTENTIAL_POWER_REG 0x85
+#define P9221R7_EPP_TX_CAPABILITY_FLAGS_REG 0x86
+#define P9221R7_EPP_RENEGOTIATION_REG 0x87
+#define P9221R7_EPP_CUR_RPP_HEADER_REG 0x88
+#define P9221R7_EPP_CUR_NEGOTIATED_POWER_REG 0x89
+#define P9221R7_EPP_CUR_MAXIMUM_POWER_REG 0x8A
+#define P9221R7_EPP_CUR_FSK_MODULATION_REG 0x8B
+#define P9221R7_EPP_REQ_RPP_HEADER_REG 0x8C
+#define P9221R7_EPP_REQ_NEGOTIATED_POWER_REG 0x8D
+#define P9221R7_EPP_REQ_MAXIMUM_POWER_REG 0x8E
+#define P9221R7_EPP_REQ_FSK_MODULATION_REG 0x8F
+#define P9221R7_VRECT_TARGET_REG 0x90
+#define P9221R7_VRECT_KNEE_REG 0x92
+#define P9221R7_VRECT_CORRECTION_FACTOR_REG 0x93
+#define P9221R7_VRECT_MAX_CORRECTION_FACTOR_REG 0x94
+#define P9221R7_VRECT_MIN_CORRECTION_FACTOR_REG 0x96
+#define P9221R7_FOD_SECTION_REG 0x99
+#define P9221R7_VRECT_ADJ_REG 0x9E
+#define P9221R7_ALIGN_X_ADC_REG 0xA0
+#define P9221R7_ALIGN_Y_ADC_REG 0xA1
+#define P9221R7_ASK_MODULATION_DEPTH_REG 0xA2
+#define P9221R7_OVSET_REG 0xA3
+#define P9221R7_OVSET_MASK 0x7
+#define P9221R7_EPP_TX_SPEC_REV_REG 0xA9
+#define P9221R7_EPP_TX_MFG_CODE_REG 0xAA
+#define P9221R7_GP0_RESET_VOLT_REG 0xAC
+#define P9221R7_GP1_RESET_VOLT_REG 0xAE
+#define P9221R7_GP2_RESET_VOLT_REG 0xB0
+#define P9221R7_GP3_RESET_VOLT_REG 0xB2
+#define P9221R7_PROP_TX_ID_REG 0xB4
+#define P9221R7_PROP_TX_ID_SIZE 4
+#define P9221R7_DATA_SEND_BUF_START 0x100
+#define P9221R7_DATA_SEND_BUF_SIZE 0x80
+#define P9221R7_DATA_RECV_BUF_START 0x180
+#define P9221R7_DATA_RECV_BUF_SIZE 0x80
+#define P9221R7_MAX_PP_BUF_SIZE 16
+#define P9221R7_LAST_REG 0x1FF
/*
* System Mode Mask (r7+/0x4C)
*/
-#define P9221R7_SYSTEM_MODE_EXTENDED_MASK (1 << 3)
+#define P9221R7_SYSTEM_MODE_EXTENDED_MASK (1 << 3)
/*
* TX ID GPP Mask (r7+/0xB4->0xB7)
*/
-#define P9221R7_PROP_TX_ID_GPP_MASK (1 << 29)
+#define P9221R7_PROP_TX_ID_GPP_MASK (1 << 29)
/*
* Com Channel Commands
*/
-#define P9221R7_COM_CHAN_CCRESET BIT(7)
-#define P9221_COM_CHAN_RETRIES 5
+#define P9221R7_COM_CHAN_CCRESET BIT(7)
+#define P9221_COM_CHAN_RETRIES 5
/*
* End of Power packet types
*/
-#define P9221_EOP_UNKNOWN 0x00
-#define P9221_EOP_EOC 0x01
-#define P9221_EOP_INTERNAL_FAULT 0x02
-#define P9221_EOP_OVER_TEMP 0x03
-#define P9221_EOP_OVER_VOLT 0x04
-#define P9221_EOP_OVER_CURRENT 0x05
-#define P9221_EOP_BATT_FAIL 0x06
-#define P9221_EOP_RECONFIG 0x07
-#define P9221_EOP_NO_RESPONSE 0x08
-#define P9221_EOP_NEGOTIATION_FAIL 0x0A
-#define P9221_EOP_RESTART_POWER 0x0B
+#define P9221_EOP_UNKNOWN 0x00
+#define P9221_EOP_EOC 0x01
+#define P9221_EOP_INTERNAL_FAULT 0x02
+#define P9221_EOP_OVER_TEMP 0x03
+#define P9221_EOP_OVER_VOLT 0x04
+#define P9221_EOP_OVER_CURRENT 0x05
+#define P9221_EOP_BATT_FAIL 0x06
+#define P9221_EOP_RECONFIG 0x07
+#define P9221_EOP_NO_RESPONSE 0x08
+#define P9221_EOP_NEGOTIATION_FAIL 0x0A
+#define P9221_EOP_RESTART_POWER 0x0B
/*
* Command flags
*/
-#define P9221R7_COM_RENEGOTIATE P9221_COM_RENEGOTIATE
-#define P9221R7_COM_SWITCH2RAM P9221_COM_SWITCH_TO_RAM_MASK
-#define P9221R7_COM_CLRINT P9221_COM_CLEAR_INT_MASK
-#define P9221R7_COM_SENDCSP P9221_COM_SEND_CHG_STAT_MASK
-#define P9221R7_COM_SENDEPT P9221_COM_SEND_EOP_MASK
-#define P9221R7_COM_LDOTGL P9221_COM_LDO_TOGGLE
-#define P9221R7_COM_CCACTIVATE BIT(0)
+#define P9221R7_COM_RENEGOTIATE P9221_COM_RENEGOTIATE
+#define P9221R7_COM_SWITCH2RAM P9221_COM_SWITCH_TO_RAM_MASK
+#define P9221R7_COM_CLRINT P9221_COM_CLEAR_INT_MASK
+#define P9221R7_COM_SENDCSP P9221_COM_SEND_CHG_STAT_MASK
+#define P9221R7_COM_SENDEPT P9221_COM_SEND_EOP_MASK
+#define P9221R7_COM_LDOTGL P9221_COM_LDO_TOGGLE
+#define P9221R7_COM_CCACTIVATE BIT(0)
-#define P9221_COM_RENEGOTIATE BIT(7)
-#define P9221_COM_SWITCH_TO_RAM_MASK BIT(6)
-#define P9221_COM_CLEAR_INT_MASK BIT(5)
-#define P9221_COM_SEND_CHG_STAT_MASK BIT(4)
-#define P9221_COM_SEND_EOP_MASK BIT(3)
-#define P9221_COM_LDO_TOGGLE BIT(1)
+#define P9221_COM_RENEGOTIATE BIT(7)
+#define P9221_COM_SWITCH_TO_RAM_MASK BIT(6)
+#define P9221_COM_CLEAR_INT_MASK BIT(5)
+#define P9221_COM_SEND_CHG_STAT_MASK BIT(4)
+#define P9221_COM_SEND_EOP_MASK BIT(3)
+#define P9221_COM_LDO_TOGGLE BIT(1)
/*
* Interrupt/Status flags for P9221
*/
-#define P9221_STAT_VOUT BIT(7)
-#define P9221_STAT_VRECT BIT(6)
-#define P9221_STAT_ACMISSING BIT(5)
-#define P9221_STAT_OV_TEMP BIT(2)
-#define P9221_STAT_OV_VOLT BIT(1)
-#define P9221_STAT_OV_CURRENT BIT(0)
-#define P9221_STAT_LIMIT_MASK (P9221_STAT_OV_TEMP | \
- P9221_STAT_OV_VOLT | \
- P9221_STAT_OV_CURRENT)
+#define P9221_STAT_VOUT BIT(7)
+#define P9221_STAT_VRECT BIT(6)
+#define P9221_STAT_ACMISSING BIT(5)
+#define P9221_STAT_OV_TEMP BIT(2)
+#define P9221_STAT_OV_VOLT BIT(1)
+#define P9221_STAT_OV_CURRENT BIT(0)
+#define P9221_STAT_LIMIT_MASK \
+ (P9221_STAT_OV_TEMP | P9221_STAT_OV_VOLT | P9221_STAT_OV_CURRENT)
/*
* Interrupt/Status flags for P9221R7
*/
-#define P9221R7_STAT_CCRESET BIT(12)
-#define P9221R7_STAT_CCERROR BIT(11)
-#define P9221R7_STAT_PPRCVD BIT(10)
-#define P9221R7_STAT_CCDATARCVD BIT(9)
-#define P9221R7_STAT_CCSENDBUSY BIT(8)
-#define P9221R7_STAT_VOUTCHANGED BIT(7)
-#define P9221R7_STAT_VRECTON BIT(6)
-#define P9221R7_STAT_MODECHANGED BIT(5)
-#define P9221R7_STAT_UV BIT(3)
-#define P9221R7_STAT_OVT BIT(2)
-#define P9221R7_STAT_OVV BIT(1)
-#define P9221R7_STAT_OVC BIT(0)
-#define P9221R7_STAT_MASK 0x1FFF
-#define P9221R7_STAT_CC_MASK (P9221R7_STAT_CCRESET | \
- P9221R7_STAT_PPRCVD | \
- P9221R7_STAT_CCERROR | \
- P9221R7_STAT_CCDATARCVD | \
- P9221R7_STAT_CCSENDBUSY)
-#define P9221R7_STAT_LIMIT_MASK (P9221R7_STAT_UV | \
- P9221R7_STAT_OVV | \
- P9221R7_STAT_OVT | \
- P9221R7_STAT_OVC)
+#define P9221R7_STAT_CCRESET BIT(12)
+#define P9221R7_STAT_CCERROR BIT(11)
+#define P9221R7_STAT_PPRCVD BIT(10)
+#define P9221R7_STAT_CCDATARCVD BIT(9)
+#define P9221R7_STAT_CCSENDBUSY BIT(8)
+#define P9221R7_STAT_VOUTCHANGED BIT(7)
+#define P9221R7_STAT_VRECTON BIT(6)
+#define P9221R7_STAT_MODECHANGED BIT(5)
+#define P9221R7_STAT_UV BIT(3)
+#define P9221R7_STAT_OVT BIT(2)
+#define P9221R7_STAT_OVV BIT(1)
+#define P9221R7_STAT_OVC BIT(0)
+#define P9221R7_STAT_MASK 0x1FFF
+#define P9221R7_STAT_CC_MASK \
+ (P9221R7_STAT_CCRESET | P9221R7_STAT_PPRCVD | P9221R7_STAT_CCERROR | \
+ P9221R7_STAT_CCDATARCVD | P9221R7_STAT_CCSENDBUSY)
+#define P9221R7_STAT_LIMIT_MASK \
+ (P9221R7_STAT_UV | P9221R7_STAT_OVV | P9221R7_STAT_OVT | \
+ P9221R7_STAT_OVC)
-#define P9221_DC_ICL_BPP_MA 1000
-#define P9221_DC_ICL_EPP_MA 1100
-#define P9221_DC_IVL_BPP_MV 5000
-#define P9221_DC_IVL_EPP_MV 9000
-#define P9221_EPP_THRESHOLD_UV 7000000
+#define P9221_DC_ICL_BPP_MA 1000
+#define P9221_DC_ICL_EPP_MA 1100
+#define P9221_DC_IVL_BPP_MV 5000
+#define P9221_DC_IVL_EPP_MV 9000
+#define P9221_EPP_THRESHOLD_UV 7000000
-#define true 1
-#define false 0
+#define true 1
+#define false 0
struct wpc_charger_info {
- uint8_t online; /* wpc is online */
- uint8_t cust_id; /* customer id */
- uint8_t i2c_port; /* i2c port */
+ uint8_t online; /* wpc is online */
+ uint8_t cust_id; /* customer id */
+ uint8_t i2c_port; /* i2c port */
/* Proprietary Packets receive buffer, to get Proprietary data from TX*/
uint8_t pp_buf[P9221R7_MAX_PP_BUF_SIZE];
uint8_t pp_buf_valid;
@@ -267,8 +261,8 @@ struct wpc_charger_info {
uint8_t rx_done;
/* Message packets send buffer, used when send messages from RX to TX*/
uint8_t tx_buf[P9221R7_DATA_SEND_BUF_SIZE];
- uint8_t tx_id; /* TX device id */
- uint8_t tx_len; /* The data size need send to TX */
+ uint8_t tx_id; /* TX device id */
+ uint8_t tx_len; /* The data size need send to TX */
uint8_t tx_done; /* TX data send has done */
uint8_t tx_busy; /* when tx_busy=1, can't transfer data from RX to TX */
/* p9221_check_vbus=1 when VBUS has changed, need update charge state */