mbox series

[v6,00/15] staging: typec: tcpci: move out of staging

Message ID 1527475967-15201-1-git-send-email-jun.li@nxp.com
Headers show
Series staging: typec: tcpci: move out of staging | expand

Message

Jun Li May 28, 2018, 2:52 a.m. UTC
This patch set attempts to move the tcpci drivers out of staging by fix
some tcpci driver issues and define typec and power delivery device
properties, the changes are verified on NXP PTN5110, which is a standard
tcpci typec port controller device with power delivery support, tested
power source and sink with drp config.

Changes for v6:
- Change function name to be typec_find_port_power/data_role for find
  capability, and typec_find_power_role for find one specific power role.
- Fix rt1711h driver move missing.
- Add one patch to improve the error checking in tcpci driver, use IS_ERR()
  instead of PTR_ERR_OR_ZERO().
- Add Rob's Reviewed-by for patch [2/15].
- Misc typos fix.
 
Changes for v5:
- Use "power-role" and "data-role" for typec port power and data capability
  property name.  
- Use macro defintion instead of cryptic numbers for readability of
  power delivery properties(PDO).
- Add one tcpci driver binding string to be "nxp,ptn5110" to follow binding
  name rule "<vendor prefix>,<device>".
- Change operating power property name to be op-sink-microwatt.
- Add one patch(remove unused tcpci_tcpc_config) to resolve bisectablitity
  issue of patch usb: typec: add fwnode to tcpc.
- A minor error handling change to keep the error path and success path
  separate in patch: register port before request irq
- Rebase to latest Greg's tree with max_snk_* removed.

Changes for v4:
- Remove max-sink-* properties as we will purge max_snk_* in tcpm,
  see patch set[4].
- Get typec power and data type value via name string(patch 5).
- Move finding typec and pd properties code from tcpci to tcpm(patch 6)
- Add a compatible string for nxp ptn5110 typec controller in tcpci driver.
  (patch 3)
- Add set cc for drp toggling without try.src/snk in tcpm(patch 10), then
  patch 11 can only update CCx bits for keep disconnect cc line open.
- Update op-sink-microwatt-hours example value to be the right value in
  micorwatts, and accordingly divide 1000 to get its miliwatts value
  in patch 6.
- Add Guenter's Reviewed-by for patch(8/9/12)

[4] https://www.spinics.net/lists/linux-usb/msg167261.html

Changes for v3:
- Use 2 properties to separate power and data capability of typec port:
  "power-type" and "data-type", this is based on Heikki's typec class code
  change[2]. use "try-power-role" to present if the typec port can support
  Try.SNK or Try.SRC.
- 4 sink properties(max_sink_mv/ma/mw and op_sink_mw) are kept because the
  counterpart code is back, see revert patch[3], meanwhile I post a patch
  to fix the reported problem of current source pdo select machinism(which
  completely ignored those 4 sink settings), to see if we can keep current
  code, once it was discussed and have conclusion I can update this
  accordingly.
- Use fwnode to get the connector node for dt setting parse.

Main changes for v2:
- Typec properties are based on general usb connector bindings[1] proposed
  by Andrzej Hajda, use the standard unit suffixes as defined in
  property-units.txt.
- Add 2 infra APIs to get power sink and source config from dt.
- Don't change the set_cc api, to keep the uncontacted cc line open,
  set cc1/cc2 to be open in tcpci driver when set polarity.
- Directly enable vbus detect in tcpci driver rather than add a API.
- Details added in each patch.

[1] https://patchwork.kernel.org/patch/10231447/
[2] https://patchwork.kernel.org/patch/10276483/
[3] https://www.spinics.net/lists/linux-usb/msg166366.html

Li Jun (14):
  dt-bindings: connector: add properties for typec
  dt-bindings: usb: add documentation for typec port controller(TCPCI)
  staging: typec: tcpci: add compatible string for nxp ptn5110
  usb: typec: add fwnode to tcpc
  usb: typec: add API to get typec basic port power and data config
  usb: typec: tcpm: support get typec and pd config from device
    properties
  staging: typec: tcpci: remove unused tcpci_tcpc_config
  staging: typec: tcpci: use IS_ERR() instead of PTR_ERR_OR_ZERO()
  staging: typec: tcpci: enable vbus detection
  typec: tcpm: add starting value for drp toggling
  usb: typec: tcpm: set cc for drp toggling attach
  staging: typec: tcpci: keep the disconnected cc line open
  staging: typec: tcpci: Only touch target bit when enable vconn
  staging: typec: tcpci: move tcpci drivers out of staging

Peter Chen (1):
  staging: typec: tcpci: register port before request irq

 .../bindings/connector/usb-connector.txt           |  44 ++++++
 .../devicetree/bindings/usb/typec-tcpci.txt        |  49 +++++++
 drivers/staging/Kconfig                            |   2 -
 drivers/staging/Makefile                           |   1 -
 drivers/staging/typec/Kconfig                      |  22 ---
 drivers/staging/typec/Makefile                     |   2 -
 drivers/staging/typec/TODO                         |   5 -
 drivers/usb/typec/Kconfig                          |  15 +++
 drivers/usb/typec/Makefile                         |   2 +
 drivers/usb/typec/class.c                          |  50 +++++++
 drivers/{staging => usb}/typec/tcpci.c             |  66 +++++----
 drivers/{staging => usb}/typec/tcpci.h             |   0
 drivers/{staging => usb}/typec/tcpci_rt1711h.c     |   0
 drivers/usb/typec/tcpm.c                           | 148 +++++++++++++++++----
 include/dt-bindings/usb/pd.h                       |  62 +++++++++
 include/linux/usb/tcpm.h                           |   2 +
 include/linux/usb/typec.h                          |   3 +
 17 files changed, 389 insertions(+), 84 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/usb/typec-tcpci.txt
 delete mode 100644 drivers/staging/typec/Kconfig
 delete mode 100644 drivers/staging/typec/Makefile
 delete mode 100644 drivers/staging/typec/TODO
 rename drivers/{staging => usb}/typec/tcpci.c (92%)
 rename drivers/{staging => usb}/typec/tcpci.h (100%)
 rename drivers/{staging => usb}/typec/tcpci_rt1711h.c (100%)
 create mode 100644 include/dt-bindings/usb/pd.h

Comments

Mats Karrman June 6, 2018, 9:44 p.m. UTC | #1
Hello Li Jun,

I have been testing these patches on top of usb-next using an i.MX6,
a nxp ptn5110 evaluation board and a bunch of usbc devices. So far
everything seem to work fine! :-)
However, I have only tested host mode and I have some test cases
left I want to cover.

Just to let you know your patches are not forgotten :-)

BR // Mats

