Linux USB “On-The-Go” (OTG) on OMAP H2

來源:互聯網
上載者:User
文章目錄
  • OMAP H2 Platform
  • OTG
  • Outline
  • Peripheral Side: USB Device Controller
  • Peripheral Side: Gadget Drivers
  • Host Side: usbcore

The new USB "On-The-Go" (OTG) capabilities are not yet widely
understood, or even generally available. The most visible feature of
OTG is that it defines the behavior of intelligent "Dual-Role" USB
devices, such as cameras or wireless handsets, which act either as USB
host or as USB peripheral. That role choice is made each time the
device is used, rather than once when it's designed, giving a
flexibility previously unknown with USB. Using a new kind of USB
connector, OTG lets USB support more "peer to peer" style application
models. You could

  • Hook a cell phone to a laptop to synchronize schedules, get new audio recordings, or swap other documents;
  • Print a picture from a camera to a USB printer;
  • Connect a USB keyboard to your PDA;
  • Update game data on your portable console over USB.

This document should be useful to developers investigating the use
of Linux to implement OTG-capable products. It presents the USB OTG
support contributed by Texas Instruments for the OMAP

H2 software development platform running an Linux 2.6 kernel. That
builds on the standard Linux USB host and peripheral side driver
frameworks, making small additions as described here. It also includes
drivers implementing OTG support on OMAP platforms.

OMAP H2 Platform

The H2 software development platform includes a Texas Instruments
OMAP 5912/16xx series processor, with an ARM 926TEJ cpu, a DSP, battery
power management, and a wealth of other features often used in cell
phones. USB support includes:

  • Three integrated USB controllers: OHCI host, USB Device Controller
    (UDC), and an OTG controller, all supporting full speed USB (12
    Mbit/s).
  • "Mini-AB" connector on the H2 sample board. All "dual-role" OTG devices should have exactly one such external USB connector.
  • External USB OTG transceiver, Philips ISP1301 (controlled over I2C), with an alternate software-visible wiring option.
  • USB VBUS is hooked up to a TI TPS65010 power controller
    (controlled over I2C) so that an A-role system can supply up to 500mA
    of current for battery charging to a B-role (default peripheral) H2. In
    A-role (default host), the H2 itself supplies 8mA.

The "Mini-AB" connector is compatible with standard USB 2.0 "Mini-B" connectors, which appear in some new USB peripherals.

Most OMAP processors support this and similar product designs.
Register interfaces to the different USB controllers are largely
source-compatible, although older chips don't support OTG.

OTG

It's reasonable to think about OTG support as revolving around that
"Mini-AB" connector, since that's what demands the highly visible
"dual-role" capability implemented by the OTG drivers. OTG uses two
methods to chose device role:

  • The simplest is built into the special Mini-A to Mini-B cables that
    OTG uses: the Mini-A connector grounds the ID pin, while the Mini-B end
    of the cable doesn't. That controls startup in A-Host or B-Peripheral
    role, and is the only method needed
    unless you're hooking up
    to another dual-role device. Call this "cable based role switching";
    some incomplete OTG implementations stop at this point.
  • When connected to a dual-role device, a fancier software-driven method can be used later: switching roles using the Host Negotiation Protocol
    (HNP). That protects against the inevitable cases where the cable gets
    hooked up going the "wrong" direction for at least one of the tasks at
    hand.

That dynamic role selection is the most procedurally visible aspect
of OTG, but there's more to OTG than that; see the OTG specification
(and errata). The primary target of OTG is battery powered devices, so
several aspects of the specification support reduced power usage. These
include a new Session Request Protocol (SRP), which may be supported
even by single-role USB devices.

To someone providing hardware-level drivers, an OTG solution
starts with support for the standard Linux-USB host side and peripheral
side driver stacks. Add protocol support for SRP and HNP, match the
state machines in the OTG specification well enough to pass OTG
hardware and software compliance testing, and then your product can use
the OTG logo.

USB OTG
Logo
full-speed version
Outline

The current Linux kernel updates for OTG support break down as follows:

  • Programming Interfaces

    have been updated; mainstream Linux 2.6.9 kernels have all of these changes.

    • USB Device Controller Drivers export some new interfaces.
    • USB Gadget Drivers have some new responsibilities that involve
      using those new interfaces. Some still need to be updated accordingly,
      to work on dual-role systems.
    • The Linux-USB Host side "usbcore" module acquired a few new
      OTG-specific responsibilities affecting enumeration, which are mostly
      invisible to device drivers. It also needed to learn about USB
      suspend/resume and remote wakeup to fully support HNP. These relate to
      Linux power management interfaces.
    • The host side also needs to define an OTG "Targeted
      Peripheral List". Each product must define its own such list of "good"
      devices. Some component should probably also suspend inactive devices,
      saving power and/or initiating HNP protocol.
  • USB Controller Drivers

    are in Linux 2.6.8 and later OMAP kernels:

    • Responsibility for USB initialization belongs to the board-specific
      INIT_MACHINE call. This knows about chip-specific setup and creates
      platform devices as needed, making platform_data available to the
      various USB controller drivers.
    • Core OTG protocol support is wrapped in a otg_transceiver
      object. On H2, the isp1301_omap
      driver ties the transceiver the OMAP OTG controller, and talks to the OHCI and UDC drivers using the usb_bus
      and usb_gadget
      programming interfaces. Other boards might need to implement this differently.
    • The UDC needed a new omap_udc
      driver in the "USB
      Gadget" framework, providing immediate access to several standard
      gadget drivers (including Ethernet/RNDIS, Mass Storage, serial/ACM, and
      more). This UDC is quite full-featured, supporting numerous endpoints,
      DMA, and isochronous transfers; it can easily implement composite
      multi-function devices.
    • The OHCI host controller was already supported by Linux 2.6 kernels using ohci_hcd
      to access a large and growing set of Linux-USB device drivers.

