All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] extcon: Inform the state of both ID and VBUS pin for USB
@ 2015-05-22 10:49 Chanwoo Choi
  2015-05-22 10:49 ` [PATCH 1/2] extcon: Add extcon_set_cable_line_state() to inform the additional state of external connectors Chanwoo Choi
  2015-05-22 10:49 ` [PATCH 2/2] extcon: usb-gpio: Update the ID pin state of USB when cable state is changed Chanwoo Choi
  0 siblings, 2 replies; 4+ messages in thread
From: Chanwoo Choi @ 2015-05-22 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: rogerq, r.baldyga, peter.chen, kishon, balbi, iivanov, cw00.choi,
	myungjoo.ham

Previously, I discussed how to inform the changed state of both ID
and VBUS pin for USB connector on patch-set[1].
[1] https://lkml.org/lkml/2015/4/2/310

So, this patch adds the extcon_set_cable_line_state() function to inform
the additional state of external connectors without additional register/
unregister functions. This function uses the existing notifier chain
which is registered by extcon_register_notifier() / extcon_register_interest().

The extcon_set_cable_line_state() can inform the new state of both
ID and VBUS pin state through extcon_set_cable_line_state().

For exmaple:
- On extcon-usb-gpio.c as extcon provider driver as following:
	static void usb_extcon_detect_cable(struct work_struct *work)
	{
		...
		/* check ID and update cable state */
		id = gpiod_get_value_cansleep(info->id_gpiod);
		if (id) {
			extcon_set_cable_state_(info->edev, EXTCON_USB_HOST, false);
			extcon_set_cable_state_(info->edev, EXTCON_USB, true);

			extcon_set_cable_line_state(info->edev, EXTCON_USB,
							EXTCON_USB_ID_HIGH);
		} else {
			extcon_set_cable_state_(info->edev, EXTCON_USB, false);
			extcon_set_cable_state_(info->edev, EXTCON_USB_HOST, true);

			extcon_set_cable_line_state(info->edev, EXTCON_USB,
							EXTCON_USB_ID_LOW);
		}
	}

- On specific extcon consumder driver as following:
	static int xxx_probe(struct platform_device *pdev)
	{
		struct notifier_chain nh;

		nb.notifier_call = extcon_usb_notifier;
		ret = extcon_register_notifier(edev, EXTCON_USB, &nb);
		...
	}

	static int extcon_usb_notifier(struct notifier_block *self,
		unsigned long event, void *ptr)
	{
		switch (event) {
		case EXTCON_DETACHED:
			printk("USB is detached\n");
			break;
		case EXTCON_ATTACHED:
			printk("USB is attached\n");
			break;

		case EXTCON_USB_ID_LOW:
			printk("USB's ID pin is low state\n");
			break;
		case EXTCON_USB_ID_HIGH:
			printk("USB's ID pin is high state\n");
			break;
		case EXTCON_USB_VBUS_LOW:
			printk("USB's VBUS pin is high state\n");
			break;
		case EXTCON_USB_VBUS_HIGH:
			printk("USB's VBUS pin is high state\n");
			break;
		default:
			return -EINVAL;
		};
	}

Chanwoo Choi (2):
  extcon: Add extcon_set_cable_line_state() to inform the additional state of external connectors
  extcon: usb-gpio: Update the ID pin state of USB when cable state is changed

 drivers/extcon/extcon-usb-gpio.c |  6 ++++
 drivers/extcon/extcon.c          | 74 +++++++++++++++++++++++++++++++++++++++-
 include/linux/extcon.h           | 24 +++++++++++++
 3 files changed, 103 insertions(+), 1 deletion(-)

-- 
1.8.5.5


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] extcon: Add extcon_set_cable_line_state() to inform the additional state of external connectors
  2015-05-22 10:49 [PATCH 0/2] extcon: Inform the state of both ID and VBUS pin for USB Chanwoo Choi
