linux/arch/arm/mach-omap2/usb-musb.c
<<
>>
Prefs
   1/*
   2 * linux/arch/arm/mach-omap2/usb-musb.c
   3 *
   4 * This file will contain the board specific details for the
   5 * MENTOR USB OTG controller on OMAP3430
   6 *
   7 * Copyright (C) 2007-2008 Texas Instruments
   8 * Copyright (C) 2008 Nokia Corporation
   9 * Author: Vikram Pandita
  10 *
  11 * Generalization by:
  12 * Felipe Balbi <felipe.balbi@nokia.com>
  13 *
  14 * This program is free software; you can redistribute it and/or modify
  15 * it under the terms of the GNU General Public License version 2 as
  16 * published by the Free Software Foundation.
  17 */
  18
  19#include <linux/types.h>
  20#include <linux/errno.h>
  21#include <linux/delay.h>
  22#include <linux/platform_device.h>
  23#include <linux/clk.h>
  24#include <linux/dma-mapping.h>
  25#include <linux/io.h>
  26
  27#include <linux/usb/musb.h>
  28
  29#include <mach/hardware.h>
  30#include <mach/irqs.h>
  31#include <mach/mux.h>
  32#include <mach/usb.h>
  33
  34#ifdef CONFIG_USB_MUSB_SOC
  35
  36static struct resource musb_resources[] = {
  37        [0] = { /* start and end set dynamically */
  38                .flags  = IORESOURCE_MEM,
  39        },
  40        [1] = { /* general IRQ */
  41                .start  = INT_243X_HS_USB_MC,
  42                .flags  = IORESOURCE_IRQ,
  43        },
  44        [2] = { /* DMA IRQ */
  45                .start  = INT_243X_HS_USB_DMA,
  46                .flags  = IORESOURCE_IRQ,
  47        },
  48};
  49
  50static int clk_on;
  51
  52static int musb_set_clock(struct clk *clk, int state)
  53{
  54        if (state) {
  55                if (clk_on > 0)
  56                        return -ENODEV;
  57
  58                clk_enable(clk);
  59                clk_on = 1;
  60        } else {
  61                if (clk_on == 0)
  62                        return -ENODEV;
  63
  64                clk_disable(clk);
  65                clk_on = 0;
  66        }
  67
  68        return 0;
  69}
  70
  71static struct musb_hdrc_eps_bits musb_eps[] = {
  72        {       "ep1_tx", 10,   },
  73        {       "ep1_rx", 10,   },
  74        {       "ep2_tx", 9,    },
  75        {       "ep2_rx", 9,    },
  76        {       "ep3_tx", 3,    },
  77        {       "ep3_rx", 3,    },
  78        {       "ep4_tx", 3,    },
  79        {       "ep4_rx", 3,    },
  80        {       "ep5_tx", 3,    },
  81        {       "ep5_rx", 3,    },
  82        {       "ep6_tx", 3,    },
  83        {       "ep6_rx", 3,    },
  84        {       "ep7_tx", 3,    },
  85        {       "ep7_rx", 3,    },
  86        {       "ep8_tx", 2,    },
  87        {       "ep8_rx", 2,    },
  88        {       "ep9_tx", 2,    },
  89        {       "ep9_rx", 2,    },
  90        {       "ep10_tx", 2,   },
  91        {       "ep10_rx", 2,   },
  92        {       "ep11_tx", 2,   },
  93        {       "ep11_rx", 2,   },
  94        {       "ep12_tx", 2,   },
  95        {       "ep12_rx", 2,   },
  96        {       "ep13_tx", 2,   },
  97        {       "ep13_rx", 2,   },
  98        {       "ep14_tx", 2,   },
  99        {       "ep14_rx", 2,   },
 100        {       "ep15_tx", 2,   },
 101        {       "ep15_rx", 2,   },
 102};
 103
 104static struct musb_hdrc_config musb_config = {
 105        .multipoint     = 1,
 106        .dyn_fifo       = 1,
 107        .soft_con       = 1,
 108        .dma            = 1,
 109        .num_eps        = 16,
 110        .dma_channels   = 7,
 111        .dma_req_chan   = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3),
 112        .ram_bits       = 12,
 113        .eps_bits       = musb_eps,
 114};
 115
 116static struct musb_hdrc_platform_data musb_plat = {
 117#ifdef CONFIG_USB_MUSB_OTG
 118        .mode           = MUSB_OTG,
 119#elif defined(CONFIG_USB_MUSB_HDRC_HCD)
 120        .mode           = MUSB_HOST,
 121#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
 122        .mode           = MUSB_PERIPHERAL,
 123#endif
 124        /* .clock is set dynamically */
 125        .set_clock      = musb_set_clock,
 126        .config         = &musb_config,
 127
 128        /* REVISIT charge pump on TWL4030 can supply up to
 129         * 100 mA ... but this value is board-specific, like
 130         * "mode", and should be passed to usb_musb_init().
 131         */
 132        .power          = 50,                   /* up to 100 mA */
 133};
 134
 135static u64 musb_dmamask = DMA_BIT_MASK(32);
 136
 137static struct platform_device musb_device = {
 138        .name           = "musb_hdrc",
 139        .id             = -1,
 140        .dev = {
 141                .dma_mask               = &musb_dmamask,
 142                .coherent_dma_mask      = DMA_BIT_MASK(32),
 143                .platform_data          = &musb_plat,
 144        },
 145        .num_resources  = ARRAY_SIZE(musb_resources),
 146        .resource       = musb_resources,
 147};
 148
 149void __init usb_musb_init(void)
 150{
 151        if (cpu_is_omap243x())
 152                musb_resources[0].start = OMAP243X_HS_BASE;
 153        else
 154                musb_resources[0].start = OMAP34XX_HSUSB_OTG_BASE;
 155        musb_resources[0].end = musb_resources[0].start + SZ_8K - 1;
 156
 157        /*
 158         * REVISIT: This line can be removed once all the platforms using
 159         * musb_core.c have been converted to use use clkdev.
 160         */
 161        musb_plat.clock = "ick";
 162
 163        if (platform_device_register(&musb_device) < 0) {
 164                printk(KERN_ERR "Unable to register HS-USB (MUSB) device\n");
 165                return;
 166        }
 167}
 168
 169#else
 170void __init usb_musb_init(void)
 171{
 172}
 173#endif /* CONFIG_USB_MUSB_SOC */
 174