board-n800-usb.c 2.29 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 31 32 33 34 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 61 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 100 101 102
/*
 * linux/arch/arm/mach-omap2/board-n800-usb.c
 *
 * Copyright (C) 2006 Nokia Corporation
 * Author: Juha Yrjola
 *
 * 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/usb/musb.h>
#include <asm/arch/gpmc.h>
#include <asm/arch/gpio.h>

#define TUSB_ASYNC_CS		1
#define TUSB_SYNC_CS		4
#define GPIO_TUSB_INT		58
#define GPIO_TUSB_ENABLE	0

static int tusb_set_power(int state);

#if	defined(CONFIG_USB_MUSB_OTG)
#	define BOARD_MODE	MUSB_OTG
#elif	defined(CONFIG_USB_MUSB_PERIPHERAL)
#	define BOARD_MODE	MUSB_PERIPHERAL
#else	/* defined(CONFIG_USB_MUSB_HOST) */
#	define BOARD_MODE	MUSB_HOST
#endif

static struct musb_hdrc_platform_data tusb_data = {
	.mode		= BOARD_MODE,
	.multipoint	= 1,
	.set_power	= tusb_set_power,
	.min_power	= 25,	/* x2 = 50 mA drawn from VBUS as peripheral */
};

/*
 * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and
 * 1.5 V voltage regulators of PM companion chip. Companion chip will then
 * provide then PGOOD signal to TUSB6010 which will release it from reset.
 */
static int tusb_set_power(int state)
{
	int i, retval = 0;

	if (state) {
		omap_set_gpio_dataout(GPIO_TUSB_ENABLE, 1);
		msleep(1);

		/* Wait until TUSB6010 pulls INT pin down */
		i = 100;
		while (i && omap_get_gpio_datain(GPIO_TUSB_INT)) {
			msleep(1);
			i--;
		}

		if (!i) {
			printk(KERN_ERR "tusb: powerup failed\n");
			retval = -ENODEV;
		}
	} else {
		omap_set_gpio_dataout(GPIO_TUSB_ENABLE, 0);
		msleep(10);
	}

	return retval;
}

void __init n800_usb_init(void)
{
	int ret = 0;
	static char	announce[] __initdata = KERN_INFO "TUSB 6010\n";

	/* PM companion chip power control pin */
	ret = omap_request_gpio(GPIO_TUSB_ENABLE);
	if (ret != 0) {
		printk(KERN_ERR "Could not get TUSB power GPIO%i\n",
		       GPIO_TUSB_ENABLE);
		return;
	}
	omap_set_gpio_direction(GPIO_TUSB_ENABLE, 0);

	tusb_set_power(0);

	ret = tusb6010_setup_interface(&tusb_data, TUSB6010_REFCLK_19, 2,
					TUSB_ASYNC_CS, TUSB_SYNC_CS,
					GPIO_TUSB_INT, 0x3f);
	if (ret != 0)
		goto err;

	printk(announce);

	return;

err:
	omap_free_gpio(GPIO_TUSB_ENABLE);
}