On 2018-05-28 04:52, Li Jun wrote:
> This patch set attempts to move the tcpci drivers out of staging by fix
> some tcpci driver issues and define typec and power delivery device
> properties, the changes are verified on NXP PTN5110, which is a standard
> tcpci typec port controller device with power delivery support, tested
> power source and sink with drp config.
>
> Changes for v6:
> - Change function name to be typec_find_port_power/data_role for find
>    capability, and typec_find_power_role for find one specific power role.
> - Fix rt1711h driver move missing.
> - Add one patch to improve the error checking in tcpci driver, use IS_ERR()
>    instead of PTR_ERR_OR_ZERO().
> - Add Rob's Reviewed-by for patch [2/15].
> - Misc typos fix.
>   
> Changes for v5:
> - Use "power-role" and "data-role" for typec port power and data capability
>    property name.
> - Use macro defintion instead of cryptic numbers for readability of
>    power delivery properties(PDO).
> - Add one tcpci driver binding string to be "nxp,ptn5110" to follow binding
>    name rule "<vendor prefix>,<device>".
> - Change operating power property name to be op-sink-microwatt.
> - Add one patch(remove unused tcpci_tcpc_config) to resolve bisectablitity
>    issue of patch usb: typec: add fwnode to tcpc.
> - A minor error handling change to keep the error path and success path
>    separate in patch: register port before request irq
> - Rebase to latest Greg's tree with max_snk_* removed.
>
> Changes for v4:
> - Remove max-sink-* properties as we will purge max_snk_* in tcpm,
>    see patch set[4].
> - Get typec power and data type value via name string(patch 5).
> - Move finding typec and pd properties code from tcpci to tcpm(patch 6)
> - Add a compatible string for nxp ptn5110 typec controller in tcpci driver.
>    (patch 3)
> - Add set cc for drp toggling without try.src/snk in tcpm(patch 10), then
>    patch 11 can only update CCx bits for keep disconnect cc line open.
> - Update op-sink-microwatt-hours example value to be the right value in
>    micorwatts, and accordingly divide 1000 to get its miliwatts value
>    in patch 6.
> - Add Guenter's Reviewed-by for patch(8/9/12)
>
> [4] https://www.spinics.net/lists/linux-usb/msg167261.html
>
> Changes for v3:
> - Use 2 properties to separate power and data capability of typec port:
>    "power-type" and "data-type", this is based on Heikki's typec class code
>    change[2]. use "try-power-role" to present if the typec port can support
>    Try.SNK or Try.SRC.
> - 4 sink properties(max_sink_mv/ma/mw and op_sink_mw) are kept because the
>    counterpart code is back, see revert patch[3], meanwhile I post a patch
>    to fix the reported problem of current source pdo select machinism(which
>    completely ignored those 4 sink settings), to see if we can keep current
>    code, once it was discussed and have conclusion I can update this
>    accordingly.
> - Use fwnode to get the connector node for dt setting parse.
>
> Main changes for v2:
> - Typec properties are based on general usb connector bindings[1] proposed
>    by Andrzej Hajda, use the standard unit suffixes as defined in
>    property-units.txt.
> - Add 2 infra APIs to get power sink and source config from dt.
> - Don't change the set_cc api, to keep the uncontacted cc line open,
>    set cc1/cc2 to be open in tcpci driver when set polarity.
> - Directly enable vbus detect in tcpci driver rather than add a API.
> - Details added in each patch.
>
> [1] https://patchwork.kernel.org/patch/10231447/
> [2] https://patchwork.kernel.org/patch/10276483/
> [3] https://www.spinics.net/lists/linux-usb/msg166366.html
>
> Li Jun (14):
>    dt-bindings: connector: add properties for typec
>    dt-bindings: usb: add documentation for typec port controller(TCPCI)
>    staging: typec: tcpci: add compatible string for nxp ptn5110
>    usb: typec: add fwnode to tcpc
>    usb: typec: add API to get typec basic port power and data config
>    usb: typec: tcpm: support get typec and pd config from device
>      properties
>    staging: typec: tcpci: remove unused tcpci_tcpc_config
>    staging: typec: tcpci: use IS_ERR() instead of PTR_ERR_OR_ZERO()
>    staging: typec: tcpci: enable vbus detection
>    typec: tcpm: add starting value for drp toggling
>    usb: typec: tcpm: set cc for drp toggling attach
>    staging: typec: tcpci: keep the disconnected cc line open
>    staging: typec: tcpci: Only touch target bit when enable vconn
>    staging: typec: tcpci: move tcpci drivers out of staging
>
> Peter Chen (1):
>    staging: typec: tcpci: register port before request irq
>
>   .../bindings/connector/usb-connector.txt           |  44 ++++++
>   .../devicetree/bindings/usb/typec-tcpci.txt        |  49 +++++++
>   drivers/staging/Kconfig                            |   2 -
>   drivers/staging/Makefile                           |   1 -
>   drivers/staging/typec/Kconfig                      |  22 ---
>   drivers/staging/typec/Makefile                     |   2 -
>   drivers/staging/typec/TODO                         |   5 -
>   drivers/usb/typec/Kconfig                          |  15 +++
>   drivers/usb/typec/Makefile                         |   2 +
>   drivers/usb/typec/class.c                          |  50 +++++++
>   drivers/{staging => usb}/typec/tcpci.c             |  66 +++++----
>   drivers/{staging => usb}/typec/tcpci.h             |   0
>   drivers/{staging => usb}/typec/tcpci_rt1711h.c     |   0
>   drivers/usb/typec/tcpm.c                           | 148 +++++++++++++++++----
>   include/dt-bindings/usb/pd.h                       |  62 +++++++++
>   include/linux/usb/tcpm.h                           |   2 +
>   include/linux/usb/typec.h                          |   3 +
>   17 files changed, 389 insertions(+), 84 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/usb/typec-tcpci.txt
>   delete mode 100644 drivers/staging/typec/Kconfig
>   delete mode 100644 drivers/staging/typec/Makefile
>   delete mode 100644 drivers/staging/typec/TODO
>   rename drivers/{staging => usb}/typec/tcpci.c (92%)
>   rename drivers/{staging => usb}/typec/tcpci.h (100%)
>   rename drivers/{staging => usb}/typec/tcpci_rt1711h.c (100%)
>   create mode 100644 include/dt-bindings/usb/pd.h
>

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jun Li June 7, 2018, 12:47 a.m. UTC | #2
Hi Mats,
> -----Original Message-----
> From: Mats Karrman [mailto:mats.dev.list@gmail.com]
> Sent: 2018年6月7日 5:45
> To: Jun Li <jun.li@nxp.com>; robh+dt@kernel.org; gregkh@linuxfoundation.org;
> heikki.krogerus@linux.intel.com; linux@roeck-us.net
> Cc: cw00.choi@samsung.com; a.hajda@samsung.com; shufan_lee@richtek.com;
> Peter Chen <peter.chen@nxp.com>; garsilva@embeddedor.com;
> gsomlo@gmail.com; linux-usb@vger.kernel.org; devicetree@vger.kernel.org;
> dl-linux-imx <linux-imx@nxp.com>
> Subject: Re: [PATCH v6 00/15] staging: typec: tcpci: move out of staging
> 
> Hello Li Jun,
> 
> I have been testing these patches on top of usb-next using an i.MX6, a nxp
> ptn5110 evaluation board and a bunch of usbc devices. So far everything seem to
> work fine! :-) However, I have only tested host mode and I have some test cases
> left I want to cover.
> 
> Just to let you know your patches are not forgotten :-)

Good to know that, thanks, Mats, those patches was tested on my i.MX8M
HW with PTN5110 for both source and sink mode, hope you can test your
device mode as well soon.

Li Jun
Heikki Krogerus June 11, 2018, 11:44 a.m. UTC | #3
On Mon, May 28, 2018 at 10:52:36AM +0800, Li Jun wrote:
> Add fwnode handle to get the fwnode so we can get typec configs
> it contains.
> 
> Suggested-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Signed-off-by: Li Jun <jun.li@nxp.com>

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>

