Re: Adding tps65986 to your tps6598x driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Apr 22, 2020 at 04:25:36PM +0300, Heikki Krogerus wrote:
> I'm attaching a diff that has all the changes that you should need to
> do to the tps6598x.c in order to get the role swapping working on your
> board.

Trying again...

-- 
heikki
diff --git a/drivers/usb/typec/tps6598x.c b/drivers/usb/typec/tps6598x.c
index 0698addd1185..5f51397f0007 100644
--- a/drivers/usb/typec/tps6598x.c
+++ b/drivers/usb/typec/tps6598x.c
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/regmap.h>
 #include <linux/interrupt.h>
+#include <linux/usb/role.h>
 #include <linux/usb/typec.h>
 
 /* Register offsets */
@@ -94,6 +95,8 @@ struct tps6598x {
 	struct typec_port *port;
 	struct typec_partner *partner;
 	struct usb_pd_identity partner_identity;
+
+	struct usb_role_switch *role_sw;
 };
 
 /*
@@ -175,6 +178,18 @@ tps6598x_write_4cc(struct tps6598x *tps, u8 reg, const char *val)
 	return tps6598x_block_write(tps, reg, val, 4);
 }
 
+static int tps6598x_set_data_role(struct tps6598x *tps,
+				  enum typec_data_role role)
+{
+	enum usb_role usb_role;
+
+	usb_role = role == TYPEC_HOST ? USB_ROLE_HOST : USB_ROLE_DEVICE;
+
+	typec_set_data_role(tps->port, role);
+
+	return usb_role_switch_set_role(tps->role_sw, usb_role);
+}
+
 static int tps6598x_read_partner_identity(struct tps6598x *tps)
 {
 	struct tps6598x_rx_identity_reg id;
@@ -220,7 +235,7 @@ static int tps6598x_connect(struct tps6598x *tps, u32 status)
 	typec_set_pwr_opmode(tps->port, mode);
 	typec_set_pwr_role(tps->port, TPS_STATUS_PORTROLE(status));
 	typec_set_vconn_role(tps->port, TPS_STATUS_VCONN(status));
-	typec_set_data_role(tps->port, TPS_STATUS_DATAROLE(status));
+	tps6598x_set_data_role(tps, TPS_STATUS_DATAROLE(status));
 
 	tps->partner = typec_register_partner(tps->port, &desc);
 	if (IS_ERR(tps->partner))
@@ -241,6 +256,7 @@ static void tps6598x_disconnect(struct tps6598x *tps, u32 status)
 	typec_set_pwr_role(tps->port, TPS_STATUS_PORTROLE(status));
 	typec_set_vconn_role(tps->port, TPS_STATUS_VCONN(status));
 	typec_set_data_role(tps->port, TPS_STATUS_DATAROLE(status));
+	usb_role_switch_set_role(tps->role_sw, USB_ROLE_NONE);
 }
 
 static int tps6598x_exec_cmd(struct tps6598x *tps, const char *cmd,
@@ -328,7 +344,7 @@ static int tps6598x_dr_set(struct typec_port *port, enum typec_data_role role)
 		goto out_unlock;
 	}
 
-	typec_set_data_role(tps->port, role);
+	ret = tps6598x_set_data_role(tps, role);
 
 out_unlock:
 	mutex_unlock(&tps->lock);
@@ -472,6 +488,10 @@ static int tps6598x_probe(struct i2c_client *client)
 	if (ret < 0 || !vid)
 		return -ENODEV;
 
+	tps->role_sw = usb_role_switch_get(&client->dev);
+	if (IS_ERR(tps->role_sw))
+		return PTR_ERR(tps->role_sw);
+
 	/*
 	 * Checking can the adapter handle SMBus protocol. If it can not, the
 	 * driver needs to take care of block reads separately.

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux