Commit | Line | Data |
---|---|---|
60b6dbef AS |
1 | <?xml version="1.0" encoding="UTF-8"?> |
2 | <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" | |
3 | "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> | |
4 | ||
5 | <book id="Writing-MUSB-Glue-Layer"> | |
6 | <bookinfo> | |
7 | <title>Writing an MUSB Glue Layer</title> | |
8 | ||
9 | <authorgroup> | |
10 | <author> | |
11 | <firstname>Apelete</firstname> | |
12 | <surname>Seketeli</surname> | |
13 | <affiliation> | |
14 | <address> | |
15 | <email>apelete at seketeli.net</email> | |
16 | </address> | |
17 | </affiliation> | |
18 | </author> | |
19 | </authorgroup> | |
20 | ||
21 | <copyright> | |
22 | <year>2014</year> | |
23 | <holder>Apelete Seketeli</holder> | |
24 | </copyright> | |
25 | ||
26 | <legalnotice> | |
27 | <para> | |
28 | This documentation is free software; you can redistribute it | |
29 | and/or modify it under the terms of the GNU General Public | |
30 | License as published by the Free Software Foundation; either | |
31 | version 2 of the License, or (at your option) any later version. | |
32 | </para> | |
33 | ||
34 | <para> | |
35 | This documentation is distributed in the hope that it will be | |
36 | useful, but WITHOUT ANY WARRANTY; without even the implied | |
37 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
38 | See the GNU General Public License for more details. | |
39 | </para> | |
40 | ||
41 | <para> | |
42 | You should have received a copy of the GNU General Public License | |
43 | along with this documentation; if not, write to the Free Software | |
44 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
45 | 02111-1307 USA | |
46 | </para> | |
47 | ||
48 | <para> | |
49 | For more details see the file COPYING in the Linux kernel source | |
50 | tree. | |
51 | </para> | |
52 | </legalnotice> | |
53 | </bookinfo> | |
54 | ||
55 | <toc></toc> | |
56 | ||
57 | <chapter id="introduction"> | |
58 | <title>Introduction</title> | |
59 | <para> | |
60 | The Linux MUSB subsystem is part of the larger Linux USB | |
61 | subsystem. It provides support for embedded USB Device Controllers | |
62 | (UDC) that do not use Universal Host Controller Interface (UHCI) | |
63 | or Open Host Controller Interface (OHCI). | |
64 | </para> | |
65 | <para> | |
66 | Instead, these embedded UDC rely on the USB On-the-Go (OTG) | |
67 | specification which they implement at least partially. The silicon | |
68 | reference design used in most cases is the Multipoint USB | |
69 | Highspeed Dual-Role Controller (MUSB HDRC) found in the Mentor | |
70 | Graphics Inventra™ design. | |
71 | </para> | |
72 | <para> | |
73 | As a self-taught exercise I have written an MUSB glue layer for | |
74 | the Ingenic JZ4740 SoC, modelled after the many MUSB glue layers | |
75 | in the kernel source tree. This layer can be found at | |
76 | drivers/usb/musb/jz4740.c. In this documentation I will walk | |
77 | through the basics of the jz4740.c glue layer, explaining the | |
78 | different pieces and what needs to be done in order to write your | |
79 | own device glue layer. | |
80 | </para> | |
81 | </chapter> | |
82 | ||
83 | <chapter id="linux-musb-basics"> | |
84 | <title>Linux MUSB Basics</title> | |
85 | <para> | |
86 | To get started on the topic, please read USB On-the-Go Basics (see | |
87 | Resources) which provides an introduction of USB OTG operation at | |
88 | the hardware level. A couple of wiki pages by Texas Instruments | |
89 | and Analog Devices also provide an overview of the Linux kernel | |
90 | MUSB configuration, albeit focused on some specific devices | |
91 | provided by these companies. Finally, getting acquainted with the | |
92 | USB specification at USB home page may come in handy, with | |
93 | practical instance provided through the Writing USB Device Drivers | |
94 | documentation (again, see Resources). | |
95 | </para> | |
96 | <para> | |
97 | Linux USB stack is a layered architecture in which the MUSB | |
98 | controller hardware sits at the lowest. The MUSB controller driver | |
99 | abstract the MUSB controller hardware to the Linux USB stack. | |
100 | </para> | |
101 | <programlisting> | |
102 | ------------------------ | |
103 | | | <------- drivers/usb/gadget | |
104 | | Linux USB Core Stack | <------- drivers/usb/host | |
105 | | | <------- drivers/usb/core | |
106 | ------------------------ | |
107 | ⬍ | |
108 | -------------------------- | |
109 | | | <------ drivers/usb/musb/musb_gadget.c | |
110 | | MUSB Controller driver | <------ drivers/usb/musb/musb_host.c | |
111 | | | <------ drivers/usb/musb/musb_core.c | |
112 | -------------------------- | |
113 | ⬍ | |
114 | --------------------------------- | |
115 | | MUSB Platform Specific Driver | | |
116 | | | <-- drivers/usb/musb/jz4740.c | |
117 | | aka "Glue Layer" | | |
118 | --------------------------------- | |
119 | ⬍ | |
120 | --------------------------------- | |
121 | | MUSB Controller Hardware | | |
122 | --------------------------------- | |
123 | </programlisting> | |
124 | <para> | |
125 | As outlined above, the glue layer is actually the platform | |
126 | specific code sitting in between the controller driver and the | |
127 | controller hardware. | |
128 | </para> | |
129 | <para> | |
130 | Just like a Linux USB driver needs to register itself with the | |
131 | Linux USB subsystem, the MUSB glue layer needs first to register | |
132 | itself with the MUSB controller driver. This will allow the | |
133 | controller driver to know about which device the glue layer | |
134 | supports and which functions to call when a supported device is | |
135 | detected or released; remember we are talking about an embedded | |
136 | controller chip here, so no insertion or removal at run-time. | |
137 | </para> | |
138 | <para> | |
139 | All of this information is passed to the MUSB controller driver | |
140 | through a platform_driver structure defined in the glue layer as: | |
141 | </para> | |
142 | <programlisting linenumbering="numbered"> | |
143 | static struct platform_driver jz4740_driver = { | |
144 | .probe = jz4740_probe, | |
145 | .remove = jz4740_remove, | |
146 | .driver = { | |
147 | .name = "musb-jz4740", | |
148 | }, | |
149 | }; | |
150 | </programlisting> | |
151 | <para> | |
152 | The probe and remove function pointers are called when a matching | |
153 | device is detected and, respectively, released. The name string | |
154 | describes the device supported by this glue layer. In the current | |
155 | case it matches a platform_device structure declared in | |
156 | arch/mips/jz4740/platform.c. Note that we are not using device | |
157 | tree bindings here. | |
158 | </para> | |
159 | <para> | |
160 | In order to register itself to the controller driver, the glue | |
161 | layer goes through a few steps, basically allocating the | |
162 | controller hardware resources and initialising a couple of | |
163 | circuits. To do so, it needs to keep track of the information used | |
164 | throughout these steps. This is done by defining a private | |
165 | jz4740_glue structure: | |
166 | </para> | |
167 | <programlisting linenumbering="numbered"> | |
168 | struct jz4740_glue { | |
169 | struct device *dev; | |
170 | struct platform_device *musb; | |
171 | struct clk *clk; | |
172 | }; | |
173 | </programlisting> | |
174 | <para> | |
175 | The dev and musb members are both device structure variables. The | |
176 | first one holds generic information about the device, since it's | |
177 | the basic device structure, and the latter holds information more | |
178 | closely related to the subsystem the device is registered to. The | |
179 | clk variable keeps information related to the device clock | |
180 | operation. | |
181 | </para> | |
182 | <para> | |
183 | Let's go through the steps of the probe function that leads the | |
184 | glue layer to register itself to the controller driver. | |
185 | </para> | |
186 | <para> | |
187 | N.B.: For the sake of readability each function will be split in | |
188 | logical parts, each part being shown as if it was independent from | |
189 | the others. | |
190 | </para> | |
191 | <programlisting linenumbering="numbered"> | |
192 | static int jz4740_probe(struct platform_device *pdev) | |
193 | { | |
194 | struct platform_device *musb; | |
195 | struct jz4740_glue *glue; | |
196 | struct clk *clk; | |
197 | int ret; | |
198 | ||
199 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); | |
200 | if (!glue) | |
201 | return -ENOMEM; | |
202 | ||
203 | musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); | |
204 | if (!musb) { | |
205 | dev_err(&pdev->dev, "failed to allocate musb device\n"); | |
206 | return -ENOMEM; | |
207 | } | |
208 | ||
209 | clk = devm_clk_get(&pdev->dev, "udc"); | |
210 | if (IS_ERR(clk)) { | |
211 | dev_err(&pdev->dev, "failed to get clock\n"); | |
212 | ret = PTR_ERR(clk); | |
213 | goto err_platform_device_put; | |
214 | } | |
215 | ||
216 | ret = clk_prepare_enable(clk); | |
217 | if (ret) { | |
218 | dev_err(&pdev->dev, "failed to enable clock\n"); | |
219 | goto err_platform_device_put; | |
220 | } | |
221 | ||
222 | musb->dev.parent = &pdev->dev; | |
223 | ||
224 | glue->dev = &pdev->dev; | |
225 | glue->musb = musb; | |
226 | glue->clk = clk; | |
227 | ||
228 | return 0; | |
229 | ||
230 | err_platform_device_put: | |
231 | platform_device_put(musb); | |
232 | return ret; | |
233 | } | |
234 | </programlisting> | |
235 | <para> | |
236 | The first few lines of the probe function allocate and assign the | |
237 | glue, musb and clk variables. The GFP_KERNEL flag (line 8) allows | |
238 | the allocation process to sleep and wait for memory, thus being | |
239 | usable in a blocking situation. The PLATFORM_DEVID_AUTO flag (line | |
240 | 12) allows automatic allocation and management of device IDs in | |
241 | order to avoid device namespace collisions with explicit IDs. With | |
242 | devm_clk_get() (line 18) the glue layer allocates the clock -- the | |
243 | <literal>devm_</literal> prefix indicates that clk_get() is | |
244 | managed: it automatically frees the allocated clock resource data | |
245 | when the device is released -- and enable it. | |
246 | </para> | |
247 | <para> | |
248 | Then comes the registration steps: | |
249 | </para> | |
250 | <programlisting linenumbering="numbered"> | |
251 | static int jz4740_probe(struct platform_device *pdev) | |
252 | { | |
253 | struct musb_hdrc_platform_data *pdata = &jz4740_musb_platform_data; | |
254 | ||
255 | pdata->platform_ops = &jz4740_musb_ops; | |
256 | ||
257 | platform_set_drvdata(pdev, glue); | |
258 | ||
259 | ret = platform_device_add_resources(musb, pdev->resource, | |
260 | pdev->num_resources); | |
261 | if (ret) { | |
262 | dev_err(&pdev->dev, "failed to add resources\n"); | |
263 | goto err_clk_disable; | |
264 | } | |
265 | ||
266 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); | |
267 | if (ret) { | |
268 | dev_err(&pdev->dev, "failed to add platform_data\n"); | |
269 | goto err_clk_disable; | |
270 | } | |
271 | ||
272 | return 0; | |
273 | ||
274 | err_clk_disable: | |
275 | clk_disable_unprepare(clk); | |
276 | err_platform_device_put: | |
277 | platform_device_put(musb); | |
278 | return ret; | |
279 | } | |
280 | </programlisting> | |
281 | <para> | |
282 | The first step is to pass the device data privately held by the | |
283 | glue layer on to the controller driver through | |
284 | platform_set_drvdata() (line 7). Next is passing on the device | |
285 | resources information, also privately held at that point, through | |
286 | platform_device_add_resources() (line 9). | |
287 | </para> | |
288 | <para> | |
289 | Finally comes passing on the platform specific data to the | |
290 | controller driver (line 16). Platform data will be discussed in | |
291 | <link linkend="device-platform-data">Chapter 4</link>, but here | |
292 | we are looking at the platform_ops function pointer (line 5) in | |
293 | musb_hdrc_platform_data structure (line 3). This function | |
294 | pointer allows the MUSB controller driver to know which function | |
295 | to call for device operation: | |
296 | </para> | |
297 | <programlisting linenumbering="numbered"> | |
298 | static const struct musb_platform_ops jz4740_musb_ops = { | |
299 | .init = jz4740_musb_init, | |
300 | .exit = jz4740_musb_exit, | |
301 | }; | |
302 | </programlisting> | |
303 | <para> | |
304 | Here we have the minimal case where only init and exit functions | |
305 | are called by the controller driver when needed. Fact is the | |
306 | JZ4740 MUSB controller is a basic controller, lacking some | |
307 | features found in other controllers, otherwise we may also have | |
308 | pointers to a few other functions like a power management function | |
309 | or a function to switch between OTG and non-OTG modes, for | |
310 | instance. | |
311 | </para> | |
312 | <para> | |
313 | At that point of the registration process, the controller driver | |
314 | actually calls the init function: | |
315 | </para> | |
316 | <programlisting linenumbering="numbered"> | |
317 | static int jz4740_musb_init(struct musb *musb) | |
318 | { | |
319 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); | |
320 | if (!musb->xceiv) { | |
321 | pr_err("HS UDC: no transceiver configured\n"); | |
322 | return -ENODEV; | |
323 | } | |
324 | ||
325 | /* Silicon does not implement ConfigData register. | |
326 | * Set dyn_fifo to avoid reading EP config from hardware. | |
327 | */ | |
328 | musb->dyn_fifo = true; | |
329 | ||
330 | musb->isr = jz4740_musb_interrupt; | |
331 | ||
332 | return 0; | |
333 | } | |
334 | </programlisting> | |
335 | <para> | |
336 | The goal of jz4740_musb_init() is to get hold of the transceiver | |
337 | driver data of the MUSB controller hardware and pass it on to the | |
338 | MUSB controller driver, as usual. The transceiver is the circuitry | |
339 | inside the controller hardware responsible for sending/receiving | |
340 | the USB data. Since it is an implementation of the physical layer | |
341 | of the OSI model, the transceiver is also referred to as PHY. | |
342 | </para> | |
343 | <para> | |
344 | Getting hold of the MUSB PHY driver data is done with | |
345 | usb_get_phy() which returns a pointer to the structure | |
346 | containing the driver instance data. The next couple of | |
347 | instructions (line 12 and 14) are used as a quirk and to setup | |
348 | IRQ handling respectively. Quirks and IRQ handling will be | |
349 | discussed later in <link linkend="device-quirks">Chapter | |
350 | 5</link> and <link linkend="handling-irqs">Chapter 3</link>. | |
351 | </para> | |
352 | <programlisting linenumbering="numbered"> | |
353 | static int jz4740_musb_exit(struct musb *musb) | |
354 | { | |
355 | usb_put_phy(musb->xceiv); | |
356 | ||
357 | return 0; | |
358 | } | |
359 | </programlisting> | |
360 | <para> | |
361 | Acting as the counterpart of init, the exit function releases the | |
362 | MUSB PHY driver when the controller hardware itself is about to be | |
363 | released. | |
364 | </para> | |
365 | <para> | |
366 | Again, note that init and exit are fairly simple in this case due | |
367 | to the basic set of features of the JZ4740 controller hardware. | |
368 | When writing an musb glue layer for a more complex controller | |
369 | hardware, you might need to take care of more processing in those | |
370 | two functions. | |
371 | </para> | |
372 | <para> | |
373 | Returning from the init function, the MUSB controller driver jumps | |
374 | back into the probe function: | |
375 | </para> | |
376 | <programlisting linenumbering="numbered"> | |
377 | static int jz4740_probe(struct platform_device *pdev) | |
378 | { | |
379 | ret = platform_device_add(musb); | |
380 | if (ret) { | |
381 | dev_err(&pdev->dev, "failed to register musb device\n"); | |
382 | goto err_clk_disable; | |
383 | } | |
384 | ||
385 | return 0; | |
386 | ||
387 | err_clk_disable: | |
388 | clk_disable_unprepare(clk); | |
389 | err_platform_device_put: | |
390 | platform_device_put(musb); | |
391 | return ret; | |
392 | } | |
393 | </programlisting> | |
394 | <para> | |
395 | This is the last part of the device registration process where the | |
396 | glue layer adds the controller hardware device to Linux kernel | |
397 | device hierarchy: at this stage, all known information about the | |
398 | device is passed on to the Linux USB core stack. | |
399 | </para> | |
400 | <programlisting linenumbering="numbered"> | |
401 | static int jz4740_remove(struct platform_device *pdev) | |
402 | { | |
403 | struct jz4740_glue *glue = platform_get_drvdata(pdev); | |
404 | ||
405 | platform_device_unregister(glue->musb); | |
406 | clk_disable_unprepare(glue->clk); | |
407 | ||
408 | return 0; | |
409 | } | |
410 | </programlisting> | |
411 | <para> | |
412 | Acting as the counterpart of probe, the remove function unregister | |
413 | the MUSB controller hardware (line 5) and disable the clock (line | |
414 | 6), allowing it to be gated. | |
415 | </para> | |
416 | </chapter> | |
417 | ||
418 | <chapter id="handling-irqs"> | |
419 | <title>Handling IRQs</title> | |
420 | <para> | |
421 | Additionally to the MUSB controller hardware basic setup and | |
422 | registration, the glue layer is also responsible for handling the | |
423 | IRQs: | |
424 | </para> | |
425 | <programlisting linenumbering="numbered"> | |
426 | static irqreturn_t jz4740_musb_interrupt(int irq, void *__hci) | |
427 | { | |
428 | unsigned long flags; | |
429 | irqreturn_t retval = IRQ_NONE; | |
430 | struct musb *musb = __hci; | |
431 | ||
432 | spin_lock_irqsave(&musb->lock, flags); | |
433 | ||
434 | musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); | |
435 | musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX); | |
436 | musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX); | |
437 | ||
438 | /* | |
439 | * The controller is gadget only, the state of the host mode IRQ bits is | |
440 | * undefined. Mask them to make sure that the musb driver core will | |
441 | * never see them set | |
442 | */ | |
443 | musb->int_usb &= MUSB_INTR_SUSPEND | MUSB_INTR_RESUME | | |
444 | MUSB_INTR_RESET | MUSB_INTR_SOF; | |
445 | ||
446 | if (musb->int_usb || musb->int_tx || musb->int_rx) | |
447 | retval = musb_interrupt(musb); | |
448 | ||
449 | spin_unlock_irqrestore(&musb->lock, flags); | |
450 | ||
451 | return retval; | |
452 | } | |
453 | </programlisting> | |
454 | <para> | |
455 | Here the glue layer mostly has to read the relevant hardware | |
456 | registers and pass their values on to the controller driver which | |
457 | will handle the actual event that triggered the IRQ. | |
458 | </para> | |
459 | <para> | |
460 | The interrupt handler critical section is protected by the | |
461 | spin_lock_irqsave() and counterpart spin_unlock_irqrestore() | |
462 | functions (line 7 and 24 respectively), which prevent the | |
463 | interrupt handler code to be run by two different threads at the | |
464 | same time. | |
465 | </para> | |
466 | <para> | |
467 | Then the relevant interrupt registers are read (line 9 to 11): | |
468 | </para> | |
469 | <itemizedlist> | |
470 | <listitem> | |
471 | <para> | |
472 | MUSB_INTRUSB: indicates which USB interrupts are currently | |
473 | active, | |
474 | </para> | |
475 | </listitem> | |
476 | <listitem> | |
477 | <para> | |
478 | MUSB_INTRTX: indicates which of the interrupts for TX | |
479 | endpoints are currently active, | |
480 | </para> | |
481 | </listitem> | |
482 | <listitem> | |
483 | <para> | |
484 | MUSB_INTRRX: indicates which of the interrupts for TX | |
485 | endpoints are currently active. | |
486 | </para> | |
487 | </listitem> | |
488 | </itemizedlist> | |
489 | <para> | |
490 | Note that musb_readb() is used to read 8-bit registers at most, | |
491 | while musb_readw() allows us to read at most 16-bit registers. | |
492 | There are other functions that can be used depending on the size | |
493 | of your device registers. See musb_io.h for more information. | |
494 | </para> | |
495 | <para> | |
496 | Instruction on line 18 is another quirk specific to the JZ4740 | |
497 | USB device controller, which will be discussed later in <link | |
498 | linkend="device-quirks">Chapter 5</link>. | |
499 | </para> | |
500 | <para> | |
501 | The glue layer still needs to register the IRQ handler though. | |
502 | Remember the instruction on line 14 of the init function: | |
503 | </para> | |
504 | <programlisting linenumbering="numbered"> | |
505 | static int jz4740_musb_init(struct musb *musb) | |
506 | { | |
507 | musb->isr = jz4740_musb_interrupt; | |
508 | ||
509 | return 0; | |
510 | } | |
511 | </programlisting> | |
512 | <para> | |
513 | This instruction sets a pointer to the glue layer IRQ handler | |
514 | function, in order for the controller hardware to call the handler | |
515 | back when an IRQ comes from the controller hardware. The interrupt | |
516 | handler is now implemented and registered. | |
517 | </para> | |
518 | </chapter> | |
519 | ||
520 | <chapter id="device-platform-data"> | |
521 | <title>Device Platform Data</title> | |
522 | <para> | |
523 | In order to write an MUSB glue layer, you need to have some data | |
524 | describing the hardware capabilities of your controller hardware, | |
525 | which is called the platform data. | |
526 | </para> | |
527 | <para> | |
528 | Platform data is specific to your hardware, though it may cover a | |
529 | broad range of devices, and is generally found somewhere in the | |
530 | arch/ directory, depending on your device architecture. | |
531 | </para> | |
532 | <para> | |
533 | For instance, platform data for the JZ4740 SoC is found in | |
534 | arch/mips/jz4740/platform.c. In the platform.c file each device of | |
535 | the JZ4740 SoC is described through a set of structures. | |
536 | </para> | |
537 | <para> | |
538 | Here is the part of arch/mips/jz4740/platform.c that covers the | |
539 | USB Device Controller (UDC): | |
540 | </para> | |
541 | <programlisting linenumbering="numbered"> | |
542 | /* USB Device Controller */ | |
543 | struct platform_device jz4740_udc_xceiv_device = { | |
544 | .name = "usb_phy_gen_xceiv", | |
545 | .id = 0, | |
546 | }; | |
547 | ||
548 | static struct resource jz4740_udc_resources[] = { | |
549 | [0] = { | |
550 | .start = JZ4740_UDC_BASE_ADDR, | |
551 | .end = JZ4740_UDC_BASE_ADDR + 0x10000 - 1, | |
552 | .flags = IORESOURCE_MEM, | |
553 | }, | |
554 | [1] = { | |
555 | .start = JZ4740_IRQ_UDC, | |
556 | .end = JZ4740_IRQ_UDC, | |
557 | .flags = IORESOURCE_IRQ, | |
558 | .name = "mc", | |
559 | }, | |
560 | }; | |
561 | ||
562 | struct platform_device jz4740_udc_device = { | |
563 | .name = "musb-jz4740", | |
564 | .id = -1, | |
565 | .dev = { | |
566 | .dma_mask = &jz4740_udc_device.dev.coherent_dma_mask, | |
567 | .coherent_dma_mask = DMA_BIT_MASK(32), | |
568 | }, | |
569 | .num_resources = ARRAY_SIZE(jz4740_udc_resources), | |
570 | .resource = jz4740_udc_resources, | |
571 | }; | |
572 | </programlisting> | |
573 | <para> | |
574 | The jz4740_udc_xceiv_device platform device structure (line 2) | |
575 | describes the UDC transceiver with a name and id number. | |
576 | </para> | |
577 | <para> | |
578 | At the time of this writing, note that | |
579 | "usb_phy_gen_xceiv" is the specific name to be used for | |
580 | all transceivers that are either built-in with reference USB IP or | |
581 | autonomous and doesn't require any PHY programming. You will need | |
582 | to set CONFIG_NOP_USB_XCEIV=y in the kernel configuration to make | |
583 | use of the corresponding transceiver driver. The id field could be | |
584 | set to -1 (equivalent to PLATFORM_DEVID_NONE), -2 (equivalent to | |
585 | PLATFORM_DEVID_AUTO) or start with 0 for the first device of this | |
586 | kind if we want a specific id number. | |
587 | </para> | |
588 | <para> | |
589 | The jz4740_udc_resources resource structure (line 7) defines the | |
590 | UDC registers base addresses. | |
591 | </para> | |
592 | <para> | |
593 | The first array (line 9 to 11) defines the UDC registers base | |
594 | memory addresses: start points to the first register memory | |
595 | address, end points to the last register memory address and the | |
596 | flags member defines the type of resource we are dealing with. So | |
597 | IORESOURCE_MEM is used to define the registers memory addresses. | |
598 | The second array (line 14 to 17) defines the UDC IRQ registers | |
599 | addresses. Since there is only one IRQ register available for the | |
600 | JZ4740 UDC, start and end point at the same address. The | |
601 | IORESOURCE_IRQ flag tells that we are dealing with IRQ resources, | |
602 | and the name "mc" is in fact hard-coded in the MUSB core | |
603 | in order for the controller driver to retrieve this IRQ resource | |
604 | by querying it by its name. | |
605 | </para> | |
606 | <para> | |
607 | Finally, the jz4740_udc_device platform device structure (line 21) | |
608 | describes the UDC itself. | |
609 | </para> | |
610 | <para> | |
611 | The "musb-jz4740" name (line 22) defines the MUSB | |
612 | driver that is used for this device; remember this is in fact | |
613 | the name that we used in the jz4740_driver platform driver | |
614 | structure in <link linkend="linux-musb-basics">Chapter | |
615 | 2</link>. The id field (line 23) is set to -1 (equivalent to | |
616 | PLATFORM_DEVID_NONE) since we do not need an id for the device: | |
617 | the MUSB controller driver was already set to allocate an | |
618 | automatic id in <link linkend="linux-musb-basics">Chapter | |
619 | 2</link>. In the dev field we care for DMA related information | |
620 | here. The dma_mask field (line 25) defines the width of the DMA | |
621 | mask that is going to be used, and coherent_dma_mask (line 26) | |
622 | has the same purpose but for the alloc_coherent DMA mappings: in | |
623 | both cases we are using a 32 bits mask. Then the resource field | |
624 | (line 29) is simply a pointer to the resource structure defined | |
625 | before, while the num_resources field (line 28) keeps track of | |
626 | the number of arrays defined in the resource structure (in this | |
627 | case there were two resource arrays defined before). | |
628 | </para> | |
629 | <para> | |
630 | With this quick overview of the UDC platform data at the arch/ | |
631 | level now done, let's get back to the MUSB glue layer specific | |
632 | platform data in drivers/usb/musb/jz4740.c: | |
633 | </para> | |
634 | <programlisting linenumbering="numbered"> | |
635 | static struct musb_hdrc_config jz4740_musb_config = { | |
636 | /* Silicon does not implement USB OTG. */ | |
637 | .multipoint = 0, | |
638 | /* Max EPs scanned, driver will decide which EP can be used. */ | |
639 | .num_eps = 4, | |
640 | /* RAMbits needed to configure EPs from table */ | |
641 | .ram_bits = 9, | |
642 | .fifo_cfg = jz4740_musb_fifo_cfg, | |
643 | .fifo_cfg_size = ARRAY_SIZE(jz4740_musb_fifo_cfg), | |
644 | }; | |
645 | ||
646 | static struct musb_hdrc_platform_data jz4740_musb_platform_data = { | |
647 | .mode = MUSB_PERIPHERAL, | |
648 | .config = &jz4740_musb_config, | |
649 | }; | |
650 | </programlisting> | |
651 | <para> | |
652 | First the glue layer configures some aspects of the controller | |
653 | driver operation related to the controller hardware specifics. | |
654 | This is done through the jz4740_musb_config musb_hdrc_config | |
655 | structure. | |
656 | </para> | |
657 | <para> | |
658 | Defining the OTG capability of the controller hardware, the | |
659 | multipoint member (line 3) is set to 0 (equivalent to false) | |
660 | since the JZ4740 UDC is not OTG compatible. Then num_eps (line | |
661 | 5) defines the number of USB endpoints of the controller | |
662 | hardware, including endpoint 0: here we have 3 endpoints + | |
663 | endpoint 0. Next is ram_bits (line 7) which is the width of the | |
664 | RAM address bus for the MUSB controller hardware. This | |
665 | information is needed when the controller driver cannot | |
666 | automatically configure endpoints by reading the relevant | |
667 | controller hardware registers. This issue will be discussed when | |
668 | we get to device quirks in <link linkend="device-quirks">Chapter | |
669 | 5</link>. Last two fields (line 8 and 9) are also about device | |
670 | quirks: fifo_cfg points to the USB endpoints configuration table | |
671 | and fifo_cfg_size keeps track of the size of the number of | |
672 | entries in that configuration table. More on that later in <link | |
673 | linkend="device-quirks">Chapter 5</link>. | |
674 | </para> | |
675 | <para> | |
676 | Then this configuration is embedded inside | |
677 | jz4740_musb_platform_data musb_hdrc_platform_data structure (line | |
678 | 11): config is a pointer to the configuration structure itself, | |
679 | and mode tells the controller driver if the controller hardware | |
680 | may be used as MUSB_HOST only, MUSB_PERIPHERAL only or MUSB_OTG | |
681 | which is a dual mode. | |
682 | </para> | |
683 | <para> | |
684 | Remember that jz4740_musb_platform_data is then used to convey | |
685 | platform data information as we have seen in the probe function | |
686 | in <link linkend="linux-musb-basics">Chapter 2</link> | |
687 | </para> | |
688 | </chapter> | |
689 | ||
690 | <chapter id="device-quirks"> | |
691 | <title>Device Quirks</title> | |
692 | <para> | |
693 | Completing the platform data specific to your device, you may also | |
694 | need to write some code in the glue layer to work around some | |
695 | device specific limitations. These quirks may be due to some | |
696 | hardware bugs, or simply be the result of an incomplete | |
697 | implementation of the USB On-the-Go specification. | |
698 | </para> | |
699 | <para> | |
700 | The JZ4740 UDC exhibits such quirks, some of which we will discuss | |
701 | here for the sake of insight even though these might not be found | |
702 | in the controller hardware you are working on. | |
703 | </para> | |
704 | <para> | |
705 | Let's get back to the init function first: | |
706 | </para> | |
707 | <programlisting linenumbering="numbered"> | |
708 | static int jz4740_musb_init(struct musb *musb) | |
709 | { | |
710 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); | |
711 | if (!musb->xceiv) { | |
712 | pr_err("HS UDC: no transceiver configured\n"); | |
713 | return -ENODEV; | |
714 | } | |
715 | ||
716 | /* Silicon does not implement ConfigData register. | |
717 | * Set dyn_fifo to avoid reading EP config from hardware. | |
718 | */ | |
719 | musb->dyn_fifo = true; | |
720 | ||
721 | musb->isr = jz4740_musb_interrupt; | |
722 | ||
723 | return 0; | |
724 | } | |
725 | </programlisting> | |
726 | <para> | |
727 | Instruction on line 12 helps the MUSB controller driver to work | |
728 | around the fact that the controller hardware is missing registers | |
729 | that are used for USB endpoints configuration. | |
730 | </para> | |
731 | <para> | |
732 | Without these registers, the controller driver is unable to read | |
733 | the endpoints configuration from the hardware, so we use line 12 | |
734 | instruction to bypass reading the configuration from silicon, and | |
735 | rely on a hard-coded table that describes the endpoints | |
736 | configuration instead: | |
737 | </para> | |
738 | <programlisting linenumbering="numbered"> | |
739 | static struct musb_fifo_cfg jz4740_musb_fifo_cfg[] = { | |
740 | { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, | |
741 | { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, | |
742 | { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 64, }, | |
743 | }; | |
744 | </programlisting> | |
745 | <para> | |
746 | Looking at the configuration table above, we see that each | |
747 | endpoints is described by three fields: hw_ep_num is the endpoint | |
748 | number, style is its direction (either FIFO_TX for the controller | |
749 | driver to send packets in the controller hardware, or FIFO_RX to | |
750 | receive packets from hardware), and maxpacket defines the maximum | |
751 | size of each data packet that can be transmitted over that | |
752 | endpoint. Reading from the table, the controller driver knows that | |
753 | endpoint 1 can be used to send and receive USB data packets of 512 | |
754 | bytes at once (this is in fact a bulk in/out endpoint), and | |
755 | endpoint 2 can be used to send data packets of 64 bytes at once | |
756 | (this is in fact an interrupt endpoint). | |
757 | </para> | |
758 | <para> | |
759 | Note that there is no information about endpoint 0 here: that one | |
760 | is implemented by default in every silicon design, with a | |
761 | predefined configuration according to the USB specification. For | |
762 | more examples of endpoint configuration tables, see musb_core.c. | |
763 | </para> | |
764 | <para> | |
765 | Let's now get back to the interrupt handler function: | |
766 | </para> | |
767 | <programlisting linenumbering="numbered"> | |
768 | static irqreturn_t jz4740_musb_interrupt(int irq, void *__hci) | |
769 | { | |
770 | unsigned long flags; | |
771 | irqreturn_t retval = IRQ_NONE; | |
772 | struct musb *musb = __hci; | |
773 | ||
774 | spin_lock_irqsave(&musb->lock, flags); | |
775 | ||
776 | musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); | |
777 | musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX); | |
778 | musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX); | |
779 | ||
780 | /* | |
781 | * The controller is gadget only, the state of the host mode IRQ bits is | |
782 | * undefined. Mask them to make sure that the musb driver core will | |
783 | * never see them set | |
784 | */ | |
785 | musb->int_usb &= MUSB_INTR_SUSPEND | MUSB_INTR_RESUME | | |
786 | MUSB_INTR_RESET | MUSB_INTR_SOF; | |
787 | ||
788 | if (musb->int_usb || musb->int_tx || musb->int_rx) | |
789 | retval = musb_interrupt(musb); | |
790 | ||
791 | spin_unlock_irqrestore(&musb->lock, flags); | |
792 | ||
793 | return retval; | |
794 | } | |
795 | </programlisting> | |
796 | <para> | |
797 | Instruction on line 18 above is a way for the controller driver to | |
798 | work around the fact that some interrupt bits used for USB host | |
799 | mode operation are missing in the MUSB_INTRUSB register, thus left | |
800 | in an undefined hardware state, since this MUSB controller | |
801 | hardware is used in peripheral mode only. As a consequence, the | |
802 | glue layer masks these missing bits out to avoid parasite | |
803 | interrupts by doing a logical AND operation between the value read | |
804 | from MUSB_INTRUSB and the bits that are actually implemented in | |
805 | the register. | |
806 | </para> | |
807 | <para> | |
808 | These are only a couple of the quirks found in the JZ4740 USB | |
809 | device controller. Some others were directly addressed in the MUSB | |
810 | core since the fixes were generic enough to provide a better | |
811 | handling of the issues for others controller hardware eventually. | |
812 | </para> | |
813 | </chapter> | |
814 | ||
815 | <chapter id="conclusion"> | |
816 | <title>Conclusion</title> | |
817 | <para> | |
818 | Writing a Linux MUSB glue layer should be a more accessible task, | |
819 | as this documentation tries to show the ins and outs of this | |
820 | exercise. | |
821 | </para> | |
822 | <para> | |
823 | The JZ4740 USB device controller being fairly simple, I hope its | |
824 | glue layer serves as a good example for the curious mind. Used | |
825 | with the current MUSB glue layers, this documentation should | |
826 | provide enough guidance to get started; should anything gets out | |
827 | of hand, the linux-usb mailing list archive is another helpful | |
828 | resource to browse through. | |
829 | </para> | |
830 | </chapter> | |
831 | ||
832 | <chapter id="acknowledgements"> | |
833 | <title>Acknowledgements</title> | |
834 | <para> | |
835 | Many thanks to Lars-Peter Clausen and Maarten ter Huurne for | |
836 | answering my questions while I was writing the JZ4740 glue layer | |
837 | and for helping me out getting the code in good shape. | |
838 | </para> | |
839 | <para> | |
840 | I would also like to thank the Qi-Hardware community at large for | |
841 | its cheerful guidance and support. | |
842 | </para> | |
843 | </chapter> | |
844 | ||
845 | <chapter id="resources"> | |
846 | <title>Resources</title> | |
847 | <para> | |
848 | USB Home Page: | |
849 | <ulink url="http://www.usb.org">http://www.usb.org</ulink> | |
850 | </para> | |
851 | <para> | |
852 | linux-usb Mailing List Archives: | |
853 | <ulink url="http://marc.info/?l=linux-usb">http://marc.info/?l=linux-usb</ulink> | |
854 | </para> | |
855 | <para> | |
856 | USB On-the-Go Basics: | |
857 | <ulink url="http://www.maximintegrated.com/app-notes/index.mvp/id/1822">http://www.maximintegrated.com/app-notes/index.mvp/id/1822</ulink> | |
858 | </para> | |
859 | <para> | |
860 | Writing USB Device Drivers: | |
861 | <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> | |
862 | </para> | |
863 | <para> | |
864 | Texas Instruments USB Configuration Wiki Page: | |
865 | <ulink url="http://processors.wiki.ti.com/index.php/Usbgeneralpage">http://processors.wiki.ti.com/index.php/Usbgeneralpage</ulink> | |
866 | </para> | |
867 | <para> | |
868 | Analog Devices Blackfin MUSB Configuration: | |
869 | <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> | |
870 | </para> | |
871 | </chapter> | |
872 | ||
873 | </book> |