[v12,2/4] gadget: Support for the usb charger framework

Message ID f7bae2566824a5e1da14c1a19dee6af5f250262f.1466497506.git.baolin.wang@linaro.org
State New
Headers show

Commit Message

(Exiting) Baolin Wang June 21, 2016, 8:39 a.m.
For supporting the usb charger, it adds the usb_charger_init() and
usb_charger_exit() functions for usb charger initialization and exit.

It will report to the usb charger when the gadget state is changed,
then the usb charger can do the power things.

Signed-off-by: Baolin Wang <baolin.wang@linaro.org>

Reviewed-by: Li Jun <jun.li@nxp.com>

Tested-by: Li Jun <jun.li@nxp.com>

 drivers/usb/gadget/udc/udc-core.c |   11 +++++++++++
 include/linux/usb/gadget.h        |   11 +++++++++++
 2 files changed, 22 insertions(+)


To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


(Exiting) Baolin Wang June 22, 2016, 1:45 a.m. | #1
On 21 June 2016 at 20:53, Felipe Balbi <balbi@kernel.org> wrote:

> Hi,


> Baolin Wang <baolin.wang@linaro.org> writes:

>>>>>>>>> Can't you just tie a charger to a UDC and avoid the charger class

>>>>>>>>> completely?


>>>>>>>> Yeah, I also hope so. But we really want something to manage the

>>>>>>>> charger devices, do you have any good suggestion to avoid the 'class'

>>>>>>>> but also can manage the charger devices?


>>>>>>> manage in what way? It seems to me that they don't need to be real

>>>>>>> devices, just a handle as part of struct usb_gadget, no?


>>>>>> Although charger device is not one real hardware device, we also use

>>>>>> one 'struct device' to describe it in charger.c file. So we should

>>>>>> manage the 'struct device' with one proper way.


>>>>> that's fine, but why do you think they need a struct device to start with?


>>>> We can get/put usb charger and mange usb charger attributes with the

>>>> device model if we use a struct device.


>>> We already have that as part of struct usb_udc. Why don't you just

>>> create a subdirectory called charger which will hold all your

>>> charger-related attributes. That directory will only be created if a

>>> valid ->charger pointer exists.


>> That means we can remove all the device and class things in charger.c

>> file, right? OK, I try to do that. Thanks.


> right. Keep your charger.c file, because to conditionally compile and

> link that to udc-core.ko, but remove all the class initialization and

> all of that extra code.

Make sense.

Best Regards
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
index 6e8300d..84c098c 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -28,6 +28,7 @@ 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb.h>
+#include <linux/usb/charger.h>
  * struct usb_udc - describes one usb device controller
@@ -242,6 +243,9 @@  static void usb_gadget_state_work(struct work_struct *work)
 	struct usb_gadget *gadget = work_to_gadget(work);
 	struct usb_udc *udc = gadget->udc;
+	/* when the gadget state is changed, then report to USB charger */
+	usb_charger_plug_by_gadget(gadget, gadget->state);
 	if (udc)
 		sysfs_notify(&udc->dev.kobj, NULL, "state");
@@ -411,6 +415,10 @@  int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
 	if (ret)
 		goto err4;
+	ret = usb_charger_init(gadget);
+	if (ret)
+		goto err5;
 	usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
 	udc->vbus = true;
@@ -431,6 +439,8 @@  int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
 	return 0;
+	device_del(&udc->dev);
@@ -539,6 +549,7 @@  void usb_del_gadget_udc(struct usb_gadget *gadget)
 	kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE);
+	usb_charger_exit(gadget);
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 457651b..40390ec 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -24,6 +24,7 @@ 
 #include <linux/types.h>
 #include <linux/workqueue.h>
 #include <linux/usb/ch9.h>
+#include <linux/usb/charger.h>
 struct usb_ep;
@@ -639,6 +640,8 @@  struct usb_gadget {
 	unsigned			out_epnum;
 	unsigned			in_epnum;
 	struct usb_otg_caps		*otg_caps;
+	/* negotiate the power with the usb charger */
+	struct usb_charger		*charger;
 	unsigned			sg_supported:1;
 	unsigned			is_otg:1;
@@ -855,10 +858,18 @@  static inline int usb_gadget_vbus_connect(struct usb_gadget *gadget)
  * reporting how much power the device may consume.  For example, this
  * could affect how quickly batteries are recharged.
+ * It will also notify the USB charger how much power the device may
+ * consume if there is a USB charger linking with the gadget.
+ *
  * Returns zero on success, else negative errno.
 static inline int usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA)
+	if (gadget->charger)
+		usb_charger_set_cur_limit_by_type(gadget->charger,
+						  gadget->charger->type,
+						  mA);
 	if (!gadget->ops->vbus_draw)
 		return -EOPNOTSUPP;
 	return gadget->ops->vbus_draw(gadget, mA);