These points are addressed in the rest of this document, in that same order.

Programming Interface Updates

It was a goal to keep these interface changes small, and to have
them be useful outside of OTG support where possible. That way the new
code paths can get better testing, rather than being used only for
(currently uncommon) OTG devices.

In particular, this doesn't change the existing programming models or calls for host side USB (still uses urb
and usb_device
) or for peripheral side USB (still uses usb_request
and usb_gadget
).
At some point it might become desirable to move away from "URB" to a
lighter weight model like "usb_request", and maybe to a more symmetric
programming interface; but that's not necessary at this time.

Peripheral Side: USB Device Controller

Several OTG state flags, and a few new usb_gadget_*()
calls, are all the changes needed in the gadget programming interfaces.
The flags support user interface reporting requirements for OTG
devices, and the calls support new USB state transitions (some of which
are also useful for non-OTG systems). Except for the flag reporting
whether the gadget is_otg
, the state flags are current only
when the gadget driver could participate in HNP: after it receives the
SET_CONFIGURATION request, or before it suspends. In addition, if HNP
is ever enabled, it can't be disabled without re-enumerating the
device.

struct usb_gadget {
...
unsignedis_otg:1;
unsignedis_a_peripheral:1;
unsignedb_hnp_enable:1;
unsigneda_hnp_support:1;
unsigneda_alt_hnp_support:1;
...
};

/* used by external USB transceiver */
int usb_gadget_vbus_connect(struct usb_gadget *gadget);
int usb_gadget_vbus_disconnect(struct usb_gadget *gadget);

/* call this during SET_CONFIGURATION */
int usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA);

/* these logically control the USB D+ pullup */
int usb_gadget_connect(struct usb_gadget *gadget);
int usb_gadget_disconnect(struct usb_gadget *gadget);

In addition, usb_gadget_wakeup()
is now defined as the
way SRP may be invoked. If the device is in a USB suspend state, remote
wakeup is used (and OTG peripherals don't always need hosts to enable
wakeup). If there's no VBUS power, SRP may be used instead.

There's kerneldoc for all of those, and many of the symbols
have the same meaning as in the OTG specification. For example,
b_hnp_enable is the device feature flag that may be set by the USB
A-Host; if it's set, the B-Peripheral device may be well into an
HNP-driven role switch when suspend() is called.

Peripheral Side: Gadget Drivers

To see how those are used in drivers, see the small changes to Gadget Zero
which, using omap_udc
,
were sufficient to pass the USBCV OTG tests. All USB gadget drivers
that will be used on OTG-capable hardware should have corresponding
changes; at this writing, some of the gadget drivers still haven't been
modified to know about OTG.

  • Provide an OTG descriptor in each configuration, when gadget->is_otg
    is true.
  • Report HNP availability "through the user interface" (printk, LED, etc) at SET_CONFIGURATION
  • Report start of HNP role switch (B-Peripheral to B-Host, or
    A-Peripheral to A-Host) "through the user interface" as suspend starts.

This framework is currently not set up to handle the SRP-only subset
of OTG; that would need another gadget flag. Also, so far there's no
gadgetfs support for OTG: OTG feature flags aren't exported to user
mode drivers, though user mode drivers can certainly provide OTG
descriptors if they know (out of band) that they're appropriate.

Host Side: usbcore

There are several updates that affect host side support for OTG dual-role devices.

OTG Enumeration and the Targeted Peripherals List

USB enumeration (khubd and usb_new_device
) needed updates:

  • When an OTG A-host enumerates an OTG dual-role device, and it's
    directly connected to a root hub port, it's responsible for setting one
    of the HNP device features before it issues any SET_CONFIGURATION. For
    now, it immediately sets b_hnp_enable
    on the B-Peripheral (unless a_alt_hnp_support
    is appropriate instead, because it's not on the OTG port).
  • Check the OTG Targeted Peripheral List, which is kept in the drivers/usb/core/otg_whitelist.h
    file. In addition to a whitelist of device IDs, this holds a single
    blacklist entry for the OTG HNP test device (which always triggers HNP
    from a dual-role device).
  • Devices on the whitelist are allowed to configure.
  • Devices not on the whitelist trigger a diagnostic, and
    normally disable the device. Instead of being disabled, dual-role
    devices may be immediately switched to host role using HNP, in case
    this device is on the other's whitelist. (For developer/tester
    convenience, the "disable" step can be prevented with a Kconfig
    option.)
  • The OTG controller driver needs to be able to ask the HCD to
    start enumeration "immediately", starting at least the port reset
    before a one millisecond HNP timer expires.

So that the updated enumeration code can set OTG device features appropriately, the usb_bus
interface reports which port has the Mini-AB connector. It also
provides more visibility of key HNP protocol state, reporting if this
is a B-Host rather than an A-Host (so that it shouldn't set OTG device
features during enumeration); and whether the A-Host has set b_hnp_enable
on the B-Peripheral (needed by OTG controllers and drivers). (This information is not currently visible in sysfs.)

struct usb_bus {
...
u8 otg_port;/* 0, or index of OTG/HNP port */
unsigned is_b_host:1;/* true during some HNP roleswitches */
unsigned b_hnp_enable:1;/* OTG: did A-Host enable HNP? */
...
};
CONFIG_USB_SUSPEND

The CONFIG_USB_SUSPEND patch adds generic experimental support for USB suspend/resume to Linux, as needed to implement HNP.

/* selective suspend/resume */
extern int usb_suspend_device(struct usb_device *dev, u32 state);
extern int usb_resume_device(struct usb_device *dev);
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.