Commit 40cedbdb authored by Juha Yrjola's avatar Juha Yrjola

Merge branch 'master' of /home/git/linux-omap-2.6

parents 248fa081 1eee4332
OMAP GPIO API's HowTo
=====================
This document is a short summary how to use OMAP Linux GPIO API. It is
mainly focussed on OMAP5912 OSK, but should fit with extensions (more
or less GPIOs) to other OMAP processors as well.
If anything is missing, is wrong, needs extension or update, please send
update to Linux-omap-open-source@linux.omap.com.
I. GPIO Modules/Banks
---------------------
OMAP5912 OSK has 64 GPIOs (general purpose IO pins). These are organized
in four modules (banks) with 16 pins each. OMAP GPIO API doesn't distinguish
between modules and numbers the pins from 0 - 63:
A) GPIO MODULE/BANK 0 - PIN 0-15
B) GPIO MODULE/BANK 1 - PIN 16-31
C) GPIO MODULE/BANK 2 - PIN 32-47
D) GPIO MODULE/BANK 3 - PIN 48-63
See
http://www-s.ti.com/sc/psheets/spru767a/spru767a.pdf
for more details.
II. GPIO API's
--------------
A) Include
#include <asm/arch/gpio.h>
B) omap_cfg_reg(xxxx);
Description: Configure pin mux.
Parameter: Pin to be configured for GPIO.
Note: This function may only be necessary for some GPIO pins. Because OMAP
chip itself has less real hardware pins than necessary to use all
its functionality at the same time, some pins share different
functions (called pin multiplexing, short pin mux). E.g. one pin may
be used for serial interface *or* GPIO. Check if this is the case for
the GPIO you want to use and if you have to configure the pin mux.
C) omap_request_gpio(int gpio)
Description: Request GPIO to be used.
Parameter: int gpio - GPIO PIN (Pin 0-63)
Note: Using this function, you dont have to worry about banks/modules where
the gpio pin is.
D) omap_set_gpio_direction(int gpio, int is_input)
Description: This function is responsible for setting the gpio pin direction
(input or output).
Parameter: int gpio - GPIO PIN (Pin 0-63)
int is_input - pin direction (0 = output, 1 = input)
E) omap_set_gpio_dataout(int gpio, int enable)
Description: This function is responsible for writing to a pin.
Parameter: int gpio - GPIO PIN (Pin 0-63)
int enable - pin value (0 or 1)
F) omap_get_gpio_datain(int gpio)
Description: This function is responsible for reading pin values.
Parameter: int gpio - GPIO PIN (Pin 0-63)
G) omap_free_gpio(int gpio)
Description: This function is responsible for freeing the pin used.
Parameter: int gpio - GPIO PIN (Pin 0-63)
H) OMAP_GPIO_IRQ(int gpio)
Description: Returns the Interrupt number for the specified gpio pin.
Parameter: int gpio - GPIO PIN (Pin 0-63)
I) set_irq_type(unsigned int irq, unsigned int type)
Description: This function is responsible for setting the type of interrupt
(RISING or FALLING).
Parameter: unsigned int irq - The interrupt number for the gpio pin.
unsigned int type - (IRQT_RISING = rising, IRQT_FALLING= falling)
III. Example
------------
1) Writing to gpio pin#3 a value 1 and reading the value of gpio pin#3.
#include <asm/arch/gpio.h>
int ret; /* Return value */
omap_request_gpio(3); /* Request for gpio pin */
omap_set_gpio_direction(3,0);
omap_set_set_dataout(3,1); /* Writing a 1 to gpio pin # 3: */
ret = omap_get_datain(3); /* Reading the value of pin # 3 */
printk("value of pin # 3 = %d\n",ret);
omap_free_gpio(3); /* Freeing gpio pin # 3 */
2) Interrupt input by gpio pin#3
#include <asm/arch/gpio.h>
omap_request_gpio(3); /* Request for gpio pin */
omap_set_gpio_direction(3,0);
set_irq_type(OMAP_GPIO_IRQ(3),IRQT_RISING); /* Setting up pin for interrupt */
request_irq(OMAP_GPIO_IRQ(3), (void *)&my_int_handler, SA_SHIRQ,....);
... /* Do stuff, handle interrupts in my_int_handler */
free_irq(OMAP_GPIO_IRQ(3),&id); /* Freeing interrupt and gpio pin */
omap_free_gpio(3);
------------------------------------------------------------------
Last modified 14. August 2006
The OMAP Linux Kernel Team
Arnold <abo_gwapo@yahoo.com>
Dirk Behme <dirk.behme@gmail.com>
OMAP GPIO API's HowTo
=====================
This document is a short summary how to use OMAP Linux GPIO API. It is
mainly focussed on OMAP5912 OSK, but should fit with extensions (more
or less GPIOs) to other OMAP processors as well.
If anything is missing, is wrong, needs extension or update, please send
update to Linux-omap-open-source@linux.omap.com.
I. GPIO Modules/Banks
---------------------
OMAP5912 OSK has 64 GPIOs (general purpose IO pins). These are organized
in four modules (banks) with 16 pins each. OMAP GPIO API doesn't distinguish
between modules and numbers the pins from 0 - 63:
A) GPIO MODULE/BANK 0 - PIN 0-15
B) GPIO MODULE/BANK 1 - PIN 16-31
C) GPIO MODULE/BANK 2 - PIN 32-47
D) GPIO MODULE/BANK 3 - PIN 48-63
See
http://www-s.ti.com/sc/psheets/spru767a/spru767a.pdf
for more details.
II. GPIO API's
--------------
A) Include
#include <asm/arch/gpio.h>
B) omap_cfg_reg(xxxx);
Description: Configure pin mux.
Parameter: Pin to be configured for GPIO.
Note: This function may only be necessary for some GPIO pins. Because OMAP
chip itself has less real hardware pins than necessary to use all
its functionality at the same time, some pins share different
functions (called pin multiplexing, short pin mux). E.g. one pin may
be used for serial interface *or* GPIO. Check if this is the case for
the GPIO you want to use and if you have to configure the pin mux.
C) omap_request_gpio(int gpio)
Description: Request GPIO to be used.
Parameter: int gpio - GPIO PIN (Pin 0-63)
Note: Using this function, you dont have to worry about banks/modules where
the gpio pin is.
D) omap_set_gpio_direction(int gpio, int is_input)
Description: This function is responsible for setting the gpio pin direction
(input or output).
Parameter: int gpio - GPIO PIN (Pin 0-63)
int is_input - pin direction (0 = output, 1 = input)
E) omap_set_gpio_dataout(int gpio, int enable)
Description: This function is responsible for writing to a pin.
Parameter: int gpio - GPIO PIN (Pin 0-63)
int enable - pin value (0 or 1)
F) omap_get_gpio_datain(int gpio)
Description: This function is responsible for reading pin values.
Parameter: int gpio - GPIO PIN (Pin 0-63)
G) omap_free_gpio(int gpio)
Description: This function is responsible for freeing the pin used.
Parameter: int gpio - GPIO PIN (Pin 0-63)
H) OMAP_GPIO_IRQ(int gpio)
Description: Returns the Interrupt number for the specified gpio pin.
Parameter: int gpio - GPIO PIN (Pin 0-63)
I) set_irq_type(unsigned int irq, unsigned int type)
Description: This function is responsible for setting the type of interrupt
(RISING or FALLING).
Parameter: unsigned int irq - The interrupt number for the gpio pin.
unsigned int type - (IRQT_RISING = rising, IRQT_FALLING= falling)
III. Example
------------
1) Writing to gpio pin#3 a value 1 and reading the value of gpio pin#3.
#include <asm/arch/gpio.h>
int ret; /* Return value */
omap_request_gpio(3); /* Request for gpio pin */
omap_set_gpio_direction(3,0);
omap_set_set_dataout(3,1); /* Writing a 1 to gpio pin # 3: */
ret = omap_get_datain(3); /* Reading the value of pin # 3 */
printk("value of pin # 3 = %d\n",ret);
omap_free_gpio(3); /* Freeing gpio pin # 3 */
2) Interrupt input by gpio pin#3
#include <asm/arch/gpio.h>
omap_request_gpio(3); /* Request for gpio pin */
omap_set_gpio_direction(3,0);
set_irq_type(OMAP_GPIO_IRQ(3),IRQT_RISING); /* Setting up pin for interrupt */
request_irq(OMAP_GPIO_IRQ(3), (void *)&my_int_handler, SA_SHIRQ,....);
... /* Do stuff, handle interrupts in my_int_handler */
free_irq(OMAP_GPIO_IRQ(3),&id); /* Freeing interrupt and gpio pin */
omap_free_gpio(3);
------------------------------------------------------------------
Last modified 14. August 2006
The OMAP Linux Kernel Team
Arnold <abo_gwapo@yahoo.com>
Dirk Behme <dirk.behme@gmail.com>
......@@ -76,6 +76,10 @@ static struct map_desc ams_delta_io_desc[] __initdata = {
}
};
static struct omap_lcd_config ams_delta_lcd_config __initdata = {
.ctrl_name = "internal",
};
static struct omap_uart_config ams_delta_uart_config __initdata = {
.enabled_uarts = 1,
};
......@@ -87,16 +91,23 @@ static struct omap_usb_config ams_delta_usb_config __initdata = {
};
static struct omap_board_config_kernel ams_delta_config[] = {
{ OMAP_TAG_LCD, &ams_delta_lcd_config },
{ OMAP_TAG_UART, &ams_delta_uart_config },
{ OMAP_TAG_USB, &ams_delta_usb_config },
};
static struct platform_device ams_delta_lcd_device = {
.name = "lcd_ams_delta",
.id = -1,
};
static struct platform_device ams_delta_led_device = {
.name = "ams-delta-led",
.id = -1
};
static struct platform_device *ams_delta_devices[] __initdata = {
&ams_delta_lcd_device,
&ams_delta_led_device,
};
......
......@@ -44,6 +44,8 @@
#include <asm/arch/keypad.h>
#include <asm/arch/dma.h>
#include <asm/arch/common.h>
#include <asm/arch/mcbsp.h>
#include <asm/arch/omap-alsa.h>
extern int omap_gpio_init(void);
......@@ -363,6 +365,41 @@ static struct platform_device h3_lcd_device = {
.id = -1,
};
static struct omap_mcbsp_reg_cfg mcbsp_regs = {
.spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
.spcr1 = RINTM(3) | RRST,
.rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(1),
.rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16),
.xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(1) | XFIG,
.xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16),
.srgr1 = FWID(15),
.srgr2 = GSYNC | CLKSP | FSGM | FPER(31),
.pcr0 = CLKRM | SCLKME | FSXP | FSRP | CLKXP | CLKRP,
//.pcr0 = CLKXP | CLKRP, /* mcbsp: slave */
};
static struct omap_alsa_codec_config alsa_config = {
.name = "H3 TSC2101",
.mcbsp_regs_alsa = &mcbsp_regs,
.codec_configure_dev = NULL, // tsc2101_configure,
.codec_set_samplerate = NULL, // tsc2101_set_samplerate,
.codec_clock_setup = NULL, // tsc2101_clock_setup,
.codec_clock_on = NULL, // tsc2101_clock_on,
.codec_clock_off = NULL, // tsc2101_clock_off,
.get_default_samplerate = NULL, // tsc2101_get_default_samplerate,
};
static struct platform_device h3_mcbsp1_device = {
.name = "omap_alsa_mcbsp",
.id = 1,
.dev = {
.platform_data = &alsa_config,
},
};
static struct platform_device *devices[] __initdata = {
&nor_device,
&nand_device,
......@@ -371,6 +408,7 @@ static struct platform_device *devices[] __initdata = {
&h3_irda_device,
&h3_kp_device,
&h3_lcd_device,
&h3_mcbsp1_device,
};
static struct omap_usb_config h3_usb_config __initdata = {
......
......@@ -43,8 +43,21 @@ static struct platform_device palmte_lcd_device = {
.id = -1,
};
static struct omap_backlight_config palmte_backlight_config = {
.default_intensity = 0xa0,
};
static struct platform_device palmte_backlight_device = {
.name = "omap-bl",
.id = -1,
.dev = {
.platform_data = &palmte_backlight_config,
},
};
static struct platform_device *devices[] __initdata = {
&palmte_lcd_device,
&palmte_backlight_device,
};
static struct omap_usb_config palmte_usb_config __initdata = {
......
......@@ -20,6 +20,7 @@
#include <linux/clk.h>
#include <asm/io.h>
#include <asm/mach-types.h>
#include <asm/arch/cpu.h>
#include <asm/arch/usb.h>
......@@ -756,6 +757,12 @@ int __init omap1_clk_init(void)
omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
#endif
/* Amstrad Delta wants BCLK high when inactive */
if (machine_is_ams_delta())
omap_writel(omap_readl(ULPD_CLOCK_CTRL) |
(1 << SDW_MCLK_INV_BIT),
ULPD_CLOCK_CTRL);
/* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */
/* (on 730, bit 13 must not be cleared) */
if (cpu_is_omap730())
......
......@@ -89,6 +89,7 @@ struct arm_idlect1_clk {
#define EN_DSPTIMCK 5
/* Various register defines for clock controls scattered around OMAP chip */
#define SDW_MCLK_INV_BIT 2 /* In ULPD_CLKC_CTRL */
#define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */
#define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */
#define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */
......
......@@ -32,6 +32,7 @@
#include <linux/mm.h>
#include <linux/clk.h>
#include <linux/mutex.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/tlbflush.h>
#include <asm/irq.h>
......
......@@ -37,6 +37,7 @@
#include <linux/mm.h>
#include <linux/proc_fs.h>
#include <linux/mutex.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/signal.h>
......
......@@ -53,6 +53,7 @@ obj-$(CONFIG_ATA_OVER_ETH) += block/aoe/
obj-$(CONFIG_PARIDE) += block/paride/
obj-$(CONFIG_TC) += tc/
obj-$(CONFIG_USB) += usb/
obj-$(CONFIG_USB_MUSB_HDRC) += usb/musb/
obj-$(CONFIG_PCI) += usb/
obj-$(CONFIG_USB_GADGET) += usb/gadget/
obj-$(CONFIG_GAMEPORT) += input/gameport/
......
......@@ -33,6 +33,7 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <asm/arch/irqs.h>
#include <asm/arch/gpio.h>
#include <asm/arch/hardware.h>
......@@ -59,6 +60,8 @@ struct omap_kp {
int irq;
unsigned int rows;
unsigned int cols;
int suspended;
spinlock_t suspend_lock;
};
DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0);
......@@ -99,6 +102,14 @@ static irqreturn_t omap_kp_interrupt(int irq, void *dev_id,
struct pt_regs *regs)
{
struct omap_kp *omap_kp = dev_id;
unsigned long flags;
spin_lock_irqsave(&omap_kp->suspend_lock, flags);
if (omap_kp->suspended) {
spin_unlock_irqrestore(&omap_kp->suspend_lock, flags);
return IRQ_HANDLED;
}
spin_unlock_irqrestore(&omap_kp->suspend_lock, flags);
/* disable keyboard interrupt and schedule for handling */
if (cpu_is_omap24xx()) {
......@@ -269,15 +280,29 @@ static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, omap_kp_enable_show, omap_kp_enabl
#ifdef CONFIG_PM
static int omap_kp_suspend(struct platform_device *dev, pm_message_t state)
{
/* Nothing yet */
struct omap_kp *omap_kp = platform_get_drvdata(dev);
unsigned long flags;
spin_lock_irqsave(&omap_kp->suspend_lock, flags);
/*
* Re-enable the interrupt in case it has been masked by the
* handler and a key is still pressed. We need the interrupt
* to wake us up from suspended.
*/
if (cpu_class_is_omap1())
omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
omap_kp->suspended = 1;
spin_unlock_irqrestore(&omap_kp->suspend_lock, flags);
return 0;
}
static int omap_kp_resume(struct platform_device *dev)
{
/* Nothing yet */
struct omap_kp *omap_kp = platform_get_drvdata(dev);
omap_kp->suspended = 0;
return 0;
}
#else
......@@ -349,6 +374,9 @@ static int __init omap_kp_probe(struct platform_device *pdev)
}
}
spin_lock_init(&omap_kp->suspend_lock);
omap_kp->suspended = 0;
init_timer(&omap_kp->timer);
omap_kp->timer.function = omap_kp_timer;
omap_kp->timer.data = (unsigned long) omap_kp;
......
......@@ -1163,8 +1163,9 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
mmc_add_host(mmc);
no_switch:
return 0;
no_switch:
/* FIXME: Free other resources too. */
if (host) {
if (host->iclk && !IS_ERR(host->iclk))
......
......@@ -80,6 +80,8 @@ source "drivers/usb/core/Kconfig"
source "drivers/usb/host/Kconfig"
source "drivers/usb/musb/Kconfig"
source "drivers/usb/class/Kconfig"
source "drivers/usb/storage/Kconfig"
......
......@@ -155,6 +155,16 @@ config USB_LH7A40X
select USB_GADGET_SELECTED
# built in ../musb along with host support
config USB_GADGET_MUSB_HDRC
boolean "Inventra HDRC USB Peripheral (TI, ...)"
depends on USB_MUSB_HDRC && (USB_MUSB_PERIPHERAL || USB_MUSB_OTG)
select USB_GADGET_DUALSPEED
select USB_GADGET_SELECTED
help
This OTG-capable silicon IP is used in dual designs including
the TI DaVinci, OMAP 243x, OMAP 343x, and TUSB 6010.
config USB_GADGET_OMAP
boolean "OMAP USB Device Controller"
depends on ARCH_OMAP1
......
#
# USB Dual Role (OTG-ready) Controller Drivers
# for silicon based on Mentor Graphics INVENTRA designs
#
comment "Enable Host or Gadget support to see Inventra options"
depends on !USB && USB_GADGET=n
# (M)HDRC = (Multipoint) Highspeed Dual-Role Controller
config USB_MUSB_HDRC
depends on USB || USB_GADGET
tristate 'Inventra Highspeed Dual Role Controller (TI, ...)'
help
Say Y here if your system has a dual role high speed USB
controller based on the Mentor Graphics silicon IP. Then
configure options to match your silicon and the board
it's being used with, including the USB peripheral role,
or the USB host role, or both.
Texas Instruments parts using this IP include DaVinci 644x,
OMAP 243x, OMAP 343x, and TUSB 6010.
If you do not know what this is, please say N.
To compile this driver as a module, choose M here; the
module will be called "musb_hdrc".
config USB_MUSB_SOC
boolean
depends on USB_MUSB_HDRC
default y if ARCH_DAVINCI
default y if ARCH_OMAP243X
default y if ARCH_OMAP343X
help
Use a static <asm/arch/hdrc_cnf.h> file to describe how the
controller is configured (endpoints, mechanisms, etc) on the
current iteration of a given system-on-chip.
comment "DaVinci 644x USB support"
depends on USB_MUSB_HDRC && ARCH_DAVINCI
comment "OMAP 243x high speed USB support"
depends on USB_MUSB_HDRC && ARCH_OMAP243X
comment "OMAP 343x high speed USB support"
depends on USB_MUSB_HDRC && ARCH_OMAP343X
config USB_TUSB6010
boolean "TUSB 6010 support"
depends on USB_MUSB_HDRC && !USB_MUSB_SOC
default y
help
The TUSB 6010 chip, from Texas Instruments, connects a discrete
HDRC core using a 16-bit parallel bus (NOR flash style) or VLYNQ
(a high speed serial link). It can use system-specific external
DMA controllers.
choice
prompt "Driver Mode"
depends on USB_MUSB_HDRC
help
Dual-Role devices can support both host and peripheral roles,
as well as a the special "OTG Device" role which can switch
between both roles as needed.
# use USB_MUSB_HDRC_HCD not USB_MUSB_HOST to #ifdef host side support;
# OTG needs both roles, not just USB_MUSB_HOST.
config USB_MUSB_HOST
depends on USB
bool "USB Host"
help
Say Y here if your system supports the USB host role.
If it has a USB "A" (rectangular), "Mini-A" (uncommon),
or "Mini-AB" connector, it supports the host role.
(With a "Mini-AB" connector, you should enable USB OTG.)
# use USB_GADGET_MUSB_HDRC not USB_MUSB_PERIPHERAL to #ifdef peripheral
# side support ... OTG needs both roles
config USB_MUSB_PERIPHERAL
depends on USB_GADGET
bool "USB Peripheral (gadget stack)"
select USB_GADGET_MUSB_HDRC
help
Say Y here if your system supports the USB peripheral role.
If it has a USB "B" (squarish), "Mini-B", or "Mini-AB"
connector, it supports the peripheral role.
(With a "Mini-AB" connector, you should enable USB OTG.)
config USB_MUSB_OTG
depends on USB && USB_GADGET && EXPERIMENTAL
bool "Both host and peripheral: USB OTG (On The Go) Device"
select USB_GADGET_MUSB_HDRC
select USB_OTG
select PM
help
The most notable feature of USB OTG is support for a
"Dual-Role" device, which can act as either a device
or a host. The initial role choice can be changed
later, when two dual-role devices talk to each other.
At this writing, the OTG support in this driver is incomplete,
omitting the mandatory HNP or SRP protocols. However, some
of the cable based role switching works. (That is, grounding
the ID pin switches the controller to host mode, while leaving
it floating leaves it in peripheral mode.)
Select this if your system has a Mini-AB connector, or
to simplify certain kinds of configuration.
To implement your OTG Targeted Peripherals List (TPL), enable
USB_OTG_WHITELIST and update "drivers/usb/core/otg_whitelist.h"
to match your requirements.
endchoice
# enable peripheral support (including with OTG)
config USB_GADGET_MUSB_HDRC
bool
depends on USB_MUSB_HDRC && (USB_MUSB_PERIPHERAL || USB_MUSB_OTG)
# default y
# select USB_GADGET_DUALSPEED
# select USB_GADGET_SELECTED
# enables host support (including with OTG)
config USB_MUSB_HDRC_HCD
bool
depends on USB_MUSB_HDRC && (USB_MUSB_HOST || USB_MUSB_OTG)
select USB_OTG if USB_GADGET_MUSB_HDRC
default y
config USB_INVENTRA_FIFO
bool 'Disable DMA (always use PIO)'
depends on USB_MUSB_HDRC
default y if USB_TUSB6010
help
All data is copied between memory and FIFO by the CPU.
DMA controllers are ignored.
Do not select 'n' here unless DMA support for your SOC or board
is unavailable (or unstable). When DMA is enabled at compile time,
you can still disable it at run time using the "use_dma=n" module
parameter.
config USB_INVENTRA_DMA
bool
depends on USB_MUSB_HDRC && !USB_INVENTRA_FIFO
default ARCH_OMAP243X || ARCH_OMAP343X
help
Enable DMA transfers using Mentor's engine.
config USB_TI_CPPI_DMA
bool
depends on USB_MUSB_HDRC && !USB_INVENTRA_FIFO
default ARCH_DAVINCI
help
Enable DMA transfers when TI CPPI DMA is available.
config USB_TUSB_OMAP_DMA
bool
depends on USB_MUSB_HDRC && !USB_INVENTRA_FIFO
depends on USB_TUSB6010
depends on ARCH_OMAP
default y
help
Enable DMA transfers on TUSB 6010 when OMAP DMA is available.
config USB_INVENTRA_HCD_LOGGING
depends on USB_MUSB_HDRC
int 'Logging Level (0 - none / 3 - annoying / ... )'
default 0
help
Set the logging level. 0 disables the debugging altogether,
although when USB_DEBUG is set the value is at least 1.
Starting at level 3, per-transfer (urb, usb_request, packet,
or dma transfer) tracing may kick in.
#
# for USB OTG silicon based on Mentor Graphics INVENTRA designs
#
musb_hdrc-objs := plat_uds.o
obj-$(CONFIG_USB_MUSB_HDRC) += musb_hdrc.o
ifeq ($(CONFIG_ARCH_DAVINCI),y)
musb_hdrc-objs += davinci.o
endif
ifeq ($(CONFIG_USB_TUSB6010),y)
musb_hdrc-objs += tusb6010.o
endif
ifeq ($(CONFIG_ARCH_OMAP243X),y)
musb_hdrc-objs += omap2430.o
endif
ifeq ($(CONFIG_USB_MUSB_OTG),y)
musb_hdrc-objs += otg.o
endif
ifeq ($(CONFIG_USB_GADGET_MUSB_HDRC),y)
musb_hdrc-objs += g_ep0.o musb_gadget.o
endif
ifeq ($(CONFIG_USB_MUSB_HDRC_HCD),y)
musb_hdrc-objs += virthub.o musb_host.o
endif
# the kconfig must guarantee that only one of the
# possible I/O schemes will be enabled at a time ...
# PIO (INVENTRA_FIFO), or DMA (several potential schemes).
# though PIO is always there to back up DMA, and for ep0
ifneq ($(CONFIG_USB_INVENTRA_FIFO),y)
ifeq ($(CONFIG_USB_INVENTRA_DMA),y)
musb_hdrc-objs += musbhsdma.o
else
ifeq ($(CONFIG_USB_TI_CPPI_DMA),y)
musb_hdrc-objs += cppi_dma.o
else
ifeq ($(CONFIG_USB_TUSB_OMAP_DMA),y)
musb_hdrc-objs += tusb6010_omap.o
endif
endif
endif
endif
################################################################################
# FIXME remove all these extra "-DMUSB_* things, stick to CONFIG_*
ifeq ($(CONFIG_USB_INVENTRA_MUSB_HAS_AHB_ID),y)
EXTRA_CFLAGS += -DMUSB_AHB_ID
endif
# Debugging
MUSB_DEBUG:=$(CONFIG_USB_INVENTRA_HCD_LOGGING)
ifeq ("$(strip $(MUSB_DEBUG))","")
ifdef CONFIG_USB_DEBUG
MUSB_DEBUG:=1
else
MUSB_DEBUG:=0
endif
endif
ifneq ($(MUSB_DEBUG),0)
EXTRA_CFLAGS += -DDEBUG
ifeq ($(CONFIG_PROC_FS),y)
musb_hdrc-objs += musb_procfs.o
endif
endif
EXTRA_CFLAGS += -DMUSB_DEBUG=$(MUSB_DEBUG)
This diff is collapsed.
/* Copyright (C) 2005-2006 by Texas Instruments */
#ifndef _CPPI_DMA_H_
#define _CPPI_DMA_H_
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/dmapool.h>
#include "dma.h"
#include "musbdefs.h"
#include "davinci.h"
/* hOptions bit masks for CPPI BDs */
#define CPPI_SOP_SET ((u32)(1 << 31))
#define CPPI_EOP_SET ((u32)(1 << 30))
#define CPPI_OWN_SET ((u32)(1 << 29)) /* owned by cppi */
#define CPPI_EOQ_MASK ((u32)(1 << 28))
#define CPPI_ZERO_SET ((u32)(1 << 23)) /* rx saw zlp; tx issues one */
#define CPPI_RXABT_MASK ((u32)(1 << 19)) /* need more rx buffers */
#define CPPI_RECV_PKTLEN_MASK 0xFFFF
#define CPPI_BUFFER_LEN_MASK 0xFFFF
#define CPPI_TEAR_READY ((u32)(1 << 31))
/* CPPI data structure definitions */
#define CPPI_DESCRIPTOR_ALIGN 16 // bytes; 5-dec docs say 4-byte align
struct cppi_descriptor {
/* Hardware Overlay */
u32 hNext; /**< Next(hardware) Buffer Descriptor Pointer */
u32 buffPtr; /**<Buffer Pointer (dma_addr_t) */
u32 bOffBLen; /**<Buffer_offset16,buffer_length16 */
u32 hOptions; /**<Option fields for SOP,EOP etc*/
struct cppi_descriptor *next;
dma_addr_t dma; /* address of this descriptor */
/* for Rx Desc, track original Buffer len to detect short packets */
u32 enqBuffLen;
} __attribute__ ((aligned(CPPI_DESCRIPTOR_ALIGN)));
/* forward declaration for CppiDmaController structure */
struct cppi;
/**
* Channel Control Structure
*
* CPPI Channel Control structure. Using he same for Tx/Rx. If need be
* derive out of this later.
*/
struct cppi_channel {
/* First field must be dma_channel for easy type casting
* FIXME just use container_of() and be typesafe instead!
*/
struct dma_channel Channel;
/* back pointer to the Dma Controller structure */
struct cppi *pController;
/* which direction of which endpoint? */
struct musb_hw_ep *pEndPt;
u8 bTransmit;
u8 chNo;
/* DMA modes: RNDIS or "transparent" */
u8 bLastModeRndis;
/* book keeping for current transfer request */
dma_addr_t startAddr;
u32 transferSize;
u32 pktSize;
u32 currOffset; /* requested segments */
u32 actualLen; /* completed (Channel.actual) */
void __iomem *stateRam; /* CPPI state */
/* BD management fields */
struct cppi_descriptor *bdPoolHead;
struct cppi_descriptor *activeQueueHead;
struct cppi_descriptor *activeQueueTail;
struct cppi_descriptor *lastHwBDProcessed;
/* use tx_complete in host role to track endpoints waiting for
* FIFONOTEMPTY to clear.
*/
struct list_head tx_complete;
};
/**
* CPPI Dma Controller Object
*
* CPPI Dma controller object.Encapsulates all bookeeping and Data
* structures pertaining to the CPPI Dma Controller.
*/
struct cppi {
struct dma_controller Controller;
struct musb *musb;
void __iomem *pCoreBase;
struct cppi_channel txCppi[MUSB_C_NUM_EPT - 1];
struct cppi_channel rxCppi[MUSB_C_NUM_EPR - 1];
struct dma_pool *pool;
struct list_head tx_complete;
};
/* irq handling hook */
extern void cppi_completion(struct musb *, u32 rx, u32 tx);
#endif /* end of ifndef _CPPI_DMA_H_ */
/*
* Copyright (C) 2005-2006 by Texas Instruments
*
* This file is part of the Inventra Controller Driver for Linux.
*
* The Inventra Controller Driver for Linux 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.
*
* The Inventra Controller Driver for Linux is distributed in
* the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License
* along with The Inventra Controller Driver for Linux ; if not,
* write to the Free Software Foundation, Inc., 59 Temple Place,
* Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <asm/io.h>
#include <asm/arch/hardware.h>
#include <asm/arch/memory.h>
// #include <asm/arch/gpio.h>
#include <asm/mach-types.h>
#include "musbdefs.h"
#ifdef CONFIG_ARCH_DAVINCI
#ifdef CONFIG_MACH_DAVINCI_EVM
#include <asm/arch/i2c-client.h>
#endif
#include "davinci.h"
#endif
#ifdef CONFIG_USB_TI_CPPI_DMA
#include "cppi_dma.h"
#endif
static inline void phy_on(void)
{
/* start the on-chip PHY and its PLL */
__raw_writel(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON,
IO_ADDRESS(USBPHY_CTL_PADDR));
while ((__raw_readl(IO_ADDRESS(USBPHY_CTL_PADDR))
& USBPHY_PHYCLKGD) == 0)
cpu_relax();
}
static inline void phy_off(void)
{
/* powerdown the on-chip PHY and its oscillator */
__raw_writel(USBPHY_OSCPDWN | USBPHY_PHYSPDWN,
IO_ADDRESS(USBPHY_CTL_PADDR));
}
static int dma_off = 1;
void musb_platform_enable(struct musb *musb)
{
u32 tmp, old, val;
/* workaround: setup irqs through both register sets */
tmp = (musb->wEndMask & DAVINCI_USB_TX_ENDPTS_MASK)
<< DAVINCI_USB_TXINT_SHIFT;
musb_writel(musb->ctrl_base, DAVINCI_USB_INT_MASK_SET_REG, tmp);
old = tmp;
tmp = (musb->wEndMask & (0xfffe & DAVINCI_USB_RX_ENDPTS_MASK))
<< DAVINCI_USB_RXINT_SHIFT;
musb_writel(musb->ctrl_base, DAVINCI_USB_INT_MASK_SET_REG, tmp);
tmp |= old;
val = ~MGC_M_INTR_SOF;
tmp |= ((val & 0x01ff) << DAVINCI_USB_USBINT_SHIFT);
musb_writel(musb->ctrl_base, DAVINCI_USB_INT_MASK_SET_REG, tmp);
if (is_dma_capable() && !dma_off)
printk(KERN_WARNING "%s %s: dma not reactivated\n",
__FILE__, __FUNCTION__);
else
dma_off = 0;
}
/*
* Disable the HDRC and flush interrupts
*/
void musb_platform_disable(struct musb *musb)
{
/* because we don't set CTRLR.UINT, "important" to:
* - not read/write INTRUSB/INTRUSBE
* - (except during initial setup, as workaround)
* - use INTSETR/INTCLRR instead
*/
musb_writel(musb->ctrl_base, DAVINCI_USB_INT_MASK_CLR_REG,
DAVINCI_USB_USBINT_MASK
| DAVINCI_USB_TXINT_MASK
| DAVINCI_USB_RXINT_MASK);
musb_writeb(musb->pRegs, MGC_O_HDRC_DEVCTL, 0);
musb_writel(musb->ctrl_base, DAVINCI_USB_EOI_REG, 0);
if (is_dma_capable() && !dma_off)
WARN("dma still active\n");
}
/* REVISIT this file shouldn't modify the OTG state machine ...
*
* The OTG infrastructure needs updating, to include things like
* offchip DRVVBUS support and replacing MGC_OtgMachineInputs with
* musb struct members (so e.g. vbus_state vanishes).
*/
static int vbus_state = -1;
#ifdef CONFIG_USB_MUSB_HDRC_HCD
#define portstate(stmt) stmt
#else
#define portstate(stmt)
#endif
static void session(struct musb *musb, int is_on)
{
void *__iomem mregs = musb->pRegs;
u8 devctl = musb_readb(mregs, MGC_O_HDRC_DEVCTL);
/* NOTE: after drvvbus off the state _could_ be A_IDLE;
* but the silicon seems to couple vbus to "ID grounded".
*/
devctl |= MGC_M_DEVCTL_SESSION;
if (is_on) {
musb->xceiv.state = OTG_STATE_A_WAIT_BCON;
portstate(musb->port1_status |= USB_PORT_STAT_POWER);
} else {
musb->xceiv.state = OTG_STATE_B_IDLE;
portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
}
musb_writeb(mregs, MGC_O_HDRC_DEVCTL, devctl);
}
/* VBUS SWITCHING IS BOARD-SPECIFIC */
#ifdef CONFIG_MACH_DAVINCI_EVM
/* I2C operations are always synchronous, and require a task context.
* With unloaded systems, using the shared workqueue seems to suffice
* to satisfy the 100msec A_WAIT_VRISE timeout...
*/
static void evm_deferred_drvvbus(void *_musb)
{
struct musb *musb = _musb;
int is_on = (musb->xceiv.state == OTG_STATE_A_WAIT_VRISE);
davinci_i2c_expander_op(0x3a, USB_DRVVBUS, !is_on);
vbus_state = is_on;
session(musb, is_on);
}
DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus, 0);
#endif
static void davinci_vbus_power(struct musb *musb, int is_on, int sleeping)
{
if (is_on)
is_on = 1;
if (vbus_state == is_on)
return;
if (is_on) {
musb->xceiv.state = OTG_STATE_A_WAIT_VRISE;
MUSB_HST_MODE(musb);
} else {
switch (musb->xceiv.state) {
case OTG_STATE_UNDEFINED:
case OTG_STATE_B_IDLE:
MUSB_DEV_MODE(musb);
musb->xceiv.state = OTG_STATE_B_IDLE;
break;
case OTG_STATE_A_IDLE:
break;
default:
musb->xceiv.state = OTG_STATE_A_WAIT_VFALL;
break;
}
}
#ifdef CONFIG_MACH_DAVINCI_EVM
if (machine_is_davinci_evm()) {
#ifdef CONFIG_MACH_DAVINCI_EVM_OTG
/* modified EVM board switching VBUS with GPIO(6) not I2C
* NOTE: PINMUX0.RGB888 (bit23) must be clear
*/
if (is_on)
gpio_set(GPIO(6));
else
gpio_clear(GPIO(6));
#else
if (sleeping)
davinci_i2c_expander_op(0x3a, USB_DRVVBUS, !is_on);
else
schedule_work(&evm_vbus_work);
#endif
}
#endif
if (sleeping) {
vbus_state = is_on;
session(musb, is_on);
}
DBG(2, "VBUS power %s, %s\n", is_on ? "on" : "off",
sleeping ? "immediate" : "deferred");
}
static irqreturn_t davinci_interrupt(int irq, void *__hci, struct pt_regs *r)
{
unsigned long flags;
irqreturn_t retval = IRQ_NONE;
struct musb *musb = __hci;
void *__iomem tibase = musb->ctrl_base;
u32 tmp;
spin_lock_irqsave(&musb->Lock, flags);
/* NOTE: DaVinci shadows the Mentor IRQs. Don't manage them through
* the Mentor registers (except for setup), use the TI ones and EOI.
*
* Docs describe irq "vector" registers asociated with the CPPI and
* USB EOI registers. These hold a bitmask corresponding to the
* current IRQ, not an irq handler address. Would using those bits
* resolve some of the races observed in this dispatch code??
*/
#ifdef CONFIG_USB_TI_CPPI_DMA
/* CPPI interrupts share the same IRQ line, but have their own
* mask, state, "vector", and EOI registers.
*/
{
u32 cppi_tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG);
u32 cppi_rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG);
if (cppi_tx || cppi_rx) {
DBG(4, "<== CPPI IRQ t%x r%x\n", cppi_tx, cppi_rx);
cppi_completion(musb, cppi_rx, cppi_tx);
retval = IRQ_HANDLED;
}
}
#endif
/* ack and handle non-CPPI interrupts */
tmp = musb_readl(tibase, DAVINCI_USB_INT_SRC_MASKED_REG);
musb_writel(tibase, DAVINCI_USB_INT_SRC_CLR_REG, tmp);
musb->int_rx = (tmp & DAVINCI_USB_RXINT_MASK)
>> DAVINCI_USB_RXINT_SHIFT;
musb->int_tx = (tmp & DAVINCI_USB_TXINT_MASK)
>> DAVINCI_USB_TXINT_SHIFT;
musb->int_usb = (tmp & DAVINCI_USB_USBINT_MASK)
>> DAVINCI_USB_USBINT_SHIFT;
musb->int_regs = r;
if (tmp & (1 << (8 + DAVINCI_USB_USBINT_SHIFT))) {
int drvvbus = musb_readl(tibase, DAVINCI_USB_STAT_REG);
/* NOTE: this must complete poweron within 100 msec */
davinci_vbus_power(musb, drvvbus, 0);
DBG(2, "DRVVBUS %d (state %d)\n", drvvbus, musb->xceiv.state);
retval = IRQ_HANDLED;
}
if (musb->int_tx || musb->int_rx || musb->int_usb)
retval |= musb_interrupt(musb);
/* irq stays asserted until EOI is written */
musb_writel(tibase, DAVINCI_USB_EOI_REG, 0);
musb->int_regs = NULL;
spin_unlock_irqrestore(&musb->Lock, flags);
/* REVISIT we sometimes get unhandled IRQs
* (e.g. ep0). not clear why...
*/
if (retval != IRQ_HANDLED)
DBG(5, "unhandled? %08x\n", tmp);
return IRQ_HANDLED;
}
int __devinit musb_platform_init(struct musb *musb)
{
void *__iomem tibase = musb->ctrl_base;
u32 revision;
musb->pRegs += DAVINCI_BASE_OFFSET;
#if 0
/* REVISIT there's something odd about clocking, this
* didn't appear do the job ...
*/
musb->clock = clk_get(pDevice, "usb");
if (IS_ERR(musb->clock))
return PTR_ERR(musb->clock);
status = clk_enable(musb->clock);
if (status < 0)
return -ENODEV;
#endif
/* returns zero if e.g. not clocked */
revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG);
if (revision == 0)
return -ENODEV;
/* note that transceiver issues make us want to charge
* VBUS only when the PHY PLL is not active.
*/
#ifdef CONFIG_MACH_DAVINCI_EVM
evm_vbus_work.data = musb;
#endif
davinci_vbus_power(musb, musb->board_mode == MUSB_HOST, 1);
/* reset the controller */
musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);
/* start the on-chip PHY and its PLL */
phy_on();
msleep(5);
/* NOTE: irqs are in mixed mode, not bypass to pure-musb */
pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n",
revision,
__raw_readl((void *__iomem) IO_ADDRESS(USBPHY_CTL_PADDR)),
musb_readb(tibase, DAVINCI_USB_CTRL_REG));
musb->isr = davinci_interrupt;
return 0;
}
int musb_platform_exit(struct musb *musb)
{
phy_off();
davinci_vbus_power(musb, 0 /*off*/, 1);
return 0;
}
/*
* Copyright (C) 2005-2006 by Texas Instruments
*
* The Inventra Controller Driver for Linux 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.
*/
#ifndef __MUSB_HDRDF_H__
#define __MUSB_HDRDF_H__
/*
* DaVinci-specific definitions
*/
/* Integrated highspeed/otg PHY */
#define USBPHY_CTL_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x34)
#define USBPHY_PHYCLKGD (1 << 8)
#define USBPHY_SESNDEN (1 << 7) /* v(sess_end) comparator */
#define USBPHY_VBDTCTEN (1 << 6) /* v(bus) comparator */
#define USBPHY_PHYPLLON (1 << 4) /* override pll suspend */
#define USBPHY_CLK01SEL (1 << 3)
#define USBPHY_OSCPDWN (1 << 2)
#define USBPHY_PHYSPDWN (1 << 0)
/* For now include usb OTG module registers here */
#define DAVINCI_USB_VERSION_REG 0x00
#define DAVINCI_USB_CTRL_REG 0x04
#define DAVINCI_USB_STAT_REG 0x08
#define DAVINCI_RNDIS_REG 0x10
#define DAVINCI_AUTOREQ_REG 0x14
#define DAVINCI_USB_INT_SOURCE_REG 0x20
#define DAVINCI_USB_INT_SET_REG 0x24
#define DAVINCI_USB_INT_SRC_CLR_REG 0x28
#define DAVINCI_USB_INT_MASK_REG 0x2c
#define DAVINCI_USB_INT_MASK_SET_REG 0x30
#define DAVINCI_USB_INT_MASK_CLR_REG 0x34
#define DAVINCI_USB_INT_SRC_MASKED_REG 0x38
#define DAVINCI_USB_EOI_REG 0x3c
#define DAVINCI_USB_EOI_INTVEC 0x40
/* CPPI related registers */
#define DAVINCI_TXCPPI_CTRL_REG 0x80
#define DAVINCI_TXCPPI_TEAR_REG 0x84
#define DAVINCI_CPPI_EOI_REG 0x88
#define DAVINCI_CPPI_INTVEC_REG 0x8c
#define DAVINCI_TXCPPI_MASKED_REG 0x90
#define DAVINCI_TXCPPI_RAW_REG 0x94
#define DAVINCI_TXCPPI_INTENAB_REG 0x98
#define DAVINCI_TXCPPI_INTCLR_REG 0x9c
#define DAVINCI_RXCPPI_CTRL_REG 0xC0
#define DAVINCI_RXCPPI_MASKED_REG 0xD0
#define DAVINCI_RXCPPI_RAW_REG 0xD4
#define DAVINCI_RXCPPI_INTENAB_REG 0xD8
#define DAVINCI_RXCPPI_INTCLR_REG 0xDC
#define DAVINCI_RXCPPI_BUFCNT0_REG 0xE0
#define DAVINCI_RXCPPI_BUFCNT1_REG 0xE4
#define DAVINCI_RXCPPI_BUFCNT2_REG 0xE8
#define DAVINCI_RXCPPI_BUFCNT3_REG 0xEC
/* CPPI state RAM entries */
#define DAVINCI_CPPI_STATERAM_BASE_OFFSET 0x100
#define DAVINCI_TXCPPI_STATERAM_OFFSET(channelNum) \
(DAVINCI_CPPI_STATERAM_BASE_OFFSET + ((channelNum)* 0x40))
#define DAVINCI_RXCPPI_STATERAM_OFFSET(channelNum) \
(DAVINCI_CPPI_STATERAM_BASE_OFFSET + 0x20 +((channelNum)* 0x40))
/* CPPI masks */
#define DAVINCI_DMA_CTRL_ENABLE 1
#define DAVINCI_DMA_CTRL_DISABLE 0
#define DAVINCI_DMA_ALL_CHANNELS_ENABLE 0xF
#define DAVINCI_DMA_ALL_CHANNELS_DISABLE 0xF
/* REVISIT relying on "volatile" here is wrong ... */
/* define structures of Rx/Tx stateRam entries */
struct cppi_tx_stateram {
volatile u32 headPtr;
volatile u32 sopDescPtr;
volatile u32 currDescPtr;
volatile u32 currBuffPtr;
volatile u32 flags;
volatile u32 remLength;
volatile u32 dummy;
volatile u32 completionPtr;
};
struct cppi_rx_stateram {
volatile u32 buffOffset;
volatile u32 headPtr;
volatile u32 sopDescPtr;
volatile u32 currDescPtr;
volatile u32 currBuffPtr;
volatile u32 pktLength;
volatile u32 byteCount;
volatile u32 completionPtr;
};
#define DAVINCI_USB_TX_ENDPTS_MASK 0x1f /* ep0 + 4 tx */
#define DAVINCI_USB_RX_ENDPTS_MASK 0x1e /* 4 rx */
#define DAVINCI_USB_USBINT_SHIFT 16
#define DAVINCI_USB_TXINT_SHIFT 0
#define DAVINCI_USB_RXINT_SHIFT 8
#define DAVINCI_USB_USBINT_MASK 0x01ff0000 /* 8 Mentor, DRVVBUS */
#define DAVINCI_USB_TXINT_MASK \
(DAVINCI_USB_TX_ENDPTS_MASK << DAVINCI_USB_TXINT_SHIFT)
#define DAVINCI_USB_RXINT_MASK \
(DAVINCI_USB_RX_ENDPTS_MASK << DAVINCI_USB_RXINT_SHIFT)
#define DAVINCI_BASE_OFFSET 0x400
#endif /* __MUSB_HDRDF_H__ */
/******************************************************************
* Copyright 2005 Mentor Graphics Corporation
* Copyright (C) 2005-2006 by Texas Instruments
*
* This file is part of the Inventra Controller Driver for Linux.
*
* The Inventra Controller Driver for Linux 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.
*
* The Inventra Controller Driver for Linux is distributed in
* the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License
* along with The Inventra Controller Driver for Linux ; if not,
* write to the Free Software Foundation, Inc., 59 Temple Place,
* Suite 330, Boston, MA 02111-1307 USA
*
* ANY DOWNLOAD, USE, REPRODUCTION, MODIFICATION OR DISTRIBUTION
* OF THIS DRIVER INDICATES YOUR COMPLETE AND UNCONDITIONAL ACCEPTANCE
* OF THOSE TERMS.THIS DRIVER IS PROVIDED "AS IS" AND MENTOR GRAPHICS
* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, RELATED TO THIS DRIVER.
* MENTOR GRAPHICS SPECIFICALLY DISCLAIMS ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY; FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT. MENTOR GRAPHICS DOES NOT PROVIDE SUPPORT
* SERVICES OR UPDATES FOR THIS DRIVER, EVEN IF YOU ARE A MENTOR
* GRAPHICS SUPPORT CUSTOMER.
******************************************************************/
#ifndef __MUSB_LINUX_DEBUG_H__
#define __MUSB_LINUX_DEBUG_H__
#define yprintk(facility, format, args...) \
do { printk(facility "%s %d: " format , \
__FUNCTION__, __LINE__ , ## args); } while (0)
#define WARN(fmt, args...) yprintk(KERN_WARNING,fmt, ## args)
#define INFO(fmt,args...) yprintk(KERN_INFO,fmt, ## args)
#define ERR(fmt,args...) yprintk(KERN_ERR,fmt, ## args)
#define xprintk(level, facility, format, args...) do { \
if ( _dbg_level(level) ) { \
printk(facility "%s %d: " format , \
__FUNCTION__, __LINE__ , ## args); \
} } while (0)
#if MUSB_DEBUG > 0
extern unsigned debug;
#else
#define debug 0
#endif
static inline int _dbg_level(unsigned l)
{
return debug >= l;
}
#define DBG(level,fmt,args...) xprintk(level,KERN_DEBUG,fmt, ## args)
#endif // __MUSB_LINUX_DEBUG_H__
/******************************************************************
* Copyright 2005 Mentor Graphics Corporation
* Copyright (C) 2005-2006 by Texas Instruments
*
* This file is part of the Inventra Controller Driver for Linux.
*
* The Inventra Controller Driver for Linux 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.
*
* The Inventra Controller Driver for Linux is distributed in
* the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License
* along with The Inventra Controller Driver for Linux ; if not,
* write to the Free Software Foundation, Inc., 59 Temple Place,
* Suite 330, Boston, MA 02111-1307 USA
*
* ANY DOWNLOAD, USE, REPRODUCTION, MODIFICATION OR DISTRIBUTION
* OF THIS DRIVER INDICATES YOUR COMPLETE AND UNCONDITIONAL ACCEPTANCE
* OF THOSE TERMS.THIS DRIVER IS PROVIDED "AS IS" AND MENTOR GRAPHICS
* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, RELATED TO THIS DRIVER.
* MENTOR GRAPHICS SPECIFICALLY DISCLAIMS ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY; FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT. MENTOR GRAPHICS DOES NOT PROVIDE SUPPORT
* SERVICES OR UPDATES FOR THIS DRIVER, EVEN IF YOU ARE A MENTOR
* GRAPHICS SUPPORT CUSTOMER.
******************************************************************/
#ifndef __MUSB_DMA_H__
#define __MUSB_DMA_H__
struct musb_hw_ep;
/*
* DMA Controller Abstraction
*
* DMA Controllers are abstracted to allow use of a variety of different
* implementations of DMA, as allowed by the Inventra USB cores. On the
* host side, usbcore sets up the DMA mappings and flushes caches; on the
* peripheral side, the gadget controller driver does. Responsibilities
* of a DMA controller driver include:
*
* - Handling the details of moving multiple USB packets
* in cooperation with the Inventra USB core, including especially
* the correct RX side treatment of short packets and buffer-full
* states (both of which terminate transfers).
*
* - Knowing the correlation between dma channels and the
* Inventra core's local endpoint resources and data direction.
*
* - Maintaining a list of allocated/available channels.
*
* - Updating channel status on interrupts,
* whether shared with the Inventra core or separate.
*/
#define DMA_ADDR_INVALID (~(dma_addr_t)0)
#ifndef CONFIG_USB_INVENTRA_FIFO
#define is_dma_capable() (1)
#else
#define is_dma_capable() (0)
#endif
#if defined(CONFIG_USB_TI_CPPI_DMA) && defined(CONFIG_USB_MUSB_HDRC_HCD)
extern void cppi_hostdma_start(struct musb * pThis, u8 bEnd);
#else
static inline void cppi_hostdma_start(struct musb * pThis, u8 bEnd) {}
#endif
/*
* DMA channel status ... updated by the dma controller driver whenever that
* status changes, and protected by the overall controller spinlock.
*/
enum dma_channel_status {
/* unallocated */
MGC_DMA_STATUS_UNKNOWN,
/* allocated ... but not busy, no errors */
MGC_DMA_STATUS_FREE,
/* busy ... transactions are active */
MGC_DMA_STATUS_BUSY,
/* transaction(s) aborted due to ... dma or memory bus error */
MGC_DMA_STATUS_BUS_ABORT,
/* transaction(s) aborted due to ... core error or USB fault */
MGC_DMA_STATUS_CORE_ABORT
};
struct dma_controller;
/**
* struct dma_channel - A DMA channel.
* @pPrivateData: channel-private data
* @wMaxLength: the maximum number of bytes the channel can move in one
* transaction (typically representing many USB maximum-sized packets)
* @dwActualLength: how many bytes have been transferred
* @bStatus: current channel status (updated e.g. on interrupt)
* @bDesiredMode: TRUE if mode 1 is desired; FALSE if mode 0 is desired
*
* channels are associated with an endpoint for the duration of at least
* one usb transfer.
*/
struct dma_channel {
void *pPrivateData;
// FIXME not void* private_data, but a dma_controller *
size_t dwMaxLength;
size_t dwActualLength;
enum dma_channel_status bStatus;
u8 bDesiredMode;
};
/*
* Program a DMA channel to move data at the core's request.
* The local core endpoint and direction should already be known,
* since they are specified in the channel_alloc call.
*
* @channel: pointer to a channel obtained by channel_alloc
* @maxpacket: the maximum packet size
* @bMode: TRUE if mode 1; FALSE if mode 0
* @dma_addr: base address of data (in DMA space)
* @length: the number of bytes to transfer; no larger than the channel's
* reported dwMaxLength
*
* Returns TRUE on success, else FALSE
*/
typedef int (*MGC_pfDmaProgramChannel) (
struct dma_channel *channel,
u16 maxpacket,
u8 bMode,
dma_addr_t dma_addr,
u32 length);
/*
* dma_channel_status - return status of dma channel
* @c: the channel
*
* Returns the software's view of the channel status. If that status is BUSY
* then it's possible that the hardware has completed (or aborted) a transfer,
* so the driver needs to update that status.
*/
static inline enum dma_channel_status
dma_channel_status(struct dma_channel *c)
{
return (is_dma_capable() && c) ? c->bStatus : MGC_DMA_STATUS_UNKNOWN;
}
/**
* struct dma_controller - A DMA Controller.
* @pPrivateData: controller-private data;
* @start: call this to start a DMA controller;
* return 0 on success, else negative errno
* @stop: call this to stop a DMA controller
* return 0 on success, else negative errno
* @channel_alloc: call this to allocate a DMA channel
* @channel_release: call this to release a DMA channel
* @channel_abort: call this to abort a pending DMA transaction,
* returning it to FREE (but allocated) state
*
* Controllers manage dma channels.
*/
struct dma_controller {
void *pPrivateData;
int (*start)(struct dma_controller *);
int (*stop)(struct dma_controller *);
struct dma_channel *(*channel_alloc)(struct dma_controller *,
struct musb_hw_ep *, u8 is_tx);
void (*channel_release)(struct dma_channel *);
MGC_pfDmaProgramChannel channel_program;
int (*channel_abort)(struct dma_channel *);
};
/* called after channel_program(), may indicate a fault */
extern void musb_dma_completion(struct musb *musb, u8 bLocalEnd, u8 bTransmit);
/**
* struct dma_controller_factory - DMA controller factory
* @create: create a DMA controller
* @destroy: destroy a DMA controller
*
* To allow for multi-core implementations and different
* types of cores and DMA controllers to co-exist,
* (only at the source level; no runtime coexistence supported)
* it is necessary to create them from factories.
*/
struct dma_controller_factory {
struct dma_controller *(*create)(struct musb *, void __iomem *);
void (*destroy)(struct dma_controller *);
};
extern const struct dma_controller_factory dma_controller_factory;
#endif /* __MUSB_DMA_H__ */
This diff is collapsed.
This diff is collapsed.
/******************************************************************
* Copyright 2005 Mentor Graphics Corporation
* Copyright (C) 2005-2006 by Texas Instruments
*
* This file is part of the Inventra Controller Driver for Linux.
*
* The Inventra Controller Driver for Linux 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.
*
* The Inventra Controller Driver for Linux is distributed in
* the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License
* along with The Inventra Controller Driver for Linux ; if not,
* write to the Free Software Foundation, Inc., 59 Temple Place,
* Suite 330, Boston, MA 02111-1307 USA
*
* ANY DOWNLOAD, USE, REPRODUCTION, MODIFICATION OR DISTRIBUTION
* OF THIS DRIVER INDICATES YOUR COMPLETE AND UNCONDITIONAL ACCEPTANCE
* OF THOSE TERMS.THIS DRIVER IS PROVIDED "AS IS" AND MENTOR GRAPHICS
* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, RELATED TO THIS DRIVER.
* MENTOR GRAPHICS SPECIFICALLY DISCLAIMS ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY; FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT. MENTOR GRAPHICS DOES NOT PROVIDE SUPPORT
* SERVICES OR UPDATES FOR THIS DRIVER, EVEN IF YOU ARE A MENTOR
* GRAPHICS SUPPORT CUSTOMER.
******************************************************************/
#ifndef __MUSB_GADGET_H
#define __MUSB_GADGET_H
struct musb_request {
struct usb_request request;
struct musb_ep *ep;
struct musb *musb;
u8 bTx; /* endpoint direction */
u8 bEnd;
u8 mapped;
};
static inline struct musb_request *to_musb_request(struct usb_request *req)
{
return req ? container_of(req, struct musb_request, request) : NULL;
}
extern struct usb_request *
musb_alloc_request(struct usb_ep *ep, gfp_t gfp_flags);
extern void musb_free_request(struct usb_ep *ep, struct usb_request *req);
/*
* struct musb_ep - peripheral side view of endpoint rx or tx side
*/
struct musb_ep {
/* stuff towards the head is basically write-once. */
struct usb_ep end_point;
char name[12];
struct musb_hw_ep *hw_ep;
struct musb *pThis;
u8 bEndNumber;
/* ... when enabled/disabled ... */
u8 type;
u8 is_in;
u16 wPacketSize;
const struct usb_endpoint_descriptor *desc;
struct dma_channel *dma;
/* later things are modified based on usage */
struct list_head req_list;
u8 busy;
};
static inline struct musb_ep *to_musb_ep(struct usb_ep *ep)
{
return ep ? container_of(ep, struct musb_ep, end_point) : NULL;
}
static inline struct usb_request *next_request(struct musb_ep *ep)
{
struct list_head *queue = &ep->req_list;
if (list_empty(queue))
return NULL;
return container_of(queue->next, struct usb_request, list);
}
extern void musb_g_tx(struct musb *pThis, u8 bEnd);
extern void musb_g_rx(struct musb *pThis, u8 bEnd);
extern const struct usb_ep_ops musb_g_ep0_ops;
extern int musb_gadget_setup(struct musb *);
extern void musb_gadget_cleanup(struct musb *);
extern void musb_g_giveback(struct musb_ep *, struct usb_request *, int);
extern int musb_gadget_set_halt(struct usb_ep *ep, int value);
#endif /* __MUSB_GADGET_H */
This diff is collapsed.
/******************************************************************
* Copyright 2005 Mentor Graphics Corporation
* Copyright (C) 2005-2006 by Texas Instruments
*
* This file is part of the Inventra Controller Driver for Linux.
*
* The Inventra Controller Driver for Linux 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.
*
* The Inventra Controller Driver for Linux is distributed in
* the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License
* along with The Inventra Controller Driver for Linux ; if not,
* write to the Free Software Foundation, Inc., 59 Temple Place,
* Suite 330, Boston, MA 02111-1307 USA
*
* ANY DOWNLOAD, USE, REPRODUCTION, MODIFICATION OR DISTRIBUTION
* OF THIS DRIVER INDICATES YOUR COMPLETE AND UNCONDITIONAL ACCEPTANCE
* OF THOSE TERMS.THIS DRIVER IS PROVIDED "AS IS" AND MENTOR GRAPHICS
* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, RELATED TO THIS DRIVER.
* MENTOR GRAPHICS SPECIFICALLY DISCLAIMS ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY; FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT. MENTOR GRAPHICS DOES NOT PROVIDE SUPPORT
* SERVICES OR UPDATES FOR THIS DRIVER, EVEN IF YOU ARE A MENTOR
* GRAPHICS SUPPORT CUSTOMER.
******************************************************************/
#ifndef _MUSB_HOST_H
#define _MUSB_HOST_H
static inline struct usb_hcd *musb_to_hcd(struct musb *musb)
{
return (struct usb_hcd *) (((void *)musb)
- offsetof(struct usb_hcd, hcd_priv));
}
static inline struct musb *hcd_to_musb(struct usb_hcd *hcd)
{
return (void *) hcd->hcd_priv;
}
/* stored in "usb_host_endpoint.hcpriv" for scheduled endpoints
*/
struct musb_qh {
struct usb_host_endpoint *hep; /* usbcore info */
struct usb_device *dev;
struct musb_hw_ep *hw_ep; /* current binding */
struct list_head ring; /* of musb_qh */
//struct musb_qh *next; /* for periodic tree */
unsigned offset; /* in urb->transfer_buffer */
unsigned segsize; /* current xfer fragment */
u8 type_reg; /* {rx,tx} type register */
u8 intv_reg; /* {rx,tx} interval register */
u8 addr_reg; /* device address register */
u8 h_addr_reg; /* hub address register */
u8 h_port_reg; /* hub port register */
u8 is_ready; /* safe to modify hw_ep */
u8 type; /* XFERTYPE_* */
u8 epnum;
u16 maxpacket;
u16 frame; /* for periodic schedule */
unsigned iso_idx; /* in urb->iso_frame_desc[] */
};
/* map from control or bulk queue head to the first qh on that ring */
static inline struct musb_qh *first_qh(struct list_head *q)
{
if (list_empty(q))
return NULL;
return container_of(q->next, struct musb_qh, ring);
}
extern void musb_h_tx_start(struct musb *, u8 bEnd);
extern void musb_root_disconnect(struct musb *musb);
struct usb_hcd;
extern int musb_hub_status_data(struct usb_hcd *hcd, char *buf);
extern int musb_hub_control(struct usb_hcd *hcd,
u16 typeReq, u16 wValue, u16 wIndex,
char *buf, u16 wLength);
extern int musb_bus_suspend(struct usb_hcd *);
extern int musb_bus_resume(struct usb_hcd *);
extern const struct hc_driver musb_hc_driver;
static inline struct urb *next_urb(struct musb_qh *qh)
{
#ifdef CONFIG_USB_MUSB_HDRC_HCD
struct list_head *queue;
if (!qh)
return NULL;
queue = &qh->hep->urb_list;
if (list_empty(queue))
return NULL;
return container_of(queue->next, struct urb, urb_list);
#else
return NULL;
#endif
}
#endif /* _MUSB_HOST_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (C) 2005-2006 by Texas Instruments
*
* The Inventra Controller Driver for Linux 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.
*/
#ifndef __MUSB_OMAP243X_H__
#define __MUSB_OMAP243X_H__
#ifdef CONFIG_ARCH_OMAP243X
/*
* OMAP2430-specific definitions
*/
#define MENTOR_BASE_OFFSET 0
#define HS_OTG(offset) (OMAP243X_HS_BASE + (offset))
#define OTG_REVISION HS_OTG(0x400)
#define OTG_SYSCONFIG HS_OTG(0x404)
#define OTG_SYSSTATUS HS_OTG(0x408)
#define OTG_INTERFSEL HS_OTG(0x40c)
#define OTG_SIMENABLE HS_OTG(0x410)
#endif /* CONFIG_ARCH_OMAP243X */
#endif /* __MUSB_OMAP243X_H__ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -66,3 +66,11 @@ config BACKLIGHT_HP680
If you have a HP Jornada 680, say y to enable the
backlight driver.
config BACKLIGHT_OMAP
tristate "OMAP LCD Backlight"
depends on BACKLIGHT_DEVICE && (ARCH_OMAP1 || ARCH_OMAP2)
default y
help
This driver controls the LCD backlight level and power
for the PWL module of OMAP processors. Say Y if you plan
to use power saving.
......@@ -5,3 +5,4 @@ obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o
obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
obj-$(CONFIG_BACKLIGHT_OMAP) += omap_bl.o
This diff is collapsed.
......@@ -105,6 +105,14 @@ struct omap_lcd_config {
u8 data_lines;
};
struct device;
struct fb_info;
struct omap_backlight_config {
int default_intensity;
int (*set_power)(struct device *dev, int state);
int (*check_fb)(struct fb_info *fb);
};
struct omap_fbmem_config {
u32 start;
u32 size;
......
This diff is collapsed.
This diff is collapsed.
......@@ -56,9 +56,10 @@
#define INPUT_VOLUME_MAX 0x7D
#define INPUT_VOLUME_RANGE (INPUT_VOLUME_MAX - INPUT_VOLUME_MIN)
#define PLAYBACK_TARGET_COUNT 0x02
#define PLAYBACK_TARGET_COUNT 0x03
#define PLAYBACK_TARGET_LOUDSPEAKER 0x00
#define PLAYBACK_TARGET_HEADPHONE 0x01
#define PLAYBACK_TARGET_CELLPHONE 0x02
/* following are used for register 03h Mixer PGA control bits D7-D5 for selecting record source */
#define REC_SRC_TARGET_COUNT 0x08
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment