diff options
Diffstat (limited to 'arch/arm/mach-pxa/tosa.c')
-rw-r--r-- | arch/arm/mach-pxa/tosa.c | 297 |
1 files changed, 226 insertions, 71 deletions
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index f99112d50b41..6458f6d371d9 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -23,6 +23,7 @@ #include <linux/delay.h> #include <linux/gpio_keys.h> #include <linux/input.h> +#include <linux/gpio.h> #include <asm/setup.h> #include <asm/memory.h> @@ -32,7 +33,9 @@ #include <asm/system.h> #include <asm/arch/pxa-regs.h> #include <asm/arch/pxa2xx-regs.h> +#include <asm/arch/mfp-pxa25x.h> #include <asm/arch/irda.h> +#include <asm/arch/i2c.h> #include <asm/arch/mmc.h> #include <asm/arch/udc.h> @@ -47,6 +50,110 @@ #include "generic.h" #include "devices.h" +static unsigned long tosa_pin_config[] = { + GPIO78_nCS_2, /* Scoop */ + GPIO80_nCS_4, /* tg6393xb */ + GPIO33_nCS_5, /* Scoop */ + + // GPIO76 CARD_VCC_ON1 + + GPIO19_GPIO, /* Reset out */ + GPIO1_RST | WAKEUP_ON_EDGE_FALL, + + GPIO0_GPIO | WAKEUP_ON_EDGE_FALL, /* WAKE_UP */ + GPIO2_GPIO | WAKEUP_ON_EDGE_BOTH, /* AC_IN */ + GPIO3_GPIO | WAKEUP_ON_EDGE_FALL, /* RECORD */ + GPIO4_GPIO | WAKEUP_ON_EDGE_FALL, /* SYNC */ + GPIO20_GPIO, /* EAR_IN */ + GPIO22_GPIO, /* On */ + + GPIO5_GPIO, /* USB_IN */ + GPIO32_GPIO, /* Pen IRQ */ + + GPIO7_GPIO, /* Jacket Detect */ + GPIO14_GPIO, /* BAT0_CRG */ + GPIO12_GPIO, /* BAT1_CRG */ + GPIO17_GPIO, /* BAT0_LOW */ + GPIO84_GPIO, /* BAT1_LOW */ + GPIO38_GPIO, /* BAT_LOCK */ + + GPIO11_3_6MHz, + GPIO15_GPIO, /* TC6393XB IRQ */ + GPIO18_RDY, + GPIO27_GPIO, /* LCD Sync */ + + /* MMC */ + GPIO6_MMC_CLK, + GPIO8_MMC_CS0, + GPIO9_GPIO, /* Detect */ + // GPIO10 nSD_INT + + /* CF */ + GPIO13_GPIO, /* CD_IRQ */ + GPIO21_GPIO, /* Main Slot IRQ */ + GPIO36_GPIO, /* Jacket Slot IRQ */ + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO52_nPCE_1, + GPIO53_nPCE_2, + GPIO54_nPSKTSEL, + GPIO55_nPREG, + GPIO56_nPWAIT, + GPIO57_nIOIS16, + + /* AC97 */ + GPIO31_AC97_SYNC, + GPIO30_AC97_SDATA_OUT, + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + // GPIO79 nAUD_IRQ + + /* FFUART */ + GPIO34_FFUART_RXD, + GPIO35_FFUART_CTS, + GPIO37_FFUART_DSR, + GPIO39_FFUART_TXD, + GPIO40_FFUART_DTR, + GPIO41_FFUART_RTS, + + /* BTUART */ + GPIO42_BTUART_RXD, + GPIO43_BTUART_TXD, + GPIO44_BTUART_CTS, + GPIO45_BTUART_RTS, + + /* IrDA */ + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, + + /* Keybd */ + GPIO58_GPIO, + GPIO59_GPIO, + GPIO60_GPIO, + GPIO61_GPIO, + GPIO62_GPIO, + GPIO63_GPIO, + GPIO64_GPIO, + GPIO65_GPIO, + GPIO66_GPIO, + GPIO67_GPIO, + GPIO68_GPIO, + GPIO69_GPIO, + GPIO70_GPIO, + GPIO71_GPIO, + GPIO72_GPIO, + GPIO73_GPIO, + GPIO74_GPIO, + GPIO75_GPIO, + + /* SPI */ + GPIO81_SSP2_CLK_OUT, + GPIO82_SSP2_FRM_OUT, + GPIO83_SSP2_TXD, +}; + /* * SCOOP Device */ @@ -60,11 +167,10 @@ static struct resource tosa_scoop_resources[] = { static struct scoop_config tosa_scoop_setup = { .io_dir = TOSA_SCOOP_IO_DIR, - .io_out = TOSA_SCOOP_IO_OUT, - + .gpio_base = TOSA_SCOOP_GPIO_BASE, }; -struct platform_device tosascoop_device = { +static struct platform_device tosascoop_device = { .name = "sharp-scoop", .id = 0, .dev = { @@ -88,10 +194,10 @@ static struct resource tosa_scoop_jc_resources[] = { static struct scoop_config tosa_scoop_jc_setup = { .io_dir = TOSA_SCOOP_JC_IO_DIR, - .io_out = TOSA_SCOOP_JC_IO_OUT, + .gpio_base = TOSA_SCOOP_JC_GPIO_BASE, }; -struct platform_device tosascoop_jc_device = { +static struct platform_device tosascoop_jc_device = { .name = "sharp-scoop", .id = 1, .dev = { @@ -118,50 +224,16 @@ static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = { }, }; -static void tosa_pcmcia_init(void) -{ - /* Setup default state of GPIO outputs - before we enable them as outputs. */ - GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) | - GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) | - GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) | - GPIO_bit(GPIO53_nPCE_2); - - pxa_gpio_mode(GPIO48_nPOE_MD); - pxa_gpio_mode(GPIO49_nPWE_MD); - pxa_gpio_mode(GPIO50_nPIOR_MD); - pxa_gpio_mode(GPIO51_nPIOW_MD); - pxa_gpio_mode(GPIO55_nPREG_MD); - pxa_gpio_mode(GPIO56_nPWAIT_MD); - pxa_gpio_mode(GPIO57_nIOIS16_MD); - pxa_gpio_mode(GPIO52_nPCE_1_MD); - pxa_gpio_mode(GPIO53_nPCE_2_MD); - pxa_gpio_mode(GPIO54_pSKTSEL_MD); -} - static struct scoop_pcmcia_config tosa_pcmcia_config = { .devs = &tosa_pcmcia_scoop[0], .num_devs = 2, - .pcmcia_init = tosa_pcmcia_init, }; /* * USB Device Controller */ -static void tosa_udc_command(int cmd) -{ - switch(cmd) { - case PXA2XX_UDC_CMD_CONNECT: - set_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_USB_PULLUP); - break; - case PXA2XX_UDC_CMD_DISCONNECT: - reset_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_USB_PULLUP); - break; - } -} - static struct pxa2xx_udc_mach_info udc_info __initdata = { - .udc_command = tosa_udc_command, + .gpio_pullup = TOSA_GPIO_USB_PULLUP, .gpio_vbus = TOSA_GPIO_USB_IN, .gpio_vbus_inverted = 1, }; @@ -175,19 +247,44 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void { int err; - /* setup GPIO for PXA25x MMC controller */ - pxa_gpio_mode(GPIO6_MMCCLK_MD); - pxa_gpio_mode(GPIO8_MMCCS0_MD); - pxa_gpio_mode(TOSA_GPIO_nSD_DETECT | GPIO_IN); - tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250); err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int, IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "MMC/SD card detect", data); - if (err) + if (err) { printk(KERN_ERR "tosa_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); + goto err_irq; + } + err = gpio_request(TOSA_GPIO_SD_WP, "sd_wp"); + if (err) { + printk(KERN_ERR "tosa_mci_init: can't request SD_WP gpio\n"); + goto err_gpio_wp; + } + err = gpio_direction_input(TOSA_GPIO_SD_WP); + if (err) + goto err_gpio_wp_dir; + + err = gpio_request(TOSA_GPIO_PWR_ON, "sd_pwr"); + if (err) { + printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n"); + goto err_gpio_pwr; + } + err = gpio_direction_output(TOSA_GPIO_PWR_ON, 0); + if (err) + goto err_gpio_pwr_dir; + + return 0; + +err_gpio_pwr_dir: + gpio_free(TOSA_GPIO_PWR_ON); +err_gpio_pwr: +err_gpio_wp_dir: + gpio_free(TOSA_GPIO_SD_WP); +err_gpio_wp: + free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data); +err_irq: return err; } @@ -196,19 +293,21 @@ static void tosa_mci_setpower(struct device *dev, unsigned int vdd) struct pxamci_platform_data* p_d = dev->platform_data; if (( 1 << vdd) & p_d->ocr_mask) { - set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_PWR_ON); + gpio_set_value(TOSA_GPIO_PWR_ON, 1); } else { - reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_PWR_ON); + gpio_set_value(TOSA_GPIO_PWR_ON, 0); } } static int tosa_mci_get_ro(struct device *dev) { - return (read_scoop_reg(&tosascoop_device.dev, SCOOP_GPWR)&TOSA_SCOOP_SD_WP); + return gpio_get_value(TOSA_GPIO_SD_WP); } static void tosa_mci_exit(struct device *dev, void *data) { + gpio_free(TOSA_GPIO_PWR_ON); + gpio_free(TOSA_GPIO_SD_WP); free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data); } @@ -223,21 +322,36 @@ static struct pxamci_platform_data tosa_mci_platform_data = { /* * Irda */ -static void tosa_irda_transceiver_mode(struct device *dev, int mode) +static int tosa_irda_startup(struct device *dev) { - if (mode & IR_OFF) { - reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_IR_POWERDWN); - pxa_gpio_mode(GPIO47_STTXD|GPIO_DFLT_LOW); - pxa_gpio_mode(GPIO47_STTXD|GPIO_OUT); - } else { - pxa_gpio_mode(GPIO47_STTXD_MD); - set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_IR_POWERDWN); + int ret; + + ret = gpio_request(TOSA_GPIO_IR_POWERDWN, "IrDA powerdown"); + if (ret) + return ret; + + ret = gpio_direction_output(TOSA_GPIO_IR_POWERDWN, 0); + if (ret) + gpio_free(TOSA_GPIO_IR_POWERDWN); + + return ret; } + +static void tosa_irda_shutdown(struct device *dev) +{ + gpio_free(TOSA_GPIO_IR_POWERDWN); +} + +static void tosa_irda_transceiver_mode(struct device *dev, int mode) +{ + gpio_set_value(TOSA_GPIO_IR_POWERDWN, !(mode & IR_OFF)); } static struct pxaficp_platform_data tosa_ficp_platform_data = { .transceiver_cap = IR_SIRMODE | IR_OFF, .transceiver_mode = tosa_irda_transceiver_mode, + .startup = tosa_irda_startup, + .shutdown = tosa_irda_shutdown, }; /* @@ -249,12 +363,28 @@ static struct platform_device tosakbd_device = { }; static struct gpio_keys_button tosa_gpio_keys[] = { + /* + * Two following keys are directly tied to "ON" button of tosa. Why? + * The first one can be used as a wakeup source, the second can't; + * also the first one is OR of ac_powered and on_button. + */ + { + .type = EV_PWR, + .code = KEY_RESERVED, + .gpio = TOSA_GPIO_POWERON, + .desc = "Poweron", + .wakeup = 1, + .active_low = 1, + }, { .type = EV_PWR, .code = KEY_SUSPEND, .gpio = TOSA_GPIO_ON_KEY, .desc = "On key", - .wakeup = 1, + /* + * can't be used as wakeup + * .wakeup = 1, + */ .active_low = 1, }, { @@ -291,9 +421,40 @@ static struct platform_device tosa_gpio_keys_device = { /* * Tosa LEDs */ +static struct gpio_led tosa_gpio_leds[] = { + { + .name = "tosa:amber:charge", + .default_trigger = "main-battery-charging", + .gpio = TOSA_GPIO_CHRG_ERR_LED, + }, + { + .name = "tosa:green:mail", + .default_trigger = "nand-disk", + .gpio = TOSA_GPIO_NOTE_LED, + }, + { + .name = "tosa:dual:wlan", + .default_trigger = "none", + .gpio = TOSA_GPIO_WLAN_LED, + }, + { + .name = "tosa:blue:bluetooth", + .default_trigger = "none", + .gpio = TOSA_GPIO_BT_LED, + }, +}; + +static struct gpio_led_platform_data tosa_gpio_leds_platform_data = { + .leds = tosa_gpio_leds, + .num_leds = ARRAY_SIZE(tosa_gpio_leds), +}; + static struct platform_device tosaled_device = { - .name = "tosa-led", - .id = -1, + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &tosa_gpio_leds_platform_data, + }, }; static struct platform_device *devices[] __initdata = { @@ -326,20 +487,13 @@ static void tosa_restart(char mode) static void __init tosa_init(void) { + pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_config)); + gpio_set_wake(MFP_PIN_GPIO1, 1); + /* We can't pass to gpio-keys since it will drop the Reset altfunc */ + pm_power_off = tosa_poweroff; arm_pm_restart = tosa_restart; - pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_IN); - pxa_gpio_mode(TOSA_GPIO_TC6393_INT | GPIO_IN); - pxa_gpio_mode(TOSA_GPIO_USB_IN | GPIO_IN); - - /* setup sleep mode values */ - PWER = 0x00000002; - PFER = 0x00000000; - PRER = 0x00000002; - PGSR0 = 0x00000000; - PGSR1 = 0x00FF0002; - PGSR2 = 0x00014000; PCFR |= PCFR_OPDE; /* enable batt_fault */ @@ -348,6 +502,7 @@ static void __init tosa_init(void) pxa_set_mci_info(&tosa_mci_platform_data); pxa_set_udc_info(&udc_info); pxa_set_ficp_info(&tosa_ficp_platform_data); + pxa_set_i2c_info(NULL); platform_scoop_config = &tosa_pcmcia_config; platform_add_devices(devices, ARRAY_SIZE(devices)); |