|  | /* | 
|  | * 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> | 
|  | #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, | 
|  | }; | 
|  |  | 
|  | static struct atmel_lcdfb_info __initdata rmt_lcdc_data = { | 
|  | .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, | 
|  | }; | 
|  |  | 
|  | static struct atmel_lcdfb_info __initdata rmt_lcdc_data = { | 
|  | .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 */ | 
|  | static struct gpio_led rmt_pwm_led[] = { | 
|  | /* here the "gpio" is actually a PWM channel */ | 
|  | { .name = "backlight",	.gpio = PWM_CH_BL, }, | 
|  | }; | 
|  |  | 
|  | static struct gpio_led_platform_data rmt_pwm_led_data = { | 
|  | .num_leds	= ARRAY_SIZE(rmt_pwm_led), | 
|  | .leds		= rmt_pwm_led, | 
|  | }; | 
|  |  | 
|  | static struct platform_device rmt_pwm_led_dev = { | 
|  | .name		= "leds-atmel-pwm", | 
|  | .id		= -1, | 
|  | .dev		= { | 
|  | .platform_data	= &rmt_pwm_led_data, | 
|  | }, | 
|  | }; | 
|  | #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); | 
|  | irq_set_irq_type(AT32_EXTINT(TS_IRQ), IRQ_TYPE_EDGE_FALLING); | 
|  | at32_spi_setup_slaves(0,spi01_board_info,ARRAY_SIZE(spi01_board_info)); | 
|  | 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); | 
|  | platform_device_register(&rmt_pwm_led_dev); | 
|  | #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); |