> ---
>  drivers/staging/typec/tcpci.c | 7 +++++++
>  drivers/usb/typec/tcpm.c      | 1 +
>  include/linux/usb/tcpm.h      | 2 ++
>  3 files changed, 10 insertions(+)
> 
> diff --git a/drivers/staging/typec/tcpci.c b/drivers/staging/typec/tcpci.c
> index dd29288..e59547a 100644
> --- a/drivers/staging/typec/tcpci.c
> +++ b/drivers/staging/typec/tcpci.c
> @@ -10,6 +10,7 @@
>  #include <linux/module.h>
>  #include <linux/i2c.h>
>  #include <linux/interrupt.h>
> +#include <linux/property.h>
>  #include <linux/regmap.h>
>  #include <linux/usb/pd.h>
>  #include <linux/usb/tcpm.h>
> @@ -474,6 +475,12 @@ static int tcpci_parse_config(struct tcpci *tcpci)
>  
>  	/* TODO: Populate struct tcpc_config from ACPI/device-tree */
>  	tcpci->tcpc.config = &tcpci_tcpc_config;
> +	tcpci->tcpc.fwnode = device_get_named_child_node(tcpci->dev,
> +							 "connector");
> +	if (!tcpci->tcpc.fwnode) {
> +		dev_err(tcpci->dev, "Can't find connector node.\n");
> +		return -EINVAL;
> +	}
>  
>  	return 0;
>  }
> diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c
> index 0ccd2ce..fcd22e8 100644
> --- a/drivers/usb/typec/tcpm.c
> +++ b/drivers/usb/typec/tcpm.c
> @@ -4581,6 +4581,7 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
>  	else
>  		port->try_role = TYPEC_NO_PREFERRED_ROLE;
>  
> +	port->typec_caps.fwnode = tcpc->fwnode;
>  	port->typec_caps.prefer_role = tcpc->config->default_role;
>  	port->typec_caps.type = tcpc->config->type;
>  	port->typec_caps.data = tcpc->config->data;
> diff --git a/include/linux/usb/tcpm.h b/include/linux/usb/tcpm.h
> index b231b93..193920a 100644
> --- a/include/linux/usb/tcpm.h
> +++ b/include/linux/usb/tcpm.h
> @@ -110,6 +110,7 @@ enum tcpc_mux_mode {
>  /**
>   * struct tcpc_dev - Port configuration and callback functions
>   * @config:	Pointer to port configuration
> + * @fwnode:	Pointer to port fwnode
>   * @get_vbus:	Called to read current VBUS state
>   * @get_current_limit:
>   *		Optional; called by the tcpm core when configured as a snk
> @@ -138,6 +139,7 @@ enum tcpc_mux_mode {
>   */
>  struct tcpc_dev {
>  	const struct tcpc_config *config;
> +	struct fwnode_handle *fwnode;
>  
>  	int (*init)(struct tcpc_dev *dev);
>  	int (*get_vbus)(struct tcpc_dev *dev);
> -- 
> 2.7.4
Heikki Krogerus June 11, 2018, 12:05 p.m. UTC | #4
On Mon, May 28, 2018 at 10:52:38AM +0800, Li Jun wrote:
> This patch adds support of get typec and power delivery config from
> firmware description.
> 
> Signed-off-by: Li Jun <jun.li@nxp.com>

This looks good to me, assuming that everybody agrees with the names
used in the bindings. As usual, I would like Guenter to check tcpm.c
changes. I'm putting a few nitpicks below, but in any case:

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>

> ---
>  drivers/usb/typec/tcpm.c | 132 +++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 110 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c
> index fcd22e8..aa17cd5 100644
> --- a/drivers/usb/typec/tcpm.c
> +++ b/drivers/usb/typec/tcpm.c
> @@ -4241,6 +4241,81 @@ static int tcpm_copy_vdos(u32 *dest_vdo, const u32 *src_vdo,
>  	return nr_vdo;
>  }
>  
> +static int tcpm_fw_get_caps(struct tcpm_port *port,
> +			    struct fwnode_handle *fwnode)
> +{
> +	const char *cap_str;
> +	int ret;
> +	u32 mw;
> +
> +	if (!port || !fwnode)

if (!fwnode) is enough.

> +		return -EINVAL;
> +
> +	/* USB data support is optional */
> +	ret = fwnode_property_read_string(fwnode, "data-role", &cap_str);
> +	if (ret == 0) {
> +		port->typec_caps.data = typec_find_port_data_role(cap_str);
> +		if (port->typec_caps.data < 0)
> +			return -EINVAL;
> +	}
> +
> +	ret = fwnode_property_read_string(fwnode, "power-role", &cap_str);
> +	if (ret < 0)
> +		return ret;
> +
> +	port->typec_caps.type = typec_find_port_power_role(cap_str);
> +	if (port->typec_caps.type < 0)
> +		return -EINVAL;
> +	port->port_type = port->typec_caps.type;
> +
> +	if (port->port_type == TYPEC_PORT_SNK)
> +		goto sink;
> +
> +	/* Get soruce pdos */

s/soruce/source/

> +	ret = fwnode_property_read_u32_array(fwnode, "source-pdos",
> +					     NULL, 0);
> +	if (ret <= 0)
> +		return -EINVAL;
> +
> +	port->nr_src_pdo = min(ret, PDO_MAX_OBJECTS);
> +	ret = fwnode_property_read_u32_array(fwnode, "source-pdos",
> +					     port->src_pdo, port->nr_src_pdo);
> +	if ((ret < 0) || tcpm_validate_caps(port, port->src_pdo,
> +					    port->nr_src_pdo))
> +		return -EINVAL;
> +
> +	if (port->port_type == TYPEC_PORT_SRC)
> +		return 0;
> +
> +	/* Get the preferred power role for DRP */
> +	ret = fwnode_property_read_string(fwnode, "try-power-role", &cap_str);
> +	if (ret < 0)
> +		return ret;
> +
> +	port->typec_caps.prefer_role = typec_find_power_role(cap_str);
> +	if (port->typec_caps.prefer_role < 0)
> +		return -EINVAL;
> +sink:
> +	/* Get sink pdos */
> +	ret = fwnode_property_read_u32_array(fwnode, "sink-pdos",
> +					     NULL, 0);
> +	if (ret <= 0)
> +		return -EINVAL;
> +
> +	port->nr_snk_pdo = min(ret, PDO_MAX_OBJECTS);
> +	ret = fwnode_property_read_u32_array(fwnode, "sink-pdos",
> +					     port->snk_pdo, port->nr_snk_pdo);
> +	if ((ret < 0) || tcpm_validate_caps(port, port->snk_pdo,
> +					    port->nr_snk_pdo))
> +		return -EINVAL;
> +
> +	if (fwnode_property_read_u32(fwnode, "op-sink-microwatt", &mw) < 0)
> +		return -EINVAL;
> +	port->operating_snk_mw = mw / 1000;
> +
> +	return 0;
> +}

Thanks,
Heikki Krogerus June 11, 2018, 12:28 p.m. UTC | #5
On Mon, May 28, 2018 at 10:52:43AM +0800, Li Jun wrote:
> As DRP port autonomously toggles the Rp/Rd need a start value to
> begin with, so add one parameter for it in tcpm_start_drp_toggling.
> 
> Reviewed-by: Guenter Roeck <linux@roeck-us.net>
> Signed-off-by: Li Jun <jun.li@nxp.com>

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>

> ---
>  drivers/usb/typec/tcpm.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c
> index aa17cd5..d885bff 100644
> --- a/drivers/usb/typec/tcpm.c
> +++ b/drivers/usb/typec/tcpm.c
> @@ -2436,15 +2436,15 @@ static int tcpm_set_charge(struct tcpm_port *port, bool charge)
>  	return 0;
>  }
>  
> -static bool tcpm_start_drp_toggling(struct tcpm_port *port)
> +static bool tcpm_start_drp_toggling(struct tcpm_port *port,
> +				    enum typec_cc_status cc)
>  {
>  	int ret;
>  
>  	if (port->tcpc->start_drp_toggling &&
>  	    port->port_type == TYPEC_PORT_DRP) {
>  		tcpm_log_force(port, "Start DRP toggling");
> -		ret = port->tcpc->start_drp_toggling(port->tcpc,
> -						     tcpm_rp_cc(port));
> +		ret = port->tcpc->start_drp_toggling(port->tcpc, cc);
>  		if (!ret)
>  			return true;
>  	}
> @@ -2752,7 +2752,7 @@ static void run_state_machine(struct tcpm_port *port)
>  		if (!port->non_pd_role_swap)
>  			tcpm_swap_complete(port, -ENOTCONN);
>  		tcpm_src_detach(port);
> -		if (tcpm_start_drp_toggling(port)) {
> +		if (tcpm_start_drp_toggling(port, tcpm_rp_cc(port))) {
>  			tcpm_set_state(port, DRP_TOGGLING, 0);
>  			break;
>  		}
> @@ -2927,7 +2927,7 @@ static void run_state_machine(struct tcpm_port *port)
>  			tcpm_swap_complete(port, -ENOTCONN);
>  		tcpm_pps_complete(port, -ENOTCONN);
>  		tcpm_snk_detach(port);
> -		if (tcpm_start_drp_toggling(port)) {
> +		if (tcpm_start_drp_toggling(port, TYPEC_CC_RD)) {
>  			tcpm_set_state(port, DRP_TOGGLING, 0);
>  			break;
>  		}
> -- 
> 2.7.4
Heikki Krogerus June 11, 2018, 12:29 p.m. UTC | #6
On Mon, May 28, 2018 at 10:52:44AM +0800, Li Jun wrote:
> In case of drp toggling, we may need set correct cc value for role control
> after attach as it may never been set.

Is this something that should be considered as a fix?

> Signed-off-by: Li Jun <jun.li@nxp.com>
> ---
>  drivers/usb/typec/tcpm.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c
> index d885bff..98ea916 100644
> --- a/drivers/usb/typec/tcpm.c
> +++ b/drivers/usb/typec/tcpm.c
> @@ -2599,6 +2599,7 @@ static void tcpm_reset_port(struct tcpm_port *port)
>  	tcpm_set_attached_state(port, false);
>  	port->try_src_count = 0;
>  	port->try_snk_count = 0;
> +	port->cc_req = TYPEC_CC_OPEN;
>  	port->supply_voltage = 0;
>  	port->current_limit = 0;
>  	port->usb_type = POWER_SUPPLY_USB_TYPE_C;
> @@ -2831,6 +2832,8 @@ static void run_state_machine(struct tcpm_port *port)
>  		break;
>  
>  	case SRC_ATTACHED:
> +		if (port->cc_req == TYPEC_CC_OPEN)
> +			tcpm_set_cc(port, tcpm_rp_cc(port));
>  		ret = tcpm_src_attach(port);
>  		tcpm_set_state(port, SRC_UNATTACHED,
>  			       ret < 0 ? 0 : PD_T_PS_SOURCE_ON);
> @@ -3004,6 +3007,8 @@ static void run_state_machine(struct tcpm_port *port)
>  		tcpm_set_state(port, SNK_UNATTACHED, PD_T_PD_DEBOUNCE);
>  		break;
>  	case SNK_ATTACHED:
> +		if (port->cc_req == TYPEC_CC_OPEN)
> +			tcpm_set_cc(port, TYPEC_CC_RD);
>  		ret = tcpm_snk_attach(port);
>  		if (ret < 0)
>  			tcpm_set_state(port, SNK_UNATTACHED, 0);
Heikki Krogerus June 11, 2018, 12:32 p.m. UTC | #7
On Mon, May 28, 2018 at 10:52:35AM +0800, Li Jun wrote:
> Add nxp ptn5110 typec controller compatible string: "nxp,ptn5110",
> which is a standard tcpci chip with power delivery support. Meanwhile
> remove "usb,tcpci" because it doesn't follow the binding format rule
> and has not been used yet.
> 
> Signed-off-by: Li Jun <jun.li@nxp.com>

FWIW:

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>

> ---
>  drivers/staging/typec/tcpci.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/staging/typec/tcpci.c b/drivers/staging/typec/tcpci.c
> index 076d97e..dd29288 100644
> --- a/drivers/staging/typec/tcpci.c
> +++ b/drivers/staging/typec/tcpci.c
> @@ -575,7 +575,7 @@ MODULE_DEVICE_TABLE(i2c, tcpci_id);
>  
>  #ifdef CONFIG_OF
>  static const struct of_device_id tcpci_of_match[] = {
> -	{ .compatible = "usb,tcpci", },
> +	{ .compatible = "nxp,ptn5110", },
>  	{},
>  };
>  MODULE_DEVICE_TABLE(of, tcpci_of_match);
Heikki Krogerus June 11, 2018, 12:33 p.m. UTC | #8
On Mon, May 28, 2018 at 10:52:39AM +0800, Li Jun wrote:
> Since we will use config settings via device properties, so
> remove the hard code tcpci_tcpc_config.
> 
> Signed-off-by: Li Jun <jun.li@nxp.com>

FWIW:

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>

> ---
>  drivers/staging/typec/tcpci.c | 7 -------
>  1 file changed, 7 deletions(-)
> 
> diff --git a/drivers/staging/typec/tcpci.c b/drivers/staging/typec/tcpci.c
> index e59547a..076498a 100644
> --- a/drivers/staging/typec/tcpci.c
> +++ b/drivers/staging/typec/tcpci.c
> @@ -464,17 +464,10 @@ static const struct regmap_config tcpci_regmap_config = {
>  	.max_register = 0x7F, /* 0x80 .. 0xFF are vendor defined */
>  };
>  
> -static const struct tcpc_config tcpci_tcpc_config = {
> -	.type = TYPEC_PORT_DFP,
> -	.default_role = TYPEC_SINK,
> -};
> -
>  static int tcpci_parse_config(struct tcpci *tcpci)
>  {
>  	tcpci->controls_vbus = true; /* XXX */
>  
> -	/* TODO: Populate struct tcpc_config from ACPI/device-tree */
> -	tcpci->tcpc.config = &tcpci_tcpc_config;
>  	tcpci->tcpc.fwnode = device_get_named_child_node(tcpci->dev,
>  							 "connector");
>  	if (!tcpci->tcpc.fwnode) {
> -- 
> 2.7.4
Heikki Krogerus June 11, 2018, 12:34 p.m. UTC | #9
On Mon, May 28, 2018 at 10:52:40AM +0800, Li Jun wrote:
> As tcpm_register_port() and tcpci_register_port() never return
> NULL and NULL is not a success in this case, use IS_ERR() to check
> the return value of both.
> 
> Signed-off-by: Li Jun <jun.li@nxp.com>

FWIW:

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>

> ---
>  drivers/staging/typec/tcpci.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/staging/typec/tcpci.c b/drivers/staging/typec/tcpci.c
> index 076498a..b63f147 100644
> --- a/drivers/staging/typec/tcpci.c
> +++ b/drivers/staging/typec/tcpci.c
> @@ -509,7 +509,7 @@ struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data)
>  		return ERR_PTR(err);
>  
>  	tcpci->port = tcpm_register_port(tcpci->dev, &tcpci->tcpc);
> -	if (PTR_ERR_OR_ZERO(tcpci->port))
> +	if (IS_ERR(tcpci->port))
>  		return ERR_CAST(tcpci->port);
>  
>  	return tcpci;
> @@ -551,7 +551,7 @@ static int tcpci_probe(struct i2c_client *client,
>  		return err;
>  
>  	chip->tcpci = tcpci_register_port(&client->dev, &chip->data);
> -	if (PTR_ERR_OR_ZERO(chip->tcpci))
> +	if (IS_ERR(chip->tcpci))
>  		return PTR_ERR(chip->tcpci);
>  
>  	i2c_set_clientdata(client, chip);

Thanks,
Heikki Krogerus June 11, 2018, 12:35 p.m. UTC | #10
On Mon, May 28, 2018 at 10:52:41AM +0800, Li Jun wrote:
> From: Peter Chen <peter.chen@nxp.com>
> 
> With that we can clear any pending events and the port is registered
> so driver can be ready to handle typec events once we request irq.
> 
> Signed-off-by: Peter Chen <peter.chen@nxp.com>
> Signed-off-by: Li Jun <jun.li@nxp.com>

FWIW:

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>

> ---
>  drivers/staging/typec/tcpci.c | 15 +++++++++------
>  1 file changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/staging/typec/tcpci.c b/drivers/staging/typec/tcpci.c
> index b63f147..3b35fce 100644
> --- a/drivers/staging/typec/tcpci.c
> +++ b/drivers/staging/typec/tcpci.c
> @@ -537,24 +537,27 @@ static int tcpci_probe(struct i2c_client *client,
>  	if (IS_ERR(chip->data.regmap))
>  		return PTR_ERR(chip->data.regmap);
>  
> +	i2c_set_clientdata(client, chip);
> +
>  	/* Disable chip interrupts before requesting irq */
>  	err = regmap_raw_write(chip->data.regmap, TCPC_ALERT_MASK, &val,
>  			       sizeof(u16));
>  	if (err < 0)
>  		return err;
>  
> +	chip->tcpci = tcpci_register_port(&client->dev, &chip->data);
> +	if (IS_ERR(chip->tcpci))
> +		return PTR_ERR(chip->tcpci);
> +
>  	err = devm_request_threaded_irq(&client->dev, client->irq, NULL,
>  					_tcpci_irq,
>  					IRQF_ONESHOT | IRQF_TRIGGER_LOW,
>  					dev_name(&client->dev), chip);
> -	if (err < 0)
> +	if (err < 0) {
> +		tcpci_unregister_port(chip->tcpci);
>  		return err;
> +	}
>  
> -	chip->tcpci = tcpci_register_port(&client->dev, &chip->data);
> -	if (IS_ERR(chip->tcpci))
> -		return PTR_ERR(chip->tcpci);
> -
> -	i2c_set_clientdata(client, chip);
>  	return 0;
>  }

Thanks,
Heikki Krogerus June 11, 2018, 12:36 p.m. UTC | #11
On Mon, May 28, 2018 at 10:52:42AM +0800, Li Jun wrote:
> TCPCI implementation may need SW to enable VBUS detection to generate
> power status events.
> 
> Reviewed-by: Guenter Roeck <linux@roeck-us.net>
> Signed-off-by: Li Jun <jun.li@nxp.com>

FWIW:

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>

> ---
>  drivers/staging/typec/tcpci.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/staging/typec/tcpci.c b/drivers/staging/typec/tcpci.c
> index 3b35fce..4d3b0ae 100644
> --- a/drivers/staging/typec/tcpci.c
> +++ b/drivers/staging/typec/tcpci.c
> @@ -373,6 +373,12 @@ static int tcpci_init(struct tcpc_dev *tcpc)
>  	if (ret < 0)
>  		return ret;
>  
> +	/* Enable Vbus detection */
> +	ret = regmap_write(tcpci->regmap, TCPC_COMMAND,
> +			   TCPC_CMD_ENABLE_VBUS_DETECT);
> +	if (ret < 0)
> +		return ret;
> +
>  	reg = TCPC_ALERT_TX_SUCCESS | TCPC_ALERT_TX_FAILED |
>  		TCPC_ALERT_TX_DISCARDED | TCPC_ALERT_RX_STATUS |
>  		TCPC_ALERT_RX_HARD_RST | TCPC_ALERT_CC_STATUS;

Thanks,
Heikki Krogerus June 11, 2018, 1:14 p.m. UTC | #12
On Mon, May 28, 2018 at 10:52:45AM +0800, Li Jun wrote:
> While set polarity, we should keep the disconnected cc line to be
> open.
> 
> Signed-off-by: Li Jun <jun.li@nxp.com>

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>

> ---
>  drivers/staging/typec/tcpci.c | 18 ++++++++++++++----
>  1 file changed, 14 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/staging/typec/tcpci.c b/drivers/staging/typec/tcpci.c
> index 4d3b0ae..11c2d37 100644
> --- a/drivers/staging/typec/tcpci.c
> +++ b/drivers/staging/typec/tcpci.c
> @@ -185,15 +185,25 @@ static int tcpci_set_polarity(struct tcpc_dev *tcpc,
>  			      enum typec_cc_polarity polarity)
>  {
>  	struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
> +	unsigned int reg;
>  	int ret;
>  
> -	ret = regmap_write(tcpci->regmap, TCPC_TCPC_CTRL,
> -			   (polarity == TYPEC_POLARITY_CC2) ?
> -			   TCPC_TCPC_CTRL_ORIENTATION : 0);
> +	/* Keep the disconnect cc line open */
> +	ret = regmap_read(tcpci->regmap, TCPC_ROLE_CTRL, &reg);
>  	if (ret < 0)
>  		return ret;
>  
> -	return 0;
> +	if (polarity == TYPEC_POLARITY_CC2)
> +		reg |= TCPC_ROLE_CTRL_CC_OPEN << TCPC_ROLE_CTRL_CC1_SHIFT;
> +	else
> +		reg |= TCPC_ROLE_CTRL_CC_OPEN << TCPC_ROLE_CTRL_CC2_SHIFT;
> +	ret = regmap_write(tcpci->regmap, TCPC_ROLE_CTRL, reg);
> +	if (ret < 0)
> +		return ret;
> +
> +	return regmap_write(tcpci->regmap, TCPC_TCPC_CTRL,
> +			   (polarity == TYPEC_POLARITY_CC2) ?
> +			   TCPC_TCPC_CTRL_ORIENTATION : 0);
>  }
>  
>  static int tcpci_set_vconn(struct tcpc_dev *tcpc, bool enable)

Thanks,
Heikki Krogerus June 11, 2018, 1:15 p.m. UTC | #13
On Mon, May 28, 2018 at 10:52:46AM +0800, Li Jun wrote:
> We need regmap_update_bits to avoid touch any other bits when
> enable or disable vconn.
> 
> Reviewed-by: Guenter Roeck <linux@roeck-us.net>
> Signed-off-by: Li Jun <jun.li@nxp.com>

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>

> ---
>  drivers/staging/typec/tcpci.c | 9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/staging/typec/tcpci.c b/drivers/staging/typec/tcpci.c
> index 11c2d37..ac6b418 100644
> --- a/drivers/staging/typec/tcpci.c
> +++ b/drivers/staging/typec/tcpci.c
> @@ -218,12 +218,9 @@ static int tcpci_set_vconn(struct tcpc_dev *tcpc, bool enable)
>  			return ret;
>  	}
>  
> -	ret = regmap_write(tcpci->regmap, TCPC_POWER_CTRL,
> -			   enable ? TCPC_POWER_CTRL_VCONN_ENABLE : 0);
> -	if (ret < 0)
> -		return ret;
> -
> -	return 0;
> +	return regmap_update_bits(tcpci->regmap, TCPC_POWER_CTRL,
> +				TCPC_POWER_CTRL_VCONN_ENABLE,
> +				enable ? TCPC_POWER_CTRL_VCONN_ENABLE : 0);
>  }
>  
>  static int tcpci_set_roles(struct tcpc_dev *tcpc, bool attached,

Thanks,
Guenter Roeck June 11, 2018, 1:27 p.m. UTC | #14
On 05/27/2018 07:52 PM, Li Jun wrote:
> This patch adds support of get typec and power delivery config from
> firmware description.
> 
> Signed-off-by: Li Jun <jun.li@nxp.com>

Except for the nitpick. on top of Heikki's comments:

Reviewed-by: Guenter Roeck <linux@roeck-us.net>

> ---
>   drivers/usb/typec/tcpm.c | 132 +++++++++++++++++++++++++++++++++++++++--------
>   1 file changed, 110 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c
> index fcd22e8..aa17cd5 100644
> --- a/drivers/usb/typec/tcpm.c
> +++ b/drivers/usb/typec/tcpm.c
> @@ -4241,6 +4241,81 @@ static int tcpm_copy_vdos(u32 *dest_vdo, const u32 *src_vdo,
>   	return nr_vdo;
>   }
>   
> +static int tcpm_fw_get_caps(struct tcpm_port *port,
> +			    struct fwnode_handle *fwnode)
> +{
> +	const char *cap_str;
> +	int ret;
> +	u32 mw;
> +
> +	if (!port || !fwnode)
> +		return -EINVAL;
> +
> +	/* USB data support is optional */
> +	ret = fwnode_property_read_string(fwnode, "data-role", &cap_str);
> +	if (ret == 0) {
> +		port->typec_caps.data = typec_find_port_data_role(cap_str);
> +		if (port->typec_caps.data < 0)
> +			return -EINVAL;
> +	}
> +
> +	ret = fwnode_property_read_string(fwnode, "power-role", &cap_str);
> +	if (ret < 0)
> +		return ret;
> +
> +	port->typec_caps.type = typec_find_port_power_role(cap_str);
> +	if (port->typec_caps.type < 0)
> +		return -EINVAL;
> +	port->port_type = port->typec_caps.type;
> +
> +	if (port->port_type == TYPEC_PORT_SNK)
> +		goto sink;
> +
> +	/* Get soruce pdos */
> +	ret = fwnode_property_read_u32_array(fwnode, "source-pdos",
> +					     NULL, 0);
> +	if (ret <= 0)
> +		return -EINVAL;
> +
> +	port->nr_src_pdo = min(ret, PDO_MAX_OBJECTS);
> +	ret = fwnode_property_read_u32_array(fwnode, "source-pdos",
> +					     port->src_pdo, port->nr_src_pdo);
> +	if ((ret < 0) || tcpm_validate_caps(port, port->src_pdo,
> +					    port->nr_src_pdo))
> +		return -EINVAL;
> +
> +	if (port->port_type == TYPEC_PORT_SRC)
> +		return 0;
> +
> +	/* Get the preferred power role for DRP */
> +	ret = fwnode_property_read_string(fwnode, "try-power-role", &cap_str);
> +	if (ret < 0)
> +		return ret;
> +
> +	port->typec_caps.prefer_role = typec_find_power_role(cap_str);
> +	if (port->typec_caps.prefer_role < 0)
> +		return -EINVAL;
> +sink:
> +	/* Get sink pdos */
> +	ret = fwnode_property_read_u32_array(fwnode, "sink-pdos",
> +					     NULL, 0);
> +	if (ret <= 0)
> +		return -EINVAL;
> +
> +	port->nr_snk_pdo = min(ret, PDO_MAX_OBJECTS);
> +	ret = fwnode_property_read_u32_array(fwnode, "sink-pdos",
> +					     port->snk_pdo, port->nr_snk_pdo);
> +	if ((ret < 0) || tcpm_validate_caps(port, port->snk_pdo,
> +					    port->nr_snk_pdo))
> +		return -EINVAL;
> +
> +	if (fwnode_property_read_u32(fwnode, "op-sink-microwatt", &mw) < 0)
> +		return -EINVAL;
> +	port->operating_snk_mw = mw / 1000;
> +

"mw" should be "uw", really. The variable never holds "milliwatt".

> +	return 0;
> +}
> +
>   int tcpm_update_source_capabilities(struct tcpm_port *port, const u32 *pdo,
>   				    unsigned int nr_pdo)
>   {
> @@ -4526,12 +4601,36 @@ static int devm_tcpm_psy_register(struct tcpm_port *port)
>   	return PTR_ERR_OR_ZERO(port->psy);
>   }
>   
> +static int tcpm_copy_caps(struct tcpm_port *port,
> +			  const struct tcpc_config *tcfg)
> +{
> +	if (tcpm_validate_caps(port, tcfg->src_pdo, tcfg->nr_src_pdo) ||
> +	    tcpm_validate_caps(port, tcfg->snk_pdo, tcfg->nr_snk_pdo))
> +		return -EINVAL;
> +
> +	port->nr_src_pdo = tcpm_copy_pdos(port->src_pdo, tcfg->src_pdo,
> +					  tcfg->nr_src_pdo);
> +	port->nr_snk_pdo = tcpm_copy_pdos(port->snk_pdo, tcfg->snk_pdo,
> +					  tcfg->nr_snk_pdo);
> +
> +	port->nr_snk_vdo = tcpm_copy_vdos(port->snk_vdo, tcfg->snk_vdo,
> +					  tcfg->nr_snk_vdo);
> +
> +	port->operating_snk_mw = tcfg->operating_snk_mw;
> +
> +	port->typec_caps.prefer_role = tcfg->default_role;
> +	port->typec_caps.type = tcfg->type;
> +	port->typec_caps.data = tcfg->data;
> +
> +	return 0;
> +}
> +
>   struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
>   {
>   	struct tcpm_port *port;
>   	int i, err;
>   
> -	if (!dev || !tcpc || !tcpc->config ||
> +	if (!dev || !tcpc ||
>   	    !tcpc->get_vbus || !tcpc->set_cc || !tcpc->get_cc ||
>   	    !tcpc->set_polarity || !tcpc->set_vconn || !tcpc->set_vbus ||
>   	    !tcpc->set_pd_rx || !tcpc->set_roles || !tcpc->pd_transmit)
> @@ -4561,30 +4660,19 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
>   	init_completion(&port->pps_complete);
>   	tcpm_debugfs_init(port);
>   
> -	if (tcpm_validate_caps(port, tcpc->config->src_pdo,
> -			       tcpc->config->nr_src_pdo) ||
> -	    tcpm_validate_caps(port, tcpc->config->snk_pdo,
> -			       tcpc->config->nr_snk_pdo)) {
> -		err = -EINVAL;
> +	if (tcpc->config)
> +		err = tcpm_copy_caps(port, tcpc->config);
> +	else
> +		err = tcpm_fw_get_caps(port, tcpc->fwnode);
> +	if (err < 0)
>   		goto out_destroy_wq;
> -	}
> -	port->nr_src_pdo = tcpm_copy_pdos(port->src_pdo, tcpc->config->src_pdo,
> -					  tcpc->config->nr_src_pdo);
> -	port->nr_snk_pdo = tcpm_copy_pdos(port->snk_pdo, tcpc->config->snk_pdo,
> -					  tcpc->config->nr_snk_pdo);
> -	port->nr_snk_vdo = tcpm_copy_vdos(port->snk_vdo, tcpc->config->snk_vdo,
> -					  tcpc->config->nr_snk_vdo);
> -
> -	port->operating_snk_mw = tcpc->config->operating_snk_mw;
> -	if (!tcpc->config->try_role_hw)
> -		port->try_role = tcpc->config->default_role;
> +
> +	if (!tcpc->config || !tcpc->config->try_role_hw)
> +		port->try_role = port->typec_caps.prefer_role;
>   	else
>   		port->try_role = TYPEC_NO_PREFERRED_ROLE;
> 
>   	port->typec_caps.fwnode = tcpc->fwnode;
> -	port->typec_caps.prefer_role = tcpc->config->default_role;
> -	port->typec_caps.type = tcpc->config->type;
> -	port->typec_caps.data = tcpc->config->data;
>   	port->typec_caps.revision = 0x0120;	/* Type-C spec release 1.2 */
>   	port->typec_caps.pd_revision = 0x0300;	/* USB-PD spec release 3.0 */
>   	port->typec_caps.dr_set = tcpm_dr_set;
> @@ -4594,7 +4682,7 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
>   	port->typec_caps.port_type_set = tcpm_port_type_set;
>   
>   	port->partner_desc.identity = &port->partner_ident;
> -	port->port_type = tcpc->config->type;
> +	port->port_type = port->typec_caps.type;
>   
>   	port->role_sw = usb_role_switch_get(port->dev);
>   	if (IS_ERR(port->role_sw)) {
> @@ -4612,7 +4700,7 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
>   		goto out_destroy_wq;
>   	}
>   
> -	if (tcpc->config->alt_modes) {
> +	if (tcpc->config && tcpc->config->alt_modes) {
>   		const struct typec_altmode_desc *paltmode = tcpc->config->alt_modes;
>   
>   		i = 0;
> 

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Guenter Roeck June 11, 2018, 1:35 p.m. UTC | #15
On 06/11/2018 05:29 AM, Heikki Krogerus wrote:
> On Mon, May 28, 2018 at 10:52:44AM +0800, Li Jun wrote:
>> In case of drp toggling, we may need set correct cc value for role control
>> after attach as it may never been set.
> 
> Is this something that should be considered as a fix?
> 

The problem with this patch is that it hides a problem. CC should have been set
by the time a port reaches the attached state. The patch means that there is
a state machine path where this does not happen. I'd rather understand that
path and fix the problem where it happens.

Guenter

>> Signed-off-by: Li Jun <jun.li@nxp.com>
>> ---
>>   drivers/usb/typec/tcpm.c | 5 +++++
>>   1 file changed, 5 insertions(+)
>>
>> diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c
>> index d885bff..98ea916 100644
>> --- a/drivers/usb/typec/tcpm.c
>> +++ b/drivers/usb/typec/tcpm.c
>> @@ -2599,6 +2599,7 @@ static void tcpm_reset_port(struct tcpm_port *port)
>>   	tcpm_set_attached_state(port, false);
>>   	port->try_src_count = 0;
>>   	port->try_snk_count = 0;
>> +	port->cc_req = TYPEC_CC_OPEN;
>>   	port->supply_voltage = 0;
>>   	port->current_limit = 0;
>>   	port->usb_type = POWER_SUPPLY_USB_TYPE_C;
>> @@ -2831,6 +2832,8 @@ static void run_state_machine(struct tcpm_port *port)
>>   		break;
>>   
>>   	case SRC_ATTACHED:
>> +		if (port->cc_req == TYPEC_CC_OPEN)
>> +			tcpm_set_cc(port, tcpm_rp_cc(port));
>>   		ret = tcpm_src_attach(port);
>>   		tcpm_set_state(port, SRC_UNATTACHED,
>>   			       ret < 0 ? 0 : PD_T_PS_SOURCE_ON);
>> @@ -3004,6 +3007,8 @@ static void run_state_machine(struct tcpm_port *port)
>>   		tcpm_set_state(port, SNK_UNATTACHED, PD_T_PD_DEBOUNCE);
>>   		break;
>>   	case SNK_ATTACHED:
>> +		if (port->cc_req == TYPEC_CC_OPEN)
>> +			tcpm_set_cc(port, TYPEC_CC_RD);
>>   		ret = tcpm_snk_attach(port);
>>   		if (ret < 0)
>>   			tcpm_set_state(port, SNK_UNATTACHED, 0);
> 

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jun Li June 13, 2018, 9:47 a.m. UTC | #16
Hi Heikki,
> -----Original Message-----
> From: Heikki Krogerus [mailto:heikki.krogerus@linux.intel.com]
> Sent: 2018年6月11日 19:09
> To: Jun Li <jun.li@nxp.com>
> Cc: robh+dt@kernel.org; gregkh@linuxfoundation.org; linux@roeck-us.net;
> cw00.choi@samsung.com; a.hajda@samsung.com; shufan_lee@richtek.com;
> Peter Chen <peter.chen@nxp.com>; garsilva@embeddedor.com;
> gsomlo@gmail.com; linux-usb@vger.kernel.org; devicetree@vger.kernel.org;
> dl-linux-imx <linux-imx@nxp.com>
> Subject: Re: [PATCH v6 05/15] usb: typec: add API to get typec basic port power
> and data config
> 
> Hi Jun,
> 
> On Mon, May 28, 2018 at 10:52:37AM +0800, Li Jun wrote:
> > This patch adds 3 APIs to get the typec port power and data type, and
> > preferred power role by its name string.
> >
> > Signed-off-by: Li Jun <jun.li@nxp.com>
> > ---
> >  drivers/usb/typec/class.c | 50
> > +++++++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/usb/typec.h |  3 +++
> >  2 files changed, 53 insertions(+)
> >
> > diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
> > index 53df10d..4c7d18c 100644
> > --- a/drivers/usb/typec/class.c
> > +++ b/drivers/usb/typec/class.c
> > @@ -802,6 +802,12 @@ static const char * const typec_port_types[] = {
> >  	[TYPEC_PORT_DRP] = "dual",
> >  };
> >
> > +static const char * const typec_data_caps[] = {
> > +	[TYPEC_PORT_DFP] = "host",
> > +	[TYPEC_PORT_UFP] = "device",
> > +	[TYPEC_PORT_DRD] = "dual",
> > +};
> 
> Since I guess you need to fix this patch in any case, could you rename that to
> "typec_port_data_roles".

OK.

> 
> And while at it, how about using this as an opportunity to rename
> typec_port_types to typec_port_power_roles?
> 
> So this just a suggestion, no need to actually change it :-) :

Also OK for me, I can rename it by this chance.

> 
> diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index
> abbd33939109..97f7eb0e9879 100644
> --- a/drivers/usb/typec/class.c
> +++ b/drivers/usb/typec/class.c
> @@ -918,12 +918,18 @@ static const char * const typec_data_roles[] = {
>         [TYPEC_HOST]    = "host",
>  };
> 
> -static const char * const typec_port_types[] = {
> +static const char * const typec_port_power_roles[] = {
>         [TYPEC_PORT_SRC] = "source",
>         [TYPEC_PORT_SNK] = "sink",
>         [TYPEC_PORT_DRP] = "dual",
>  };
> 
> +static const char * const typec_port_data_roles[] = {
> +       [TYPEC_PORT_DFP] = "host",
> +       [TYPEC_PORT_UFP] = "device",
> +       [TYPEC_PORT_DRD] = "dual",
> +};
> +
>  static const char * const typec_port_types_drp[] = {
>         [TYPEC_PORT_SRC] = "dual [source] sink",
>         [TYPEC_PORT_SNK] = "dual source [sink]", @@ -1054,7 +1060,7 @@
> static ssize_t power_role_store(struct device *dev,
>         mutex_lock(&port->port_type_lock);
>         if (port->port_type != TYPEC_PORT_DRP) {
>                 dev_dbg(dev, "port type fixed at \"%s\"",
> -                            typec_port_types[port->port_type]);
> +                       typec_port_power_roles[port->port_type]);
>                 ret = -EOPNOTSUPP;
>                 goto unlock_and_ret;
>         }
> @@ -1095,7 +1101,7 @@ port_type_store(struct device *dev, struct
> device_attribute *attr,
>                 return -EOPNOTSUPP;
>         }
> 
> -       ret = sysfs_match_string(typec_port_types, buf);
> +       ret = sysfs_match_string(typec_port_power_roles, buf);
>         if (ret < 0)
>                 return ret;
> 
> @@ -1129,7 +1135,7 @@ port_type_show(struct device *dev, struct
> device_attribute *attr,
>                 return sprintf(buf, "%s\n",
>                                typec_port_types_drp[port->port_type]);
> 
> -       return sprintf(buf, "[%s]\n", typec_port_types[port->cap->type]);
> +       return sprintf(buf, "[%s]\n",
> + typec_port_power_roles[port->cap->type]);
>  }
>  static DEVICE_ATTR_RW(port_type);
> 
> 
> Thanks,
> 
> --
> heikki
Jun Li June 13, 2018, 11:14 a.m. UTC | #17
Hi
> -----Original Message-----
> From: Jun Li
> Sent: 2018年6月13日 19:07
> To: Guenter Roeck <linux@roeck-us.net>; Heikki Krogerus
> <heikki.krogerus@linux.intel.com>; shufan_lee@richtek.com
> Cc: robh+dt@kernel.org; gregkh@linuxfoundation.org; cw00.choi@samsung.com;
> a.hajda@samsung.com; Peter Chen <peter.chen@nxp.com>;
> garsilva@embeddedor.com; gsomlo@gmail.com; linux-usb@vger.kernel.org;
> devicetree@vger.kernel.org; dl-linux-imx <linux-imx@nxp.com>
> Subject: RE: [PATCH v6 12/15] usb: typec: tcpm: set cc for drp toggling attach
> 
> Hi,
> > -----Original Message-----
> > From: Guenter Roeck [mailto:groeck7@gmail.com] On Behalf Of Guenter
> > Roeck
> > Sent: 2018年6月11日 21:35
> > To: Heikki Krogerus <heikki.krogerus@linux.intel.com>; Jun Li
> > <jun.li@nxp.com>
> > Cc: robh+dt@kernel.org; gregkh@linuxfoundation.org;
> > cw00.choi@samsung.com; a.hajda@samsung.com; shufan_lee@richtek.com;
> > Peter Chen <peter.chen@nxp.com>; garsilva@embeddedor.com;
> > gsomlo@gmail.com; linux-usb@vger.kernel.org;
> > devicetree@vger.kernel.org; dl-linux-imx <linux-imx@nxp.com>
> > Subject: Re: [PATCH v6 12/15] usb: typec: tcpm: set cc for drp
> > toggling attach
> >
> > On 06/11/2018 05:29 AM, Heikki Krogerus wrote:
> > > On Mon, May 28, 2018 at 10:52:44AM +0800, Li Jun wrote:
> > >> In case of drp toggling, we may need set correct cc value for role
> > >> control after attach as it may never been set.
> > >
> > > Is this something that should be considered as a fix?
> > >
> >
> > The problem with this patch is that it hides a problem. CC should have
> > been set by the time a port reaches the attached state. The patch
> > means that there is a state machine path where this does not happen.
> > I'd rather understand that path and fix the problem where it happens.
> 
> Here is my previous explanation about this state machine path[1]
> 
> [1]https://www.spinics.net/lists/linux-usb/msg167467.html
> 
> The physical CC line state is correct, just the Role Control register value may
> mismatch on some(e.g. shufan's) HW, if the common change in tcpm is not the
> right way, I have to ask shufan to try resolve this in his custom rt1711h driver.
> 
> I understand the concern of setting cc at attached state is late, should be done
> before that, how about I move this in cc_change like below:
> 
> @@ -3492,10 +3492,13 @@ static void _tcpm_cc_change(struct tcpm_port *port,
> enum typec_cc_status cc1,
>         switch (port->state) {
>         case DRP_TOGGLING:
>                 if (tcpm_port_is_debug(port) || tcpm_port_is_audio(port) ||
> -                   tcpm_port_is_source(port))
> +                   tcpm_port_is_source(port)) {
> +                       tcpm_set_cc(port, tcpm_rp_cc(port));
>                         tcpm_set_state(port, SRC_ATTACH_WAIT, 0);
> -               else if (tcpm_port_is_sink(port))
> +               } else if (tcpm_port_is_sink(port)) {
> +                       if (port->cc_req == TYPEC_CC_OPEN)

Sorry, here should be:

+               } else if (tcpm_port_is_sink(port)) {
+                       tcpm_set_cc(port, TYPEC_CC_RD);
                        tcpm_set_state(port, SNK_ATTACH_WAIT, 0);
+               }
>                         tcpm_set_state(port, SNK_ATTACH_WAIT, 0);
> +               }
>                 break;
>         case SRC_UNATTACHED:
>         case ACC_UNATTACHED:
> 
> thanks
> Li Jun
> 
> >
> > Guenter
> >
> > >> Signed-off-by: Li Jun <jun.li@nxp.com>
> > >> ---
> > >>   drivers/usb/typec/tcpm.c | 5 +++++
> > >>   1 file changed, 5 insertions(+)
> > >>
> > >> diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c
> > >> index d885bff..98ea916 100644
> > >> --- a/drivers/usb/typec/tcpm.c
> > >> +++ b/drivers/usb/typec/tcpm.c
> > >> @@ -2599,6 +2599,7 @@ static void tcpm_reset_port(struct tcpm_port
> *port)
> > >>   	tcpm_set_attached_state(port, false);
> > >>   	port->try_src_count = 0;
> > >>   	port->try_snk_count = 0;
> > >> +	port->cc_req = TYPEC_CC_OPEN;
> > >>   	port->supply_voltage = 0;
> > >>   	port->current_limit = 0;
> > >>   	port->usb_type = POWER_SUPPLY_USB_TYPE_C; @@ -2831,6 +2832,8
> > @@
> > >> static void run_state_machine(struct tcpm_port *port)
> > >>   		break;
> > >>
> > >>   	case SRC_ATTACHED:
> > >> +		if (port->cc_req == TYPEC_CC_OPEN)
> > >> +			tcpm_set_cc(port, tcpm_rp_cc(port));
> > >>   		ret = tcpm_src_attach(port);
> > >>   		tcpm_set_state(port, SRC_UNATTACHED,
> > >>   			       ret < 0 ? 0 : PD_T_PS_SOURCE_ON); @@ -3004,6
> > +3007,8 @@
> > >> static void run_state_machine(struct tcpm_port *port)
> > >>   		tcpm_set_state(port, SNK_UNATTACHED,
> > PD_T_PD_DEBOUNCE);
> > >>   		break;
> > >>   	case SNK_ATTACHED:
> > >> +		if (port->cc_req == TYPEC_CC_OPEN)
> > >> +			tcpm_set_cc(port, TYPEC_CC_RD);
> > >>   		ret = tcpm_snk_attach(port);
> > >>   		if (ret < 0)
> > >>   			tcpm_set_state(port, SNK_UNATTACHED, 0);
> > >