USB fixes for 5.13-rc6

Here are a number of tiny USB fixes for 5.13-rc6.
 
 There are more than I would normally like, but there's been a bunch of
 people banging on the gadget and dwc3 and typec code recently for I
 think an Android release, which has resulted in a number of small fixes.
 It's nice to see companies send fixes upstream for this type of work, a
 notable change from years ago.
 
 Anyway, fixes in here are:
 	- usb-serial device id updates
 	- usb-serial cp210x driver fixes for broken firmware versions
 	- typec fixes for crazy charging devices and other reported
 	  problems
 	- dwc3 fixes for reported problems found
 	- gadget fixes for reported problems
 	- tiny xhci fixes
 	- other small fixes for reported issues.
 	- revert of a problem fix found by linux-next testing
 
 All of these have passed 0-day and linux-next testing with no reported
 problems (the revert for the found linux-next build problem included).
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCYMS6uA8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+yknTgCeKSmtJABTIcZ3LLRgArqUFEroUqEAni2ZRv/8
 3mGzeXFKvvoEO/WoILmV
 =WqGE
 -----END PGP SIGNATURE-----

Merge tag 'usb-5.13-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB fixes from Greg KH:
 "Here are a number of tiny USB fixes for 5.13-rc6.

  There are more than I would normally like, but there's been a bunch of
  people banging on the gadget and dwc3 and typec code recently for I
  think an Android release, which has resulted in a number of small
  fixes. It's nice to see companies send fixes upstream for this type of
  work, a notable change from years ago.

  Anyway, fixes in here are:

   - usb-serial device id updates

   - usb-serial cp210x driver fixes for broken firmware versions

   - typec fixes for crazy charging devices and other reported problems

   - dwc3 fixes for reported problems found

   - gadget fixes for reported problems

   - tiny xhci fixes

   - other small fixes for reported issues.

   - revert of a problem fix found by linux-next testing

  All of these have passed 0-day and linux-next testing with no reported
  problems (the revert for the found linux-next build problem included)"

* tag 'usb-5.13-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (44 commits)
  Revert "usb: gadget: fsl: Re-enable driver for ARM SoCs"
  usb: typec: mux: Fix copy-paste mistake in typec_mux_match
  usb: typec: ucsi: Clear PPM capability data in ucsi_init() error path
  usb: gadget: fsl: Re-enable driver for ARM SoCs
  usb: typec: wcove: Use LE to CPU conversion when accessing msg->header
  USB: serial: cp210x: fix CP2102N-A01 modem control
  USB: serial: cp210x: fix alternate function for CP2102N QFN20
  usb: misc: brcmstb-usb-pinmap: check return value after calling platform_get_resource()
  usb: dwc3: ep0: fix NULL pointer exception
  usb: gadget: eem: fix wrong eem header operation
  usb: typec: intel_pmc_mux: Put ACPI device using acpi_dev_put()
  usb: typec: intel_pmc_mux: Add missed error check for devm_ioremap_resource()
  usb: typec: intel_pmc_mux: Put fwnode in error case during ->probe()
  usb: typec: tcpm: Do not finish VDM AMS for retrying Responses
  usb: fix various gadget panics on 10gbps cabling
  usb: fix various gadgets null ptr deref on 10gbps cabling.
  usb: pci-quirks: disable D3cold on xhci suspend for s2idle on AMD Renoir
  usb: f_ncm: only first packet of aggregate needs to start timer
  USB: f_ncm: ncm_bitrate (speed) is unsigned
  MAINTAINERS: usb: add entry for isp1760
  ...
This commit is contained in:
Linus Torvalds 2021-06-12 12:34:49 -07:00
commit 43cb5d49a9
40 changed files with 357 additions and 144 deletions

View File

@ -149,6 +149,17 @@ properties:
maxItems: 6
$ref: /schemas/types.yaml#/definitions/uint32-array
sink-vdos-v1:
description: An array of u32 with each entry, a Vendor Defined Message Object (VDO),
providing additional information corresponding to the product, the detailed bit
definitions and the order of each VDO can be found in
"USB Power Delivery Specification Revision 2.0, Version 1.3" chapter 6.4.4.3.1 Discover
Identity. User can specify the VDO array via VDO_IDH/_CERT/_PRODUCT/_CABLE/_AMA defined in
dt-bindings/usb/pd.h.
minItems: 3
maxItems: 6
$ref: /schemas/types.yaml#/definitions/uint32-array
op-sink-microwatt:
description: Sink required operating power in microwatt, if source can't
offer the power, Capability Mismatch is set. Required for power sink and
@ -207,6 +218,10 @@ properties:
SNK_READY for non-pd link.
type: boolean
dependencies:
sink-vdos-v1: [ 'sink-vdos' ]
sink-vdos: [ 'sink-vdos-v1' ]
required:
- compatible

View File

