/*
* TUSB6010 USB 2.0 OTG Dual Role controller
*
* Copyright (C) 2006 Nokia Corporation
* Tony Lindgren <tony@atomide.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.
*
* Notes:
* - Driver assumes that interface to external host (main CPU) is
* configured for NOR FLASH interface instead of VLYNQ serial
* interface.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/usb.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include "musb_core.h"
struct tusb6010_glue {
struct device *dev;
struct platform_device *musb;
};
static void tusb_musb_set_vbus(struct musb *musb, int is_on);
#define TUSB_REV_MAJOR(reg_val) ((reg_val >> 4) & 0xf)
#define TUSB_REV_MINOR(reg_val) (reg_val & 0xf)
/*
* Checks the revision. We need to use the DMA register as 3.0 does not
* have correct versions for TUSB_PRCM_REV or TUSB_INT_CTRL_REV.
*/
u8 tusb_get_revision(struct musb *musb)
{
void __iomem *tbase = musb->ctrl_base;
u32 die_id;
u8 rev;
rev = musb_readl(tbase, TUSB_DMA_CTRL_REV) & 0xff;
if (TUSB_REV_MAJOR(rev) == 3) {
die_id = TUSB_DIDR1_HI_CHIP_REV(musb_readl(tbase,
TUSB_DIDR1_HI));
if (die_id >= TUSB_DIDR1_HI_REV_31)
rev |= 1;
}
return rev;
}
static int tusb_print_revision(struct musb *musb)
{
void __iomem *tbase = musb->ctrl_base;
u8 rev;
rev = tusb_get_revision(musb);
pr_info("tusb: %s%i.%i %s%i.%i %s%i.%i %s%i.%i %s%i %s%i.%i\n",
"prcm",
TUSB_REV_MAJOR(musb_readl(tbase, TUSB_PRCM_REV)),
TUSB_REV_MINOR(musb_readl(tbase, TUSB_PRCM_REV)),
"int",
TUSB_REV_MAJOR(musb_readl(tbase, TUSB_INT_CTRL_REV)),
TUSB_REV_MINOR(musb_readl(tbase, TUSB_INT_CTRL_REV)),
"gpio",
TUSB_REV_MAJOR(musb_readl(tbase, TUSB_GPIO_REV)),
TUSB_REV_MINOR(musb_readl(tbase, TUSB_GPIO_REV)),
"dma",
TUSB_REV_MAJOR(musb_readl(tbase, TUSB_DMA_CTRL_REV)),
TUSB_REV_MINOR(musb_readl(tbase, TUSB_DMA_CTRL_REV)),
"dieid",
TUSB_DIDR1_HI_CHIP_REV(musb_readl(tbase, TUSB_DIDR1_HI)),
"rev",
TUSB_REV_MAJOR(rev), TUSB_REV_MINOR(rev));
return tusb_get_revision(musb);
}
#define WBUS_QUIRK_MASK (TUSB_PHY_OTG_CTRL_TESTM2 | TUSB_PHY_OTG_CTRL_TESTM1 \
| TUSB_PHY_OTG_CTRL_TESTM0)
/*
* Workaround for spontaneous WBUS wake-up issue #2 for tusb3.0.
* Disables power detection in PHY for the duration of idle.
*/
static void tusb_wbus_quirk(struct musb *musb, int enabled)
{
void __iomem *tbase = musb->ctrl_base;
static u32 phy_otg_ctrl, phy_otg_ena;
u32 tmp;
if (enabled) {