@ 2015-05-22 10:49 ` Chanwoo Choi
  2015-05-25  2:12   ` Peter Chen
  2015-05-22 10:49 ` [PATCH 2/2] extcon: usb-gpio: Update the ID pin state of USB when cable state is changed Chanwoo Choi
  1 sibling, 1 reply; 4+ messages in thread
From: Chanwoo Choi @ 2015-05-22 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: rogerq, r.baldyga, peter.chen, kishon, balbi, iivanov, cw00.choi,
	myungjoo.ham

This patch adds the extcon_set_cable_line_state() function to inform
the additional state of each external connector and 'enum extcon_line_state'
enumeration which include the specific states of each external connector.

The each external connector might need the different line state. So, current
'extcon_line_state' enumeration contains the specific state for USB as
following:

- Following the state mean the state of both ID and VBUS line for USB:
enum extcon_line_state {
	EXTCON_USB_ID_LOW	= BIT(1),	/* ID line is low. */
	EXTCON_USB_ID_HIGH	= BIT(2),	/* ID line is high. */
	EXTCON_USB_VBUS_LOW	= BIT(3),	/* VBUS line is low. */
	EXTCON_USB_VBUS_HIGH	= BIT(4),	/* VBUS line is high. */
};

Cc: Myungjoo Ham <cw00.choi@samsung.com>
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
---
 drivers/extcon/extcon.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++-
 include/linux/extcon.h  | 24 ++++++++++++++++
 2 files changed, 97 insertions(+), 1 deletion(-)

diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c
index 5099c11..2f7db54 100644
--- a/drivers/extcon/extcon.c
+++ b/drivers/extcon/extcon.c
@@ -279,7 +279,9 @@ int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state)
 
 		for (index = 0; index < edev->max_supported; index++) {
 			if (is_extcon_changed(edev->state, state, index, &attached))
-				raw_notifier_call_chain(&edev->nh[index], attached, edev);
+				raw_notifier_call_chain(&edev->nh[index],
+					attached ? EXTCON_ATTACHED :
+					EXTCON_DETACHED, edev);
 		}
 
 		edev->state &= ~mask;
@@ -418,6 +420,69 @@ int extcon_set_cable_state(struct extcon_dev *edev,
 EXPORT_SYMBOL_GPL(extcon_set_cable_state);
 
 /**
+ * extcon_set_cable_line_state() - Set the line state of specific cable.
+ * @edev:		the extcon device that has the cable.
+ * @id:			the unique id of each external connector.
+ * @state:		the line state for specific cable.
+ *
+ * Note that this function support the only USB connector to inform the state
+ * of both ID and VBUS line until now. This function may be extended to support
+ * the additional external connectors.
+ *
+ * If the id is EXTCON_USB, it can support only following line states:
+ * - EXTCON_USB_ID_LOW
+ * - EXTCON_USB_ID_HIGH,
+ * - EXTCON_USB_VBUS_LOW
+ * - EXTCON_USB_VBUS_HIGH
+ */
+int extcon_set_cable_line_state(struct extcon_dev *edev, enum extcon id,
+				enum extcon_line_state state)
+{
+	unsigned long flags;
+	unsigned long line_state;
+	int ret = 0, index;
+
+	index = find_cable_index_by_id(edev, id);
+	if (index < 0)
+		return index;
+
+	spin_lock_irqsave(&edev->lock, flags);
+	line_state = edev->line_state[index];
+
+	switch (id) {
+	case EXTCON_USB:
+		if (line_state & state) {
+			dev_info(&edev->dev,
+				"0x%x state is already set for %s\n",
+				state, extcon_name[id]);
+			goto err;
+		}
+
+		if ((state & EXTCON_USB_ID_LOW) || (state & EXTCON_USB_ID_HIGH))
+			line_state &= ~(EXTCON_USB_ID_LOW | EXTCON_USB_ID_HIGH);
+
+		if ((state & EXTCON_USB_VBUS_LOW)
+			|| (state & EXTCON_USB_VBUS_HIGH))
+			line_state &=
+				~(EXTCON_USB_VBUS_LOW | EXTCON_USB_VBUS_HIGH);
+
+		line_state |= state;
+		break;
+	default:
+		ret = -EINVAL;
+		goto err;
+	}
+	edev->line_state[index] = line_state;
+
+	ret = raw_notifier_call_chain(&edev->nh[index], line_state, edev);
+err:
+	spin_unlock_irqrestore(&edev->lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(extcon_set_cable_line_state);
+
+/**
  * extcon_get_extcon_dev() - Get the extcon device instance from the name
  * @extcon_name:	The extcon name provided with extcon_dev_register()
  */
@@ -897,6 +962,13 @@ int extcon_dev_register(struct extcon_dev *edev)
 		goto err_dev;
 	}
 
+	edev->line_state = devm_kzalloc(&edev->dev,
+		sizeof(*edev->line_state) * edev->max_supported, GFP_KERNEL);
+	if (!edev->line_state) {
+		ret = -ENOMEM;
+		goto err_dev;
+	}
+
 	for (index = 0; index < edev->max_supported; index++)
 		RAW_INIT_NOTIFIER_HEAD(&edev->nh[index]);
 
diff --git a/include/linux/extcon.h b/include/linux/extcon.h
index be9652b..79e5073 100644
--- a/include/linux/extcon.h
+++ b/include/linux/extcon.h
@@ -66,6 +66,19 @@ enum extcon {
 	EXTCON_END,
 };
 
+enum extcon_line_state {
+	/* Following two definition are used for whether external connectors
+	 * is attached or detached. */
+	EXTCON_DETACHED		= 0x0,
+	EXTCON_ATTACHED		= 0x1,
+
+	/* Following states are only used for EXTCON_USB. */
+	EXTCON_USB_ID_LOW	= BIT(1),	/* ID line is low. */
+	EXTCON_USB_ID_HIGH	= BIT(2),	/* ID line is high. */
+	EXTCON_USB_VBUS_LOW	= BIT(3),	/* VBUS line is low. */
+	EXTCON_USB_VBUS_HIGH	= BIT(4),	/* VBUS line is high. */
+};
+
 struct extcon_cable;
 
 /**
@@ -90,6 +103,8 @@ struct extcon_cable;
  * @dev:		Device of this extcon.
  * @state:		Attach/detach state of this extcon. Do not provide at
  *			register-time.
+ * @line_state:		Line state for each external connecotrs are included in
+ *			this extcon device.
  * @nh:			Notifier for the state change events from this extcon
  * @entry:		To support list of extcon devices so that users can
  *			search for extcon devices based on the extcon name.
@@ -121,6 +136,7 @@ struct extcon_dev {
 	int max_supported;
 	spinlock_t lock;	/* could be called by irq handler */
 	u32 state;
+	unsigned long *line_state;
 
 	/* /sys/class/extcon/.../cable.n/... */
 	struct device_type extcon_dev_type;
@@ -217,6 +233,8 @@ extern int extcon_get_cable_state(struct extcon_dev *edev,
 				  const char *cable_name);
 extern int extcon_set_cable_state(struct extcon_dev *edev,
 				  const char *cable_name, bool cable_state);
+extern int extcon_set_cable_line_state(struct extcon_dev *edev, enum extcon id,
+					enum extcon_line_state state);
 
 /*
  * Following APIs are for notifiees (those who want to be notified)
@@ -324,6 +342,12 @@ static inline int extcon_set_cable_state(struct extcon_dev *edev,
 	return 0;
 }
 
+static inline int extcon_set_cable_line_state(struct extcon_dev *edev,
+			enum extcon id, enum extcon_line_state state)
+{
+	return 0;
+}
+
 static inline struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name)
 {
 	return NULL;
-- 
1.8.5.5


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] extcon: usb-gpio: Update the ID pin state of USB when cable state is changed
  2015-05-22 10:49 [PATCH 0/2] extcon: Inform the state of both ID and VBUS pin for USB Chanwoo Choi
  2015-05-22 10:49 ` [PATCH 1/2] extcon: Add extcon_set_cable_line_state() to inform the additional state of external connectors Chanwoo Choi