@ -18873,6 +18873,13 @@ S: Maintained
F: drivers/usb/host/isp116x*
F: include/linux/usb/isp116x.h
USB ISP1760 DRIVER
M: Rui Miguel Silva <rui.silva@linaro.org>
L: linux-usb@vger.kernel.org
S: Maintained
F: drivers/usb/isp1760/*
F: Documentation/devicetree/bindings/usb/nxp,isp1760.yaml
USB LAN78XX ETHERNET DRIVER
M: Woojung Huh <woojung.huh@microchip.com>
M: UNGLinuxDriver@microchip.com

View File

@ -2007,7 +2007,7 @@ static void cdns3_configure_dmult(struct cdns3_device *priv_dev,
else
mask = BIT(priv_ep->num);
if (priv_ep->type != USB_ENDPOINT_XFER_ISOC) {
if (priv_ep->type != USB_ENDPOINT_XFER_ISOC && !priv_ep->dir) {
cdns3_set_register_bit(&regs->tdl_from_trb, mask);
cdns3_set_register_bit(&regs->tdl_beh, mask);
cdns3_set_register_bit(&regs->tdl_beh2, mask);
@ -2046,15 +2046,13 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable)
case USB_ENDPOINT_XFER_INT:
ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_INT);
if ((priv_dev->dev_ver == DEV_VER_V2 && !priv_ep->dir) ||
priv_dev->dev_ver > DEV_VER_V2)
if (priv_dev->dev_ver >= DEV_VER_V2 && !priv_ep->dir)
ep_cfg |= EP_CFG_TDL_CHK;
break;
case USB_ENDPOINT_XFER_BULK:
ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_BULK);
if ((priv_dev->dev_ver == DEV_VER_V2 && !priv_ep->dir) ||
priv_dev->dev_ver > DEV_VER_V2)
if (priv_dev->dev_ver >= DEV_VER_V2 && !priv_ep->dir)
ep_cfg |= EP_CFG_TDL_CHK;
break;
default:

View File

@ -1517,13 +1517,14 @@ irqreturn_t cdnsp_thread_irq_handler(int irq, void *data)
{
struct cdnsp_device *pdev = (struct cdnsp_device *)data;
union cdnsp_trb *event_ring_deq;
unsigned long flags;
int counter = 0;
spin_lock(&pdev->lock);
spin_lock_irqsave(&pdev->lock, flags);
if (pdev->cdnsp_state & (CDNSP_STATE_HALTED | CDNSP_STATE_DYING)) {
cdnsp_died(pdev);
spin_unlock(&pdev->lock);
spin_unlock_irqrestore(&pdev->lock, flags);
return IRQ_HANDLED;
}
@ -1539,7 +1540,7 @@ irqreturn_t cdnsp_thread_irq_handler(int irq, void *data)
cdnsp_update_erst_dequeue(pdev, event_ring_deq, 1);
spin_unlock(&pdev->lock);
spin_unlock_irqrestore(&pdev->lock, flags);
return IRQ_HANDLED;
}

View File

@ -1690,11 +1690,6 @@ static int dwc3_remove(struct platform_device *pdev)
return 0;
}
static void dwc3_shutdown(struct platform_device *pdev)
{
dwc3_remove(pdev);
}
#ifdef CONFIG_PM
static int dwc3_core_init_for_resume(struct dwc3 *dwc)
{
@ -2012,7 +2007,6 @@ MODULE_DEVICE_TABLE(acpi, dwc3_acpi_match);
static struct platform_driver dwc3_driver = {
.probe = dwc3_probe,
.remove = dwc3_remove,
.shutdown = dwc3_shutdown,
.driver = {
.name = "dwc3",
.of_match_table = of_match_ptr(of_dwc3_match),

View File

@ -413,9 +413,12 @@ static inline const char *dwc3_gadget_generic_cmd_status_string(int status)
#ifdef CONFIG_DEBUG_FS
extern void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep);
extern void dwc3_debugfs_init(struct dwc3 *d);
extern void dwc3_debugfs_exit(struct dwc3 *d);
#else
static inline void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep)
{ }
static inline void dwc3_debugfs_init(struct dwc3 *d)
{ }
static inline void dwc3_debugfs_exit(struct dwc3 *d)

View File

@ -886,30 +886,14 @@ static void dwc3_debugfs_create_endpoint_files(struct dwc3_ep *dep,
}
}
static void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep,
struct dentry *parent)
void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep)
{
struct dentry *dir;
dir = debugfs_create_dir(dep->name, parent);
dir = debugfs_create_dir(dep->name, dep->dwc->root);
dwc3_debugfs_create_endpoint_files(dep, dir);
}
static void dwc3_debugfs_create_endpoint_dirs(struct dwc3 *dwc,
struct dentry *parent)
{
int i;
for (i = 0; i < dwc->num_eps; i++) {
struct dwc3_ep *dep = dwc->eps[i];
if (!dep)
continue;
dwc3_debugfs_create_endpoint_dir(dep, parent);
}
}
void dwc3_debugfs_init(struct dwc3 *dwc)
{
struct dentry *root;
@ -940,7 +924,6 @@ void dwc3_debugfs_init(struct dwc3 *dwc)
&dwc3_testmode_fops);
debugfs_create_file("link_state", 0644, root, dwc,
&dwc3_link_state_fops);
dwc3_debugfs_create_endpoint_dirs(dwc, root);
}
}

View File

@ -651,7 +651,7 @@ static int dwc3_meson_g12a_setup_regmaps(struct dwc3_meson_g12a *priv,
return PTR_ERR(priv->usb_glue_regmap);
/* Create a regmap for each USB2 PHY control register set */
for (i = 0; i < priv->usb2_ports; i++) {
for (i = 0; i < priv->drvdata->num_phys; i++) {
struct regmap_config u2p_regmap_config = {
.reg_bits = 8,
.val_bits = 32,
@ -659,6 +659,9 @@ static int dwc3_meson_g12a_setup_regmaps(struct dwc3_meson_g12a *priv,
.max_register = U2P_R1,
};
if (!strstr(priv->drvdata->phy_names[i], "usb2"))
continue;
u2p_regmap_config.name = devm_kasprintf(priv->dev, GFP_KERNEL,
"u2p-%d", i);
if (!u2p_regmap_config.name)
@ -772,13 +775,13 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
ret = priv->drvdata->usb_init(priv);
if (ret)
goto err_disable_clks;
goto err_disable_regulator;
/* Init PHYs */
for (i = 0 ; i < PHY_COUNT ; ++i) {
ret = phy_init(priv->phys[i]);
if (ret)
goto err_disable_clks;
goto err_disable_regulator;
}
/* Set PHY Power */
@ -816,6 +819,10 @@ err_phys_exit:
for (i = 0 ; i < PHY_COUNT ; ++i)
phy_exit(priv->phys[i]);
err_disable_regulator:
if (priv->vbus)
regulator_disable(priv->vbus);
err_disable_clks:
clk_bulk_disable_unprepare(priv->drvdata->num_clks,
priv->drvdata->clks);

View File

@ -292,6 +292,9 @@ static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le)
epnum |= 1;
dep = dwc->eps[epnum];
if (dep == NULL)
return NULL;
if (dep->flags & DWC3_EP_ENABLED)
return dep;

View File

@ -2261,13 +2261,10 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
}
/*
* Synchronize any pending event handling before executing the controller
* halt routine.
* Synchronize and disable any further event handling while controller
* is being enabled/disabled.
*/
if (!is_on) {
dwc3_gadget_disable_irq(dwc);
synchronize_irq(dwc->irq_gadget);
}
disable_irq(dwc->irq_gadget);
spin_lock_irqsave(&dwc->lock, flags);
@ -2305,6 +2302,8 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
ret = dwc3_gadget_run_stop(dwc, is_on, false);
spin_unlock_irqrestore(&dwc->lock, flags);
enable_irq(dwc->irq_gadget);
pm_runtime_put(dwc->dev);
return ret;
@ -2754,6 +2753,8 @@ static int dwc3_gadget_init_endpoint(struct dwc3 *dwc, u8 epnum)
INIT_LIST_HEAD(&dep->started_list);
INIT_LIST_HEAD(&dep->cancelled_list);
dwc3_debugfs_create_endpoint_dir(dep);
return 0;
}
@ -2797,6 +2798,7 @@ static void dwc3_gadget_free_endpoints(struct dwc3 *dwc)
list_del(&dep->endpoint.ep_list);
}
debugfs_remove_recursive(debugfs_lookup(dep->name, dwc->root));
kfree(dep);
}
}
@ -4046,6 +4048,7 @@ err5:
dwc3_gadget_free_endpoints(dwc);
err4:
usb_put_gadget(dwc->gadget);
dwc->gadget = NULL;
err3:
dma_free_coherent(dwc->sysdev, DWC3_BOUNCE_SIZE, dwc->bounce,
dwc->bounce_addr);
@ -4065,6 +4068,9 @@ err0:
void dwc3_gadget_exit(struct dwc3 *dwc)
{
if (!dwc->gadget)
return;
usb_del_gadget(dwc->gadget);
dwc3_gadget_free_endpoints(dwc);
usb_put_gadget(dwc->gadget);

View File

@ -164,6 +164,14 @@ int usb_assign_descriptors(struct usb_function *f,
{
struct usb_gadget *g = f->config->cdev->gadget;
/* super-speed-plus descriptor falls back to super-speed one,
* if such a descriptor was provided, thus avoiding a NULL
* pointer dereference if a 5gbps capable gadget is used with
* a 10gbps capable config (device port + cable + host port)
*/
if (!ssp)
ssp = ss;
if (fs) {
f->fs_descriptors = usb_copy_descriptors(fs);
if (!f->fs_descriptors)

View File

@ -791,7 +791,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
fs_ecm_notify_desc.bEndpointAddress;
status = usb_assign_descriptors(f, ecm_fs_function, ecm_hs_function,
ecm_ss_function, NULL);
ecm_ss_function, ecm_ss_function);
if (status)
goto fail;

View File

@ -302,7 +302,7 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f)
eem_ss_out_desc.bEndpointAddress = eem_fs_out_desc.bEndpointAddress;
status = usb_assign_descriptors(f, eem_fs_function, eem_hs_function,
eem_ss_function, NULL);
eem_ss_function, eem_ss_function);
if (status)
goto fail;
@ -495,7 +495,7 @@ static int eem_unwrap(struct gether *port,
skb2 = skb_clone(skb, GFP_ATOMIC);
if (unlikely(!skb2)) {
DBG(cdev, "unable to unframe EEM packet\n");
continue;
goto next;
}
skb_trim(skb2, len - ETH_FCS_LEN);
@ -505,7 +505,7 @@ static int eem_unwrap(struct gether *port,
GFP_ATOMIC);
if (unlikely(!skb3)) {
dev_kfree_skb_any(skb2);
continue;
goto next;
}
dev_kfree_skb_any(skb2);
skb_queue_tail(list, skb3);

View File

@ -3567,6 +3567,9 @@ static void ffs_func_unbind(struct usb_configuration *c,
ffs->func = NULL;
}
/* Drain any pending AIO completions */
drain_workqueue(ffs->io_completion_wq);
if (!--opts->refcnt)
functionfs_unbind(ffs);

View File

@ -802,7 +802,8 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
hidg_fs_out_ep_desc.bEndpointAddress;
status = usb_assign_descriptors(f, hidg_fs_descriptors,
hidg_hs_descriptors, hidg_ss_descriptors, NULL);
hidg_hs_descriptors, hidg_ss_descriptors,
hidg_ss_descriptors);
if (status)
goto fail;

View File

@ -207,7 +207,7 @@ autoconf_fail:
ss_loop_sink_desc.bEndpointAddress = fs_loop_sink_desc.bEndpointAddress;
ret = usb_assign_descriptors(f, fs_loopback_descs, hs_loopback_descs,
ss_loopback_descs, NULL);
ss_loopback_descs, ss_loopback_descs);
if (ret)
return ret;

