diff options
-rw-r--r-- | driver/usb_mux/ps8822.c | 50 | ||||
-rw-r--r-- | driver/usb_mux/ps8822.h | 27 |
2 files changed, 67 insertions, 10 deletions
diff --git a/driver/usb_mux/ps8822.c b/driver/usb_mux/ps8822.c index 43ea22de3d..f7a60df6fa 100644 --- a/driver/usb_mux/ps8822.c +++ b/driver/usb_mux/ps8822.c @@ -12,16 +12,45 @@ #include "usb_mux.h" #include "util.h" -static int ps8822_read(const struct usb_mux *me, uint8_t reg, int *val) +static int ps8822_read(const struct usb_mux *me, int page, uint8_t reg, + int *val) { - return i2c_read8(me->i2c_port, me->i2c_addr_flags, + return i2c_read8(me->i2c_port, me->i2c_addr_flags + page, reg, val); } -static int ps8822_write(const struct usb_mux *me, uint8_t reg, uint8_t val) +static int ps8822_write(const struct usb_mux *me, int page, uint8_t reg, + int val) { - return i2c_write8(me->i2c_port, me->i2c_addr_flags, - reg, val); + return i2c_write8(me->i2c_port, me->i2c_addr_flags + page, + reg, val); +} + +int ps8822_set_dp_rx_eq(const struct usb_mux *me, int db) +{ + int dpeq_reg; + int rv; + + /* Read DP EQ register */ + rv = ps8822_read(me, PS8822_REG_PAGE1, PS8822_REG_DP_EQ, + &dpeq_reg); + if (rv) + return rv; + + if (db < PS8822_DPEQ_LEVEL_UP_9DB || db > PS8822_DPEQ_LEVEL_UP_21DB) + return EC_ERROR_INVAL; + + /* Disable auto eq */ + dpeq_reg &= ~PS8822_DP_EQ_AUTO_EN; + + /* Set gain to the requested value */ + dpeq_reg &= ~(PS8822_DPEQ_LEVEL_UP_MASK << + PS8822_REG_DP_EQ_SHIFT); + dpeq_reg |= (db << PS8822_REG_DP_EQ_SHIFT); + + /* Apply new EQ setting */ + return ps8822_write(me, PS8822_REG_PAGE1, PS8822_REG_DP_EQ, + dpeq_reg); } static int ps8822_init(const struct usb_mux *me) @@ -33,7 +62,8 @@ static int ps8822_init(const struct usb_mux *me) /* Read ID registers */ for (i = 0; i < PS8822_ID_LEN; i++) { - rv |= ps8822_read(me, PS8822_REG_DEV_ID1 + i, ®); + rv |= ps8822_read(me, PS8822_REG_PAGE0, PS8822_REG_DEV_ID1 + i, + ®); if (!rv) id[i] = reg; } @@ -41,7 +71,7 @@ static int ps8822_init(const struct usb_mux *me) if (!rv) { id[PS8822_ID_LEN] = '\0'; /* Set mode register to default value */ - rv = ps8822_write(me, PS8822_REG_MODE, 0); + rv = ps8822_write(me, PS8822_REG_PAGE0, PS8822_REG_MODE, 0); rv |= strcasecmp("PS8822", id); } @@ -54,7 +84,7 @@ static int ps8822_set_mux(const struct usb_mux *me, mux_state_t mux_state) int reg; int rv; - rv = ps8822_read(me, PS8822_REG_MODE, ®); + rv = ps8822_read(me, PS8822_REG_PAGE0, PS8822_REG_MODE, ®); if (rv) return rv; @@ -68,7 +98,7 @@ static int ps8822_set_mux(const struct usb_mux *me, mux_state_t mux_state) if (mux_state & USB_PD_MUX_POLARITY_INVERTED) reg |= PS8822_MODE_FLIP; - return ps8822_write(me, PS8822_REG_MODE, reg); + return ps8822_write(me, PS8822_REG_PAGE0, PS8822_REG_MODE, reg); } /* Reads control register and updates mux_state accordingly */ @@ -77,7 +107,7 @@ static int ps8822_get_mux(const struct usb_mux *me, mux_state_t *mux_state) int reg; int res; - res = ps8822_read(me, PS8822_REG_MODE, ®); + res = ps8822_read(me, PS8822_REG_PAGE0, PS8822_REG_MODE, ®); if (res) return res; diff --git a/driver/usb_mux/ps8822.h b/driver/usb_mux/ps8822.h index d37e0600f5..86b911db70 100644 --- a/driver/usb_mux/ps8822.h +++ b/driver/usb_mux/ps8822.h @@ -16,6 +16,8 @@ #define PS8822_I2C_ADDR2_FLAG 0x58 #define PS8822_I2C_ADDR3_FLAG 0x60 +#define PS8822_REG_PAGE0 0x00 + /* Mode register for setting mux */ #define PS8822_REG_MODE 0x01 #define PS8822_MODE_ALT_DP_EN BIT(7) @@ -36,4 +38,29 @@ #define PS8822_ID_LEN 6 +#define PS8822_REG_PAGE1 0x01 +#define PS8822_REG_DP_EQ 0xB6 +#define PS8822_DP_EQ_AUTO_EN BIT(7) + +#define PS8822_DPEQ_LEVEL_UP_9DB 0x00 +#define PS8822_DPEQ_LEVEL_UP_11DB 0x01 +#define PS8822_DPEQ_LEVEL_UP_12DB 0x02 +#define PS8822_DPEQ_LEVEL_UP_14DB 0x03 +#define PS8822_DPEQ_LEVEL_UP_17DB 0x04 +#define PS8822_DPEQ_LEVEL_UP_18DB 0x05 +#define PS8822_DPEQ_LEVEL_UP_19DB 0x06 +#define PS8822_DPEQ_LEVEL_UP_20DB 0x07 +#define PS8822_DPEQ_LEVEL_UP_21DB 0x08 +#define PS8822_DPEQ_LEVEL_UP_MASK 0x0F +#define PS8822_REG_DP_EQ_SHIFT 3 + +/** + * Set DP Rx Equalization value + * + * @param *me pointer to usb_mux descriptor + * @param db requested gain setting for DP Rx path + * @return EC_SUCCESS if db param is valid and I2C is successful + */ +int ps8822_set_dp_rx_eq(const struct usb_mux *me, int db); + #endif /* __CROS_EC_PS8822_H */ |