1<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>
2      In order to write an MUSB glue layer, you need to have some data
3      describing the hardware capabilities of your controller hardware,
4      which is called the platform data.
5    </p><p>
6      Platform data is specific to your hardware, though it may cover a
7      broad range of devices, and is generally found somewhere in the
8      arch/ directory, depending on your device architecture.
9    </p><p>
10      For instance, platform data for the JZ4740 SoC is found in
11      arch/mips/jz4740/platform.c. In the platform.c file each device of
12      the JZ4740 SoC is described through a set of structures.
13    </p><p>
14      Here is the part of arch/mips/jz4740/platform.c that covers the
15      USB Device Controller (UDC):
16    </p><pre class="programlisting">
17/* USB Device Controller */
18struct platform_device jz4740_udc_xceiv_device = {
19	.name = "usb_phy_gen_xceiv",
20	.id   = 0,
21};
22
23static struct resource jz4740_udc_resources[] = {
24	[0] = {
25		.start = JZ4740_UDC_BASE_ADDR,
26		.end   = JZ4740_UDC_BASE_ADDR + 0x10000 - 1,
27		.flags = IORESOURCE_MEM,
28	},
29	[1] = {
30		.start = JZ4740_IRQ_UDC,
31		.end   = JZ4740_IRQ_UDC,
32		.flags = IORESOURCE_IRQ,
33		.name  = "mc",
34	},
35};
36
37struct platform_device jz4740_udc_device = {
38	.name = "musb-jz4740",
39	.id   = -1,
40	.dev  = {
41		.dma_mask          = &amp;jz4740_udc_device.dev.coherent_dma_mask,
42		.coherent_dma_mask = DMA_BIT_MASK(32),
43	},
44	.num_resources = ARRAY_SIZE(jz4740_udc_resources),
45	.resource      = jz4740_udc_resources,
46};
47    </pre><p>
48      The jz4740_udc_xceiv_device platform device structure (line 2)
49      describes the UDC transceiver with a name and id number.
50    </p><p>
51      At the time of this writing, note that
52      "usb_phy_gen_xceiv" is the specific name to be used for
53      all transceivers that are either built-in with reference USB IP or
54      autonomous and doesn't require any PHY programming. You will need
55      to set CONFIG_NOP_USB_XCEIV=y in the kernel configuration to make
56      use of the corresponding transceiver driver. The id field could be
57      set to -1 (equivalent to PLATFORM_DEVID_NONE), -2 (equivalent to
58      PLATFORM_DEVID_AUTO) or start with 0 for the first device of this
59      kind if we want a specific id number.
60    </p><p>
61      The jz4740_udc_resources resource structure (line 7) defines the
62      UDC registers base addresses.
63    </p><p>
64      The first array (line 9 to 11) defines the UDC registers base
65      memory addresses: start points to the first register memory
66      address, end points to the last register memory address and the
67      flags member defines the type of resource we are dealing with. So
68      IORESOURCE_MEM is used to define the registers memory addresses.
69      The second array (line 14 to 17) defines the UDC IRQ registers
70      addresses. Since there is only one IRQ register available for the
71      JZ4740 UDC, start and end point at the same address. The
72      IORESOURCE_IRQ flag tells that we are dealing with IRQ resources,
73      and the name "mc" is in fact hard-coded in the MUSB core
74      in order for the controller driver to retrieve this IRQ resource
75      by querying it by its name.
76    </p><p>
77      Finally, the jz4740_udc_device platform device structure (line 21)
78      describes the UDC itself.
79    </p><p>
80      The "musb-jz4740" name (line 22) defines the MUSB
81      driver that is used for this device; remember this is in fact
82      the name that we used in the jz4740_driver platform driver
83      structure in <a class="link" href="linux-musb-basics.html" title="Chapter&#160;2.&#160;Linux MUSB Basics">Chapter
84      2</a>. The id field (line 23) is set to -1 (equivalent to
85      PLATFORM_DEVID_NONE) since we do not need an id for the device:
86      the MUSB controller driver was already set to allocate an
87      automatic id in <a class="link" href="linux-musb-basics.html" title="Chapter&#160;2.&#160;Linux MUSB Basics">Chapter
88      2</a>. In the dev field we care for DMA related information
89      here. The dma_mask field (line 25) defines the width of the DMA
90      mask that is going to be used, and coherent_dma_mask (line 26)
91      has the same purpose but for the alloc_coherent DMA mappings: in
92      both cases we are using a 32 bits mask. Then the resource field
93      (line 29) is simply a pointer to the resource structure defined
94      before, while the num_resources field (line 28) keeps track of
95      the number of arrays defined in the resource structure (in this
96      case there were two resource arrays defined before).
97    </p><p>
98      With this quick overview of the UDC platform data at the arch/
99      level now done, let's get back to the MUSB glue layer specific
100      platform data in drivers/usb/musb/jz4740.c:
101    </p><pre class="programlisting">
102static struct musb_hdrc_config jz4740_musb_config = {
103	/* Silicon does not implement USB OTG. */
104	.multipoint = 0,
105	/* Max EPs scanned, driver will decide which EP can be used. */
106	.num_eps    = 4,
107	/* RAMbits needed to configure EPs from table */
108	.ram_bits   = 9,
109	.fifo_cfg = jz4740_musb_fifo_cfg,
110	.fifo_cfg_size = ARRAY_SIZE(jz4740_musb_fifo_cfg),
111};
112
113static struct musb_hdrc_platform_data jz4740_musb_platform_data = {
114	.mode   = MUSB_PERIPHERAL,
115	.config = &amp;jz4740_musb_config,
116};
117    </pre><p>
118      First the glue layer configures some aspects of the controller
119      driver operation related to the controller hardware specifics.
120      This is done through the jz4740_musb_config musb_hdrc_config
121      structure.
122    </p><p>
123      Defining the OTG capability of the controller hardware, the
124      multipoint member (line 3) is set to 0 (equivalent to false)
125      since the JZ4740 UDC is not OTG compatible. Then num_eps (line
126      5) defines the number of USB endpoints of the controller
127      hardware, including endpoint 0: here we have 3 endpoints +
128      endpoint 0. Next is ram_bits (line 7) which is the width of the
129      RAM address bus for the MUSB controller hardware. This
130      information is needed when the controller driver cannot
131      automatically configure endpoints by reading the relevant
132      controller hardware registers. This issue will be discussed when
133      we get to device quirks in <a class="link" href="device-quirks.html" title="Chapter&#160;5.&#160;Device Quirks">Chapter
134      5</a>. Last two fields (line 8 and 9) are also about device
135      quirks: fifo_cfg points to the USB endpoints configuration table
136      and fifo_cfg_size keeps track of the size of the number of
137      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>.
138    </p><p>
139      Then this configuration is embedded inside
140      jz4740_musb_platform_data musb_hdrc_platform_data structure (line
141      11): config is a pointer to the configuration structure itself,
142      and mode tells the controller driver if the controller hardware
143      may be used as MUSB_HOST only, MUSB_PERIPHERAL only or MUSB_OTG
144      which is a dual mode.
145    </p><p>
146      Remember that jz4740_musb_platform_data is then used to convey
147      platform data information as we have seen in the probe function
148      in <a class="link" href="linux-musb-basics.html" title="Chapter&#160;2.&#160;Linux MUSB Basics">Chapter 2</a>
149    </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>
150