All of lore.kernel.org
 help / color / mirror / Atom feed
From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
To: Guenter Roeck <linux@roeck-us.net>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Hans de Goede <hdegoede@redhat.com>, Jun Li <jun.li@nxp.com>,
	"Regupathy, Rajaram" <rajaram.regupathy@intel.com>,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH v2 2/3] usb: typec: Bus type for alternate modes
Date: Mon, 19 Mar 2018 13:42:37 +0200	[thread overview]
Message-ID: <20180319114237.GG11689@kuha.fi.intel.com> (raw)
In-Reply-To: <20180316213336.GA11002@roeck-us.net>

Hi Guenter,

On Fri, Mar 16, 2018 at 02:33:36PM -0700, Guenter Roeck wrote:
> On Fri, Mar 09, 2018 at 06:19:17PM +0300, Heikki Krogerus wrote:
> > diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c
> > new file mode 100644
> > index 000000000000..92944aaf3d6a
> > --- /dev/null
> > +++ b/drivers/usb/typec/bus.c
> > @@ -0,0 +1,421 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/**
> > + * Bus for USB Type-C Alternate Modes
> > + *
> > + * Copyright (C) 2018 Intel Corporation
> > + * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> > + */
> > +
> > +#include "bus.h"
> > +
> > +/* -------------------------------------------------------------------------- */
> > +/* Common API */
> > +
> > +/**
> > + * typec_altmode_notify - Communication between the OS and alternate mode driver
> > + * @adev: Handle to the alternate mode
> > + * @conf: Alternate mode specific configuration value
> > + * @data: Alternate mode specific data
> > + *
> > + * The primary purpose for this function is to allow the alternate mode drivers
> > + * to tell which pin configuration has been negotiated with the partner. That
> > + * information will then be used for example to configure the muxes.
> > + * Communication to the other direction is also possible, and low level device
> > + * drivers can also send notifications to the alternate mode drivers. The actual
> > + * communication will be specific for every SVID.
> > + */
> > +int typec_altmode_notify(struct typec_altmode *adev,
> > +			 unsigned long conf, void *data)
> > +{
> > +	struct altmode *altmode;
> > +	struct altmode *partner;
> > +	int ret;
> > +
> > +	/*
> > +	 * All SVID specific configuration values must start from
> > +	 * TYPEC_STATE_MODAL. The first values are reserved for the pin states
> > +	 * defined in USB Type-C specification: TYPEC_STATE_USB and
> > +	 * TYPEC_STATE_SAFE. We'll follow this rule even with modes that do not
> > +	 * require pin reconfiguration for the sake of simplicity.
> > +	 */
> > +	if (conf < TYPEC_STATE_MODAL)
> > +		return -EINVAL;
> > +
> > +	if (!adev)
> > +		return 0;
> > +
> > +	altmode = to_altmode(adev);
> > +
> > +	if (!altmode->partner)
> > +		return -ENODEV;
> > +
> > +	ret = typec_set_mode(typec_altmode2port(adev), (int)conf);
> > +	if (ret)
> > +		return ret;
> > +
> > +	partner = altmode->partner;
> > +
> > +	blocking_notifier_call_chain(is_typec_port(adev->dev.parent) ?
> > +				     &altmode->nh : &partner->nh,
> > +				     conf, data);
> > +
> > +	if (partner->ops && partner->ops->notify)
> > +		return partner->ops->notify(&partner->adev, conf, data);
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(typec_altmode_notify);
> > +
> > +/**
> > + * typec_altmode_enter - Enter Mode
> > + * @adev: The alternate mode
> > + *
> > + * The alternate mode drivers use this function to enter mode. The port drivers
> > + * use this to inform the alternate mode drivers that their mode has been
> > + * entered successfully.
> > + */
> > +int typec_altmode_enter(struct typec_altmode *adev)
> > +{
> > +	struct altmode *partner = to_altmode(adev)->partner;
> > +	struct typec_altmode *pdev = &partner->adev;
> > +	int ret;
> > +
> > +	if (is_typec_port(adev->dev.parent)) {
> > +		typec_altmode_update_active(pdev, pdev->mode, true);
> > +		sysfs_notify(&pdev->dev.kobj, NULL, "active");
> > +		goto enter_mode;
> > +	}
> > +
> > +	if (!pdev->active)
> > +		return -EPERM;
> > +
> > +	/* First moving to USB Safe State */
> > +	ret = typec_set_mode(typec_altmode2port(adev), TYPEC_STATE_SAFE);
> > +	if (ret)
> > +		return ret;
> > +
> > +	blocking_notifier_call_chain(&partner->nh, TYPEC_STATE_SAFE, NULL);
> > +
> > +enter_mode:
> > +	/* Enter Mode command */
> > +	if (partner->ops && partner->ops->enter)
> > +		partner->ops->enter(pdev);
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(typec_altmode_enter);
> > +
> > +/**
> > + * typec_altmode_enter - Exit Mode
> 
> typec_altmode_exit

Yes.

> > + * @adev: The alternate mode
> > + *
> > + * The alternate mode drivers use this function to exit mode. The port drivers
> > + * can also inform the alternate mode drivers with this function that the mode
> > + * was successfully exited.
> > + */
> > +int typec_altmode_exit(struct typec_altmode *adev)
> > +{
> > +	struct altmode *partner = to_altmode(adev)->partner;
> > +	struct typec_port *port = typec_altmode2port(adev);
> > +	struct typec_altmode *pdev = &partner->adev;
> > +	int ret;
> > +
> > +	/* In case of port, just calling the driver and exiting */
> > +	if (is_typec_port(adev->dev.parent)) {
> > +		typec_altmode_update_active(pdev, pdev->mode, false);
> > +		sysfs_notify(&pdev->dev.kobj, NULL, "active");
> > +
> > +		if (partner->ops && partner->ops->exit)
> > +			partner->ops->exit(pdev);
> > +		return 0;
> > +	}
> > +
> > +	/* Moving to USB Safe State */
> > +	ret = typec_set_mode(port, TYPEC_STATE_SAFE);
> > +	if (ret)
> > +		return ret;
> > +
> > +	blocking_notifier_call_chain(&partner->nh, TYPEC_STATE_SAFE, NULL);
> > +
> > +	/* Exit Mode command */
> > +	if (partner->ops && partner->ops->exit)
> > +		partner->ops->exit(pdev);
> > +
> > +	/* Back to USB operation */
> > +	ret = typec_set_mode(port, TYPEC_STATE_USB);
> > +	if (ret)
> > +		return ret;
> > +
> > +	blocking_notifier_call_chain(&partner->nh, TYPEC_STATE_USB, NULL);
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(typec_altmode_exit);
> > +
> > +/**
> > + * typec_altmode_attention - Attention command
> > + * @adev: The alternate mode
> > + * @vdo: VDO for the Attention command
> > + *
> > + * Notifies the partner of @adev about Attention command.
> > + */
> > +void typec_altmode_attention(struct typec_altmode *adev, const u32 vdo)
> > +{
> > +	struct altmode *partner = to_altmode(adev)->partner;
> > +
> > +	if (partner && partner->ops && partner->ops->attention)
> > +		partner->ops->attention(&partner->adev, vdo);
> > +}
> > +EXPORT_SYMBOL_GPL(typec_altmode_attention);
> > +
> > +/**
> > + * typec_altmode_vdm - Send Vendor Defined Messages (VDM) to the partner
> > + * @adev: Alternate mode handle
> > + * @header: VDM Header
> > + * @vdo: Array of Vendor Defined Data Objects
> > + * @count: Number of Data Objects
> > + *
> > + * The alternate mode drivers use this function for SVID specific communication
> > + * with the partner. The port drivers use it to deliver the Structured VDMs
> > + * received from the partners to the alternate mode drivers.
> > + */
> > +int typec_altmode_vdm(struct typec_altmode *adev,
> > +		      const u32 header, const u32 *vdo, int count)
> > +{
> > +	struct altmode *altmode;
> > +	struct altmode *partner;
> > +
> > +	if (!adev)
> > +		return 0;
> > +
> > +	altmode = to_altmode(adev);
> > +
> > +	if (!altmode->partner)
> > +		return -ENODEV;
> > +
> > +	partner = altmode->partner;
> > +
> > +	if (partner->ops && partner->ops->vdm)
> > +		return partner->ops->vdm(&partner->adev, header, vdo, count);
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(typec_altmode_vdm);
> > +
> > +void typec_altmode_register_ops(struct typec_altmode *adev,
> > +				const struct typec_altmode_ops *ops)
> > +{
> > +	to_altmode(adev)->ops = ops;
> > +}
> > +EXPORT_SYMBOL_GPL(typec_altmode_register_ops);
> > +
> > +/* -------------------------------------------------------------------------- */
> > +/* API for the alternate mode drivers */
> > +
> > +/**
> > + * typec_altmode_get_plug - Find cable plug alternate mode
> > + * @adev: Handle to partner alternate mode
> > + * @index: Cable plug index
> > + *
> > + * Increment reference count for cable plug alternate mode device. Returns
> > + * handle to the cable plug alternate mode, or NULL if none is found.
> > + */
> > +struct typec_altmode *typec_altmode_get_plug(struct typec_altmode *adev,
> > +					     int index)
> > +{
> > +	struct altmode *port = to_altmode(adev)->partner;
> > +
> > +	if (port->plug[index]) {
> > +		get_device(&port->plug[index]->adev.dev);
> > +		return &port->plug[index]->adev;
> > +	}
> > +
> > +	return NULL;
> > +}
> > +EXPORT_SYMBOL_GPL(typec_altmode_get_plug);
> > +
> > +/**
> > + * typec_altmode_get_plug - Decrement cable plug alternate mode reference count
> 
> typec_altmode_put_plug

Yes.


Thanks,

-- 
heikki

WARNING: multiple messages have this Message-ID (diff)
From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
To: Guenter Roeck <linux@roeck-us.net>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Hans de Goede <hdegoede@redhat.com>, Jun Li <jun.li@nxp.com>,
	"Regupathy, Rajaram" <rajaram.regupathy@intel.com>,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [RFC,v2,2/3] usb: typec: Bus type for alternate modes
Date: Mon, 19 Mar 2018 13:42:37 +0200	[thread overview]
Message-ID: <20180319114237.GG11689@kuha.fi.intel.com> (raw)

Hi Guenter,

On Fri, Mar 16, 2018 at 02:33:36PM -0700, Guenter Roeck wrote:
> On Fri, Mar 09, 2018 at 06:19:17PM +0300, Heikki Krogerus wrote:
> > diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c
> > new file mode 100644
> > index 000000000000..92944aaf3d6a
> > --- /dev/null
> > +++ b/drivers/usb/typec/bus.c
> > @@ -0,0 +1,421 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/**
> > + * Bus for USB Type-C Alternate Modes
> > + *
> > + * Copyright (C) 2018 Intel Corporation
> > + * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> > + */
> > +
> > +#include "bus.h"
> > +
> > +/* -------------------------------------------------------------------------- */
> > +/* Common API */
> > +
> > +/**
> > + * typec_altmode_notify - Communication between the OS and alternate mode driver
> > + * @adev: Handle to the alternate mode
> > + * @conf: Alternate mode specific configuration value
> > + * @data: Alternate mode specific data
> > + *
> > + * The primary purpose for this function is to allow the alternate mode drivers
> > + * to tell which pin configuration has been negotiated with the partner. That
> > + * information will then be used for example to configure the muxes.
> > + * Communication to the other direction is also possible, and low level device
> > + * drivers can also send notifications to the alternate mode drivers. The actual
> > + * communication will be specific for every SVID.
> > + */
> > +int typec_altmode_notify(struct typec_altmode *adev,
> > +			 unsigned long conf, void *data)
> > +{
> > +	struct altmode *altmode;
> > +	struct altmode *partner;
> > +	int ret;
> > +
> > +	/*
> > +	 * All SVID specific configuration values must start from
> > +	 * TYPEC_STATE_MODAL. The first values are reserved for the pin states
> > +	 * defined in USB Type-C specification: TYPEC_STATE_USB and
> > +	 * TYPEC_STATE_SAFE. We'll follow this rule even with modes that do not
> > +	 * require pin reconfiguration for the sake of simplicity.
> > +	 */
> > +	if (conf < TYPEC_STATE_MODAL)
> > +		return -EINVAL;
> > +
> > +	if (!adev)
> > +		return 0;
> > +
> > +	altmode = to_altmode(adev);
> > +
> > +	if (!altmode->partner)
> > +		return -ENODEV;
> > +
> > +	ret = typec_set_mode(typec_altmode2port(adev), (int)conf);
> > +	if (ret)
> > +		return ret;
> > +
> > +	partner = altmode->partner;
> > +
> > +	blocking_notifier_call_chain(is_typec_port(adev->dev.parent) ?
> > +				     &altmode->nh : &partner->nh,
> > +				     conf, data);
> > +
> > +	if (partner->ops && partner->ops->notify)
> > +		return partner->ops->notify(&partner->adev, conf, data);
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(typec_altmode_notify);
> > +
> > +/**
> > + * typec_altmode_enter - Enter Mode
> > + * @adev: The alternate mode
> > + *
> > + * The alternate mode drivers use this function to enter mode. The port drivers
> > + * use this to inform the alternate mode drivers that their mode has been
> > + * entered successfully.
> > + */
> > +int typec_altmode_enter(struct typec_altmode *adev)
> > +{
> > +	struct altmode *partner = to_altmode(adev)->partner;
> > +	struct typec_altmode *pdev = &partner->adev;
> > +	int ret;
> > +
> > +	if (is_typec_port(adev->dev.parent)) {
> > +		typec_altmode_update_active(pdev, pdev->mode, true);
> > +		sysfs_notify(&pdev->dev.kobj, NULL, "active");
> > +		goto enter_mode;
> > +	}
> > +
> > +	if (!pdev->active)
> > +		return -EPERM;
> > +
> > +	/* First moving to USB Safe State */
> > +	ret = typec_set_mode(typec_altmode2port(adev), TYPEC_STATE_SAFE);
> > +	if (ret)
> > +		return ret;
> > +
> > +	blocking_notifier_call_chain(&partner->nh, TYPEC_STATE_SAFE, NULL);
> > +
> > +enter_mode:
> > +	/* Enter Mode command */
> > +	if (partner->ops && partner->ops->enter)
> > +		partner->ops->enter(pdev);
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(typec_altmode_enter);
> > +
> > +/**
> > + * typec_altmode_enter - Exit Mode
> 
> typec_altmode_exit

Yes.

> > + * @adev: The alternate mode
> > + *
> > + * The alternate mode drivers use this function to exit mode. The port drivers
> > + * can also inform the alternate mode drivers with this function that the mode
> > + * was successfully exited.
> > + */
> > +int typec_altmode_exit(struct typec_altmode *adev)
> > +{
> > +	struct altmode *partner = to_altmode(adev)->partner;
> > +	struct typec_port *port = typec_altmode2port(adev);
> > +	struct typec_altmode *pdev = &partner->adev;
> > +	int ret;
> > +
> > +	/* In case of port, just calling the driver and exiting */
> > +	if (is_typec_port(adev->dev.parent)) {
> > +		typec_altmode_update_active(pdev, pdev->mode, false);
> > +		sysfs_notify(&pdev->dev.kobj, NULL, "active");
> > +
> > +		if (partner->ops && partner->ops->exit)
> > +			partner->ops->exit(pdev);
> > +		return 0;
> > +	}
> > +
> > +	/* Moving to USB Safe State */
> > +	ret = typec_set_mode(port, TYPEC_STATE_SAFE);
> > +	if (ret)
> > +		return ret;
> > +
> > +	blocking_notifier_call_chain(&partner->nh, TYPEC_STATE_SAFE, NULL);
> > +
> > +	/* Exit Mode command */
> > +	if (partner->ops && partner->ops->exit)
> > +		partner->ops->exit(pdev);
> > +
> > +	/* Back to USB operation */
> > +	ret = typec_set_mode(port, TYPEC_STATE_USB);
> > +	if (ret)
> > +		return ret;
> > +
> > +	blocking_notifier_call_chain(&partner->nh, TYPEC_STATE_USB, NULL);
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(typec_altmode_exit);
> > +
> > +/**
> > + * typec_altmode_attention - Attention command
> > + * @adev: The alternate mode
> > + * @vdo: VDO for the Attention command
> > + *
> > + * Notifies the partner of @adev about Attention command.
> > + */
> > +void typec_altmode_attention(struct typec_altmode *adev, const u32 vdo)
> > +{
> > +	struct altmode *partner = to_altmode(adev)->partner;
> > +
> > +	if (partner && partner->ops && partner->ops->attention)
> > +		partner->ops->attention(&partner->adev, vdo);
> > +}
> > +EXPORT_SYMBOL_GPL(typec_altmode_attention);
> > +
> > +/**
> > + * typec_altmode_vdm - Send Vendor Defined Messages (VDM) to the partner
> > + * @adev: Alternate mode handle
> > + * @header: VDM Header
> > + * @vdo: Array of Vendor Defined Data Objects
> > + * @count: Number of Data Objects
> > + *
> > + * The alternate mode drivers use this function for SVID specific communication
> > + * with the partner. The port drivers use it to deliver the Structured VDMs
> > + * received from the partners to the alternate mode drivers.
> > + */
> > +int typec_altmode_vdm(struct typec_altmode *adev,
> > +		      const u32 header, const u32 *vdo, int count)
> > +{
> > +	struct altmode *altmode;
> > +	struct altmode *partner;
> > +
> > +	if (!adev)
> > +		return 0;
> > +
> > +	altmode = to_altmode(adev);
> > +
> > +	if (!altmode->partner)
> > +		return -ENODEV;
> > +
> > +	partner = altmode->partner;
> > +
> > +	if (partner->ops && partner->ops->vdm)
> > +		return partner->ops->vdm(&partner->adev, header, vdo, count);
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(typec_altmode_vdm);
> > +
> > +void typec_altmode_register_ops(struct typec_altmode *adev,
> > +				const struct typec_altmode_ops *ops)
> > +{
> > +	to_altmode(adev)->ops = ops;
> > +}
> > +EXPORT_SYMBOL_GPL(typec_altmode_register_ops);
> > +
> > +/* -------------------------------------------------------------------------- */
> > +/* API for the alternate mode drivers */
> > +
> > +/**
> > + * typec_altmode_get_plug - Find cable plug alternate mode
> > + * @adev: Handle to partner alternate mode
> > + * @index: Cable plug index
> > + *
> > + * Increment reference count for cable plug alternate mode device. Returns
> > + * handle to the cable plug alternate mode, or NULL if none is found.
> > + */
> > +struct typec_altmode *typec_altmode_get_plug(struct typec_altmode *adev,
> > +					     int index)
> > +{
> > +	struct altmode *port = to_altmode(adev)->partner;
> > +
> > +	if (port->plug[index]) {
> > +		get_device(&port->plug[index]->adev.dev);
> > +		return &port->plug[index]->adev;
> > +	}
> > +
> > +	return NULL;
> > +}
> > +EXPORT_SYMBOL_GPL(typec_altmode_get_plug);
> > +
> > +/**
> > + * typec_altmode_get_plug - Decrement cable plug alternate mode reference count
> 
> typec_altmode_put_plug

Yes.


Thanks,

  reply	other threads:[~2018-03-19 11:42 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-09 15:19 [RFC PATCH v2 0/3] usb: typec: Support for Alternate Modes Heikki Krogerus
2018-03-09 15:19 ` [RFC PATCH v2 1/3] usb: typec: Register a device for every mode Heikki Krogerus
2018-03-09 15:19   ` [RFC,v2,1/3] " Heikki Krogerus
2018-03-09 15:19 ` [RFC PATCH v2 2/3] usb: typec: Bus type for alternate modes Heikki Krogerus
2018-03-09 15:19   ` [RFC,v2,2/3] " Heikki Krogerus
2018-03-16 21:33   ` [RFC PATCH v2 2/3] " Guenter Roeck
2018-03-16 21:33     ` [RFC,v2,2/3] " Guenter Roeck
2018-03-19 11:42     ` Heikki Krogerus [this message]
2018-03-19 11:42       ` Heikki Krogerus
2018-03-09 15:19 ` [RFC PATCH v2 3/3] usb: typec: tcpm: Support for Alternate Modes Heikki Krogerus
2018-03-09 15:19   ` [RFC,v2,3/3] " Heikki Krogerus
2018-03-16 21:32   ` [RFC PATCH v2 3/3] " Guenter Roeck
2018-03-16 21:32     ` [RFC,v2,3/3] " Guenter Roeck
2018-03-19 12:15     ` [RFC PATCH v2 3/3] " Heikki Krogerus
2018-03-19 12:15       ` [RFC,v2,3/3] " Heikki Krogerus

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=20180319114237.GG11689@kuha.fi.intel.com \
    --to=heikki.krogerus@linux.intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=hdegoede@redhat.com \
    --cc=jun.li@nxp.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=rajaram.regupathy@intel.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.