2009-06-08 12:55:35 +02:00
/*
* Board - specific setup code for Remote Media Terminal 1 ( RMT1 )
* add - on board for the ATNGW100 Network Gateway
*
* Copyright ( C ) 2008 Mediama Technologies
* Based on ATNGW100 Network Gateway ( Copyright ( C ) Atmel )
*
* 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/gpio.h>
# include <linux/init.h>
# include <linux/irq.h>
# include <linux/linkage.h>
# include <linux/platform_device.h>
# include <linux/types.h>
# include <linux/fb.h>
# include <linux/leds.h>
2014-05-29 01:20:12 +02:00
# include <linux/pwm.h>
# include <linux/leds_pwm.h>
2009-06-08 12:55:35 +02:00
# include <linux/input.h>
# include <linux/gpio_keys.h>
# include <linux/atmel_serial.h>
# include <linux/spi/spi.h>
# include <linux/spi/ads7846.h>
# include <video/atmel_lcdc.h>
# include <sound/atmel-ac97c.h>
# include <asm/delay.h>
# include <asm/io.h>
# include <asm/setup.h>
# include <mach/at32ap700x.h>
# include <mach/board.h>
# include <mach/init.h>
# include <mach/portmux.h>
/* Define board-specifoic GPIO assignments */
# define PIN_LCD_BL GPIO_PIN_PA(28)
# define PWM_CH_BL 0 /* Must match with GPIO pin definition */
# define PIN_LCD_DISP GPIO_PIN_PA(31)
# define PIN_AC97_RST_N GPIO_PIN_PA(30)
# define PB_EXTINT_BASE 25
# define TS_IRQ 0
# define PIN_TS_EXTINT GPIO_PIN_PB(PB_EXTINT_BASE+TS_IRQ)
# define PIN_PB_LEFT GPIO_PIN_PB(11)
# define PIN_PB_RIGHT GPIO_PIN_PB(12)
# define PIN_PWR_SW_N GPIO_PIN_PB(14)
# define PIN_PWR_ON GPIO_PIN_PB(13)
# define PIN_ZB_RST_N GPIO_PIN_PA(21)
# define PIN_BT_RST GPIO_PIN_PA(22)
# define PIN_LED_SYS GPIO_PIN_PA(16)
# define PIN_LED_A GPIO_PIN_PA(19)
# define PIN_LED_B GPIO_PIN_PE(19)
# ifdef CONFIG_BOARD_MRMT_LCD_LQ043T3DX0X
/* Sharp LQ043T3DX0x (or compatible) panel */
static struct fb_videomode __initdata lcd_fb_modes [ ] = {
{
. name = " 480x272 @ 59.94Hz " ,
. refresh = 59.94 ,
. xres = 480 , . yres = 272 ,
. pixclock = KHZ2PICOS ( 9000 ) ,
. left_margin = 2 , . right_margin = 2 ,
. upper_margin = 3 , . lower_margin = 9 ,
. hsync_len = 41 , . vsync_len = 1 ,
. sync = 0 ,
. vmode = FB_VMODE_NONINTERLACED ,
} ,
} ;
static struct fb_monspecs __initdata lcd_fb_default_monspecs = {
. manufacturer = " SHA " ,
. monitor = " LQ043T3DX02 " ,
. modedb = lcd_fb_modes ,
. modedb_len = ARRAY_SIZE ( lcd_fb_modes ) ,
. hfmin = 14915 ,
. hfmax = 17638 ,
. vfmin = 53 ,
. vfmax = 61 ,
. dclkmax = 9260000 ,
} ;
2013-03-28 22:53:42 +08:00
static struct atmel_lcdfb_pdata __initdata rmt_lcdc_data = {
2009-06-08 12:55:35 +02:00
. default_bpp = 24 ,
. default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN ,
. default_lcdcon2 = ( ATMEL_LCDC_DISTYPE_TFT
| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
| ATMEL_LCDC_INVCLK_NORMAL
| ATMEL_LCDC_MEMOR_BIG ) ,
. lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB ,
. default_monspecs = & lcd_fb_default_monspecs ,
. guard_time = 2 ,
} ;
# endif
# ifdef CONFIG_BOARD_MRMT_LCD_KWH043GM08
/* Sharp KWH043GM08-Fxx (or compatible) panel */
static struct fb_videomode __initdata lcd_fb_modes [ ] = {
{
. name = " 480x272 @ 59.94Hz " ,
. refresh = 59.94 ,
. xres = 480 , . yres = 272 ,
. pixclock = KHZ2PICOS ( 9000 ) ,
. left_margin = 2 , . right_margin = 2 ,
. upper_margin = 3 , . lower_margin = 9 ,
. hsync_len = 41 , . vsync_len = 1 ,
. sync = 0 ,
. vmode = FB_VMODE_NONINTERLACED ,
} ,
} ;
static struct fb_monspecs __initdata lcd_fb_default_monspecs = {
. manufacturer = " FOR " ,
. monitor = " KWH043GM08 " ,
. modedb = lcd_fb_modes ,
. modedb_len = ARRAY_SIZE ( lcd_fb_modes ) ,
. hfmin = 14915 ,
. hfmax = 17638 ,
. vfmin = 53 ,
. vfmax = 61 ,
. dclkmax = 9260000 ,
} ;
2013-03-28 22:53:42 +08:00
static struct atmel_lcdfb_pdata __initdata rmt_lcdc_data = {
2009-06-08 12:55:35 +02:00
. default_bpp = 24 ,
. default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN ,
. default_lcdcon2 = ( ATMEL_LCDC_DISTYPE_TFT
| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
| ATMEL_LCDC_INVCLK_INVERTED
| ATMEL_LCDC_MEMOR_BIG ) ,
. lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB ,
. default_monspecs = & lcd_fb_default_monspecs ,
. guard_time = 2 ,
} ;
# endif
# ifdef CONFIG_BOARD_MRMT_AC97
static struct ac97c_platform_data __initdata ac97c0_data = {
. reset_pin = PIN_AC97_RST_N ,
} ;
# endif
# ifdef CONFIG_BOARD_MRMT_UCB1400_TS
/* NOTE: IRQ assignment relies on kernel module parameter */
static struct platform_device rmt_ts_device = {
. name = " ucb1400_ts " ,
. id = - 1 ,
} ;
# endif
# ifdef CONFIG_BOARD_MRMT_BL_PWM
/* PWM LEDs: LCD Backlight, etc */
2014-05-29 01:20:12 +02:00
static struct pwm_lookup pwm_lookup [ ] = {
PWM_LOOKUP ( " at91sam9rl-pwm " , PWM_CH_BL , " leds_pwm " , " ds1 " ,
5000 , PWM_POLARITY_INVERSED ) ,
2009-06-08 12:55:35 +02:00
} ;
2014-05-29 01:20:12 +02:00
static struct led_pwm pwm_leds [ ] = {
{
. name = " backlight " ,
. max_brightness = 255 ,
} ,
} ;
static struct led_pwm_platform_data pwm_data = {
. num_leds = ARRAY_SIZE ( pwm_leds ) ,
. leds = pwm_leds ,
2009-06-08 12:55:35 +02:00
} ;
2014-05-29 01:20:12 +02:00
static struct platform_device leds_pwm = {
. name = " leds_pwm " ,
. id = - 1 ,
. dev = {
. platform_data = & pwm_data ,
2009-06-08 12:55:35 +02:00
} ,
} ;
# endif
# ifdef CONFIG_BOARD_MRMT_ADS7846_TS
static int ads7846_pendown_state ( void )
{
return ! gpio_get_value ( PIN_TS_EXTINT ) ; /* PENIRQ.*/
}
static struct ads7846_platform_data ads_info = {
. model = 7846 ,
. keep_vref_on = 0 , /* Use external VREF pin */
. vref_delay_usecs = 0 ,
. vref_mv = 3300 , /* VREF = 3.3V */
. settle_delay_usecs = 800 ,
. penirq_recheck_delay_usecs = 800 ,
. x_plate_ohms = 750 ,
. y_plate_ohms = 300 ,
. pressure_max = 4096 ,
. debounce_max = 1 ,
. debounce_rep = 0 ,
. debounce_tol = ( ~ 0 ) ,
. get_pendown_state = ads7846_pendown_state ,
. filter = NULL ,
. filter_init = NULL ,
} ;
static struct spi_board_info spi01_board_info [ ] __initdata = {
{
. modalias = " ads7846 " ,
. max_speed_hz = 31250 * 26 ,
. bus_num = 0 ,
. chip_select = 1 ,
. platform_data = & ads_info ,
. irq = AT32_EXTINT ( TS_IRQ ) ,
} ,
} ;
# endif
/* GPIO Keys: left, right, power, etc */
static const struct gpio_keys_button rmt_gpio_keys_buttons [ ] = {
[ 0 ] = {
. type = EV_KEY ,
. code = KEY_POWER ,
. gpio = PIN_PWR_SW_N ,
. active_low = 1 ,
. desc = " power button " ,
} ,
[ 1 ] = {
. type = EV_KEY ,
. code = KEY_LEFT ,
. gpio = PIN_PB_LEFT ,
. active_low = 1 ,
. desc = " left button " ,
} ,
[ 2 ] = {
. type = EV_KEY ,
. code = KEY_RIGHT ,
. gpio = PIN_PB_RIGHT ,
. active_low = 1 ,
. desc = " right button " ,
} ,
} ;
static const struct gpio_keys_platform_data rmt_gpio_keys_data = {
. nbuttons = ARRAY_SIZE ( rmt_gpio_keys_buttons ) ,
. buttons = ( void * ) rmt_gpio_keys_buttons ,
} ;
static struct platform_device rmt_gpio_keys = {
. name = " gpio-keys " ,
. id = - 1 ,
. dev = {
. platform_data = ( void * ) & rmt_gpio_keys_data ,
}
} ;
# ifdef CONFIG_BOARD_MRMT_RTC_I2C
static struct i2c_board_info __initdata mrmt1_i2c_rtc = {
I2C_BOARD_INFO ( " s35390a " , 0x30 ) ,
. irq = 0 ,
} ;
# endif
static void mrmt_power_off ( void )
{
/* PWR_ON=0 will force power off */
gpio_set_value ( PIN_PWR_ON , 0 ) ;
}
static int __init mrmt1_init ( void )
{
gpio_set_value ( PIN_PWR_ON , 1 ) ; /* Ensure PWR_ON is enabled */
pm_power_off = mrmt_power_off ;
/* Setup USARTS (other than console) */
at32_map_usart ( 2 , 1 , 0 ) ; /* USART 2: /dev/ttyS1, RMT1:DB9M */
at32_map_usart ( 3 , 2 , ATMEL_USART_RTS | ATMEL_USART_CTS ) ;
/* USART 3: /dev/ttyS2, RMT1:Wireless, w/ RTS/CTS */
at32_add_device_usart ( 1 ) ;
at32_add_device_usart ( 2 ) ;
/* Select GPIO Key pins */
at32_select_gpio ( PIN_PWR_SW_N , AT32_GPIOF_DEGLITCH ) ;
at32_select_gpio ( PIN_PB_LEFT , AT32_GPIOF_DEGLITCH ) ;
at32_select_gpio ( PIN_PB_RIGHT , AT32_GPIOF_DEGLITCH ) ;
platform_device_register ( & rmt_gpio_keys ) ;
# ifdef CONFIG_BOARD_MRMT_RTC_I2C
i2c_register_board_info ( 0 , & mrmt1_i2c_rtc , 1 ) ;
# endif
# ifndef CONFIG_BOARD_MRMT_LCD_DISABLE
/* User "alternate" LCDC inferface on Port E & D */
/* NB: exclude LCDC_CC pin, as NGW100 reserves it for other use */
at32_add_device_lcdc ( 0 , & rmt_lcdc_data ,
fbmem_start , fbmem_size ,
( ATMEL_LCDC_ALT_24BIT | ATMEL_LCDC_PE_DVAL ) ) ;
# endif
# ifdef CONFIG_BOARD_MRMT_AC97
at32_add_device_ac97c ( 0 , & ac97c0_data , AC97C_BOTH ) ;
# endif
# ifdef CONFIG_BOARD_MRMT_ADS7846_TS
/* Select the Touchscreen interrupt pin mode */
at32_select_periph ( GPIO_PIOB_BASE , 1 < < ( PB_EXTINT_BASE + TS_IRQ ) ,
GPIO_PERIPH_A , AT32_GPIOF_DEGLITCH ) ;
2011-03-24 16:39:32 +01:00
irq_set_irq_type ( AT32_EXTINT ( TS_IRQ ) , IRQ_TYPE_EDGE_FALLING ) ;
2009-08-27 00:56:43 -07:00
at32_spi_setup_slaves ( 0 , spi01_board_info , ARRAY_SIZE ( spi01_board_info ) ) ;
2009-06-08 12:55:35 +02:00
spi_register_board_info ( spi01_board_info , ARRAY_SIZE ( spi01_board_info ) ) ;
# endif
# ifdef CONFIG_BOARD_MRMT_UCB1400_TS
/* Select the Touchscreen interrupt pin mode */
at32_select_periph ( GPIO_PIOB_BASE , 1 < < ( PB_EXTINT_BASE + TS_IRQ ) ,
GPIO_PERIPH_A , AT32_GPIOF_DEGLITCH ) ;
platform_device_register ( & rmt_ts_device ) ;
# endif
at32_select_gpio ( PIN_LCD_DISP , AT32_GPIOF_OUTPUT ) ;
gpio_request ( PIN_LCD_DISP , " LCD_DISP " ) ;
gpio_direction_output ( PIN_LCD_DISP , 0 ) ; /* LCD DISP */
# ifdef CONFIG_BOARD_MRMT_LCD_DISABLE
/* Keep Backlight and DISP off */
at32_select_gpio ( PIN_LCD_BL , AT32_GPIOF_OUTPUT ) ;
gpio_request ( PIN_LCD_BL , " LCD_BL " ) ;
gpio_direction_output ( PIN_LCD_BL , 0 ) ; /* Backlight */
# else
gpio_set_value ( PIN_LCD_DISP , 1 ) ; /* DISP asserted first */
# ifdef CONFIG_BOARD_MRMT_BL_PWM
/* Use PWM for Backlight controls */
at32_add_device_pwm ( 1 < < PWM_CH_BL ) ;
2014-05-29 01:20:12 +02:00
pwm_add_table ( pwm_lookup , ARRAY_SIZE ( pwm_lookup ) ) ;
platform_device_register ( & leds_pwm ) ;
2009-06-08 12:55:35 +02:00
# else
/* Backlight always on */
udelay ( 1 ) ;
at32_select_gpio ( PIN_LCD_BL , AT32_GPIOF_OUTPUT ) ;
gpio_request ( PIN_LCD_BL , " LCD_BL " ) ;
gpio_direction_output ( PIN_LCD_BL , 1 ) ;
# endif
# endif
/* Make sure BT and Zigbee modules in reset */
at32_select_gpio ( PIN_BT_RST , AT32_GPIOF_OUTPUT ) ;
gpio_request ( PIN_BT_RST , " BT_RST " ) ;
gpio_direction_output ( PIN_BT_RST , 1 ) ;
/* BT Module in Reset */
at32_select_gpio ( PIN_ZB_RST_N , AT32_GPIOF_OUTPUT ) ;
gpio_request ( PIN_ZB_RST_N , " ZB_RST_N " ) ;
gpio_direction_output ( PIN_ZB_RST_N , 0 ) ;
/* XBee Module in Reset */
# ifdef CONFIG_BOARD_MRMT_WIRELESS_ZB
udelay ( 1000 ) ;
/* Unreset the XBee Module */
gpio_set_value ( PIN_ZB_RST_N , 1 ) ;
# endif
# ifdef CONFIG_BOARD_MRMT_WIRELESS_BT
udelay ( 1000 ) ;
/* Unreset the BT Module */
gpio_set_value ( PIN_BT_RST , 0 ) ;
# endif
return 0 ;
}
arch_initcall ( mrmt1_init ) ;
static int __init mrmt1_early_init ( void )
{
/* To maintain power-on signal in case boot loader did not already */
at32_select_gpio ( PIN_PWR_ON , AT32_GPIOF_OUTPUT ) ;
gpio_request ( PIN_PWR_ON , " PIN_PWR_ON " ) ;
gpio_direction_output ( PIN_PWR_ON , 1 ) ;
return 0 ;
}
core_initcall ( mrmt1_early_init ) ;