Sophie

Sophie

distrib > Fedora > 20 > x86_64 > by-pkgid > 888a2f3d4ea212b694328c0525364729 > files > 6455

kernel-doc-3.19.8-100.fc20.noarch.rpm

<html><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968"><title>Chapter&#160;4.&#160;Device Platform Data</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="Writing an MUSB Glue Layer"><link rel="up" href="index.html" title="Writing an MUSB Glue Layer"><link rel="prev" href="handling-irqs.html" title="Chapter&#160;3.&#160;Handling IRQs"><link rel="next" href="device-quirks.html" title="Chapter&#160;5.&#160;Device Quirks"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter&#160;4.&#160;Device Platform Data</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="handling-irqs.html">Prev</a>&#160;</td><th width="60%" align="center">&#160;</th><td width="20%" align="right">&#160;<a accesskey="n" href="device-quirks.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="device-platform-data"></a>Chapter&#160;4.&#160;Device Platform Data</h1></div></div></div><p>
      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.
    </p><p>
      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.
    </p><p>
      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.
    </p><p>
      Here is the part of arch/mips/jz4740/platform.c that covers the
      USB Device Controller (UDC):
    </p><pre class="programlisting">
/* 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          = &amp;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,
};
    </pre><p>
      The jz4740_udc_xceiv_device platform device structure (line 2)
      describes the UDC transceiver with a name and id number.
    </p><p>
      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.
    </p><p>
      The jz4740_udc_resources resource structure (line 7) defines the
      UDC registers base addresses.
    </p><p>
      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.
    </p><p>
      Finally, the jz4740_udc_device platform device structure (line 21)
      describes the UDC itself.
    </p><p>
      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 <a class="link" href="linux-musb-basics.html" title="Chapter&#160;2.&#160;Linux MUSB Basics">Chapter
      2</a>. 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 <a class="link" href="linux-musb-basics.html" title="Chapter&#160;2.&#160;Linux MUSB Basics">Chapter
      2</a>. 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).
    </p><p>
      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:
    </p><pre class="programlisting">
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 = &amp;jz4740_musb_config,
};
    </pre><p>
      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.
    </p><p>
      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 <a class="link" href="device-quirks.html" title="Chapter&#160;5.&#160;Device Quirks">Chapter
      5</a>. 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 <a class="link" href="device-quirks.html" title="Chapter&#160;5.&#160;Device Quirks">Chapter 5</a>.
    </p><p>
      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.
    </p><p>
      Remember that jz4740_musb_platform_data is then used to convey
      platform data information as we have seen in the probe function
      in <a class="link" href="linux-musb-basics.html" title="Chapter&#160;2.&#160;Linux MUSB Basics">Chapter 2</a>
    </p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="handling-irqs.html">Prev</a>&#160;</td><td width="20%" align="center">&#160;</td><td width="40%" align="right">&#160;<a accesskey="n" href="device-quirks.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter&#160;3.&#160;Handling IRQs&#160;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&#160;Chapter&#160;5.&#160;Device Quirks</td></tr></table></div></body></html>