2005-04-16 15:20:36 -07:00
/*
2005-07-10 19:58:11 +01:00
* linux / arch / arm / mach - omap1 / board - innovator . c
2005-04-16 15:20:36 -07:00
*
* Board specific inits for OMAP - 1510 and OMAP - 1610 Innovator
*
* Copyright ( C ) 2001 RidgeRun , Inc .
* Author : Greg Lonnon < glonnon @ ridgerun . com >
*
* Copyright ( C ) 2002 MontaVista Software , Inc .
*
* Separated FPGA interrupts from innovator1510 . c and cleaned up for 2.6
* Copyright ( C ) 2004 Nokia Corporation by Tony Lindrgen < 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 .
*/
2011-07-26 10:53:52 +01:00
# include <linux/gpio.h>
2005-04-16 15:20:36 -07:00
# include <linux/kernel.h>
# include <linux/init.h>
2005-10-29 19:07:23 +01:00
# include <linux/platform_device.h>
2005-04-16 15:20:36 -07:00
# include <linux/delay.h>
# include <linux/mtd/mtd.h>
# include <linux/mtd/partitions.h>
2010-02-15 10:03:32 -08:00
# include <linux/mtd/physmap.h>
2006-04-02 17:46:30 +01:00
# include <linux/input.h>
2009-12-11 16:16:33 -08:00
# include <linux/smc91x.h>
2011-09-20 15:23:13 +03:00
# include <linux/omapfb.h>
2005-04-16 15:20:36 -07:00
# include <asm/mach-types.h>
# include <asm/mach/arch.h>
# include <asm/mach/map.h>
2012-09-19 10:46:56 -07:00
# include <mach/mux.h>
2012-09-20 11:41:37 -07:00
# include <mach/flash.h>
2012-10-02 13:39:28 -07:00
# include <mach/tc.h>
2012-08-24 15:21:06 +02:00
# include <linux/platform_data/keypad-omap.h>
2005-04-16 15:20:36 -07:00
2012-02-24 10:34:34 -08:00
# include <mach/hardware.h>
2012-06-04 00:56:15 -07:00
# include <mach/usb.h>
2012-02-24 10:34:34 -08:00
# include "iomap.h"
# include "common.h"
2012-10-15 12:09:43 -07:00
# include "mmc.h"
2012-02-24 10:34:34 -08:00
2009-03-23 18:07:34 -07:00
/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
# define INNOVATOR1610_ETHR_START 0x04000300
2010-12-20 21:09:22 +00:00
static const unsigned int innovator_keymap [ ] = {
2006-04-02 17:46:30 +01:00
KEY ( 0 , 0 , KEY_F1 ) ,
2010-12-20 21:09:22 +00:00
KEY ( 3 , 0 , KEY_DOWN ) ,
2006-04-02 17:46:30 +01:00
KEY ( 1 , 1 , KEY_F2 ) ,
2010-12-20 21:09:22 +00:00
KEY ( 2 , 1 , KEY_RIGHT ) ,
KEY ( 0 , 2 , KEY_F3 ) ,
KEY ( 1 , 2 , KEY_F4 ) ,
2006-04-02 17:46:30 +01:00
KEY ( 2 , 2 , KEY_UP ) ,
2010-12-20 21:09:22 +00:00
KEY ( 2 , 3 , KEY_ENTER ) ,
2006-04-02 17:46:30 +01:00
KEY ( 3 , 3 , KEY_LEFT ) ,
} ;
2005-04-16 15:20:36 -07:00
static struct mtd_partition innovator_partitions [ ] = {
/* bootloader (U-Boot, etc) in first sector */
{
. name = " bootloader " ,
. offset = 0 ,
. size = SZ_128K ,
. mask_flags = MTD_WRITEABLE , /* force read-only */
} ,
/* bootloader params in the next sector */
{
. name = " params " ,
. offset = MTDPART_OFS_APPEND ,
. size = SZ_128K ,
. mask_flags = 0 ,
} ,
/* kernel */
{
. name = " kernel " ,
. offset = MTDPART_OFS_APPEND ,
. size = SZ_2M ,
. mask_flags = 0
} ,
/* rest of flash1 is a file system */
{
. name = " rootfs " ,
. offset = MTDPART_OFS_APPEND ,
. size = SZ_16M - SZ_2M - 2 * SZ_128K ,
. mask_flags = 0
} ,
/* file system */
{
. name = " filesystem " ,
. offset = MTDPART_OFS_APPEND ,
. size = MTDPART_SIZ_FULL ,
. mask_flags = 0
}
} ;
2010-02-15 10:03:32 -08:00
static struct physmap_flash_data innovator_flash_data = {
2005-04-16 15:20:36 -07:00
. width = 2 ,
2010-02-15 10:03:32 -08:00
. set_vpp = omap1_set_vpp ,
2005-04-16 15:20:36 -07:00
. parts = innovator_partitions ,
. nr_parts = ARRAY_SIZE ( innovator_partitions ) ,
} ;
static struct resource innovator_flash_resource = {
. start = OMAP_CS0_PHYS ,
. end = OMAP_CS0_PHYS + SZ_32M - 1 ,
. flags = IORESOURCE_MEM ,
} ;
static struct platform_device innovator_flash_device = {
2010-02-15 10:03:32 -08:00
. name = " physmap-flash " ,
2005-04-16 15:20:36 -07:00
. id = 0 ,
. dev = {
. platform_data = & innovator_flash_data ,
} ,
. num_resources = 1 ,
. resource = & innovator_flash_resource ,
} ;
2006-04-02 17:46:30 +01:00
static struct resource innovator_kp_resources [ ] = {
[ 0 ] = {
. start = INT_KEYBOARD ,
. end = INT_KEYBOARD ,
. flags = IORESOURCE_IRQ ,
} ,
} ;
2010-12-20 21:09:22 +00:00
static const struct matrix_keymap_data innovator_keymap_data = {
. keymap = innovator_keymap ,
. keymap_size = ARRAY_SIZE ( innovator_keymap ) ,
} ;
2006-04-02 17:46:30 +01:00
static struct omap_kp_platform_data innovator_kp_data = {
2006-09-29 01:59:20 -07:00
. rows = 8 ,
. cols = 8 ,
2010-12-20 21:09:22 +00:00
. keymap_data = & innovator_keymap_data ,
2006-09-29 01:59:20 -07:00
. delay = 4 ,
2006-04-02 17:46:30 +01:00
} ;
static struct platform_device innovator_kp_device = {
. name = " omap-keypad " ,
. id = - 1 ,
. dev = {
. platform_data = & innovator_kp_data ,
} ,
. num_resources = ARRAY_SIZE ( innovator_kp_resources ) ,
. resource = innovator_kp_resources ,
} ;
2009-12-11 16:16:33 -08:00
static struct smc91x_platdata innovator_smc91x_info = {
. flags = SMC91X_USE_16BIT | SMC91X_NOWAIT ,
. leda = RPC_LED_100_10 ,
. ledb = RPC_LED_TX_RX ,
} ;
2006-04-02 17:46:30 +01:00
2005-11-10 14:26:48 +00:00
# ifdef CONFIG_ARCH_OMAP15XX
2005-04-16 15:20:36 -07:00
2006-06-26 16:16:09 -07:00
# include <linux/spi/spi.h>
# include <linux/spi/ads7846.h>
2005-04-16 15:20:36 -07:00
/* Only FPGA needs to be mapped here. All others are done with ioremap */
static struct map_desc innovator1510_io_desc [ ] __initdata = {
2005-10-28 15:19:00 +01:00
{
. virtual = OMAP1510_FPGA_BASE ,
. pfn = __phys_to_pfn ( OMAP1510_FPGA_START ) ,
. length = OMAP1510_FPGA_SIZE ,
. type = MT_DEVICE
}
2005-04-16 15:20:36 -07:00
} ;
static struct resource innovator1510_smc91x_resources [ ] = {
[ 0 ] = {
. start = OMAP1510_FPGA_ETHR_START , /* Physical */
. end = OMAP1510_FPGA_ETHR_START + 0xf ,
. flags = IORESOURCE_MEM ,
} ,
[ 1 ] = {
. start = OMAP1510_INT_ETHER ,
. end = OMAP1510_INT_ETHER ,
2008-01-14 22:30:10 +00:00
. flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE ,
2005-04-16 15:20:36 -07:00
} ,
} ;
static struct platform_device innovator1510_smc91x_device = {
. name = " smc91x " ,
. id = 0 ,
2009-12-11 16:16:33 -08:00
. dev = {
. platform_data = & innovator_smc91x_info ,
} ,
2005-04-16 15:20:36 -07:00
. num_resources = ARRAY_SIZE ( innovator1510_smc91x_resources ) ,
. resource = innovator1510_smc91x_resources ,
} ;
2006-04-02 17:46:30 +01:00
static struct platform_device innovator1510_lcd_device = {
. name = " lcd_inn1510 " ,
. id = - 1 ,
} ;
2006-06-26 16:16:09 -07:00
static struct platform_device innovator1510_spi_device = {
. name = " spi_inn1510 " ,
. id = - 1 ,
} ;
2005-04-16 15:20:36 -07:00
static struct platform_device * innovator1510_devices [ ] __initdata = {
& innovator_flash_device ,
& innovator1510_smc91x_device ,
2006-04-02 17:46:30 +01:00
& innovator_kp_device ,
& innovator1510_lcd_device ,
2006-06-26 16:16:09 -07:00
& innovator1510_spi_device ,
2005-04-16 15:20:36 -07:00
} ;
2006-06-26 16:16:09 -07:00
static int innovator_get_pendown_state ( void )
{
2012-10-02 12:39:09 -07:00
return ! ( __raw_readb ( OMAP1510_FPGA_TOUCHSCREEN ) & ( 1 < < 5 ) ) ;
2006-06-26 16:16:09 -07:00
}
static const struct ads7846_platform_data innovator1510_ts_info = {
. model = 7846 ,
. vref_delay_usecs = 100 , /* internal, no capacitor */
. x_plate_ohms = 419 ,
. y_plate_ohms = 486 ,
. get_pendown_state = innovator_get_pendown_state ,
} ;
static struct spi_board_info __initdata innovator1510_boardinfo [ ] = { {
/* FPGA (bus "10") CS0 has an ads7846e */
. modalias = " ads7846 " ,
. platform_data = & innovator1510_ts_info ,
. irq = OMAP1510_INT_FPGA_TS ,
. max_speed_hz = 120000 /* max sample rate at 3V */
* 26 /* command + data + overhead */ ,
. bus_num = 10 ,
. chip_select = 0 ,
} } ;
2005-11-10 14:26:48 +00:00
# endif /* CONFIG_ARCH_OMAP15XX */
2005-04-16 15:20:36 -07:00
# ifdef CONFIG_ARCH_OMAP16XX
static struct resource innovator1610_smc91x_resources [ ] = {
[ 0 ] = {
. start = INNOVATOR1610_ETHR_START , /* Physical */
. end = INNOVATOR1610_ETHR_START + 0xf ,
. flags = IORESOURCE_MEM ,
} ,
[ 1 ] = {
2008-01-14 22:30:10 +00:00
. flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE ,
2005-04-16 15:20:36 -07:00
} ,
} ;
static struct platform_device innovator1610_smc91x_device = {
. name = " smc91x " ,
. id = 0 ,
2009-12-11 16:16:33 -08:00
. dev = {
. platform_data = & innovator_smc91x_info ,
} ,
2005-04-16 15:20:36 -07:00
. num_resources = ARRAY_SIZE ( innovator1610_smc91x_resources ) ,
. resource = innovator1610_smc91x_resources ,
} ;
2006-04-02 17:46:30 +01:00
static struct platform_device innovator1610_lcd_device = {
. name = " inn1610_lcd " ,
. id = - 1 ,
} ;
2005-04-16 15:20:36 -07:00
static struct platform_device * innovator1610_devices [ ] __initdata = {
& innovator_flash_device ,
& innovator1610_smc91x_device ,
2006-04-02 17:46:30 +01:00
& innovator_kp_device ,
& innovator1610_lcd_device ,
2005-04-16 15:20:36 -07:00
} ;
# endif /* CONFIG_ARCH_OMAP16XX */
static void __init innovator_init_smc91x ( void )
{
if ( cpu_is_omap1510 ( ) ) {
2012-10-02 12:39:09 -07:00
__raw_writeb ( __raw_readb ( OMAP1510_FPGA_RST ) & ~ 1 ,
2005-04-16 15:20:36 -07:00
OMAP1510_FPGA_RST ) ;
udelay ( 750 ) ;
} else {
2008-12-10 17:35:30 -08:00
if ( gpio_request ( 0 , " SMC91x irq " ) < 0 ) {
2005-04-16 15:20:36 -07:00
printk ( " Error requesting gpio 0 for smc91x irq \n " ) ;
return ;
}
}
}
2005-11-10 14:26:48 +00:00
# ifdef CONFIG_ARCH_OMAP15XX
2005-04-16 15:20:36 -07:00
static struct omap_usb_config innovator1510_usb_config __initdata = {
/* for bundled non-standard host and peripheral cables */
. hmc_mode = 4 ,
. register_host = 1 ,
. pins [ 1 ] = 6 ,
. pins [ 2 ] = 6 , /* Conflicts with UART2 */
. register_dev = 1 ,
. pins [ 0 ] = 2 ,
} ;
2005-11-10 14:26:48 +00:00
static struct omap_lcd_config innovator1510_lcd_config __initdata = {
. ctrl_name = " internal " ,
} ;
2005-04-16 15:20:36 -07:00
# endif
# ifdef CONFIG_ARCH_OMAP16XX
static struct omap_usb_config h2_usb_config __initdata = {
/* usb1 has a Mini-AB port and external isp1301 transceiver */
. otg = 2 ,
2014-05-16 12:00:57 +02:00
# if IS_ENABLED(CONFIG_USB_OMAP)
2007-12-13 22:27:15 -04:00
. hmc_mode = 19 , /* 0:host(off) 1:dev|otg 2:disabled */
/* .hmc_mode = 21,*/ /* 0:host(off) 1:dev(loopback) 2:host(loopback) */
2005-04-16 15:20:36 -07:00
# elif defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
/* NONSTANDARD CABLE NEEDED (B-to-Mini-B) */
2007-12-13 22:27:15 -04:00
. hmc_mode = 20 , /* 1:dev|otg(off) 1:host 2:disabled */
2005-04-16 15:20:36 -07:00
# endif
. pins [ 1 ] = 3 ,
} ;
2005-11-10 14:26:48 +00:00
static struct omap_lcd_config innovator1610_lcd_config __initdata = {
. ctrl_name = " internal " ,
} ;
2005-04-16 15:20:36 -07:00
# endif
2008-12-10 17:37:16 -08:00
# if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
static int mmc_set_power ( struct device * dev , int slot , int power_on ,
int vdd )
{
if ( power_on )
2012-10-02 12:39:09 -07:00
__raw_writeb ( __raw_readb ( OMAP1510_FPGA_POWER ) | ( 1 < < 3 ) ,
2008-12-10 17:37:16 -08:00
OMAP1510_FPGA_POWER ) ;
else
2012-10-02 12:39:09 -07:00
__raw_writeb ( __raw_readb ( OMAP1510_FPGA_POWER ) & ~ ( 1 < < 3 ) ,
2008-12-10 17:37:16 -08:00
OMAP1510_FPGA_POWER ) ;
return 0 ;
}
/*
* Innovator could use the following functions tested :
* - mmc_get_wp that uses OMAP_MPUIO ( 3 )
* - mmc_get_cover_state that uses FPGA F4 UIO43
*/
static struct omap_mmc_platform_data mmc1_data = {
. nr_slots = 1 ,
. slots [ 0 ] = {
. set_power = mmc_set_power ,
2008-12-10 17:37:17 -08:00
. wires = 4 ,
2008-12-10 17:37:16 -08:00
. name = " mmcblk " ,
2005-09-08 23:07:38 +01:00
} ,
} ;
2008-12-10 17:37:16 -08:00
static struct omap_mmc_platform_data * mmc_data [ OMAP16XX_NR_MMC ] ;
2011-01-27 16:39:44 -08:00
static void __init innovator_mmc_init ( void )
2008-12-10 17:37:16 -08:00
{
mmc_data [ 0 ] = & mmc1_data ;
omap1_init_mmc ( mmc_data , OMAP15XX_NR_MMC ) ;
}
# else
static inline void innovator_mmc_init ( void )
{
}
# endif
2005-04-16 15:20:36 -07:00
static void __init innovator_init ( void )
{
2010-12-17 18:37:08 -08:00
if ( cpu_is_omap1510 ( ) )
omap1510_fpga_init_irq ( ) ;
2010-12-07 16:26:55 -08:00
innovator_init_smc91x ( ) ;
2005-11-10 14:26:48 +00:00
# ifdef CONFIG_ARCH_OMAP15XX
2005-04-16 15:20:36 -07:00
if ( cpu_is_omap1510 ( ) ) {
2009-10-22 14:47:42 -07:00
unsigned char reg ;
/* mux pins for uarts */
omap_cfg_reg ( UART1_TX ) ;
omap_cfg_reg ( UART1_RTS ) ;
omap_cfg_reg ( UART2_TX ) ;
omap_cfg_reg ( UART2_RTS ) ;
omap_cfg_reg ( UART3_TX ) ;
omap_cfg_reg ( UART3_RX ) ;
2012-10-02 12:39:09 -07:00
reg = __raw_readb ( OMAP1510_FPGA_POWER ) ;
2009-10-22 14:47:42 -07:00
reg | = OMAP1510_FPGA_PCR_COM1_EN ;
2012-10-02 12:39:09 -07:00
__raw_writeb ( reg , OMAP1510_FPGA_POWER ) ;
2009-10-22 14:47:42 -07:00
udelay ( 10 ) ;
2012-10-02 12:39:09 -07:00
reg = __raw_readb ( OMAP1510_FPGA_POWER ) ;
2009-10-22 14:47:42 -07:00
reg | = OMAP1510_FPGA_PCR_COM2_EN ;
2012-10-02 12:39:09 -07:00
__raw_writeb ( reg , OMAP1510_FPGA_POWER ) ;
2009-10-22 14:47:42 -07:00
udelay ( 10 ) ;
2005-04-16 15:20:36 -07:00
platform_add_devices ( innovator1510_devices , ARRAY_SIZE ( innovator1510_devices ) ) ;
2006-06-26 16:16:09 -07:00
spi_register_board_info ( innovator1510_boardinfo ,
ARRAY_SIZE ( innovator1510_boardinfo ) ) ;
2005-04-16 15:20:36 -07:00
}
# endif
# ifdef CONFIG_ARCH_OMAP16XX
if ( ! cpu_is_omap1510 ( ) ) {
2012-03-29 08:41:01 -07:00
innovator1610_smc91x_resources [ 1 ] . start = gpio_to_irq ( 0 ) ;
innovator1610_smc91x_resources [ 1 ] . end = gpio_to_irq ( 0 ) ;
2005-04-16 15:20:36 -07:00
platform_add_devices ( innovator1610_devices , ARRAY_SIZE ( innovator1610_devices ) ) ;
}
# endif
2005-11-10 14:26:48 +00:00
# ifdef CONFIG_ARCH_OMAP15XX
if ( cpu_is_omap1510 ( ) ) {
2010-07-05 16:31:30 +03:00
omap1_usb_init ( & innovator1510_usb_config ) ;
2011-09-20 15:23:13 +03:00
omapfb_set_lcd_config ( & innovator1510_lcd_config ) ;
2005-11-10 14:26:48 +00:00
}
2005-04-16 15:20:36 -07:00
# endif
# ifdef CONFIG_ARCH_OMAP16XX
2005-11-10 14:26:48 +00:00
if ( cpu_is_omap1610 ( ) ) {
2010-07-05 16:31:30 +03:00
omap1_usb_init ( & h2_usb_config ) ;
2011-09-20 15:23:13 +03:00
omapfb_set_lcd_config ( & innovator1610_lcd_config ) ;
2005-11-10 14:26:48 +00:00
}
2005-04-16 15:20:36 -07:00
# endif
2005-11-10 14:26:48 +00:00
omap_serial_init ( ) ;
2007-11-07 06:54:32 +02:00
omap_register_i2c_bus ( 1 , 100 , NULL , 0 ) ;
2008-12-10 17:37:16 -08:00
innovator_mmc_init ( ) ;
2005-04-16 15:20:36 -07:00
}
2011-10-05 15:14:02 -07:00
/*
* REVISIT : Assume 15 xx for now , we don ' t want to do revision check
* until later on . The right way to fix this is to set up a different
* machine_id for 16 xx Innovator , or use device tree .
*/
2005-04-16 15:20:36 -07:00
static void __init innovator_map_io ( void )
{
2012-10-02 12:39:09 -07:00
# ifdef CONFIG_ARCH_OMAP15XX
2011-10-05 15:14:02 -07:00
omap15xx_map_io ( ) ;
2005-04-16 15:20:36 -07:00
2011-10-05 15:14:02 -07:00
iotable_init ( innovator1510_io_desc , ARRAY_SIZE ( innovator1510_io_desc ) ) ;
udelay ( 10 ) ; /* Delay needed for FPGA */
/* Dump the Innovator FPGA rev early - useful info for support. */
pr_debug ( " Innovator FPGA Rev %d.%d Board Rev %d \n " ,
2012-10-02 12:39:09 -07:00
__raw_readb ( OMAP1510_FPGA_REV_HIGH ) ,
__raw_readb ( OMAP1510_FPGA_REV_LOW ) ,
__raw_readb ( OMAP1510_FPGA_BOARD_REV ) ) ;
# endif
2005-04-16 15:20:36 -07:00
}
MACHINE_START ( OMAP_INNOVATOR , " TI-Innovator " )
2005-07-03 17:38:58 +01:00
/* Maintainer: MontaVista Software, Inc. */
2011-07-05 22:38:15 -04:00
. atag_offset = 0x100 ,
2005-07-03 17:38:58 +01:00
. map_io = innovator_map_io ,
2011-10-05 15:14:02 -07:00
. init_early = omap1_init_early ,
. init_irq = omap1_init_irq ,
2005-07-03 17:38:58 +01:00
. init_machine = innovator_init ,
2012-04-26 13:49:29 +08:00
. init_late = omap1_init_late ,
2012-11-08 12:40:59 -07:00
. init_time = omap1_timer_init ,
2011-11-05 17:06:28 +00:00
. restart = omap1_restart ,
2005-04-16 15:20:36 -07:00
MACHINE_END