Re: [PATCH 3/3] usb: typec: fusb302: Always provide fwnode for the port

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

 



On Wed, Aug 14, 2019 at 04:24:19PM +0300, Heikki Krogerus wrote:
> By registering a software fwnode for the port when the
> firmware does not supply one, we can always provide tcpm the
> connector capabilities by using the common USB connector
> device properties instead of using tcpc_config platform data.
> 
> Signed-off-by: Heikki Krogerus <heikki.krogerus@xxxxxxxxxxxxxxx>

Reviewed-by: Guenter Roeck <linux@xxxxxxxxxxxx>

> ---
>  drivers/usb/typec/tcpm/fusb302.c | 70 +++++++++++++++++++-------------
>  1 file changed, 41 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
> index 074fbb17fa8b..93244d6c4bff 100644
> --- a/drivers/usb/typec/tcpm/fusb302.c
> +++ b/drivers/usb/typec/tcpm/fusb302.c
> @@ -75,7 +75,6 @@ struct fusb302_chip {
>  	struct i2c_client *i2c_client;
>  	struct tcpm_port *tcpm_port;
>  	struct tcpc_dev tcpc_dev;
> -	struct tcpc_config tcpc_config;
>  
>  	struct regulator *vbus;
>  
> @@ -1110,23 +1109,6 @@ static void fusb302_bc_lvl_handler_work(struct work_struct *work)
>  	mutex_unlock(&chip->lock);
>  }
>  
> -#define PDO_FIXED_FLAGS \
> -	(PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP | PDO_FIXED_USB_COMM)
> -
> -static const u32 src_pdo[] = {
> -	PDO_FIXED(5000, 400, PDO_FIXED_FLAGS),
> -};
> -
> -static const struct tcpc_config fusb302_tcpc_config = {
> -	.src_pdo = src_pdo,
> -	.nr_src_pdo = ARRAY_SIZE(src_pdo),
> -	.operating_snk_mw = 2500,
> -	.type = TYPEC_PORT_DRP,
> -	.data = TYPEC_PORT_DRD,
> -	.default_role = TYPEC_SINK,
> -	.alt_modes = NULL,
> -};
> -
>  static void init_tcpc_dev(struct tcpc_dev *fusb302_tcpc_dev)
>  {
>  	fusb302_tcpc_dev->init = tcpm_init;
> @@ -1670,6 +1652,38 @@ static int init_gpio(struct fusb302_chip *chip)
>  	return 0;
>  }
>  
> +#define PDO_FIXED_FLAGS \
> +	(PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP | PDO_FIXED_USB_COMM)
> +
> +static const u32 src_pdo[] = {
> +	PDO_FIXED(5000, 400, PDO_FIXED_FLAGS)
> +};
> +
> +static const u32 snk_pdo[] = {
> +	PDO_FIXED(5000, 400, PDO_FIXED_FLAGS)
> +};
> +
> +static const struct property_entry port_props[] = {
> +	PROPERTY_ENTRY_STRING("data-role", "dual"),
> +	PROPERTY_ENTRY_STRING("power-role", "dual"),
> +	PROPERTY_ENTRY_STRING("try-power-role", "sink"),
> +	PROPERTY_ENTRY_U32_ARRAY("source-pdos", src_pdo),
> +	PROPERTY_ENTRY_U32_ARRAY("sink-pdos", snk_pdo),
> +	PROPERTY_ENTRY_U32("op-sink-microwatt", 2500),
> +	{ }
> +};
> +
> +static struct fwnode_handle *fusb302_fwnode_get(struct device *dev)
> +{
> +	struct fwnode_handle *fwnode;
> +
> +	fwnode = device_get_named_child_node(dev, "connector");
> +	if (!fwnode)
> +		fwnode = fwnode_create_software_node(port_props, NULL);
> +
> +	return fwnode;
> +}
> +
>  static int fusb302_probe(struct i2c_client *client,
>  			 const struct i2c_device_id *id)
>  {
> @@ -1690,19 +1704,8 @@ static int fusb302_probe(struct i2c_client *client,
>  
>  	chip->i2c_client = client;
>  	chip->dev = &client->dev;
> -	chip->tcpc_config = fusb302_tcpc_config;
> -	chip->tcpc_dev.config = &chip->tcpc_config;
>  	mutex_init(&chip->lock);
>  
> -	chip->tcpc_dev.fwnode =
> -		device_get_named_child_node(dev, "connector");
> -
> -	/* Composite sink PDO */
> -	chip->snk_pdo[0] = PDO_FIXED(5000, 400, PDO_FIXED_FLAGS);
> -
> -	chip->tcpc_config.nr_snk_pdo = 1;
> -	chip->tcpc_config.snk_pdo = chip->snk_pdo;
> -
>  	/*
>  	 * Devicetree platforms should get extcon via phandle (not yet
>  	 * supported). On ACPI platforms, we get the name from a device prop.
> @@ -1737,8 +1740,15 @@ static int fusb302_probe(struct i2c_client *client,
>  			goto destroy_workqueue;
>  	}
>  
> +	chip->tcpc_dev.fwnode = fusb302_fwnode_get(dev);
> +	if (IS_ERR(chip->tcpc_dev.fwnode)) {
> +		ret = PTR_ERR(chip->tcpc_dev.fwnode);
> +		goto destroy_workqueue;
> +	}
> +
>  	chip->tcpm_port = tcpm_register_port(&client->dev, &chip->tcpc_dev);
>  	if (IS_ERR(chip->tcpm_port)) {
> +		fwnode_handle_put(chip->tcpc_dev.fwnode);
>  		ret = PTR_ERR(chip->tcpm_port);
>  		if (ret != -EPROBE_DEFER)
>  			dev_err(dev, "cannot register tcpm port, ret=%d", ret);
> @@ -1760,6 +1770,7 @@ static int fusb302_probe(struct i2c_client *client,
>  
>  tcpm_unregister_port:
>  	tcpm_unregister_port(chip->tcpm_port);
> +	fwnode_handle_put(chip->tcpc_dev.fwnode);
>  destroy_workqueue:
>  	destroy_workqueue(chip->wq);
>  
> @@ -1775,6 +1786,7 @@ static int fusb302_remove(struct i2c_client *client)
>  	cancel_work_sync(&chip->irq_work);
>  	cancel_delayed_work_sync(&chip->bc_lvl_handler);
>  	tcpm_unregister_port(chip->tcpm_port);
> +	fwnode_handle_put(chip->tcpc_dev.fwnode);
>  	destroy_workqueue(chip->wq);
>  	fusb302_debugfs_exit(chip);
>  
> -- 
> 2.20.1
> 



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

  Powered by Linux