diff options
Diffstat (limited to 'Documentation')
17 files changed, 1280 insertions, 16 deletions
diff --git a/Documentation/ABI/testing/configfs-usb-gadget b/Documentation/ABI/testing/configfs-usb-gadget index 37559a06393b..95a36589a66b 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget +++ b/Documentation/ABI/testing/configfs-usb-gadget @@ -62,6 +62,40 @@ KernelVersion: 3.11 Description: This group contains functions available to this USB gadget. +What: /config/usb-gadget/gadget/functions/<func>.<inst>/interface.<n> +Date: May 2014 +KernelVersion: 3.16 +Description: + This group contains "Feature Descriptors" specific for one + gadget's USB interface or one interface group described + by an IAD. + + The attributes: + + compatible_id - 8-byte string for "Compatible ID" + sub_compatible_id - 8-byte string for "Sub Compatible ID" + +What: /config/usb-gadget/gadget/functions/<func>.<inst>/interface.<n>/<property> +Date: May 2014 +KernelVersion: 3.16 +Description: + This group contains "Extended Property Descriptors" specific for one + gadget's USB interface or one interface group described + by an IAD. + + The attributes: + + type - value 1..7 for interpreting the data + 1: unicode string + 2: unicode string with environment variable + 3: binary + 4: little-endian 32-bit + 5: big-endian 32-bit + 6: unicode string with a symbolic link + 7: multiple unicode strings + data - blob of data to be interpreted depending on + type + What: /config/usb-gadget/gadget/strings Date: Jun 2013 KernelVersion: 3.11 @@ -79,3 +113,14 @@ Description: product - gadget's product description manufacturer - gadget's manufacturer description +What: /config/usb-gadget/gadget/os_desc +Date: May 2014 +KernelVersion: 3.16 +Description: + This group contains "OS String" extension handling attributes. + + use - flag turning "OS Desctiptors" support on/off + b_vendor_code - one-byte value used for custom per-device and + per-interface requests + qw_sign - an identifier to be reported as "OS String" + proper diff --git a/Documentation/ABI/testing/sysfs-platform-chipidea-usb-otg b/Documentation/ABI/testing/sysfs-platform-chipidea-usb-otg new file mode 100644 index 000000000000..151c59578db4 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-chipidea-usb-otg @@ -0,0 +1,56 @@ +What: /sys/bus/platform/devices/ci_hdrc.0/inputs/a_bus_req +Date: Feb 2014 +Contact: Li Jun <b47624@freescale.com> +Description: + Can be set and read. + Set a_bus_req(A-device bus request) input to be 1 if + the application running on the A-device wants to use the bus, + and to be 0 when the application no longer wants to use + the bus(or wants to work as peripheral). a_bus_req can also + be set to 1 by kernel in response to remote wakeup signaling + from the B-device, the A-device should decide to resume the bus. + + Valid values are "1" and "0". + + Reading: returns 1 if the application running on the A-device + is using the bus as host role, otherwise 0. + +What: /sys/bus/platform/devices/ci_hdrc.0/inputs/a_bus_drop +Date: Feb 2014 +Contact: Li Jun <b47624@freescale.com> +Description: + Can be set and read + The a_bus_drop(A-device bus drop) input is 1 when the + application running on the A-device wants to power down + the bus, and is 0 otherwise, When a_bus_drop is 1, then + the a_bus_req shall be 0. + + Valid values are "1" and "0". + + Reading: returns 1 if the bus is off(vbus is turned off) by + A-device, otherwise 0. + +What: /sys/bus/platform/devices/ci_hdrc.0/inputs/b_bus_req +Date: Feb 2014 +Contact: Li Jun <b47624@freescale.com> +Description: + Can be set and read. + The b_bus_req(B-device bus request) input is 1 during the time + that the application running on the B-device wants to use the + bus as host, and is 0 when the application no longer wants to + work as host and decides to switch back to be peripheral. + + Valid values are "1" and "0". + + Reading: returns if the application running on the B device + is using the bus as host role, otherwise 0. + +What: /sys/bus/platform/devices/ci_hdrc.0/inputs/a_clr_err +Date: Feb 2014 +Contact: Li Jun <b47624@freescale.com> +Description: + Only can be set. + The a_clr_err(A-device Vbus error clear) input is used to clear + vbus error, then A-device will power down the bus. + + Valid value is "1" diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index b444f2e8fe32..bec06659e0eb 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile @@ -14,7 +14,8 @@ DOCBOOKS := z8530book.xml device-drivers.xml \ genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \ 80211.xml debugobjects.xml sh.xml regulator.xml \ alsa-driver-api.xml writing-an-alsa-driver.xml \ - tracepoint.xml drm.xml media_api.xml w1.xml + tracepoint.xml drm.xml media_api.xml w1.xml \ + writing_musb_glue_layer.xml include Documentation/DocBook/media/Makefile diff --git a/Documentation/DocBook/writing_musb_glue_layer.tmpl b/Documentation/DocBook/writing_musb_glue_layer.tmpl new file mode 100644 index 000000000000..837eca77f274 --- /dev/null +++ b/Documentation/DocBook/writing_musb_glue_layer.tmpl @@ -0,0 +1,873 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" + "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> + +<book id="Writing-MUSB-Glue-Layer"> + <bookinfo> + <title>Writing an MUSB Glue Layer</title> + + <authorgroup> + <author> + <firstname>Apelete</firstname> + <surname>Seketeli</surname> + <affiliation> + <address> + <email>apelete at seketeli.net</email> + </address> + </affiliation> + </author> + </authorgroup> + + <copyright> + <year>2014</year> + <holder>Apelete Seketeli</holder> + </copyright> + + <legalnotice> + <para> + This documentation is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + </para> + + <para> + This documentation is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + </para> + + <para> + You should have received a copy of the GNU General Public License + along with this documentation; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA + </para> + + <para> + For more details see the file COPYING in the Linux kernel source + tree. + </para> + </legalnotice> + </bookinfo> + +<toc></toc> + + <chapter id="introduction"> + <title>Introduction</title> + <para> + The Linux MUSB subsystem is part of the larger Linux USB + subsystem. It provides support for embedded USB Device Controllers + (UDC) that do not use Universal Host Controller Interface (UHCI) + or Open Host Controller Interface (OHCI). + </para> + <para> + Instead, these embedded UDC rely on the USB On-the-Go (OTG) + specification which they implement at least partially. The silicon + reference design used in most cases is the Multipoint USB + Highspeed Dual-Role Controller (MUSB HDRC) found in the Mentor + Graphics Inventra™ design. + </para> + <para> + As a self-taught exercise I have written an MUSB glue layer for + the Ingenic JZ4740 SoC, modelled after the many MUSB glue layers + in the kernel source tree. This layer can be found at + drivers/usb/musb/jz4740.c. In this documentation I will walk + through the basics of the jz4740.c glue layer, explaining the + different pieces and what needs to be done in order to write your + own device glue layer. + </para> + </chapter> + + <chapter id="linux-musb-basics"> + <title>Linux MUSB Basics</title> + <para> + To get started on the topic, please read USB On-the-Go Basics (see + Resources) which provides an introduction of USB OTG operation at + the hardware level. A couple of wiki pages by Texas Instruments + and Analog Devices also provide an overview of the Linux kernel + MUSB configuration, albeit focused on some specific devices + provided by these companies. Finally, getting acquainted with the + USB specification at USB home page may come in handy, with + practical instance provided through the Writing USB Device Drivers + documentation (again, see Resources). + </para> + <para> + Linux USB stack is a layered architecture in which the MUSB + controller hardware sits at the lowest. The MUSB controller driver + abstract the MUSB controller hardware to the Linux USB stack. + </para> + <programlisting> + ------------------------ + | | <------- drivers/usb/gadget + | Linux USB Core Stack | <------- drivers/usb/host + | | <------- drivers/usb/core + ------------------------ + ⬍ + -------------------------- + | | <------ drivers/usb/musb/musb_gadget.c + | MUSB Controller driver | <------ drivers/usb/musb/musb_host.c + | | <------ drivers/usb/musb/musb_core.c + -------------------------- + ⬍ + --------------------------------- + | MUSB Platform Specific Driver | + | | <-- drivers/usb/musb/jz4740.c + | aka "Glue Layer" | + --------------------------------- + ⬍ + --------------------------------- + | MUSB Controller Hardware | + --------------------------------- + </programlisting> + <para> + As outlined above, the glue layer is actually the platform + specific code sitting in between the controller driver and the + controller hardware. + </para> + <para> + Just like a Linux USB driver needs to register itself with the + Linux USB subsystem, the MUSB glue layer needs first to register + itself with the MUSB controller driver. This will allow the + controller driver to know about which device the glue layer + supports and which functions to call when a supported device is + detected or released; remember we are talking about an embedded + controller chip here, so no insertion or removal at run-time. + </para> + <para> + All of this information is passed to the MUSB controller driver + through a platform_driver structure defined in the glue layer as: + </para> + <programlisting linenumbering="numbered"> +static struct platform_driver jz4740_driver = { + .probe = jz4740_probe, + .remove = jz4740_remove, + .driver = { + .name = "musb-jz4740", + }, +}; + </programlisting> + <para> + The probe and remove function pointers are called when a matching + device is detected and, respectively, released. The name string + describes the device supported by this glue layer. In the current + case it matches a platform_device structure declared in + arch/mips/jz4740/platform.c. Note that we are not using device + tree bindings here. + </para> + <para> + In order to register itself to the controller driver, the glue + layer goes through a few steps, basically allocating the + controller hardware resources and initialising a couple of + circuits. To do so, it needs to keep track of the information used + throughout these steps. This is done by defining a private + jz4740_glue structure: + </para> + <programlisting linenumbering="numbered"> +struct jz4740_glue { + struct device *dev; + struct platform_device *musb; + struct clk *clk; +}; + </programlisting> + <para> + The dev and musb members are both device structure variables. The + first one holds generic information about the device, since it's + the basic device structure, and the latter holds information more + closely related to the subsystem the device is registered to. The + clk variable keeps information related to the device clock + operation. + </para> + <para> + Let's go through the steps of the probe function that leads the + glue layer to register itself to the controller driver. + </para> + <para> + N.B.: For the sake of readability each function will be split in + logical parts, each part being shown as if it was independent from + the others. + </para> + <programlisting linenumbering="numbered"> +static int jz4740_probe(struct platform_device *pdev) +{ + struct platform_device *musb; + struct jz4740_glue *glue; + struct clk *clk; + int ret; + + glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); + if (!glue) + return -ENOMEM; + + musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); + if (!musb) { + dev_err(&pdev->dev, "failed to allocate musb device\n"); + return -ENOMEM; + } + + clk = devm_clk_get(&pdev->dev, "udc"); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "failed to get clock\n"); + ret = PTR_ERR(clk); + goto err_platform_device_put; + } + + ret = clk_prepare_enable(clk); + if (ret) { + dev_err(&pdev->dev, "failed to enable clock\n"); + goto err_platform_device_put; + } + + musb->dev.parent = &pdev->dev; + + glue->dev = &pdev->dev; + glue->musb = musb; + glue->clk = clk; + + return 0; + +err_platform_device_put: + platform_device_put(musb); + return ret; +} + </programlisting> + <para> + The first few lines of the probe function allocate and assign the + glue, musb and clk variables. The GFP_KERNEL flag (line 8) allows + the allocation process to sleep and wait for memory, thus being + usable in a blocking situation. The PLATFORM_DEVID_AUTO flag (line + 12) allows automatic allocation and management of device IDs in + order to avoid device namespace collisions with explicit IDs. With + devm_clk_get() (line 18) the glue layer allocates the clock -- the + <literal>devm_</literal> prefix indicates that clk_get() is + managed: it automatically frees the allocated clock resource data + when the device is released -- and enable it. + </para> + <para> + Then comes the registration steps: + </para> + <programlisting linenumbering="numbered"> +static int jz4740_probe(struct platform_device *pdev) +{ + struct musb_hdrc_platform_data *pdata = &jz4740_musb_platform_data; + + pdata->platform_ops = &jz4740_musb_ops; + + platform_set_drvdata(pdev, glue); + + ret = platform_device_add_resources(musb, pdev->resource, + pdev->num_resources); + if (ret) { + dev_err(&pdev->dev, "failed to add resources\n"); + goto err_clk_disable; + } + + ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); + if (ret) { + dev_err(&pdev->dev, "failed to add platform_data\n"); + goto err_clk_disable; + } + + return 0; + +err_clk_disable: + clk_disable_unprepare(clk); +err_platform_device_put: + platform_device_put(musb); + return ret; +} + </programlisting> + <para> + The first step is to pass the device data privately held by the + glue layer on to the controller driver through + platform_set_drvdata() (line 7). Next is passing on the device + resources information, also privately held at that point, through + platform_device_add_resources() (line 9). + </para> + <para> + Finally comes passing on the platform specific data to the + controller driver (line 16). Platform data will be discussed in + <link linkend="device-platform-data">Chapter 4</link>, but here + we are looking at the platform_ops function pointer (line 5) in + musb_hdrc_platform_data structure (line 3). This function + pointer allows the MUSB controller driver to know which function + to call for device operation: + </para> + <programlisting linenumbering="numbered"> +static const struct musb_platform_ops jz4740_musb_ops = { + .init = jz4740_musb_init, + .exit = jz4740_musb_exit, +}; + </programlisting> + <para> + Here we have the minimal case where only init and exit functions + are called by the controller driver when needed. Fact is the + JZ4740 MUSB controller is a basic controller, lacking some + features found in other controllers, otherwise we may also have + pointers to a few other functions like a power management function + or a function to switch between OTG and non-OTG modes, for + instance. + </para> + <para> + At that point of the registration process, the controller driver + actually calls the init function: + </para> + <programlisting linenumbering="numbered"> +static int jz4740_musb_init(struct musb *musb) +{ + musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); + if (!musb->xceiv) { + pr_err("HS UDC: no transceiver configured\n"); + return -ENODEV; + } + + /* Silicon does not implement ConfigData register. + * Set dyn_fifo to avoid reading EP config from hardware. + */ + musb->dyn_fifo = true; + + musb->isr = jz4740_musb_interrupt; + + return 0; +} + </programlisting> + <para> + The goal of jz4740_musb_init() is to get hold of the transceiver + driver data of the MUSB controller hardware and pass it on to the + MUSB controller driver, as usual. The transceiver is the circuitry + inside the controller hardware responsible for sending/receiving + the USB data. Since it is an implementation of the physical layer + of the OSI model, the transceiver is also referred to as PHY. + </para> + <para> + Getting hold of the MUSB PHY driver data is done with + usb_get_phy() which returns a pointer to the structure + containing the driver instance data. The next couple of + instructions (line 12 and 14) are used as a quirk and to setup + IRQ handling respectively. Quirks and IRQ handling will be + discussed later in <link linkend="device-quirks">Chapter + 5</link> and <link linkend="handling-irqs">Chapter 3</link>. + </para> + <programlisting linenumbering="numbered"> +static int jz4740_musb_exit(struct musb *musb) +{ + usb_put_phy(musb->xceiv); + + return 0; +} + </programlisting> + <para> + Acting as the counterpart of init, the exit function releases the + MUSB PHY driver when the controller hardware itself is about to be + released. + </para> + <para> + Again, note that init and exit are fairly simple in this case due + to the basic set of features of the JZ4740 controller hardware. + When writing an musb glue layer for a more complex controller + hardware, you might need to take care of more processing in those + two functions. + </para> + <para> + Returning from the init function, the MUSB controller driver jumps + back into the probe function: + </para> + <programlisting linenumbering="numbered"> +static int jz4740_probe(struct platform_device *pdev) +{ + ret = platform_device_add(musb); + if (ret) { + dev_err(&pdev->dev, "failed to register musb device\n"); + goto err_clk_disable; + } + + return 0; + +err_clk_disable: + clk_disable_unprepare(clk); +err_platform_device_put: + platform_device_put(musb); + return ret; +} + </programlisting> + <para> + This is the last part of the device registration process where the + glue layer adds the controller hardware device to Linux kernel + device hierarchy: at this stage, all known information about the + device is passed on to the Linux USB core stack. + </para> + <programlisting linenumbering="numbered"> +static int jz4740_remove(struct platform_device *pdev) +{ + struct jz4740_glue *glue = platform_get_drvdata(pdev); + + platform_device_unregister(glue->musb); + clk_disable_unprepare(glue->clk); + + return 0; +} + </programlisting> + <para> + Acting as the counterpart of probe, the remove function unregister + the MUSB controller hardware (line 5) and disable the clock (line + 6), allowing it to be gated. + </para> + </chapter> + + <chapter id="handling-irqs"> + <title>Handling IRQs</title> + <para> + Additionally to the MUSB controller hardware basic setup and + registration, the glue layer is also responsible for handling the + IRQs: + </para> + <programlisting linenumbering="numbered"> +static irqreturn_t jz4740_musb_interrupt(int irq, void *__hci) +{ + unsigned long flags; + irqreturn_t retval = IRQ_NONE; + struct musb *musb = __hci; + + spin_lock_irqsave(&musb->lock, flags); + + musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); + musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX); + musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX); + + /* + * The controller is gadget only, the state of the host mode IRQ bits is + * undefined. Mask them to make sure that the musb driver core will + * never see them set + */ + musb->int_usb &= MUSB_INTR_SUSPEND | MUSB_INTR_RESUME | + MUSB_INTR_RESET | MUSB_INTR_SOF; + + if (musb->int_usb || musb->int_tx || musb->int_rx) + retval = musb_interrupt(musb); + + spin_unlock_irqrestore(&musb->lock, flags); + + return retval; +} + </programlisting> + <para> + Here the glue layer mostly has to read the relevant hardware + registers and pass their values on to the controller driver which + will handle the actual event that triggered the IRQ. + </para> + <para> + The interrupt handler critical section is protected by the + spin_lock_irqsave() and counterpart spin_unlock_irqrestore() + functions (line 7 and 24 respectively), which prevent the + interrupt handler code to be run by two different threads at the + same time. + </para> + <para> + Then the relevant interrupt registers are read (line 9 to 11): + </para> + <itemizedlist> + <listitem> + <para> + MUSB_INTRUSB: indicates which USB interrupts are currently + active, + </para> + </listitem> + <listitem> + <para> + MUSB_INTRTX: indicates which of the interrupts for TX + endpoints are currently active, + </para> + </listitem> + <listitem> + <para> + MUSB_INTRRX: indicates which of the interrupts for TX + endpoints are currently active. + </para> + </listitem> + </itemizedlist> + <para> + Note that musb_readb() is used to read 8-bit registers at most, + while musb_readw() allows us to read at most 16-bit registers. + There are other functions that can be used depending on the size + of your device registers. See musb_io.h for more information. + </para> + <para> + Instruction on line 18 is another quirk specific to the JZ4740 + USB device controller, which will be discussed later in <link + linkend="device-quirks">Chapter 5</link>. + </para> + <para> + The glue layer still needs to register the IRQ handler though. + Remember the instruction on line 14 of the init function: + </para> + <programlisting linenumbering="numbered"> +static int jz4740_musb_init(struct musb *musb) +{ + musb->isr = jz4740_musb_interrupt; + + return 0; +} + </programlisting> + <para> + This instruction sets a pointer to the glue layer IRQ handler + function, in order for the controller hardware to call the handler + back when an IRQ comes from the controller hardware. The interrupt + handler is now implemented and registered. + </para> + </chapter> + + <chapter id="device-platform-data"> + <title>Device Platform Data</title> + <para> + In order to write an MUSB glue layer, you need to have some data + describing the hardware capabilities of your controller hardware, + which is called the platform data. + </para> + <para> + Platform data is specific to your hardware, though it may cover a + broad range of devices, and is generally found somewhere in the + arch/ directory, depending on your device architecture. + </para> + <para> + For instance, platform data for the JZ4740 SoC is found in + arch/mips/jz4740/platform.c. In the platform.c file each device of + the JZ4740 SoC is described through a set of structures. + </para> + <para> + Here is the part of arch/mips/jz4740/platform.c that covers the + USB Device Controller (UDC): + </para> + <programlisting linenumbering="numbered"> +/* USB Device Controller */ +struct platform_device jz4740_udc_xceiv_device = { + .name = "usb_phy_gen_xceiv", + .id = 0, +}; + +static struct resource jz4740_udc_resources[] = { + [0] = { + .start = JZ4740_UDC_BASE_ADDR, + .end = JZ4740_UDC_BASE_ADDR + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = JZ4740_IRQ_UDC, + .end = JZ4740_IRQ_UDC, + .flags = IORESOURCE_IRQ, + .name = "mc", + }, +}; + +struct platform_device jz4740_udc_device = { + .name = "musb-jz4740", + .id = -1, + .dev = { + .dma_mask = &jz4740_udc_device.dev.coherent_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(jz4740_udc_resources), + .resource = jz4740_udc_resources, +}; + </programlisting> + <para> + The jz4740_udc_xceiv_device platform device structure (line 2) + describes the UDC transceiver with a name and id number. + </para> + <para> + At the time of this writing, note that + "usb_phy_gen_xceiv" is the specific name to be used for + all transceivers that are either built-in with reference USB IP or + autonomous and doesn't require any PHY programming. You will need + to set CONFIG_NOP_USB_XCEIV=y in the kernel configuration to make + use of the corresponding transceiver driver. The id field could be + set to -1 (equivalent to PLATFORM_DEVID_NONE), -2 (equivalent to + PLATFORM_DEVID_AUTO) or start with 0 for the first device of this + kind if we want a specific id number. + </para> + <para> + The jz4740_udc_resources resource structure (line 7) defines the + UDC registers base addresses. + </para> + <para> + The first array (line 9 to 11) defines the UDC registers base + memory addresses: start points to the first register memory + address, end points to the last register memory address and the + flags member defines the type of resource we are dealing with. So + IORESOURCE_MEM is used to define the registers memory addresses. + The second array (line 14 to 17) defines the UDC IRQ registers + addresses. Since there is only one IRQ register available for the + JZ4740 UDC, start and end point at the same address. The + IORESOURCE_IRQ flag tells that we are dealing with IRQ resources, + and the name "mc" is in fact hard-coded in the MUSB core + in order for the controller driver to retrieve this IRQ resource + by querying it by its name. + </para> + <para> + Finally, the jz4740_udc_device platform device structure (line 21) + describes the UDC itself. + </para> + <para> + The "musb-jz4740" name (line 22) defines the MUSB + driver that is used for this device; remember this is in fact + the name that we used in the jz4740_driver platform driver + structure in <link linkend="linux-musb-basics">Chapter + 2</link>. The id field (line 23) is set to -1 (equivalent to + PLATFORM_DEVID_NONE) since we do not need an id for the device: + the MUSB controller driver was already set to allocate an + automatic id in <link linkend="linux-musb-basics">Chapter + 2</link>. In the dev field we care for DMA related information + here. The dma_mask field (line 25) defines the width of the DMA + mask that is going to be used, and coherent_dma_mask (line 26) + has the same purpose but for the alloc_coherent DMA mappings: in + both cases we are using a 32 bits mask. Then the resource field + (line 29) is simply a pointer to the resource structure defined + before, while the num_resources field (line 28) keeps track of + the number of arrays defined in the resource structure (in this + case there were two resource arrays defined before). + </para> + <para> + With this quick overview of the UDC platform data at the arch/ + level now done, let's get back to the MUSB glue layer specific + platform data in drivers/usb/musb/jz4740.c: + </para> + <programlisting linenumbering="numbered"> +static struct musb_hdrc_config jz4740_musb_config = { + /* Silicon does not implement USB OTG. */ + .multipoint = 0, + /* Max EPs scanned, driver will decide which EP can be used. */ + .num_eps = 4, + /* RAMbits needed to configure EPs from table */ + .ram_bits = 9, + .fifo_cfg = jz4740_musb_fifo_cfg, + .fifo_cfg_size = ARRAY_SIZE(jz4740_musb_fifo_cfg), +}; + +static struct musb_hdrc_platform_data jz4740_musb_platform_data = { + .mode = MUSB_PERIPHERAL, + .config = &jz4740_musb_config, +}; + </programlisting> + <para> + First the glue layer configures some aspects of the controller + driver operation related to the controller hardware specifics. + This is done through the jz4740_musb_config musb_hdrc_config + structure. + </para> + <para> + Defining the OTG capability of the controller hardware, the + multipoint member (line 3) is set to 0 (equivalent to false) + since the JZ4740 UDC is not OTG compatible. Then num_eps (line + 5) defines the number of USB endpoints of the controller + hardware, including endpoint 0: here we have 3 endpoints + + endpoint 0. Next is ram_bits (line 7) which is the width of the + RAM address bus for the MUSB controller hardware. This + information is needed when the controller driver cannot + automatically configure endpoints by reading the relevant + controller hardware registers. This issue will be discussed when + we get to device quirks in <link linkend="device-quirks">Chapter + 5</link>. Last two fields (line 8 and 9) are also about device + quirks: fifo_cfg points to the USB endpoints configuration table + and fifo_cfg_size keeps track of the size of the number of + entries in that configuration table. More on that later in <link + linkend="device-quirks">Chapter 5</link>. + </para> + <para> + Then this configuration is embedded inside + jz4740_musb_platform_data musb_hdrc_platform_data structure (line + 11): config is a pointer to the configuration structure itself, + and mode tells the controller driver if the controller hardware + may be used as MUSB_HOST only, MUSB_PERIPHERAL only or MUSB_OTG + which is a dual mode. + </para> + <para> + Remember that jz4740_musb_platform_data is then used to convey + platform data information as we have seen in the probe function + in <link linkend="linux-musb-basics">Chapter 2</link> + </para> + </chapter> + + <chapter id="device-quirks"> + <title>Device Quirks</title> + <para> + Completing the platform data specific to your device, you may also + need to write some code in the glue layer to work around some + device specific limitations. These quirks may be due to some + hardware bugs, or simply be the result of an incomplete + implementation of the USB On-the-Go specification. + </para> + <para> + The JZ4740 UDC exhibits such quirks, some of which we will discuss + here for the sake of insight even though these might not be found + in the controller hardware you are working on. + </para> + <para> + Let's get back to the init function first: + </para> + <programlisting linenumbering="numbered"> +static int jz4740_musb_init(struct musb *musb) +{ + musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); + if (!musb->xceiv) { + pr_err("HS UDC: no transceiver configured\n"); + return -ENODEV; + } + + /* Silicon does not implement ConfigData register. + * Set dyn_fifo to avoid reading EP config from hardware. + */ + musb->dyn_fifo = true; + + musb->isr = jz4740_musb_interrupt; + + return 0; +} + </programlisting> + <para> + Instruction on line 12 helps the MUSB controller driver to work + around the fact that the controller hardware is missing registers + that are used for USB endpoints configuration. + </para> + <para> + Without these registers, the controller driver is unable to read + the endpoints configuration from the hardware, so we use line 12 + instruction to bypass reading the configuration from silicon, and + rely on a hard-coded table that describes the endpoints + configuration instead: + </para> + <programlisting linenumbering="numbered"> +static struct musb_fifo_cfg jz4740_musb_fifo_cfg[] = { +{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, +{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, +{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 64, }, +}; + </programlisting> + <para> + Looking at the configuration table above, we see that each + endpoints is described by three fields: hw_ep_num is the endpoint + number, style is its direction (either FIFO_TX for the controller + driver to send packets in the controller hardware, or FIFO_RX to + receive packets from hardware), and maxpacket defines the maximum + size of each data packet that can be transmitted over that + endpoint. Reading from the table, the controller driver knows that + endpoint 1 can be used to send and receive USB data packets of 512 + bytes at once (this is in fact a bulk in/out endpoint), and + endpoint 2 can be used to send data packets of 64 bytes at once + (this is in fact an interrupt endpoint). + </para> + <para> + Note that there is no information about endpoint 0 here: that one + is implemented by default in every silicon design, with a + predefined configuration according to the USB specification. For + more examples of endpoint configuration tables, see musb_core.c. + </para> + <para> + Let's now get back to the interrupt handler function: + </para> + <programlisting linenumbering="numbered"> +static irqreturn_t jz4740_musb_interrupt(int irq, void *__hci) +{ + unsigned long flags; + irqreturn_t retval = IRQ_NONE; + struct musb *musb = __hci; + + spin_lock_irqsave(&musb->lock, flags); + + musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); + musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX); + musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX); + + /* + * The controller is gadget only, the state of the host mode IRQ bits is + * undefined. Mask them to make sure that the musb driver core will + * never see them set + */ + musb->int_usb &= MUSB_INTR_SUSPEND | MUSB_INTR_RESUME | + MUSB_INTR_RESET | MUSB_INTR_SOF; + + if (musb->int_usb || musb->int_tx || musb->int_rx) + retval = musb_interrupt(musb); + + spin_unlock_irqrestore(&musb->lock, flags); + + return retval; +} + </programlisting> + <para> + Instruction on line 18 above is a way for the controller driver to + work around the fact that some interrupt bits used for USB host + mode operation are missing in the MUSB_INTRUSB register, thus left + in an undefined hardware state, since this MUSB controller + hardware is used in peripheral mode only. As a consequence, the + glue layer masks these missing bits out to avoid parasite + interrupts by doing a logical AND operation between the value read + from MUSB_INTRUSB and the bits that are actually implemented in + the register. + </para> + <para> + These are only a couple of the quirks found in the JZ4740 USB + device controller. Some others were directly addressed in the MUSB + core since the fixes were generic enough to provide a better + handling of the issues for others controller hardware eventually. + </para> + </chapter> + + <chapter id="conclusion"> + <title>Conclusion</title> + <para> + Writing a Linux MUSB glue layer should be a more accessible task, + as this documentation tries to show the ins and outs of this + exercise. + </para> + <para> + The JZ4740 USB device controller being fairly simple, I hope its + glue layer serves as a good example for the curious mind. Used + with the current MUSB glue layers, this documentation should + provide enough guidance to get started; should anything gets out + of hand, the linux-usb mailing list archive is another helpful + resource to browse through. + </para> + </chapter> + + <chapter id="acknowledgements"> + <title>Acknowledgements</title> + <para> + Many thanks to Lars-Peter Clausen and Maarten ter Huurne for + answering my questions while I was writing the JZ4740 glue layer + and for helping me out getting the code in good shape. + </para> + <para> + I would also like to thank the Qi-Hardware community at large for + its cheerful guidance and support. + </para> + </chapter> + + <chapter id="resources"> + <title>Resources</title> + <para> + USB Home Page: + <ulink url="http://www.usb.org">http://www.usb.org</ulink> + </para> + <para> + linux-usb Mailing List Archives: + <ulink url="http://marc.info/?l=linux-usb">http://marc.info/?l=linux-usb</ulink> + </para> + <para> + USB On-the-Go Basics: + <ulink url="http://www.maximintegrated.com/app-notes/index.mvp/id/1822">http://www.maximintegrated.com/app-notes/index.mvp/id/1822</ulink> + </para> + <para> + Writing USB Device Drivers: + <ulink url="https://www.kernel.org/doc/htmldocs/writing_usb_driver/index.html">https://www.kernel.org/doc/htmldocs/writing_usb_driver/index.html</ulink> + </para> + <para> + Texas Instruments USB Configuration Wiki Page: + <ulink url="http://processors.wiki.ti.com/index.php/Usbgeneralpage">http://processors.wiki.ti.com/index.php/Usbgeneralpage</ulink> + </para> + <para> + Analog Devices Blackfin MUSB Configuration: + <ulink url="http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:musb">http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:musb</ulink> + </para> + </chapter> + +</book> diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt index b422e38946d7..2049261d8c31 100644 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt @@ -114,3 +114,50 @@ Example: compatible = "samsung,exynos-sataphy-i2c"; reg = <0x38>; }; + +Samsung Exynos5 SoC series USB DRD PHY controller +-------------------------------------------------- + +Required properties: +- compatible : Should be set to one of the following supported values: + - "samsung,exynos5250-usbdrd-phy" - for exynos5250 SoC, + - "samsung,exynos5420-usbdrd-phy" - for exynos5420 SoC. +- reg : Register offset and length of USB DRD PHY register set; +- clocks: Clock IDs array as required by the controller +- clock-names: names of clocks correseponding to IDs in the clock property; + Required clocks: + - phy: main PHY clock (same as USB DRD controller i.e. DWC3 IP clock), + used for register access. + - ref: PHY's reference clock (usually crystal clock), used for + PHY operations, associated by phy name. It is used to + determine bit values for clock settings register. + For Exynos5420 this is given as 'sclk_usbphy30' in CMU. +- samsung,pmu-syscon: phandle for PMU system controller interface, used to + control pmu registers for power isolation. +- #phy-cells : from the generic PHY bindings, must be 1; + +For "samsung,exynos5250-usbdrd-phy" and "samsung,exynos5420-usbdrd-phy" +compatible PHYs, the second cell in the PHY specifier identifies the +PHY id, which is interpreted as follows: + 0 - UTMI+ type phy, + 1 - PIPE3 type phy, + +Example: + usbdrd_phy: usbphy@12100000 { + compatible = "samsung,exynos5250-usbdrd-phy"; + reg = <0x12100000 0x100>; + clocks = <&clock 286>, <&clock 1>; + clock-names = "phy", "ref"; + samsung,pmu-syscon = <&pmu_system_controller>; + #phy-cells = <1>; + }; + +- aliases: For SoCs like Exynos5420 having multiple USB 3.0 DRD PHY controllers, + 'usbdrd_phy' nodes should have numbered alias in the aliases node, + in the form of usbdrdphyN, N = 0, 1... (depending on number of + controllers). +Example: + aliases { + usbdrdphy0 = &usb3_phy0; + usbdrdphy1 = &usb3_phy1; + }; diff --git a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt index a82361b62015..16528b9eb561 100644 --- a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt +++ b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt @@ -2,15 +2,26 @@ Allwinner sun4i USB PHY ----------------------- Required properties: -- compatible : should be one of "allwinner,sun4i-a10-usb-phy", - "allwinner,sun5i-a13-usb-phy" or "allwinner,sun7i-a20-usb-phy" +- compatible : should be one of + * allwinner,sun4i-a10-usb-phy + * allwinner,sun5i-a13-usb-phy + * allwinner,sun6i-a31-usb-phy + * allwinner,sun7i-a20-usb-phy - reg : a list of offset + length pairs -- reg-names : "phy_ctrl", "pmu1" and for sun4i or sun7i "pmu2" +- reg-names : + * "phy_ctrl" + * "pmu1" + * "pmu2" for sun4i, sun6i or sun7i - #phy-cells : from the generic phy bindings, must be 1 -- clocks : phandle + clock specifier for the phy clock -- clock-names : "usb_phy" +- clocks : phandle + clock specifier for the phy clocks +- clock-names : + * "usb_phy" for sun4i, sun5i or sun7i + * "usb0_phy", "usb1_phy" and "usb2_phy" for sun6i - resets : a list of phandle + reset specifier pairs -- reset-names : "usb0_reset", "usb1_reset" and for sun4i or sun7i "usb2_reset" +- reset-names : + * "usb0_reset" + * "usb1_reset" + * "usb2_reset" for sun4i, sun6i or sun7i Example: usbphy: phy@0x01c13400 { diff --git a/Documentation/devicetree/bindings/phy/ti-phy.txt b/Documentation/devicetree/bindings/phy/ti-phy.txt index 788fb0fa3762..9ce458f32945 100644 --- a/Documentation/devicetree/bindings/phy/ti-phy.txt +++ b/Documentation/devicetree/bindings/phy/ti-phy.txt @@ -32,6 +32,11 @@ Required properties: - reg : Address and length of the register set for the device. - #phy-cells: determine the number of cells that should be given in the phandle while referencing this phy. + - clocks: a list of phandles and clock-specifier pairs, one for each entry in + clock-names. + - clock-names: should include: + * "wkupclk" - wakeup clock. + * "refclk" - reference clock (optional). Optional properties: - ctrl-module : phandle of the control module used by PHY driver to power on @@ -44,6 +49,8 @@ usb2phy@4a0ad080 { reg = <0x4a0ad080 0x58>; ctrl-module = <&omap_control_usb>; #phy-cells = <0>; + clocks = <&usb_phy_cm_clk32k>, <&usb_otg_ss_refclk960m>; + clock-names = "wkupclk", "refclk"; }; TI PIPE3 PHY diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-qcom.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-qcom.txt new file mode 100644 index 000000000000..f2899b550939 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-qcom.txt @@ -0,0 +1,17 @@ +Qualcomm CI13xxx (Chipidea) USB controllers + +Required properties: +- compatible: should contain "qcom,ci-hdrc" +- reg: offset and length of the register set in the memory map +- interrupts: interrupt-specifier for the controller interrupt. +- usb-phy: phandle for the PHY device +- dr_mode: Should be "peripheral" + +Examples: + gadget@f9a55000 { + compatible = "qcom,ci-hdrc"; + reg = <0xf9a55000 0x400>; + dr_mode = "peripheral"; + interrupts = <0 134 0>; + usb-phy = <&usbphy0>; + }; diff --git a/Documentation/devicetree/bindings/usb/ehci-orion.txt b/Documentation/devicetree/bindings/usb/ehci-orion.txt index 6bc09ec14c4d..17c3bc858b86 100644 --- a/Documentation/devicetree/bindings/usb/ehci-orion.txt +++ b/Documentation/devicetree/bindings/usb/ehci-orion.txt @@ -6,6 +6,11 @@ Required properties: region. - interrupts: The EHCI interrupt +Optional properties: +- clocks: reference to the clock +- phys: reference to the USB PHY +- phy-names: name of the USB PHY, should be "usb" + Example: ehci@50000 { diff --git a/Documentation/devicetree/bindings/usb/exynos-usb.txt b/Documentation/devicetree/bindings/usb/exynos-usb.txt index d967ba16de60..a3b5990d0f2c 100644 --- a/Documentation/devicetree/bindings/usb/exynos-usb.txt +++ b/Documentation/devicetree/bindings/usb/exynos-usb.txt @@ -12,6 +12,13 @@ Required properties: - interrupts: interrupt number to the cpu. - clocks: from common clock binding: handle to usb clock. - clock-names: from common clock binding: Shall be "usbhost". + - port: if in the SoC there are EHCI phys, they should be listed here. + One phy per port. Each port should have following entries: + - reg: port number on EHCI controller, e.g + On Exynos5250, port 0 is USB2.0 otg phy + port 1 is HSIC phy0 + port 2 is HSIC phy1 + - phys: from the *Generic PHY* bindings; specifying phy used by port. Optional properties: - samsung,vbus-gpio: if present, specifies the GPIO that @@ -27,6 +34,14 @@ Example: clocks = <&clock 285>; clock-names = "usbhost"; + + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + phys = <&usb2phy 1>; + status = "disabled"; + }; }; OHCI @@ -38,6 +53,13 @@ Required properties: - interrupts: interrupt number to the cpu. - clocks: from common clock binding: handle to usb clock. - clock-names: from common clock binding: Shall be "usbhost". + - port: if in the SoC there are OHCI phys, they should be listed here. + One phy per port. Each port should have following entries: + - reg: port number on OHCI controller, e.g + On Exynos5250, port 0 is USB2.0 otg phy + port 1 is HSIC phy0 + port 2 is HSIC phy1 + - phys: from the *Generic PHY* bindings, specifying phy used by port. Example: usb@12120000 { @@ -47,6 +69,15 @@ Example: clocks = <&clock 285>; clock-names = "usbhost"; + + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + phys = <&usb2phy 1>; + status = "disabled"; + }; + }; DWC3 diff --git a/Documentation/devicetree/bindings/usb/gr-udc.txt b/Documentation/devicetree/bindings/usb/gr-udc.txt index 0c5118f7a916..e9445224fabd 100644 --- a/Documentation/devicetree/bindings/usb/gr-udc.txt +++ b/Documentation/devicetree/bindings/usb/gr-udc.txt @@ -12,17 +12,23 @@ Required properties: - reg : Address and length of the register set for the device -- interrupts : Interrupt numbers for this device +- interrupts : Interrupt numbers for this device. Either one interrupt number + for all interrupts, or one for status related interrupts, one for IN + endpoint related interrupts and one for OUT endpoint related interrupts. Optional properties: -- epobufsizes : An array of buffer sizes for OUT endpoints. If the property is - not present, or for endpoints outside of the array, 1024 is assumed by - the driver. - -- epibufsizes : An array of buffer sizes for IN endpoints. If the property is - not present, or for endpoints outside of the array, 1024 is assumed by - the driver. +- epobufsizes : Array of buffer sizes for OUT endpoints when they differ + from the default size of 1024. The array is indexed by the OUT endpoint + number. If the property is present it typically contains one entry for + each OUT endpoint of the core. Fewer entries overrides the default sizes + only for as many endpoints as the array contains. + +- epibufsizes : Array of buffer sizes for IN endpoints when they differ + from the default size of 1024. The array is indexed by the IN endpoint + number. If the property is present it typically contains one entry for + each IN endpoint of the core. Fewer entries overrides the default sizes + only for as many endpoints as the array contains. For further information look in the documentation for the GLIB IP core library: http://www.gaisler.com/products/grlib/grip.pdf diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt index 5ea26c631e3a..2826f2af503a 100644 --- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt +++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt @@ -15,3 +15,81 @@ Example EHCI controller device node: usb-phy = <&usb_otg>; }; +USB PHY with optional OTG: + +Required properties: +- compatible: Should contain: + "qcom,usb-otg-ci" for chipsets with ChipIdea 45nm PHY + "qcom,usb-otg-snps" for chipsets with Synopsys 28nm PHY + +- regs: Offset and length of the register set in the memory map +- interrupts: interrupt-specifier for the OTG interrupt. + +- clocks: A list of phandle + clock-specifier pairs for the + clocks listed in clock-names +- clock-names: Should contain the following: + "phy" USB PHY reference clock + "core" Protocol engine clock + "iface" Interface bus clock + "alt_core" Protocol engine clock for targets with asynchronous + reset methodology. (optional) + +- vdccx-supply: phandle to the regulator for the vdd supply for + digital circuit operation. +- v1p8-supply: phandle to the regulator for the 1.8V supply +- v3p3-supply: phandle to the regulator for the 3.3V supply + +- resets: A list of phandle + reset-specifier pairs for the + resets listed in reset-names +- reset-names: Should contain the following: + "phy" USB PHY controller reset + "link" USB LINK controller reset + +- qcom,otg-control: OTG control (VBUS and ID notifications) can be one of + 1 - PHY control + 2 - PMIC control + +Optional properties: +- dr_mode: One of "host", "peripheral" or "otg". Defaults to "otg" + +- qcom,phy-init-sequence: PHY configuration sequence values. This is related to Device + Mode Eye Diagram test. Start address at which these values will be + written is ULPI_EXT_VENDOR_SPECIFIC. Value of -1 is reserved as + "do not overwrite default value at this address". + For example: qcom,phy-init-sequence = < -1 0x63 >; + Will update only value at address ULPI_EXT_VENDOR_SPECIFIC + 1. + +- qcom,phy-num: Select number of pyco-phy to use, can be one of + 0 - PHY one, default + 1 - Second PHY + Some platforms may have configuration to allow USB + controller work with any of the two HSPHYs present. + +- qcom,vdd-levels: This property must be a list of three integer values + (no, min, max) where each value represents either a voltage + in microvolts or a value corresponding to voltage corner. + +Example HSUSB OTG controller device node: + + usb@f9a55000 { + compatible = "qcom,usb-otg-snps"; + reg = <0xf9a55000 0x400>; + interrupts = <0 134 0>; + dr_mode = "peripheral"; + + clocks = <&gcc GCC_XO_CLK>, <&gcc GCC_USB_HS_SYSTEM_CLK>, + <&gcc GCC_USB_HS_AHB_CLK>; + + clock-names = "phy", "core", "iface"; + + vddcx-supply = <&pm8841_s2_corner>; + v1p8-supply = <&pm8941_l6>; + v3p3-supply = <&pm8941_l24>; + + resets = <&gcc GCC_USB2A_PHY_BCR>, <&gcc GCC_USB_HS_BCR>; + reset-names = "phy", "link"; + + qcom,otg-control = <1>; + qcom,phy-init-sequence = < -1 0x63 >; + qcom,vdd-levels = <1 5 7>; + }; diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt b/Documentation/devicetree/bindings/usb/usb-ehci.txt index ff151ec084c4..43c1a4e06767 100644 --- a/Documentation/devicetree/bindings/usb/usb-ehci.txt +++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt @@ -15,6 +15,7 @@ Optional properties: - clocks : a list of phandle + clock specifier pairs - phys : phandle + phy specifier pair - phy-names : "usb" + - resets : phandle + reset specifier pair Example (Sequoia 440EPx): ehci@e0000300 { diff --git a/Documentation/devicetree/bindings/usb/usb-ohci.txt b/Documentation/devicetree/bindings/usb/usb-ohci.txt index 45f67d91e888..b968a1aea995 100644 --- a/Documentation/devicetree/bindings/usb/usb-ohci.txt +++ b/Documentation/devicetree/bindings/usb/usb-ohci.txt @@ -12,6 +12,7 @@ Optional properties: - clocks : a list of phandle + clock specifier pairs - phys : phandle + phy specifier pair - phy-names : "usb" +- resets : phandle + reset specifier pair Example: diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt index 90f8f607d125..5a79377c6a96 100644 --- a/Documentation/devicetree/bindings/usb/usb-xhci.txt +++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt @@ -1,11 +1,17 @@ USB xHCI controllers Required properties: - - compatible: should be "generic-xhci" (deprecated: "xhci-platform"). + - compatible: should be one of "generic-xhci", + "marvell,armada-375-xhci", "marvell,armada-380-xhci", + "renesas,xhci-r8a7790", "renesas,xhci-r8a7791" (deprecated: + "xhci-platform"). - reg: should contain address and length of the standard XHCI register set for the device. - interrupts: one XHCI interrupt should be described here. +Optional property: + - clocks: reference to a clock + Example: usb@f0931000 { compatible = "generic-xhci"; diff --git a/Documentation/devicetree/bindings/usb/usb3503.txt b/Documentation/devicetree/bindings/usb/usb3503.txt index a018da4a7ad7..221ac0dbc678 100644 --- a/Documentation/devicetree/bindings/usb/usb3503.txt +++ b/Documentation/devicetree/bindings/usb/usb3503.txt @@ -15,6 +15,14 @@ Optional properties: - reset-gpios: Should specify GPIO for reset. - initial-mode: Should specify initial mode. (1 for HUB mode, 2 for STANDBY mode) +- refclk: Clock used for driving REFCLK signal (optional, if not provided + the driver assumes that clock signal is always available, its + rate is specified by REF_SEL pins and a value from the primary + reference clock frequencies table is used) +- refclk-frequency: Frequency of the REFCLK signal as defined by REF_SEL + pins (optional, if not provided, driver will not set rate of the + REFCLK signal and assume that a value from the primary reference + clock frequencies table is used) Examples: usb3503@08 { diff --git a/Documentation/usb/chipidea.txt b/Documentation/usb/chipidea.txt new file mode 100644 index 000000000000..995c8bca40e2 --- /dev/null +++ b/Documentation/usb/chipidea.txt @@ -0,0 +1,71 @@ +1. How to test OTG FSM(HNP and SRP) +----------------------------------- +To show how to demo OTG HNP and SRP functions via sys input files +with 2 Freescale i.MX6Q sabre SD boards. + +1.1 How to enable OTG FSM in menuconfig +--------------------------------------- +Select CONFIG_USB_OTG_FSM, rebuild kernel Image and modules. +If you want to check some internal variables for otg fsm, +select CONFIG_USB_CHIPIDEA_DEBUG, there are 2 files which +can show otg fsm variables and some controller registers value: +cat /sys/kernel/debug/ci_hdrc.0/otg +cat /sys/kernel/debug/ci_hdrc.0/registers + +1.2 Test operations +------------------- +1) Power up 2 Freescale i.MX6Q sabre SD boards with gadget class driver loaded + (e.g. g_mass_storage). + +2) Connect 2 boards with usb cable with one end is micro A plug, the other end + is micro B plug. + + The A-device(with micro A plug inserted) should enumrate B-device. + +3) Role switch + On B-device: + echo 1 > /sys/bus/platform/devices/ci_hdrc.0/inputs/b_bus_req + + if HNP polling is not supported, also need: + On A-device: + echo 0 > /sys/bus/platform/devices/ci_hdrc.0/inputs/a_bus_req + + B-device should take host role and enumrate A-device. + +4) A-device switch back to host. + On B-device: + echo 0 > /sys/bus/platform/devices/ci_hdrc.0/inputs/b_bus_req + + A-device should switch back to host and enumrate B-device. + +5) Remove B-device(unplug micro B plug) and insert again in 10 seconds, + A-device should enumrate B-device again. + +6) Remove B-device(unplug micro B plug) and insert again after 10 seconds, + A-device should NOT enumrate B-device. + + if A-device wants to use bus: + On A-device: + echo 0 > /sys/bus/platform/devices/ci_hdrc.0/inputs/a_bus_drop + echo 1 > /sys/bus/platform/devices/ci_hdrc.0/inputs/a_bus_req + + if B-device wants to use bus: + On B-device: + echo 1 > /sys/bus/platform/devices/ci_hdrc.0/inputs/b_bus_req + +7) A-device power down the bus. + On A-device: + echo 1 > /sys/bus/platform/devices/ci_hdrc.0/inputs/a_bus_drop + + A-device should disconnect with B-device and power down the bus. + +8) B-device does data pulse for SRP. + On B-device: + echo 1 > /sys/bus/platform/devices/ci_hdrc.0/inputs/b_bus_req + + A-device should resume usb bus and enumrate B-device. + +1.3 Reference document +---------------------- +"On-The-Go and Embedded Host Supplement to the USB Revision 2.0 Specification +July 27, 2012 Revision 2.0 version 1.1a" |