g-np-tx-fifo-size = <32>;
g-rx-fifo-size = <256>;
g-tx-fifo-size = <512 512 512 512 512 256 256>;
- g-extcon-notify;
status = "okay";
};
CONFIG_USB_STORAGE=y
CONFIG_USB_UAS=y
CONFIG_USB_DWC2=y
-CONFIG_USB_DWC2_EXTCON_NOTIFY=y
CONFIG_USB_SERIAL=y
CONFIG_USB_SERIAL_GENERIC=y
CONFIG_USB_SERIAL_CP210X=m
option requires USB_GADGET to be enabled.
endchoice
-config USB_DWC2_EXTCON_NOTIFY
- bool "Enable Extcon Notification"
- depends on USB_DWC2_PERIPHERAL || USB_DWC2_DUAL_ROLE
- default n
- select EXTCON
- help
- Say Y here to enable extcon notification using dwc2 gadget irq for
- the target without port gpio interrupt support or external detector.
-
config USB_DWC2_PCI
tristate "DWC2 PCI"
depends on USB_PCI
ifneq ($(filter y,$(CONFIG_USB_DWC2_PERIPHERAL) $(CONFIG_USB_DWC2_DUAL_ROLE)),)
dwc2-y += gadget.o
- dwc2-$(CONFIG_USB_DWC2_EXTCON_NOTIFY) += extcon.o
endif
ifneq ($(CONFIG_DEBUG_FS),)
#include <linux/usb/gadget.h>
#include <linux/usb/otg.h>
#include <linux/usb/phy.h>
-#include <linux/extcon-provider.h>
#include "hw.h"
/*
u32 g_rx_fifo_size;
u32 g_np_tx_fifo_size;
u32 g_tx_fifo_size[MAX_EPS_CHANNELS];
-#if IS_ENABLED(CONFIG_USB_DWC2_EXTCON_NOTIFY)
- u32 g_extcon_notify;
-#endif
bool change_speed_quirk;
};
struct dwc2_hsotg_ep *eps_in[MAX_EPS_CHANNELS];
struct dwc2_hsotg_ep *eps_out[MAX_EPS_CHANNELS];
-#if IS_ENABLED(CONFIG_USB_DWC2_EXTCON_NOTIFY)
- struct extcon_dev *edev;
- struct delayed_work extcon_work;
- unsigned int extcon_state;
-#endif /* CONFIG_DWC2_EXTCON_NOTIFY */
#endif /* CONFIG_USB_DWC2_PERIPHERAL || CONFIG_USB_DWC2_DUAL_ROLE */
};
int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg);
int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg);
void dwc2_gadget_init_lpm(struct dwc2_hsotg *hsotg);
-#if IS_ENABLED(CONFIG_USB_DWC2_EXTCON_NOTIFY)
-void dwc2_gadget_extcon_notify(struct dwc2_hsotg *hsotg, bool on);
-void dwc2_gadget_cancel_extcon_work(struct dwc2_hsotg *hsotg);
-int dwc2_gadget_extcon_init(struct dwc2_hsotg *hsotg);
-#else
-static inline void dwc2_gadget_extcon_notify(struct dwc2_hsotg *hsotg,
- bool on) {}
-static inline void dwc2_gadget_cancel_extcon_work(struct dwc2_hsotg *hsotg) {}
-static inline int dwc2_gadget_extcon_init(struct dwc2_hsotg *hsotg)
-{ return 0; }
-#endif
#else
static inline int dwc2_hsotg_remove(struct dwc2_hsotg *dwc2)
{ return 0; }
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C USB2.0 High-speed / Extcon Notification Driver
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include "core.h"
-#include "hw.h"
-
-#define DWC2_EXTCON_NOTIFY_DELAY 10 /* msec */
-
-static const unsigned int supported_cable[] = {
- EXTCON_USB,
- EXTCON_NONE,
-};
-
-void dwc2_gadget_extcon_notify(struct dwc2_hsotg *hsotg, bool on)
-{
- if (!hsotg->params.g_extcon_notify)
- return;
-
- hsotg->extcon_state = on;
-
- if (delayed_work_pending(&hsotg->extcon_work))
- cancel_delayed_work(&hsotg->extcon_work);
-
- queue_delayed_work(system_power_efficient_wq, &hsotg->extcon_work,
- msecs_to_jiffies(DWC2_EXTCON_NOTIFY_DELAY));
-}
-
-void dwc2_gadget_cancel_extcon_work(struct dwc2_hsotg *hsotg)
-{
- if (!hsotg->params.g_extcon_notify)
- return;
-
- cancel_delayed_work_sync(&hsotg->extcon_work);
-}
-
-static void dwc2_gadget_extcon_work(struct work_struct *work)
-{
- struct dwc2_hsotg *hsotg = container_of(to_delayed_work(work),
- struct dwc2_hsotg,
- extcon_work);
-
- extcon_set_state_sync(hsotg->edev, EXTCON_USB, hsotg->extcon_state);
-}
-
-int dwc2_gadget_extcon_init(struct dwc2_hsotg *hsotg)
-{
- struct device *dev = hsotg->dev;
- struct extcon_dev *edev;
- int ret;
-
- if (!hsotg->params.g_extcon_notify)
- return 0;
-
- edev = devm_extcon_dev_allocate(dev, supported_cable);
- if (IS_ERR(edev))
- return -ENODEV;
-
- ret = devm_extcon_dev_register(dev, edev);
- if (ret)
- return ret;
-
- hsotg->edev = edev;
-
- INIT_DELAYED_WORK(&hsotg->extcon_work, dwc2_gadget_extcon_work);
-
- /*
- * HACK: In order to give chance to setup gadget for user-space
- * daemon, force extcon state as connected initially. After udc is
- * successfully binded, the state will be updated as following
- * the cable connection state.
- */
- dwc2_gadget_extcon_notify(hsotg, true);
- hsotg->connected = 1;
-
- return 0;
-}
dwc2_writel(hsotg, GINTSTS_ENUMDONE, GINTSTS);
dwc2_hsotg_irq_enumdone(hsotg);
-
- dwc2_gadget_extcon_notify(hsotg, true);
}
if (gintsts & (GINTSTS_OEPINT | GINTSTS_IEPINT)) {
if (gintsts & GINTSTS_ERLYSUSP) {
dev_dbg(hsotg->dev, "GINTSTS_ErlySusp\n");
dwc2_writel(hsotg, GINTSTS_ERLYSUSP, GINTSTS);
-
- /*
- * we assume early suspend interrupt as disconnection
- * signal when connected state is true.
- */
- if (hsotg->connected)
- dwc2_gadget_extcon_notify(hsotg, false);
}
/*
dwc2_enable_acg(hsotg);
dwc2_hsotg_core_connect(hsotg);
} else {
- /*
- * If gadget disconnection makes also PHY pullup
- * disconnection, usb controller cannot generate
- * interrupt for usb connection and thus extcon
- * notification won't be working. In order to prevent
- * this situation, we have to keep PHY pullup alive
- * when extcon notification is activated.
- */
- if (hsotg->params.g_extcon_notify)
- goto skip_disconnect;
dwc2_hsotg_core_disconnect(hsotg);
dwc2_hsotg_disconnect(hsotg);
hsotg->enabled = 0;
}
-skip_disconnect:
hsotg->gadget.speed = USB_SPEED_UNKNOWN;
spin_unlock_irqrestore(&hsotg->lock, flags);
else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
hsotg->op_state = OTG_STATE_B_PERIPHERAL;
- ret = dwc2_gadget_extcon_init(hsotg);
- if (ret) {
- dev_err(dev, "failed to initialize extcon device");
- return ret;
- }
-
ret = dwc2_hsotg_hw_cfg(hsotg);
if (ret) {
dev_err(hsotg->dev, "Hardware configuration failed: %d\n", ret);
*/
int dwc2_hsotg_remove(struct dwc2_hsotg *hsotg)
{
- dwc2_gadget_cancel_extcon_work(hsotg);
usb_del_gadget_udc(&hsotg->gadget);
dwc2_hsotg_ep_free_request(&hsotg->eps_out[0]->ep, hsotg->ctrl_req);
if (hsotg->lx_state != DWC2_L0)
return 0;
- dwc2_gadget_cancel_extcon_work(hsotg);
-
if (hsotg->driver) {
int ep;
&p->g_tx_fifo_size[1],
num);
}
-#if IS_ENABLED(CONFIG_USB_DWC2_EXTCON_NOTIFY)
- if (of_find_property(hsotg->dev->of_node,
- "g-extcon-notify", NULL))
- p->g_extcon_notify = true;
-#endif
}
if (of_find_property(hsotg->dev->of_node, "disable-over-current", NULL))