View File

@ -583,7 +583,7 @@ static void ncm_do_notify(struct f_ncm *ncm)
data[0] = cpu_to_le32(ncm_bitrate(cdev->gadget));
data[1] = data[0];
DBG(cdev, "notify speed %d\n", ncm_bitrate(cdev->gadget));
DBG(cdev, "notify speed %u\n", ncm_bitrate(cdev->gadget));
ncm->notify_state = NCM_NOTIFY_CONNECT;
break;
}
@ -1101,11 +1101,11 @@ static struct sk_buff *ncm_wrap_ntb(struct gether *port,
ncm->ndp_dgram_count = 1;
/* Note: we skip opts->next_ndp_index */
}
/* Delay the timer. */
hrtimer_start(&ncm->task_timer, TX_TIMEOUT_NSECS,
HRTIMER_MODE_REL_SOFT);
/* Start the timer. */
hrtimer_start(&ncm->task_timer, TX_TIMEOUT_NSECS,
HRTIMER_MODE_REL_SOFT);
}
/* Add the datagram position entries */
ntb_ndp = skb_put_zero(ncm->skb_tx_ndp, dgram_idx_len);

View File

@ -1101,7 +1101,8 @@ autoconf_fail:
ss_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress;
ret = usb_assign_descriptors(f, fs_printer_function,
hs_printer_function, ss_printer_function, NULL);
hs_printer_function, ss_printer_function,
ss_printer_function);
if (ret)
return ret;

View File

@ -789,7 +789,7 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
ss_notify_desc.bEndpointAddress = fs_notify_desc.bEndpointAddress;
status = usb_assign_descriptors(f, eth_fs_function, eth_hs_function,
eth_ss_function, NULL);
eth_ss_function, eth_ss_function);
if (status)
goto fail;

View File

@ -233,7 +233,7 @@ static int gser_bind(struct usb_configuration *c, struct usb_function *f)
gser_ss_out_desc.bEndpointAddress = gser_fs_out_desc.bEndpointAddress;
status = usb_assign_descriptors(f, gser_fs_function, gser_hs_function,
gser_ss_function, NULL);
gser_ss_function, gser_ss_function);
if (status)
goto fail;
dev_dbg(&cdev->gadget->dev, "generic ttyGS%d: %s speed IN/%s OUT/%s\n",

View File

@ -431,7 +431,8 @@ no_iso:
ss_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
ret = usb_assign_descriptors(f, fs_source_sink_descs,
hs_source_sink_descs, ss_source_sink_descs, NULL);
hs_source_sink_descs, ss_source_sink_descs,
ss_source_sink_descs);
if (ret)
return ret;

