diff options
Diffstat (limited to 'kernel/arch/avr32/boards/atngw100/mrmt.c')
-rw-r--r-- | kernel/arch/avr32/boards/atngw100/mrmt.c | 383 |
1 files changed, 383 insertions, 0 deletions
diff --git a/kernel/arch/avr32/boards/atngw100/mrmt.c b/kernel/arch/avr32/boards/atngw100/mrmt.c new file mode 100644 index 000000000..91146b416 --- /dev/null +++ b/kernel/arch/avr32/boards/atngw100/mrmt.c @@ -0,0 +1,383 @@ +/* + * 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/pwm.h> +#include <linux/leds_pwm.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_pdata __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_pdata __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 pwm_lookup pwm_lookup[] = { + PWM_LOOKUP("at91sam9rl-pwm", PWM_CH_BL, "leds_pwm", "ds1", + 5000, PWM_POLARITY_INVERSED), +}; + +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, +}; + +static struct platform_device leds_pwm = { + .name = "leds_pwm", + .id = -1, + .dev = { + .platform_data = &pwm_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); + pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup)); + platform_device_register(&leds_pwm); +#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); |