2008-01-08 10:52:04 +03:00
/*
* arch / arm / mach - pxa / pcm990 - baseboard . c
* Support for the Phytec phyCORE - PXA270 Development Platform ( PCM - 990 ) .
*
* Refer
* http : //www.phytec.com/products/rdk/ARM-XScale/phyCORE-XScale-PXA270.html
* for additional hardware info
*
* Author : Juergen Kilb
* Created : April 05 , 2005
* Copyright : Phytec Messtechnik GmbH
* e - Mail : armlinux @ phytec . de
*
* based on Intel Mainstone Board
*
* Copyright 2007 Juergen Beisert @ Pengutronix ( j . beisert @ pengutronix . de )
*
* 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/irq.h>
# include <linux/platform_device.h>
2008-04-07 01:08:15 +04:00
# include <linux/i2c.h>
2008-06-13 14:50:44 +04:00
# include <linux/pwm_backlight.h>
2008-04-07 01:08:15 +04:00
# include <media/soc_camera.h>
# include <asm/gpio.h>
2008-08-05 19:14:15 +04:00
# include <mach/i2c.h>
# include <mach/camera.h>
2008-01-08 10:52:04 +03:00
# include <asm/mach/map.h>
2008-08-05 19:14:15 +04:00
# include <mach/pxa-regs.h>
# include <mach/audio.h>
# include <mach/mmc.h>
# include <mach/ohci.h>
# include <mach/pcm990_baseboard.h>
# include <mach/pxafb.h>
# include <mach/mfp-pxa27x.h>
2008-06-13 14:50:44 +04:00
# include "devices.h"
2008-06-16 11:16:46 +04:00
# include "generic.h"
static unsigned long pcm990_pin_config [ ] __initdata = {
/* MMC */
GPIO32_MMC_CLK ,
GPIO112_MMC_CMD ,
GPIO92_MMC_DAT_0 ,
GPIO109_MMC_DAT_1 ,
GPIO110_MMC_DAT_2 ,
GPIO111_MMC_DAT_3 ,
/* USB */
GPIO88_USBH1_PWR ,
GPIO89_USBH1_PEN ,
/* PWM0 */
GPIO16_PWM0_OUT ,
2008-11-28 11:00:24 +03:00
/* I2C */
GPIO117_I2C_SCL ,
GPIO118_I2C_SDA ,
2008-06-16 11:16:46 +04:00
} ;
2008-06-13 14:50:44 +04:00
/*
* pcm990_lcd_power - control power supply to the LCD
* @ on : 0 = switch off , 1 = switch on
*
* Called by the pxafb driver
*/
# ifndef CONFIG_PCM990_DISPLAY_NONE
static void pcm990_lcd_power ( int on , struct fb_var_screeninfo * var )
{
if ( on ) {
/* enable LCD-Latches
* power on LCD
*/
__PCM990_CTRL_REG ( PCM990_CTRL_PHYS + PCM990_CTRL_REG3 ) =
PCM990_CTRL_LCDPWR + PCM990_CTRL_LCDON ;
} else {
/* disable LCD-Latches
* power off LCD
*/
__PCM990_CTRL_REG ( PCM990_CTRL_PHYS + PCM990_CTRL_REG3 ) = 0x00 ;
}
}
# endif
# if defined(CONFIG_PCM990_DISPLAY_SHARP)
static struct pxafb_mode_info fb_info_sharp_lq084v1dg21 = {
. pixclock = 28000 ,
. xres = 640 ,
. yres = 480 ,
. bpp = 16 ,
. hsync_len = 20 ,
. left_margin = 103 ,
. right_margin = 47 ,
. vsync_len = 6 ,
. upper_margin = 28 ,
. lower_margin = 5 ,
. sync = 0 ,
. cmap_greyscale = 0 ,
} ;
static struct pxafb_mach_info pcm990_fbinfo __initdata = {
. modes = & fb_info_sharp_lq084v1dg21 ,
. num_modes = 1 ,
2008-12-07 12:49:01 +03:00
. lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL ,
2008-06-13 14:50:44 +04:00
. pxafb_lcd_power = pcm990_lcd_power ,
} ;
# elif defined(CONFIG_PCM990_DISPLAY_NEC)
struct pxafb_mode_info fb_info_nec_nl6448bc20_18d = {
. pixclock = 39720 ,
. xres = 640 ,
. yres = 480 ,
. bpp = 16 ,
. hsync_len = 32 ,
. left_margin = 16 ,
. right_margin = 48 ,
. vsync_len = 2 ,
. upper_margin = 12 ,
. lower_margin = 17 ,
. sync = 0 ,
. cmap_greyscale = 0 ,
} ;
static struct pxafb_mach_info pcm990_fbinfo __initdata = {
. modes = & fb_info_nec_nl6448bc20_18d ,
. num_modes = 1 ,
2008-12-07 12:49:01 +03:00
. lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL ,
2008-06-13 14:50:44 +04:00
. pxafb_lcd_power = pcm990_lcd_power ,
} ;
# endif
static struct platform_pwm_backlight_data pcm990_backlight_data = {
. pwm_id = 0 ,
. max_brightness = 1023 ,
. dft_brightness = 1023 ,
. pwm_period_ns = 78770 ,
} ;
static struct platform_device pcm990_backlight_device = {
. name = " pwm-backlight " ,
. dev = {
. parent = & pxa27x_device_pwm0 . dev ,
. platform_data = & pcm990_backlight_data ,
} ,
} ;
2008-01-08 10:52:04 +03:00
/*
2008-06-13 14:50:44 +04:00
* The PCM - 990 development baseboard uses PCM - 027 ' s hardware in the
2008-01-08 10:52:04 +03:00
* following way :
*
* - LCD support is in use
* - GPIO16 is output for back light on / off with PWM
* - GPIO58 . . . GPIO73 are outputs for display data
* - GPIO74 is output output for LCDFCLK
* - GPIO75 is output for LCDLCLK
* - GPIO76 is output for LCDPCLK
* - GPIO77 is output for LCDBIAS
* - MMC support is in use
* - GPIO32 is output for MMCCLK
* - GPIO92 is MMDAT0
* - GPIO109 is MMDAT1
* - GPIO110 is MMCS0
* - GPIO111 is MMCS1
* - GPIO112 is MMCMD
* - IDE / CF card is in use
* - GPIO48 is output / POE
* - GPIO49 is output / PWE
* - GPIO50 is output / PIOR
* - GPIO51 is output / PIOW
* - GPIO54 is output / PCE2
* - GPIO55 is output / PREG
* - GPIO56 is input / PWAIT
* - GPIO57 is output / PIOS16
* - GPIO79 is output PSKTSEL
* - GPIO85 is output / PCE1
* - FFUART is in use
* - GPIO34 is input FFRXD
* - GPIO35 is input FFCTS
* - GPIO36 is input FFDCD
* - GPIO37 is input FFDSR
* - GPIO38 is input FFRI
* - GPIO39 is output FFTXD
* - GPIO40 is output FFDTR
* - GPIO41 is output FFRTS
* - BTUART is in use
* - GPIO42 is input BTRXD
* - GPIO43 is output BTTXD
* - GPIO44 is input BTCTS
* - GPIO45 is output BTRTS
* - IRUART is in use
* - GPIO46 is input STDRXD
* - GPIO47 is output STDTXD
* - AC97 is in use * )
* - GPIO28 is input AC97CLK
* - GPIO29 is input AC97DatIn
* - GPIO30 is output AC97DatO
* - GPIO31 is output AC97SYNC
* - GPIO113 is output AC97_RESET
* - SSP is in use
* - GPIO23 is output SSPSCLK
* - GPIO24 is output chip select to Max7301
* - GPIO25 is output SSPTXD
* - GPIO26 is input SSPRXD
* - GPIO27 is input for Max7301 IRQ
* - GPIO53 is input SSPSYSCLK
* - SSP3 is in use
* - GPIO81 is output SSPTXD3
* - GPIO82 is input SSPRXD3
* - GPIO83 is output SSPSFRM
* - GPIO84 is output SSPCLK3
*
* Otherwise claimed GPIOs :
* GPIO1 - > IRQ from user switch
* GPIO9 - > IRQ from power management
* GPIO10 - > IRQ from WML9712 AC97 controller
* GPIO11 - > IRQ from IDE controller
* GPIO12 - > IRQ from CF controller
* GPIO13 - > IRQ from CF controller
* GPIO14 - > GPIO free
* GPIO15 - > / CS1 selects baseboard ' s Control CPLD ( U7 , 16 bit wide data path )
* GPIO19 - > GPIO free
* GPIO20 - > / SDCS2
* GPIO21 - > / CS3 PC card socket select
* GPIO33 - > / CS5 network controller select
* GPIO78 - > / CS2 ( 16 bit wide data path )
* GPIO80 - > / CS4 ( 16 bit wide data path )
* GPIO86 - > GPIO free
* GPIO87 - > GPIO free
* GPIO90 - > LED0 on CPU module
* GPIO91 - > LED1 on CPI module
* GPIO117 - > SCL
* GPIO118 - > SDA
*/
static unsigned long pcm990_irq_enabled ;
static void pcm990_mask_ack_irq ( unsigned int irq )
{
int pcm990_irq = ( irq - PCM027_IRQ ( 0 ) ) ;
PCM990_INTMSKENA = ( pcm990_irq_enabled & = ~ ( 1 < < pcm990_irq ) ) ;
}
static void pcm990_unmask_irq ( unsigned int irq )
{
int pcm990_irq = ( irq - PCM027_IRQ ( 0 ) ) ;
/* the irq can be acknowledged only if deasserted, so it's done here */
PCM990_INTSETCLR | = 1 < < pcm990_irq ;
PCM990_INTMSKENA = ( pcm990_irq_enabled | = ( 1 < < pcm990_irq ) ) ;
}
static struct irq_chip pcm990_irq_chip = {
. mask_ack = pcm990_mask_ack_irq ,
. unmask = pcm990_unmask_irq ,
} ;
static void pcm990_irq_handler ( unsigned int irq , struct irq_desc * desc )
{
unsigned long pending = ( ~ PCM990_INTSETCLR ) & pcm990_irq_enabled ;
do {
GEDR ( PCM990_CTRL_INT_IRQ_GPIO ) =
GPIO_bit ( PCM990_CTRL_INT_IRQ_GPIO ) ;
if ( likely ( pending ) ) {
irq = PCM027_IRQ ( 0 ) + __ffs ( pending ) ;
2008-10-09 16:36:24 +04:00
generic_handle_irq ( irq ) ;
2008-01-08 10:52:04 +03:00
}
pending = ( ~ PCM990_INTSETCLR ) & pcm990_irq_enabled ;
} while ( pending ) ;
}
static void __init pcm990_init_irq ( void )
{
int irq ;
/* setup extra PCM990 irqs */
for ( irq = PCM027_IRQ ( 0 ) ; irq < = PCM027_IRQ ( 3 ) ; irq + + ) {
set_irq_chip ( irq , & pcm990_irq_chip ) ;
set_irq_handler ( irq , handle_level_irq ) ;
set_irq_flags ( irq , IRQF_VALID | IRQF_PROBE ) ;
}
PCM990_INTMSKENA = 0x00 ; /* disable all Interrupts */
PCM990_INTSETCLR = 0xFF ;
set_irq_chained_handler ( PCM990_CTRL_INT_IRQ , pcm990_irq_handler ) ;
set_irq_type ( PCM990_CTRL_INT_IRQ , PCM990_CTRL_INT_IRQ_EDGE ) ;
}
static int pcm990_mci_init ( struct device * dev , irq_handler_t mci_detect_int ,
void * data )
{
int err ;
err = request_irq ( PCM027_MMCDET_IRQ , mci_detect_int , IRQF_DISABLED ,
" MMC card detect " , data ) ;
if ( err )
printk ( KERN_ERR " pcm990_mci_init: MMC/SD: can't request MMC "
" card detect IRQ \n " ) ;
return err ;
}
static void pcm990_mci_setpower ( struct device * dev , unsigned int vdd )
{
struct pxamci_platform_data * p_d = dev - > platform_data ;
if ( ( 1 < < vdd ) & p_d - > ocr_mask )
__PCM990_CTRL_REG ( PCM990_CTRL_PHYS + PCM990_CTRL_REG5 ) =
PCM990_CTRL_MMC2PWR ;
else
__PCM990_CTRL_REG ( PCM990_CTRL_PHYS + PCM990_CTRL_REG5 ) =
~ PCM990_CTRL_MMC2PWR ;
}
static void pcm990_mci_exit ( struct device * dev , void * data )
{
free_irq ( PCM027_MMCDET_IRQ , data ) ;
}
# define MSECS_PER_JIFFY (1000 / HZ)
static struct pxamci_platform_data pcm990_mci_platform_data = {
. detect_delay = 250 / MSECS_PER_JIFFY ,
. ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34 ,
. init = pcm990_mci_init ,
. setpower = pcm990_mci_setpower ,
. exit = pcm990_mci_exit ,
} ;
static struct pxaohci_platform_data pcm990_ohci_platform_data = {
. port_mode = PMM_PERPORT_MODE ,
2008-09-27 11:49:57 +04:00
. flags = ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW ,
. power_on_delay = 10 ,
2008-01-08 10:52:04 +03:00
} ;
2008-04-07 01:08:15 +04:00
/*
* PXA27x Camera specific stuff
*/
# if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE)
2008-06-16 11:16:46 +04:00
static unsigned long pcm990_camera_pin_config [ ] = {
/* CIF */
GPIO98_CIF_DD_0 ,
GPIO105_CIF_DD_1 ,
GPIO104_CIF_DD_2 ,
GPIO103_CIF_DD_3 ,
GPIO95_CIF_DD_4 ,
GPIO94_CIF_DD_5 ,
GPIO93_CIF_DD_6 ,
GPIO108_CIF_DD_7 ,
GPIO107_CIF_DD_8 ,
GPIO106_CIF_DD_9 ,
GPIO42_CIF_MCLK ,
GPIO45_CIF_PCLK ,
GPIO43_CIF_FV ,
GPIO44_CIF_LV ,
} ;
2008-04-07 01:08:15 +04:00
static int pcm990_pxacamera_init ( struct device * dev )
{
2008-06-16 11:16:46 +04:00
pxa2xx_mfp_config ( ARRAY_AND_SIZE ( pcm990_camera_pin_config ) ) ;
2008-04-07 01:08:15 +04:00
return 0 ;
}
/*
* CICR4 : PCLK_EN : Pixel clock is supplied by the sensor
* MCLK_EN : Master clock is generated by PXA
* PCP : Data sampled on the falling edge of pixel clock
*/
struct pxacamera_platform_data pcm990_pxacamera_platform_data = {
. init = pcm990_pxacamera_init ,
. flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 | PXA_CAMERA_DATAWIDTH_10 |
PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN /* | PXA_CAMERA_PCP*/ ,
. mclk_10khz = 1000 ,
} ;
# include <linux/i2c/pca953x.h>
static struct pca953x_platform_data pca9536_data = {
. gpio_base = NR_BUILTIN_GPIO + 1 ,
} ;
static struct soc_camera_link iclink [ ] = {
{
. bus_id = 0 , /* Must match with the camera ID above */
. gpio = NR_BUILTIN_GPIO + 1 ,
} , {
. bus_id = 0 , /* Must match with the camera ID above */
2008-11-25 20:57:08 +03:00
. gpio = - ENXIO ,
2008-04-07 01:08:15 +04:00
}
} ;
/* Board I2C devices. */
static struct i2c_board_info __initdata pcm990_i2c_devices [ ] = {
{
/* Must initialize before the camera(s) */
2008-04-30 01:11:40 +04:00
I2C_BOARD_INFO ( " pca9536 " , 0x41 ) ,
2008-04-07 01:08:15 +04:00
. platform_data = & pca9536_data ,
} , {
I2C_BOARD_INFO ( " mt9v022 " , 0x48 ) ,
. platform_data = & iclink [ 0 ] , /* With extender */
} , {
I2C_BOARD_INFO ( " mt9m001 " , 0x5d ) ,
. platform_data = & iclink [ 0 ] , /* With extender */
} ,
} ;
# endif /* CONFIG_VIDEO_PXA27x ||CONFIG_VIDEO_PXA27x_MODULE */
2008-01-08 10:52:04 +03:00
/*
* enable generic access to the base board control CPLDs U6 and U7
*/
static struct map_desc pcm990_io_desc [ ] __initdata = {
{
. virtual = PCM990_CTRL_BASE ,
. pfn = __phys_to_pfn ( PCM990_CTRL_PHYS ) ,
. length = PCM990_CTRL_SIZE ,
. type = MT_DEVICE /* CPLD */
} , {
. virtual = PCM990_CF_PLD_BASE ,
. pfn = __phys_to_pfn ( PCM990_CF_PLD_PHYS ) ,
. length = PCM990_CF_PLD_SIZE ,
. type = MT_DEVICE /* CPLD */
}
} ;
/*
* system init for baseboard usage . Will be called by pcm027 init .
*
* Add platform devices present on this baseboard and init
* them from CPU side as far as required to use them later on
*/
void __init pcm990_baseboard_init ( void )
{
2008-06-16 11:16:46 +04:00
pxa2xx_mfp_config ( ARRAY_AND_SIZE ( pcm990_pin_config ) ) ;
2008-01-08 10:52:04 +03:00
/* register CPLD access */
2008-06-16 11:16:46 +04:00
iotable_init ( ARRAY_AND_SIZE ( pcm990_io_desc ) ) ;
2008-01-08 10:52:04 +03:00
/* register CPLD's IRQ controller */
pcm990_init_irq ( ) ;
2008-06-13 14:50:44 +04:00
# ifndef CONFIG_PCM990_DISPLAY_NONE
set_pxa_fb_info ( & pcm990_fbinfo ) ;
# endif
platform_device_register ( & pcm990_backlight_device ) ;
2008-01-08 10:52:04 +03:00
/* MMC */
pxa_set_mci_info ( & pcm990_mci_platform_data ) ;
/* USB host */
pxa_set_ohci_info ( & pcm990_ohci_platform_data ) ;
2008-04-07 01:08:15 +04:00
pxa_set_i2c_info ( NULL ) ;
2008-06-10 15:30:05 +04:00
pxa_set_ac97_info ( NULL ) ;
2008-04-07 01:08:15 +04:00
# if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE)
pxa_set_camera_info ( & pcm990_pxacamera_platform_data ) ;
2008-06-16 11:16:46 +04:00
i2c_register_board_info ( 0 , ARRAY_AND_SIZE ( pcm990_i2c_devices ) ) ;
2008-04-07 01:08:15 +04:00
# endif
2008-06-16 11:16:46 +04:00
printk ( KERN_INFO " PCM-990 Evaluation baseboard initialized \n " ) ;
2008-01-08 10:52:04 +03:00
}