@ 2015-05-22 10:49 ` Chanwoo Choi
  1 sibling, 0 replies; 4+ messages in thread
From: Chanwoo Choi @ 2015-05-22 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: rogerq, r.baldyga, peter.chen, kishon, balbi, iivanov, cw00.choi,
	myungjoo.ham

This patch updates the ID pin state of USB when cable state is changed
by using the extcon_set_cable_line_state() function. The extcon consumer driver
can receive the changed ID pin state through registered notifier chain of
extcon consumer driver.

Cc: Roger Quadros <rogerq@ti.com>
Cc: Robert Baldyga <r.baldyga@samsung.com>
Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
---
 drivers/extcon/extcon-usb-gpio.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/extcon/extcon-usb-gpio.c b/drivers/extcon/extcon-usb-gpio.c
index 14da94c..9ff3171 100644
--- a/drivers/extcon/extcon-usb-gpio.c
+++ b/drivers/extcon/extcon-usb-gpio.c
@@ -62,12 +62,18 @@ static void usb_extcon_detect_cable(struct work_struct *work)
 		 */
 		extcon_set_cable_state_(info->edev, EXTCON_USB_HOST, false);
 		extcon_set_cable_state_(info->edev, EXTCON_USB, true);
+
+		extcon_set_cable_line_state(info->edev, EXTCON_USB,
+						EXTCON_USB_ID_HIGH);
 	} else {
 		/*
 		 * ID = 0 means USB HOST cable attached.
 		 * As we don't have event for USB peripheral cable detached,
 		 * we simulate USB peripheral detach here.
 		 */
+		extcon_set_cable_line_state(info->edev, EXTCON_USB,
+						EXTCON_USB_ID_LOW);
+
 		extcon_set_cable_state_(info->edev, EXTCON_USB, false);
 		extcon_set_cable_state_(info->edev, EXTCON_USB_HOST, true);
 	}
-- 
1.8.5.5


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] extcon: Add extcon_set_cable_line_state() to inform the additional state of external connectors
  2015-05-22 10:49 ` [PATCH 1/2] extcon: Add extcon_set_cable_line_state() to inform the additional state of external connectors Chanwoo Choi
