All of lore.kernel.org
 help / color / mirror / Atom feed
From: Angus Ainslie <angus@akkea.ca>
To: Chanwoo Choi <cw00.choi@samsung.com>
Cc: kernel@puri.sm, MyungJoo Ham <myungjoo.ham@samsung.com>,
	Heikki Krogerus <heikki.krogerus@linux.intel.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org,
	bryan.odonoghue@linaro.org
Subject: Re: [PATCH 2/4] usb: typec: tps6589x: register as an extcon provider
Date: Tue, 15 Sep 2020 06:32:51 -0700	[thread overview]
Message-ID: <b2e011b9d565bf73975a746d02429b9d@akkea.ca> (raw)
In-Reply-To: <8e7247d6-9a4f-dc22-971f-9a253c159a37@samsung.com>

Hi,

On 2020-09-14 18:19, Chanwoo Choi wrote:
> Hi,
> 
> On 9/15/20 1:46 AM, Angus Ainslie wrote:
>> The tps6598x type C chip can negotiate the VBUS sink/source status as
>> well as the VBUS voltage and current. Notify the extcon consumers of
>> these changes.
>> 
>> Signed-off-by: Angus Ainslie <angus@akkea.ca>
>> ---
>>  drivers/usb/typec/tps6598x.c | 138 
>> +++++++++++++++++++++++++++++++++++
>>  1 file changed, 138 insertions(+)
>> 
>> diff --git a/drivers/usb/typec/tps6598x.c 
>> b/drivers/usb/typec/tps6598x.c
>> index 3db33bb622c3..3b06d43c810d 100644
>> --- a/drivers/usb/typec/tps6598x.c
>> +++ b/drivers/usb/typec/tps6598x.c
>> @@ -8,6 +8,8 @@
>> 
>>  #include <linux/i2c.h>
>>  #include <linux/acpi.h>
>> +#include <linux/extcon.h>
>> +#include <linux/extcon-provider.h>
>>  #include <linux/module.h>
>>  #include <linux/regmap.h>
>>  #include <linux/interrupt.h>
>> @@ -95,7 +97,12 @@ struct tps6598x {
>>  	struct typec_port *port;
>>  	struct typec_partner *partner;
>>  	struct usb_pd_identity partner_identity;
>> +
>>  	struct usb_role_switch *role_sw;
>> +
>> +#ifdef CONFIG_EXTCON
> 
> Is it necessary of 'ifdef CONFIG_EXTCON'?
> If you just add 'select EXTCON' for this driver,
> you don't need to check CONFIG_EXTCON.
> 
> If any device driver need some framework,
> we can add the 'select EXTCON'.
> 

Sure I can change that for v2

Angus

>> +	struct extcon_dev *edev;
>> +#endif
>>  };
>> 
>>  /*
>> @@ -209,6 +216,62 @@ static void tps6598x_set_data_role(struct 
>> tps6598x *tps,
>>  	typec_set_data_role(tps->port, role);
>>  }
>> 
>> +#ifdef CONFIG_EXTCON
>> +static void tps6589x_set_extcon_state(struct tps6598x *tps,
>> +				      u32 status, u16 pwr_status, bool state)
>> +{
>> +	union extcon_property_value val;
>> +	int max_current;
>> +
>> +	if (TPS_STATUS_DATAROLE(status)) {
>> +		extcon_set_state(tps->edev, EXTCON_USB, false);
>> +		extcon_set_state(tps->edev, EXTCON_USB_HOST, state);
>> +	} else {
>> +		extcon_set_state(tps->edev, EXTCON_USB, state);
>> +		extcon_set_state(tps->edev, EXTCON_USB_HOST, false);
>> +	}
>> +
>> +	val.intval = TPS_STATUS_PORTROLE(status);
>> +	extcon_set_property(tps->edev, EXTCON_USB_HOST,
>> +			    EXTCON_PROP_USB_VBUS_SRC,
>> +			    val);
>> +
>> +	extcon_set_property(tps->edev, EXTCON_USB,
>> +			    EXTCON_PROP_USB_VBUS_SRC,
>> +			    val);
>> +
>> +	switch (TPS_POWER_STATUS_PWROPMODE(pwr_status)) {
>> +	case TYPEC_PWR_MODE_USB:
>> +		max_current = 500;
>> +		extcon_set_state(tps->edev, EXTCON_CHG_USB_SDP, state);
>> +		extcon_set_state(tps->edev, EXTCON_CHG_USB_SLOW, state);
>> +		break;
>> +	case TYPEC_PWR_MODE_1_5A:
>> +		max_current = 1500;
>> +		break;
>> +	case TYPEC_PWR_MODE_3_0A:
>> +		max_current = 3000;
>> +		break;
>> +	case TYPEC_PWR_MODE_PD:
>> +		max_current = 500;
>> +		break;
>> +	}
>> +
>> +	val.intval = max_current;
>> +	extcon_set_property(tps->edev, EXTCON_USB,
>> +			    EXTCON_PROP_USB_VBUS_CURRENT,
>> +			    val);
>> +	extcon_set_property(tps->edev, EXTCON_USB_HOST,
>> +			    EXTCON_PROP_USB_VBUS_CURRENT,
>> +			    val);
>> +
>> +	extcon_sync(tps->edev, EXTCON_USB);
>> +	extcon_sync(tps->edev, EXTCON_USB_HOST);
>> +	extcon_sync(tps->edev, EXTCON_CHG_USB_SDP);
>> +	extcon_sync(tps->edev, EXTCON_CHG_USB_SLOW);
>> +}
>> +#endif
>> +
>>  static int tps6598x_connect(struct tps6598x *tps, u32 status)
>>  {
>>  	struct typec_partner_desc desc;
>> @@ -248,18 +311,41 @@ static int tps6598x_connect(struct tps6598x 
>> *tps, u32 status)
>>  	if (desc.identity)
>>  		typec_partner_set_identity(tps->partner);
>> 
>> +#ifdef CONFIG_EXTCON
>> +	tps6598x_set_extcon_state(tps, status, pwr_status, true);
>> +#endif
>> +
>>  	return 0;
>>  }
>> 
>>  static void tps6598x_disconnect(struct tps6598x *tps, u32 status)
>>  {
>> +	enum typec_pwr_opmode mode;
>> +	u16 pwr_status;
>> +	int ret;
>> +
>>  	if (!IS_ERR(tps->partner))
>>  		typec_unregister_partner(tps->partner);
>>  	tps->partner = NULL;
>>  	typec_set_pwr_opmode(tps->port, TYPEC_PWR_MODE_USB);
>>  	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), false);
>> +
>> +	ret = tps6598x_read16(tps, TPS_REG_POWER_STATUS, &pwr_status);
>> +	if (ret < 0)
>> +		return;
>> +
>> +	mode = TPS_POWER_STATUS_PWROPMODE(pwr_status);
>> +
>> +	dev_dbg(tps->dev, "%s: mode 0x%x pwr_role %d vconn_role %d data_role 
>> %d\n",
>> +		__func__, mode, TPS_STATUS_PORTROLE(status),
>> +		TPS_STATUS_VCONN(status), TPS_STATUS_DATAROLE(status));
>> +
>> +#ifdef CONFIG_EXTCON
>> +	tps6598x_set_extcon_state(tps, status, 0, false);
>> +#endif
>>  }
>> 
>>  static int tps6598x_exec_cmd(struct tps6598x *tps, const char *cmd,
>> @@ -407,6 +493,9 @@ static irqreturn_t tps6598x_interrupt(int irq, 
>> void *data)
>>  		goto err_unlock;
>>  	}
>> 
>> +	dev_dbg(tps->dev, "Received irq event: 0x%llx: 0x%x 0x%x", event1,
>> +	       (u32)((event1 & 0xFFFFFFFF00000000) >> 32), (u32)(event1 & 
>> 0xFFFFFFFF));
>> +
>>  	ret = tps6598x_read32(tps, TPS_REG_STATUS, &status);
>>  	if (ret) {
>>  		dev_err(tps->dev, "%s: failed to read status\n", __func__);
>> @@ -467,6 +556,18 @@ static const struct regmap_config 
>> tps6598x_regmap_config = {
>>  	.max_register = 0x7F,
>>  };
>> 
>> +#ifdef CONFIG_EXTCON
>> +/* List of detectable cables */
>> +static const unsigned int tps6598x_extcon_cable[] = {
>> +	EXTCON_USB,
>> +	EXTCON_USB_HOST,
>> +	EXTCON_CHG_USB_SDP,
>> +	EXTCON_CHG_USB_SLOW,
>> +	EXTCON_CHG_USB_FAST,
>> +	EXTCON_NONE,
>> +};
>> +#endif
>> +
>>  static int tps6598x_probe(struct i2c_client *client)
>>  {
>>  	struct typec_capability typec_cap = { };
>> @@ -567,10 +668,47 @@ static int tps6598x_probe(struct i2c_client 
>> *client)
>>  	}
>>  	fwnode_handle_put(fwnode);
>> 
>> +#ifdef CONFIG_EXTCON
>> +	/* Allocate extcon device */
>> +	tps->edev = devm_extcon_dev_allocate(tps->dev, 
>> tps6598x_extcon_cable);
>> +	if (IS_ERR(tps->edev)) {
>> +		dev_err(tps->dev, "failed to allocate memory for extcon\n");
>> +		typec_unregister_port(tps->port);
>> +		return -ENOMEM;
>> +	}
>> +
>> +	/* Register extcon device */
>> +	ret = devm_extcon_dev_register(tps->dev, tps->edev);
>> +	if (ret) {
>> +		dev_err(tps->dev, "failed to register extcon device\n");
>> +		typec_unregister_port(tps->port);
>> +		return ret;
>> +	}
>> +
>> +	extcon_set_property_capability(tps->edev, EXTCON_USB,
>> +				       EXTCON_PROP_USB_VBUS);
>> +	extcon_set_property_capability(tps->edev, EXTCON_USB,
>> +				       EXTCON_PROP_USB_VBUS_SRC);
>> +	extcon_set_property_capability(tps->edev, EXTCON_USB,
>> +				       EXTCON_PROP_USB_VBUS_VOLTAGE);
>> +	extcon_set_property_capability(tps->edev, EXTCON_USB,
>> +				       EXTCON_PROP_USB_VBUS_CURRENT);
>> +	extcon_set_property_capability(tps->edev, EXTCON_USB_HOST,
>> +				       EXTCON_PROP_USB_VBUS);
>> +	extcon_set_property_capability(tps->edev, EXTCON_USB_HOST,
>> +				       EXTCON_PROP_USB_VBUS_SRC);
>> +	extcon_set_property_capability(tps->edev, EXTCON_USB_HOST,
>> +				       EXTCON_PROP_USB_VBUS_VOLTAGE);
>> +	extcon_set_property_capability(tps->edev, EXTCON_USB_HOST,
>> +				       EXTCON_PROP_USB_VBUS_CURRENT);
>> +#endif
>> +
>>  	if (status & TPS_STATUS_PLUG_PRESENT) {
>>  		ret = tps6598x_connect(tps, status);
>>  		if (ret)
>>  			dev_err(&client->dev, "failed to register partner\n");
>> +	} else {
>> +		tps6598x_disconnect(tps, status);
>>  	}
>> 
>>  	ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
>> 

  reply	other threads:[~2020-09-16  0:33 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-14 16:46 [PATCH 0/4] RFC: USB C extcon patchset for the tps6598x Angus Ainslie
2020-09-14 16:46 ` [PATCH 1/4] extcon: Add USB VBUS properties Angus Ainslie
2020-09-15  1:40   ` Chanwoo Choi
2020-09-15 13:31     ` Angus Ainslie
2020-09-14 16:46 ` [PATCH 2/4] usb: typec: tps6589x: register as an extcon provider Angus Ainslie
2020-09-15  1:19   ` Chanwoo Choi
2020-09-15 13:32     ` Angus Ainslie [this message]
2020-09-14 16:46 ` [PATCH 3/4] usb: typec: tps6598x: Add the extcon USB chargers Angus Ainslie
2020-09-14 16:46 ` [PATCH 4/4] usb: typec: tps6598x: Add the power delivery irq Angus Ainslie
2020-09-24 14:42   ` kernel test robot
2020-09-21 14:37 ` [PATCH 0/4] RFC: USB C extcon patchset for the tps6598x Heikki Krogerus
2020-09-22 21:15   ` Angus Ainslie

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b2e011b9d565bf73975a746d02429b9d@akkea.ca \
    --to=angus@akkea.ca \
    --cc=bryan.odonoghue@linaro.org \
    --cc=cw00.choi@samsung.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=heikki.krogerus@linux.intel.com \
    --cc=kernel@puri.sm \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=myungjoo.ham@samsung.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.