View File

@ -358,7 +358,7 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
fs_subset_out_desc.bEndpointAddress;
status = usb_assign_descriptors(f, fs_eth_function, hs_eth_function,
ss_eth_function, NULL);
ss_eth_function, ss_eth_function);
if (status)
goto fail;

View File

@ -2057,7 +2057,8 @@ static int tcm_bind(struct usb_configuration *c, struct usb_function *f)
uasp_fs_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress;
ret = usb_assign_descriptors(f, uasp_fs_function_desc,
uasp_hs_function_desc, uasp_ss_function_desc, NULL);
uasp_hs_function_desc, uasp_ss_function_desc,
uasp_ss_function_desc);
if (ret)
goto ep_fail;

View File

@ -59,6 +59,7 @@
#define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI 0x1138
#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI 0x461e
#define PCI_DEVICE_ID_AMD_RENOIR_XHCI 0x1639
#define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9
#define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba
#define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb
@ -182,6 +183,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
(pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_1)))
xhci->quirks |= XHCI_U2_DISABLE_WAKE;
if (pdev->vendor == PCI_VENDOR_ID_AMD &&
pdev->device == PCI_DEVICE_ID_AMD_RENOIR_XHCI)
xhci->quirks |= XHCI_BROKEN_D3COLD;
if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
xhci->quirks |= XHCI_LPM_SUPPORT;
xhci->quirks |= XHCI_INTEL_HOST;
@ -539,7 +544,7 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
* Systems with the TI redriver that loses port status change events
* need to have the registers polled during D3, so avoid D3cold.
*/
if (xhci->quirks & XHCI_COMP_MODE_QUIRK)
if (xhci->quirks & (XHCI_COMP_MODE_QUIRK | XHCI_BROKEN_D3COLD))
pci_d3cold_disable(pdev);
if (xhci->quirks & XHCI_PME_STUCK_QUIRK)

View File

