usb-musb.c 4.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
/*
 * linux/arch/arm/mach-omap2/usb-musb.c
 *
 * This file will contain the board specific details for the
 * MENTOR USB OTG controller on OMAP3430
 *
 * Copyright (C) 2007-2008 Texas Instruments
 * Copyright (C) 2008 Nokia Corporation
 * Author: Vikram Pandita
 *
 * Generalization by:
 * Felipe Balbi <felipe.balbi@nokia.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/types.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>

#include <linux/usb/musb.h>

#include <mach/hardware.h>
#include <mach/irqs.h>
A
Ajay Kumar Gupta 已提交
31
#include <mach/am35xx.h>
32
#include <plat/usb.h>
33
#include <plat/omap_device.h>
34
#include "mux.h"
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60

static struct musb_hdrc_config musb_config = {
	.multipoint	= 1,
	.dyn_fifo	= 1,
	.num_eps	= 16,
	.ram_bits	= 12,
};

static struct musb_hdrc_platform_data musb_plat = {
#ifdef CONFIG_USB_MUSB_OTG
	.mode		= MUSB_OTG,
#elif defined(CONFIG_USB_MUSB_HDRC_HCD)
	.mode		= MUSB_HOST,
#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
	.mode		= MUSB_PERIPHERAL,
#endif
	/* .clock is set dynamically */
	.config		= &musb_config,

	/* REVISIT charge pump on TWL4030 can supply up to
	 * 100 mA ... but this value is board-specific, like
	 * "mode", and should be passed to usb_musb_init().
	 */
	.power		= 50,			/* up to 100 mA */
};

61
static u64 musb_dmamask = DMA_BIT_MASK(32);
62

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
static void usb_musb_mux_init(struct omap_musb_board_data *board_data)
{
	switch (board_data->interface_type) {
	case MUSB_INTERFACE_UTMI:
		omap_mux_init_signal("usba0_otg_dp", OMAP_PIN_INPUT);
		omap_mux_init_signal("usba0_otg_dm", OMAP_PIN_INPUT);
		break;
	case MUSB_INTERFACE_ULPI:
		omap_mux_init_signal("usba0_ulpiphy_clk",
						OMAP_PIN_INPUT_PULLDOWN);
		omap_mux_init_signal("usba0_ulpiphy_stp",
						OMAP_PIN_INPUT_PULLDOWN);
		omap_mux_init_signal("usba0_ulpiphy_dir",
						OMAP_PIN_INPUT_PULLDOWN);
		omap_mux_init_signal("usba0_ulpiphy_nxt",
						OMAP_PIN_INPUT_PULLDOWN);
		omap_mux_init_signal("usba0_ulpiphy_dat0",
						OMAP_PIN_INPUT_PULLDOWN);
		omap_mux_init_signal("usba0_ulpiphy_dat1",
						OMAP_PIN_INPUT_PULLDOWN);
		omap_mux_init_signal("usba0_ulpiphy_dat2",
						OMAP_PIN_INPUT_PULLDOWN);
		omap_mux_init_signal("usba0_ulpiphy_dat3",
						OMAP_PIN_INPUT_PULLDOWN);
		omap_mux_init_signal("usba0_ulpiphy_dat4",
						OMAP_PIN_INPUT_PULLDOWN);
		omap_mux_init_signal("usba0_ulpiphy_dat5",
						OMAP_PIN_INPUT_PULLDOWN);
		omap_mux_init_signal("usba0_ulpiphy_dat6",
						OMAP_PIN_INPUT_PULLDOWN);
		omap_mux_init_signal("usba0_ulpiphy_dat7",
						OMAP_PIN_INPUT_PULLDOWN);
		break;
	default:
		break;
	}
}
100

101 102 103 104 105 106 107
static struct omap_musb_board_data musb_default_board_data = {
	.interface_type		= MUSB_INTERFACE_ULPI,
	.mode			= MUSB_OTG,
	.power			= 100,
};

void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)
108
{
109 110 111 112 113
	struct omap_hwmod		*oh;
	struct platform_device		*pdev;
	struct device			*dev;
	int				bus_id = -1;
	const char			*oh_name, *name;
114 115 116 117 118 119
	struct omap_musb_board_data	*board_data;

	if (musb_board_data)
		board_data = musb_board_data;
	else
		board_data = &musb_default_board_data;
120

121 122 123 124 125
	/*
	 * REVISIT: This line can be removed once all the platforms using
	 * musb_core.c have been converted to use use clkdev.
	 */
	musb_plat.clock = "ick";
126 127 128
	musb_plat.board_data = board_data;
	musb_plat.power = board_data->power >> 1;
	musb_plat.mode = board_data->mode;
129
	musb_plat.extvbus = board_data->extvbus;
130

131 132 133 134 135 136 137 138
	if (cpu_is_omap3517() || cpu_is_omap3505()) {
		oh_name = "am35x_otg_hs";
		name = "musb-am35x";
	} else {
		oh_name = "usb_otg_hs";
		name = "musb-omap2430";
	}

139 140 141 142
        oh = omap_hwmod_lookup(oh_name);
        if (WARN(!oh, "%s: could not find omap_hwmod for %s\n",
                 __func__, oh_name))
                return;
143

144
	pdev = omap_device_build(name, bus_id, oh, &musb_plat,
145
			       sizeof(musb_plat), NULL, 0, false);
146
	if (IS_ERR(pdev)) {
147 148 149 150 151 152 153 154 155 156
		pr_err("Could not build omap_device for %s %s\n",
						name, oh_name);
		return;
	}

	dev = &pdev->dev;
	get_device(dev);
	dev->dma_mask = &musb_dmamask;
	dev->coherent_dma_mask = musb_dmamask;
	put_device(dev);
157 158 159

	if (cpu_is_omap44xx())
		omap4430_phy_init(dev);
160
}