aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/typec/tcpm/tcpci_maxim.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--drivers/usb/typec/tcpm/tcpci_maxim.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/drivers/usb/typec/tcpm/tcpci_maxim.c b/drivers/usb/typec/tcpm/tcpci_maxim.c
index 319266329b42..041a1c393594 100644
--- a/drivers/usb/typec/tcpm/tcpci_maxim.c
+++ b/drivers/usb/typec/tcpm/tcpci_maxim.c
@@ -5,13 +5,10 @@
* MAXIM TCPCI based TCPC driver
*/
-#include <linux/gpio.h>
-#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/of_gpio.h>
#include <linux/regmap.h>
#include <linux/usb/pd.h>
#include <linux/usb/tcpm.h>
@@ -22,6 +19,9 @@
#define PD_ACTIVITY_TIMEOUT_MS 10000
#define TCPC_VENDOR_ALERT 0x80
+#define TCPC_VENDOR_USBSW_CTRL 0x93
+#define TCPC_VENDOR_USBSW_CTRL_ENABLE_USB_DATA 0x9
+#define TCPC_VENDOR_USBSW_CTRL_DISABLE_USB_DATA 0
#define TCPC_RECEIVE_BUFFER_COUNT_OFFSET 0
#define TCPC_RECEIVE_BUFFER_FRAME_TYPE_OFFSET 1
@@ -158,7 +158,7 @@ static void process_rx(struct max_tcpci_chip *chip, u16 status)
*/
ret = regmap_raw_read(chip->data.regmap, TCPC_RX_BYTE_CNT, rx_buf, 2);
if (ret < 0) {
- dev_err(chip->dev, "TCPC_RX_BYTE_CNT read failed ret:%d", ret);
+ dev_err(chip->dev, "TCPC_RX_BYTE_CNT read failed ret:%d\n", ret);
return;
}
@@ -167,13 +167,13 @@ static void process_rx(struct max_tcpci_chip *chip, u16 status)
if (count == 0 || frame_type != TCPC_RX_BUF_FRAME_TYPE_SOP) {
max_tcpci_write16(chip, TCPC_ALERT, TCPC_ALERT_RX_STATUS);
- dev_err(chip->dev, "%s", count == 0 ? "error: count is 0" :
+ dev_err(chip->dev, "%s\n", count == 0 ? "error: count is 0" :
"error frame_type is not SOP");
return;
}
if (count > sizeof(struct pd_message) || count + 1 > TCPC_RECEIVE_BUFFER_LEN) {
- dev_err(chip->dev, "Invalid TCPC_RX_BYTE_CNT %d", count);
+ dev_err(chip->dev, "Invalid TCPC_RX_BYTE_CNT %d\n", count);
return;
}
@@ -184,7 +184,7 @@ static void process_rx(struct max_tcpci_chip *chip, u16 status)
count += 1;
ret = regmap_raw_read(chip->data.regmap, TCPC_RX_BYTE_CNT, rx_buf, count);
if (ret < 0) {
- dev_err(chip->dev, "Error: TCPC_RX_BYTE_CNT read failed: %d", ret);
+ dev_err(chip->dev, "Error: TCPC_RX_BYTE_CNT read failed: %d\n", ret);
return;
}
@@ -277,6 +277,21 @@ static void process_tx(struct max_tcpci_chip *chip, u16 status)
max_tcpci_init_regs(chip);
}
+/* Enable USB switches when partner is USB communications capable */
+static void max_tcpci_set_partner_usb_comm_capable(struct tcpci *tcpci, struct tcpci_data *data,
+ bool capable)
+{
+ struct max_tcpci_chip *chip = tdata_to_max_tcpci(data);
+ int ret;
+
+ ret = max_tcpci_write8(chip, TCPC_VENDOR_USBSW_CTRL, capable ?
+ TCPC_VENDOR_USBSW_CTRL_ENABLE_USB_DATA :
+ TCPC_VENDOR_USBSW_CTRL_DISABLE_USB_DATA);
+
+ if (ret < 0)
+ dev_err(chip->dev, "Failed to enable USB switches");
+}
+
static irqreturn_t _max_tcpci_irq(struct max_tcpci_chip *chip, u16 status)
{
u16 mask;
@@ -317,7 +332,7 @@ static irqreturn_t _max_tcpci_irq(struct max_tcpci_chip *chip, u16 status)
return ret;
if (reg_status & TCPC_SINK_FAST_ROLE_SWAP) {
- dev_info(chip->dev, "FRS Signal");
+ dev_info(chip->dev, "FRS Signal\n");
tcpm_sink_frs(chip->port);
}
}
@@ -456,12 +471,12 @@ static int max_tcpci_probe(struct i2c_client *client, const struct i2c_device_id
chip->data.frs_sourcing_vbus = max_tcpci_frs_sourcing_vbus;
chip->data.auto_discharge_disconnect = true;
chip->data.vbus_vsafe0v = true;
+ chip->data.set_partner_usb_comm_capable = max_tcpci_set_partner_usb_comm_capable;
max_tcpci_init_regs(chip);
chip->tcpci = tcpci_register_port(chip->dev, &chip->data);
if (IS_ERR(chip->tcpci)) {
- dev_err(&client->dev, "TCPCI port registration failed");
- ret = PTR_ERR(chip->tcpci);
+ dev_err(&client->dev, "TCPCI port registration failed\n");
return PTR_ERR(chip->tcpci);
}
chip->port = tcpci_get_tcpm_port(chip->tcpci);