@ -1892,6 +1892,7 @@ struct xhci_hcd {
#define XHCI_DISABLE_SPARSE BIT_ULL(38)
#define XHCI_SG_TRB_CACHE_SIZE_QUIRK BIT_ULL(39)
#define XHCI_NO_SOFT_RETRY BIT_ULL(40)
#define XHCI_BROKEN_D3COLD BIT_ULL(41)
unsigned int num_active_eps;
unsigned int limit_active_eps;

View File

@ -263,6 +263,8 @@ static int __init brcmstb_usb_pinmap_probe(struct platform_device *pdev)
return -EINVAL;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r)
return -EINVAL;
pdata = devm_kzalloc(&pdev->dev,
sizeof(*pdata) +

View File

@ -2009,9 +2009,8 @@ static void musb_pm_runtime_check_session(struct musb *musb)
schedule_delayed_work(&musb->irq_work,
msecs_to_jiffies(1000));
musb->quirk_retries--;
break;
}
fallthrough;
break;
case MUSB_QUIRK_B_INVALID_VBUS_91:
if (musb->quirk_retries && !musb->flush_irq_work) {
musb_dbg(musb,

View File

@ -252,9 +252,11 @@ struct cp210x_serial_private {
u8 gpio_input;
#endif
u8 partnum;
u32 fw_version;
speed_t min_speed;
speed_t max_speed;
bool use_actual_rate;
bool no_flow_control;
};
enum cp210x_event_state {
@ -398,6 +400,7 @@ struct cp210x_special_chars {
/* CP210X_VENDOR_SPECIFIC values */
#define CP210X_READ_2NCONFIG 0x000E
#define CP210X_GET_FW_VER_2N 0x0010
#define CP210X_READ_LATCH 0x00C2
#define CP210X_GET_PARTNUM 0x370B
#define CP210X_GET_PORTCONFIG 0x370C
@ -537,6 +540,12 @@ struct cp210x_single_port_config {
#define CP210X_2NCONFIG_GPIO_RSTLATCH_IDX 587
#define CP210X_2NCONFIG_GPIO_CONTROL_IDX 600
/* CP2102N QFN20 port configuration values */
#define CP2102N_QFN20_GPIO2_TXLED_MODE BIT(2)
#define CP2102N_QFN20_GPIO3_RXLED_MODE BIT(3)
#define CP2102N_QFN20_GPIO1_RS485_MODE BIT(4)
#define CP2102N_QFN20_GPIO0_CLK_MODE BIT(6)
/* CP210X_VENDOR_SPECIFIC, CP210X_WRITE_LATCH call writes these 0x2 bytes. */
struct cp210x_gpio_write {
u8 mask;
@ -1122,6 +1131,7 @@ static bool cp210x_termios_change(const struct ktermios *a, const struct ktermio
static void cp210x_set_flow_control(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old_termios)
{
struct cp210x_serial_private *priv = usb_get_serial_data(port->serial);
struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
struct cp210x_special_chars chars;
struct cp210x_flow_ctl flow_ctl;
@ -1129,6 +1139,15 @@ static void cp210x_set_flow_control(struct tty_struct *tty,
u32 ctl_hs;
int ret;
/*
* Some CP2102N interpret ulXonLimit as ulFlowReplace (erratum
* CP2102N_E104). Report back that flow control is not supported.
*/
if (priv->no_flow_control) {
tty->termios.c_cflag &= ~CRTSCTS;
tty->termios.c_iflag &= ~(IXON | IXOFF);
}
if (old_termios &&
C_CRTSCTS(tty) == (old_termios->c_cflag & CRTSCTS) &&
I_IXON(tty) == (old_termios->c_iflag & IXON) &&
@ -1185,19 +1204,20 @@ static void cp210x_set_flow_control(struct tty_struct *tty,
port_priv->crtscts = false;
}
if (I_IXOFF(tty))
if (I_IXOFF(tty)) {
flow_repl |= CP210X_SERIAL_AUTO_RECEIVE;
else
flow_ctl.ulXonLimit = cpu_to_le32(128);
flow_ctl.ulXoffLimit = cpu_to_le32(128);
} else {
flow_repl &= ~CP210X_SERIAL_AUTO_RECEIVE;
}
if (I_IXON(tty))
flow_repl |= CP210X_SERIAL_AUTO_TRANSMIT;
else
flow_repl &= ~CP210X_SERIAL_AUTO_TRANSMIT;
flow_ctl.ulXonLimit = cpu_to_le32(128);
flow_ctl.ulXoffLimit = cpu_to_le32(128);
dev_dbg(&port->dev, "%s - ctrl = 0x%02x, flow = 0x%02x\n", __func__,
ctl_hs, flow_repl);
@ -1733,7 +1753,19 @@ static int cp2102n_gpioconf_init(struct usb_serial *serial)
priv->gpio_pushpull = (gpio_pushpull >> 3) & 0x0f;
/* 0 indicates GPIO mode, 1 is alternate function */
priv->gpio_altfunc = (gpio_ctrl >> 2) & 0x0f;
if (priv->partnum == CP210X_PARTNUM_CP2102N_QFN20) {
/* QFN20 is special... */
if (gpio_ctrl & CP2102N_QFN20_GPIO0_CLK_MODE) /* GPIO 0 */
priv->gpio_altfunc |= BIT(0);
if (gpio_ctrl & CP2102N_QFN20_GPIO1_RS485_MODE) /* GPIO 1 */
priv->gpio_altfunc |= BIT(1);
if (gpio_ctrl & CP2102N_QFN20_GPIO2_TXLED_MODE) /* GPIO 2 */
priv->gpio_altfunc |= BIT(2);
if (gpio_ctrl & CP2102N_QFN20_GPIO3_RXLED_MODE) /* GPIO 3 */
priv->gpio_altfunc |= BIT(3);
} else {
priv->gpio_altfunc = (gpio_ctrl >> 2) & 0x0f;
}
if (priv->partnum == CP210X_PARTNUM_CP2102N_QFN28) {
/*
@ -1908,6 +1940,45 @@ static void cp210x_init_max_speed(struct usb_serial *serial)
priv->use_actual_rate = use_actual_rate;
}
static int cp210x_get_fw_version(struct usb_serial *serial, u16 value)
{
struct cp210x_serial_private *priv = usb_get_serial_data(serial);
u8 ver[3];
int ret;
ret = cp210x_read_vendor_block(serial, REQTYPE_DEVICE_TO_HOST, value,
ver, sizeof(ver));
if (ret)
return ret;
dev_dbg(&serial->interface->dev, "%s - %d.%d.%d\n", __func__,
ver[0], ver[1], ver[2]);
priv->fw_version = ver[0] << 16 | ver[1] << 8 | ver[2];
return 0;
}
static void cp210x_determine_quirks(struct usb_serial *serial)
{
struct cp210x_serial_private *priv = usb_get_serial_data(serial);
int ret;
switch (priv->partnum) {
case CP210X_PARTNUM_CP2102N_QFN28:
case CP210X_PARTNUM_CP2102N_QFN24:
case CP210X_PARTNUM_CP2102N_QFN20:
ret = cp210x_get_fw_version(serial, CP210X_GET_FW_VER_2N);
if (ret)
break;
if (priv->fw_version <= 0x10004)
priv->no_flow_control = true;
break;
default:
break;
}
}
static int cp210x_attach(struct usb_serial *serial)
{
int result;
@ -1928,6 +1999,7 @@ static int cp210x_attach(struct usb_serial *serial)
usb_set_serial_data(serial, priv);
cp210x_determine_quirks(serial);
cp210x_init_max_speed(serial);
result = cp210x_gpio_init(serial);

View File

@ -611,6 +611,7 @@ static const struct usb_device_id id_table_combined[] = {
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ USB_DEVICE(FTDI_VID, FTDI_NT_ORIONLX_PLUS_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_NT_ORION_IO_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_NT_ORIONMX_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_SYNAPSE_SS200_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_CUSTOMWARE_MINIPLEX_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_CUSTOMWARE_MINIPLEX2_PID) },

View File

@ -581,6 +581,7 @@
#define FTDI_NT_ORIONLXM_PID 0x7c90 /* OrionLXm Substation Automation Platform */
#define FTDI_NT_ORIONLX_PLUS_PID 0x7c91 /* OrionLX+ Substation Automation Platform */
#define FTDI_NT_ORION_IO_PID 0x7c92 /* Orion I/O */
#define FTDI_NT_ORIONMX_PID 0x7c93 /* OrionMX */
/*
* Synapse Wireless product ids (FTDI_VID)

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
* USB ZyXEL omni.net LCD PLUS driver
* USB ZyXEL omni.net driver
*
* Copyright (C) 2013,2017 Johan Hovold <johan@kernel.org>
*
@ -22,10 +22,11 @@
#include <linux/usb/serial.h>
#define DRIVER_AUTHOR "Alessandro Zummo"
#define DRIVER_DESC "USB ZyXEL omni.net LCD PLUS Driver"
#define DRIVER_DESC "USB ZyXEL omni.net Driver"
#define ZYXEL_VENDOR_ID 0x0586
#define ZYXEL_OMNINET_ID 0x1000
#define ZYXEL_OMNI_56K_PLUS_ID 0x1500
/* This one seems to be a re-branded ZyXEL device */
#define BT_IGNITIONPRO_ID 0x2000
@ -40,6 +41,7 @@ static void omninet_port_remove(struct usb_serial_port *port);
static const struct usb_device_id id_table[] = {
{ USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) },
{ USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNI_56K_PLUS_ID) },
{ USB_DEVICE(ZYXEL_VENDOR_ID, BT_IGNITIONPRO_ID) },
{ } /* Terminating entry */
};
@ -50,7 +52,7 @@ static struct usb_serial_driver zyxel_omninet_device = {
.owner = THIS_MODULE,
.name = "omninet",
},
.description = "ZyXEL - omni.net lcd plus usb",
.description = "ZyXEL - omni.net usb",
.id_table = id_table,
.num_bulk_out = 2,
.calc_num_ports = omninet_calc_num_ports,

View File

@ -416,7 +416,7 @@ static void qt2_close(struct usb_serial_port *port)
/* flush the port transmit buffer */
i = usb_control_msg(serial->dev,
usb_rcvctrlpipe(serial->dev, 0),
usb_sndctrlpipe(serial->dev, 0),
QT2_FLUSH_DEVICE, 0x40, 1,
port_priv->device_port, NULL, 0, QT2_USB_TIMEOUT);
@ -426,7 +426,7 @@ static void qt2_close(struct usb_serial_port *port)
/* flush the port receive buffer */
i = usb_control_msg(serial->dev,
usb_rcvctrlpipe(serial->dev, 0),
usb_sndctrlpipe(serial->dev, 0),
QT2_FLUSH_DEVICE, 0x40, 0,
port_priv->device_port, NULL, 0, QT2_USB_TIMEOUT);
@ -639,7 +639,7 @@ static int qt2_attach(struct usb_serial *serial)
int status;
/* power on unit */
status = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
status = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
0xc2, 0x40, 0x8000, 0, NULL, 0,
QT2_USB_TIMEOUT);
if (status < 0) {

View File

@ -239,7 +239,7 @@ find_mux:
dev = class_find_device(&typec_mux_class, NULL, fwnode,
mux_fwnode_match);
return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER);
return dev ? to_typec_mux(dev) : ERR_PTR(-EPROBE_DEFER);
}
/**

View File

@ -582,10 +582,15 @@ static int pmc_usb_probe_iom(struct pmc_usb *pmc)
acpi_dev_free_resource_list(&resource_list);
if (!pmc->iom_base) {
put_device(&adev->dev);
acpi_dev_put(adev);
return -ENOMEM;
}
if (IS_ERR(pmc->iom_base)) {
acpi_dev_put(adev);
return PTR_ERR(pmc->iom_base);
}
pmc->iom_adev = adev;
return 0;
@ -636,8 +641,10 @@ static int pmc_usb_probe(struct platform_device *pdev)
break;
ret = pmc_usb_register_port(pmc, i, fwnode);
if (ret)
if (ret) {
fwnode_handle_put(fwnode);
goto err_remove_ports;
}
}
platform_set_drvdata(pdev, pmc);
@ -651,7 +658,7 @@ err_remove_ports:
usb_role_switch_unregister(pmc->port[i].usb_sw);
}
put_device(&pmc->iom_adev->dev);
acpi_dev_put(pmc->iom_adev);
return ret;
}
@ -667,7 +674,7 @@ static int pmc_usb_remove(struct platform_device *pdev)
usb_role_switch_unregister(pmc->port[i].usb_sw);
}
put_device(&pmc->iom_adev->dev);
acpi_dev_put(pmc->iom_adev);
return 0;
}

View File

@ -401,6 +401,8 @@ struct tcpm_port {
unsigned int nr_src_pdo;
u32 snk_pdo[PDO_MAX_OBJECTS];
unsigned int nr_snk_pdo;
u32 snk_vdo_v1[VDO_MAX_OBJECTS];
unsigned int nr_snk_vdo_v1;
u32 snk_vdo[VDO_MAX_OBJECTS];
unsigned int nr_snk_vdo;
@ -1547,42 +1549,45 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev,
if (PD_VDO_VID(p[0]) != USB_SID_PD)
break;
if (PD_VDO_SVDM_VER(p[0]) < svdm_version)
if (PD_VDO_SVDM_VER(p[0]) < svdm_version) {
typec_partner_set_svdm_version(port->partner,
PD_VDO_SVDM_VER(p[0]));
svdm_version = PD_VDO_SVDM_VER(p[0]);
}
tcpm_ams_start(port, DISCOVER_IDENTITY);
/* 6.4.4.3.1: Only respond as UFP (device) */
if (port->data_role == TYPEC_DEVICE &&
port->ams = DISCOVER_IDENTITY;
/*
* PD2.0 Spec 6.10.3: respond with NAK as DFP (data host)
* PD3.1 Spec 6.4.4.2.5.1: respond with NAK if "invalid field" or
* "wrong configuation" or "Unrecognized"
*/
if ((port->data_role == TYPEC_DEVICE || svdm_version >= SVDM_VER_2_0) &&
port->nr_snk_vdo) {
/*
* Product Type DFP and Connector Type are not defined in SVDM
* version 1.0 and shall be set to zero.
*/
if (typec_get_negotiated_svdm_version(typec) < SVDM_VER_2_0)
response[1] = port->snk_vdo[0] & ~IDH_DFP_MASK
& ~IDH_CONN_MASK;
else
response[1] = port->snk_vdo[0];
for (i = 1; i < port->nr_snk_vdo; i++)
response[i + 1] = port->snk_vdo[i];
rlen = port->nr_snk_vdo + 1;
if (svdm_version < SVDM_VER_2_0) {
for (i = 0; i < port->nr_snk_vdo_v1; i++)
response[i + 1] = port->snk_vdo_v1[i];
rlen = port->nr_snk_vdo_v1 + 1;
} else {
for (i = 0; i < port->nr_snk_vdo; i++)
response[i + 1] = port->snk_vdo[i];
rlen = port->nr_snk_vdo + 1;
}
}
break;
case CMD_DISCOVER_SVID:
tcpm_ams_start(port, DISCOVER_SVIDS);
port->ams = DISCOVER_SVIDS;
break;
case CMD_DISCOVER_MODES:
tcpm_ams_start(port, DISCOVER_MODES);
port->ams = DISCOVER_MODES;
break;
case CMD_ENTER_MODE:
tcpm_ams_start(port, DFP_TO_UFP_ENTER_MODE);
port->ams = DFP_TO_UFP_ENTER_MODE;
break;
case CMD_EXIT_MODE:
tcpm_ams_start(port, DFP_TO_UFP_EXIT_MODE);
port->ams = DFP_TO_UFP_EXIT_MODE;
break;
case CMD_ATTENTION:
tcpm_ams_start(port, ATTENTION);
/* Attention command does not have response */
*adev_action = ADEV_ATTENTION;
return 0;
@ -1937,6 +1942,9 @@ static void vdm_run_state_machine(struct tcpm_port *port)
tcpm_log(port, "VDM Tx error, retry");
port->vdm_retries++;
port->vdm_state = VDM_STATE_READY;
if (PD_VDO_SVDM(vdo_hdr) && PD_VDO_CMDT(vdo_hdr) == CMDT_INIT)
tcpm_ams_finish(port);
} else {
tcpm_ams_finish(port);
}
break;
@ -2183,20 +2191,25 @@ static void tcpm_handle_alert(struct tcpm_port *port, const __le32 *payload,
if (!type) {
tcpm_log(port, "Alert message received with no type");
tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP);
return;
}
/* Just handling non-battery alerts for now */
if (!(type & USB_PD_ADO_TYPE_BATT_STATUS_CHANGE)) {
switch (port->state) {
case SRC_READY:
case SNK_READY:
if (port->pwr_role == TYPEC_SOURCE) {
port->upcoming_state = GET_STATUS_SEND;
tcpm_ams_start(port, GETTING_SOURCE_SINK_STATUS);
} else {
/*
* Do not check SinkTxOk here in case the Source doesn't set its Rp to
* SinkTxOk in time.
*/
port->ams = GETTING_SOURCE_SINK_STATUS;
tcpm_set_state(port, GET_STATUS_SEND, 0);
break;
default:
tcpm_queue_message(port, PD_MSG_CTRL_WAIT);
break;
}
} else {
tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP);
}
}
@ -2440,7 +2453,12 @@ static void tcpm_pd_data_request(struct tcpm_port *port,
tcpm_pd_handle_state(port, BIST_RX, BIST, 0);
break;
case PD_DATA_ALERT:
tcpm_handle_alert(port, msg->payload, cnt);
if (port->state != SRC_READY && port->state != SNK_READY)
tcpm_pd_handle_state(port, port->pwr_role == TYPEC_SOURCE ?
SRC_SOFT_RESET_WAIT_SNK_TX : SNK_SOFT_RESET,
NONE_AMS, 0);
else
tcpm_handle_alert(port, msg->payload, cnt);
break;
case PD_DATA_BATT_STATUS:
case PD_DATA_GET_COUNTRY_INFO:
@ -2764,24 +2782,16 @@ static void tcpm_pd_ext_msg_request(struct tcpm_port *port,
switch (type) {
case PD_EXT_STATUS:
/*
* If PPS related events raised then get PPS status to clear
* (see USB PD 3.0 Spec, 6.5.2.4)
*/
if (msg->ext_msg.data[USB_PD_EXT_SDB_EVENT_FLAGS] &
USB_PD_EXT_SDB_PPS_EVENTS)
tcpm_pd_handle_state(port, GET_PPS_STATUS_SEND,
GETTING_SOURCE_SINK_STATUS, 0);
else
tcpm_pd_handle_state(port, ready_state(port), NONE_AMS, 0);
break;
case PD_EXT_PPS_STATUS:
/*
* For now the PPS status message is used to clear events
* and nothing more.
*/
tcpm_pd_handle_state(port, ready_state(port), NONE_AMS, 0);
if (port->ams == GETTING_SOURCE_SINK_STATUS) {
tcpm_ams_finish(port);
tcpm_set_state(port, ready_state(port), 0);
} else {
/* unexpected Status or PPS_Status Message */
tcpm_pd_handle_state(port, port->pwr_role == TYPEC_SOURCE ?
SRC_SOFT_RESET_WAIT_SNK_TX : SNK_SOFT_RESET,
NONE_AMS, 0);
}
break;
case PD_EXT_SOURCE_CAP_EXT:
case PD_EXT_GET_BATT_CAP:
@ -5947,6 +5957,22 @@ sink:
return ret;
}
/* If sink-vdos is found, sink-vdos-v1 is expected for backward compatibility. */
if (port->nr_snk_vdo) {
ret = fwnode_property_count_u32(fwnode, "sink-vdos-v1");
if (ret < 0)
return ret;
else if (ret == 0)
return -ENODATA;
port->nr_snk_vdo_v1 = min(ret, VDO_MAX_OBJECTS);
ret = fwnode_property_read_u32_array(fwnode, "sink-vdos-v1",
port->snk_vdo_v1,
port->nr_snk_vdo_v1);
if (ret < 0)
return ret;
}
return 0;
}
@ -6312,6 +6338,11 @@ void tcpm_unregister_port(struct tcpm_port *port)
{
int i;
hrtimer_cancel(&port->send_discover_timer);
hrtimer_cancel(&port->enable_frs_timer);
hrtimer_cancel(&port->vdm_state_machine_timer);
hrtimer_cancel(&port->state_machine_timer);
tcpm_reset_port(port);
for (i = 0; i < ARRAY_SIZE(port->port_altmode); i++)
typec_unregister_altmode(port->port_altmode[i]);

View File

@ -378,7 +378,7 @@ static int wcove_pd_transmit(struct tcpc_dev *tcpc,
const u8 *data = (void *)msg;
int i;
for (i = 0; i < pd_header_cnt(msg->header) * 4 + 2; i++) {
for (i = 0; i < pd_header_cnt_le(msg->header) * 4 + 2; i++) {
ret = regmap_write(wcove->regmap, USBC_TX_DATA + i,
data[i]);
if (ret)

View File

@ -1253,6 +1253,7 @@ err_unregister:
}
err_reset:
memset(&ucsi->cap, 0, sizeof(ucsi->cap));
ucsi_reset_ppm(ucsi);
err:
return ret;

View File

@ -106,6 +106,10 @@
* <20:16> :: Reserved, Shall be set to zero
* <15:0> :: USB-IF assigned VID for this cable vendor
*/
/* PD Rev2.0 definition */
#define IDH_PTYPE_UNDEF 0
/* SOP Product Type (UFP) */
#define IDH_PTYPE_NOT_UFP 0
#define IDH_PTYPE_HUB 1
@ -163,10 +167,10 @@
#define UFP_VDO_VER1_2 2
/* Device Capability */
#define DEV_USB2_CAPABLE BIT(0)
#define DEV_USB2_BILLBOARD BIT(1)
#define DEV_USB3_CAPABLE BIT(2)
#define DEV_USB4_CAPABLE BIT(3)
#define DEV_USB2_CAPABLE (1 << 0)
#define DEV_USB2_BILLBOARD (1 << 1)
#define DEV_USB3_CAPABLE (1 << 2)
#define DEV_USB4_CAPABLE (1 << 3)
/* Connector Type */
#define UFP_RECEPTACLE 2
@ -191,9 +195,9 @@
/* Alternate Modes */
#define UFP_ALTMODE_NOT_SUPP 0
#define UFP_ALTMODE_TBT3 BIT(0)
#define UFP_ALTMODE_RECFG BIT(1)
#define UFP_ALTMODE_NO_RECFG BIT(2)
#define UFP_ALTMODE_TBT3 (1 << 0)
#define UFP_ALTMODE_RECFG (1 << 1)
#define UFP_ALTMODE_NO_RECFG (1 << 2)
/* USB Highest Speed */
#define UFP_USB2_ONLY 0
@ -217,9 +221,9 @@
* <4:0> :: Port number
*/
#define DFP_VDO_VER1_1 1
#define HOST_USB2_CAPABLE BIT(0)
#define HOST_USB3_CAPABLE BIT(1)
#define HOST_USB4_CAPABLE BIT(2)
#define HOST_USB2_CAPABLE (1 << 0)
#define HOST_USB3_CAPABLE (1 << 1)
#define HOST_USB4_CAPABLE (1 << 2)
#define DFP_RECEPTACLE 2
#define DFP_CAPTIVE 3
@ -228,7 +232,25 @@
| ((pnum) & 0x1f))
/*
* Passive Cable VDO
* Cable VDO (for both Passive and Active Cable VDO in PD Rev2.0)
* ---------
* <31:28> :: Cable HW version
* <27:24> :: Cable FW version
* <23:20> :: Reserved, Shall be set to zero
* <19:18> :: type-C to Type-A/B/C/Captive (00b == A, 01 == B, 10 == C, 11 == Captive)
* <17> :: Reserved, Shall be set to zero
* <16:13> :: cable latency (0001 == <10ns(~1m length))
* <12:11> :: cable termination type (11b == both ends active VCONN req)
* <10> :: SSTX1 Directionality support (0b == fixed, 1b == cfgable)
* <9> :: SSTX2 Directionality support
* <8> :: SSRX1 Directionality support
* <7> :: SSRX2 Directionality support
* <6:5> :: Vbus current handling capability (01b == 3A, 10b == 5A)
* <4> :: Vbus through cable (0b == no, 1b == yes)
* <3> :: SOP" controller present? (0b == no, 1b == yes)
* <2:0> :: USB SS Signaling support
*
* Passive Cable VDO (PD Rev3.0+)
* ---------
* <31:28> :: Cable HW version
* <27:24> :: Cable FW version
@ -244,7 +266,7 @@
* <4:3> :: Reserved, Shall be set to zero
* <2:0> :: USB highest speed
*
* Active Cable VDO 1
* Active Cable VDO 1 (PD Rev3.0+)
* ---------
* <31:28> :: Cable HW version
* <27:24> :: Cable FW version
@ -266,7 +288,9 @@
#define CABLE_VDO_VER1_0 0
#define CABLE_VDO_VER1_3 3
/* Connector Type */
/* Connector Type (_ATYPE and _BTYPE are for PD Rev2.0 only) */
#define CABLE_ATYPE 0
#define CABLE_BTYPE 1
#define CABLE_CTYPE 2
#define CABLE_CAPTIVE 3
@ -303,12 +327,22 @@
#define CABLE_CURR_3A 1
#define CABLE_CURR_5A 2
/* USB SuperSpeed Signaling Support (PD Rev2.0) */
#define CABLE_USBSS_U2_ONLY 0
#define CABLE_USBSS_U31_GEN1 1
#define CABLE_USBSS_U31_GEN2 2
/* USB Highest Speed */
#define CABLE_USB2_ONLY 0
#define CABLE_USB32_GEN1 1
#define CABLE_USB32_4_GEN2 2
#define CABLE_USB4_GEN3 3
#define VDO_CABLE(hw, fw, cbl, lat, term, tx1d, tx2d, rx1d, rx2d, cur, vps, sopp, usbss) \
(((hw) & 0x7) << 28 | ((fw) & 0x7) << 24 | ((cbl) & 0x3) << 18 \
| ((lat) & 0x7) << 13 | ((term) & 0x3) << 11 | (tx1d) << 10 \
| (tx2d) << 9 | (rx1d) << 8 | (rx2d) << 7 | ((cur) & 0x3) << 5 \
| (vps) << 4 | (sopp) << 3 | ((usbss) & 0x7))
#define VDO_PCABLE(hw, fw, ver, conn, lat, term, vbm, cur, spd) \
(((hw) & 0xf) << 28 | ((fw) & 0xf) << 24 | ((ver) & 0x7) << 21 \
| ((conn) & 0x3) << 18 | ((lat) & 0xf) << 13 | ((term) & 0x3) << 11 \
@ -373,6 +407,35 @@
| ((hops) & 0x3) << 6 | (u2) << 5 | (u32) << 4 | (lane) << 3 \
| (iso) << 2 | (gen))
/*
* AMA VDO (PD Rev2.0)
* ---------
* <31:28> :: Cable HW version
* <27:24> :: Cable FW version
* <23:12> :: Reserved, Shall be set to zero
* <11> :: SSTX1 Directionality support (0b == fixed, 1b == cfgable)
* <10> :: SSTX2 Directionality support
* <9> :: SSRX1 Directionality support
* <8> :: SSRX2 Directionality support
* <7:5> :: Vconn power
* <4> :: Vconn power required
* <3> :: Vbus power required
* <2:0> :: USB SS Signaling support
*/
#define VDO_AMA(hw, fw, tx1d, tx2d, rx1d, rx2d, vcpwr, vcr, vbr, usbss) \
(((hw) & 0x7) << 28 | ((fw) & 0x7) << 24 \
| (tx1d) << 11 | (tx2d) << 10 | (rx1d) << 9 | (rx2d) << 8 \
| ((vcpwr) & 0x7) << 5 | (vcr) << 4 | (vbr) << 3 \
| ((usbss) & 0x7))
#define PD_VDO_AMA_VCONN_REQ(vdo) (((vdo) >> 4) & 1)
#define PD_VDO_AMA_VBUS_REQ(vdo) (((vdo) >> 3) & 1)
#define AMA_USBSS_U2_ONLY 0
#define AMA_USBSS_U31_GEN1 1
#define AMA_USBSS_U31_GEN2 2
#define AMA_USBSS_BBONLY 3
/*
* VPD VDO
* ---------

View File

@ -460,7 +460,7 @@ static inline unsigned int rdo_max_power(u32 rdo)
#define PD_T_RECEIVER_RESPONSE 15 /* 15ms max */
#define PD_T_SOURCE_ACTIVITY 45
#define PD_T_SINK_ACTIVITY 135
#define PD_T_SINK_WAIT_CAP 240
#define PD_T_SINK_WAIT_CAP 310 /* 310 - 620 ms */
#define PD_T_PS_TRANSITION 500
#define PD_T_SRC_TRANSITION 35
#define PD_T_DRP_SNK 40

View File

@ -24,8 +24,4 @@ enum usb_pd_ext_sdb_fields {
#define USB_PD_EXT_SDB_EVENT_OVP BIT(3)
#define USB_PD_EXT_SDB_EVENT_CF_CV_MODE BIT(4)
#define USB_PD_EXT_SDB_PPS_EVENTS (USB_PD_EXT_SDB_EVENT_OCP | \
USB_PD_EXT_SDB_EVENT_OTP | \
USB_PD_EXT_SDB_EVENT_OVP)
#endif /* __LINUX_USB_PD_EXT_SDB_H */