@ 2015-05-25  2:12   ` Peter Chen
  0 siblings, 0 replies; 4+ messages in thread
From: Peter Chen @ 2015-05-25  2:12 UTC (permalink / raw)
  To: Chanwoo Choi
  Cc: linux-kernel, rogerq, r.baldyga, kishon, balbi, iivanov,
	myungjoo.ham

On Fri, May 22, 2015 at 07:49:49PM +0900, Chanwoo Choi wrote:
> This patch adds the extcon_set_cable_line_state() function to inform
> the additional state of each external connector and 'enum extcon_line_state'
> enumeration which include the specific states of each external connector.
> 
> The each external connector might need the different line state. So, current
> 'extcon_line_state' enumeration contains the specific state for USB as
> following:
> 
> - Following the state mean the state of both ID and VBUS line for USB:
> enum extcon_line_state {
> 	EXTCON_USB_ID_LOW	= BIT(1),	/* ID line is low. */
> 	EXTCON_USB_ID_HIGH	= BIT(2),	/* ID line is high. */
> 	EXTCON_USB_VBUS_LOW	= BIT(3),	/* VBUS line is low. */
> 	EXTCON_USB_VBUS_HIGH	= BIT(4),	/* VBUS line is high. */
> };
> 
> Cc: Myungjoo Ham <cw00.choi@samsung.com>
> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
> ---
>  drivers/extcon/extcon.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++-
>  include/linux/extcon.h  | 24 ++++++++++++++++
>  2 files changed, 97 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c
> index 5099c11..2f7db54 100644
> --- a/drivers/extcon/extcon.c
> +++ b/drivers/extcon/extcon.c
> @@ -279,7 +279,9 @@ int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state)
>  
>  		for (index = 0; index < edev->max_supported; index++) {
>  			if (is_extcon_changed(edev->state, state, index, &attached))
> -				raw_notifier_call_chain(&edev->nh[index], attached, edev);
> +				raw_notifier_call_chain(&edev->nh[index],
> +					attached ? EXTCON_ATTACHED :
> +					EXTCON_DETACHED, edev);
>  		}
>  
>  		edev->state &= ~mask;
> @@ -418,6 +420,69 @@ int extcon_set_cable_state(struct extcon_dev *edev,
>  EXPORT_SYMBOL_GPL(extcon_set_cable_state);
>  
>  /**
> + * extcon_set_cable_line_state() - Set the line state of specific cable.
> + * @edev:		the extcon device that has the cable.
> + * @id:			the unique id of each external connector.
> + * @state:		the line state for specific cable.
> + *
> + * Note that this function support the only USB connector to inform the state
> + * of both ID and VBUS line until now. This function may be extended to support
> + * the additional external connectors.
> + *
> + * If the id is EXTCON_USB, it can support only following line states:
> + * - EXTCON_USB_ID_LOW
> + * - EXTCON_USB_ID_HIGH,
> + * - EXTCON_USB_VBUS_LOW
> + * - EXTCON_USB_VBUS_HIGH
> + */
> +int extcon_set_cable_line_state(struct extcon_dev *edev, enum extcon id,
> +				enum extcon_line_state state)
> +{
> +	unsigned long flags;
> +	unsigned long line_state;
> +	int ret = 0, index;
> +
> +	index = find_cable_index_by_id(edev, id);
> +	if (index < 0)
> +		return index;
> +
> +	spin_lock_irqsave(&edev->lock, flags);
> +	line_state = edev->line_state[index];
> +
> +	switch (id) {
> +	case EXTCON_USB:
> +		if (line_state & state) {
> +			dev_info(&edev->dev,
> +				"0x%x state is already set for %s\n",
> +				state, extcon_name[id]);
> +			goto err;
> +		}

dev_warning?


-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-05-25  2:13 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-22 10:49 [PATCH 0/2] extcon: Inform the state of both ID and VBUS pin for USB Chanwoo Choi
2015-05-22 10:49 ` [PATCH 1/2] extcon: Add extcon_set_cable_line_state() to inform the additional state of external connectors Chanwoo Choi
2015-05-25  2:12   ` Peter Chen
2015-05-22 10:49 ` [PATCH 2/2] extcon: usb-gpio: Update the ID pin state of USB when cable state is changed Chanwoo Choi

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.