diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2008-07-12 21:43:01 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-07-12 21:43:01 +0100 |
commit | 7fecc34e07e02b4d9dab1a1f4bf7fdac0a656b9b (patch) | |
tree | 110d24e6394dbd98cb33d80a5587cd18c8315e0b /arch/arm/mach-pxa | |
parent | a9da4f7ed6a702996ac9d1bbaf1a3969a4c092b3 (diff) | |
parent | 938870491f0cad030b358af47e28d124b72702d1 (diff) | |
download | linux-7fecc34e07e02b4d9dab1a1f4bf7fdac0a656b9b.tar.gz linux-7fecc34e07e02b4d9dab1a1f4bf7fdac0a656b9b.tar.bz2 linux-7fecc34e07e02b4d9dab1a1f4bf7fdac0a656b9b.zip |
Merge branch 'pxa-tosa' into pxa
Conflicts:
arch/arm/mach-pxa/Kconfig
arch/arm/mach-pxa/tosa.c
arch/arm/mach-pxa/spitz.c
Diffstat (limited to 'arch/arm/mach-pxa')
-rw-r--r-- | arch/arm/mach-pxa/Kconfig | 9 | ||||
-rw-r--r-- | arch/arm/mach-pxa/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/mach-pxa/reset.c | 96 | ||||
-rw-r--r-- | arch/arm/mach-pxa/spitz.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-pxa/tosa-bt.c | 150 | ||||
-rw-r--r-- | arch/arm/mach-pxa/tosa.c | 390 |
6 files changed, 604 insertions, 53 deletions
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 1a7ceb8866f9..7f9664dee670 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -310,4 +310,13 @@ config PXA_PWM default BACKLIGHT_PWM help Enable support for PXA2xx/PXA3xx PWM controllers + +config TOSA_BT + tristate "Control the state of built-in bluetooth chip on Sharp SL-6000" + depends on MACH_TOSA + select RFKILL + help + This is a simple driver that is able to control + the state of built in bluetooth chip on tosa. + endif diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 0865236513c7..b282412a01f5 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -4,7 +4,7 @@ # Common support (must be linked before board specific support) obj-y += clock.o devices.o generic.o irq.o dma.o \ - time.o gpio.o + time.o gpio.o reset.o obj-$(CONFIG_PM) += pm.o sleep.o standby.o obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o @@ -61,3 +61,5 @@ obj-$(CONFIG_LEDS) += $(led-y) ifeq ($(CONFIG_PCI),y) obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o endif + +obj-$(CONFIG_TOSA_BT) += tosa-bt.o diff --git a/arch/arm/mach-pxa/reset.c b/arch/arm/mach-pxa/reset.c new file mode 100644 index 000000000000..9d39dea57ce2 --- /dev/null +++ b/arch/arm/mach-pxa/reset.c @@ -0,0 +1,96 @@ +/* + * 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/kernel.h> +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <asm/io.h> +#include <asm/proc-fns.h> + +#include <asm/arch/pxa-regs.h> +#include <asm/arch/pxa2xx-regs.h> + +static void do_hw_reset(void); + +static int reset_gpio = -1; + +int init_gpio_reset(int gpio) +{ + int rc; + + rc = gpio_request(gpio, "reset generator"); + if (rc) { + printk(KERN_ERR "Can't request reset_gpio\n"); + goto out; + } + + rc = gpio_direction_input(gpio); + if (rc) { + printk(KERN_ERR "Can't configure reset_gpio for input\n"); + gpio_free(gpio); + goto out; + } + +out: + if (!rc) + reset_gpio = gpio; + + return rc; +} + +/* + * Trigger GPIO reset. + * This covers various types of logic connecting gpio pin + * to RESET pins (nRESET or GPIO_RESET): + */ +static void do_gpio_reset(void) +{ + BUG_ON(reset_gpio == -1); + + /* drive it low */ + gpio_direction_output(reset_gpio, 0); + mdelay(2); + /* rising edge or drive high */ + gpio_set_value(reset_gpio, 1); + mdelay(2); + /* falling edge */ + gpio_set_value(reset_gpio, 0); + + /* give it some time */ + mdelay(10); + + WARN_ON(1); + /* fallback */ + do_hw_reset(); +} + +static void do_hw_reset(void) +{ + /* Initialize the watchdog and let it fire */ + OWER = OWER_WME; + OSSR = OSSR_M3; + OSMR3 = OSCR + 368640; /* ... in 100 ms */ +} + +void arch_reset(char mode) +{ + if (cpu_is_pxa2xx()) + RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; + + switch (mode) { + case 's': + /* Jump into ROM at address 0 */ + cpu_reset(0); + break; + case 'h': + do_hw_reset(); + break; + case 'g': + do_gpio_reset(); + break; + } +} + diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index e7d0fcd9b43f..d58c3e906a93 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -38,6 +38,7 @@ #include <asm/arch/pxa-regs.h> #include <asm/arch/pxa2xx-regs.h> #include <asm/arch/pxa2xx-gpio.h> +#include <asm/arch/pxa27x-udc.h> #include <asm/arch/irda.h> #include <asm/arch/mmc.h> #include <asm/arch/ohci.h> @@ -529,11 +530,7 @@ static struct platform_device *devices[] __initdata = { static void spitz_poweroff(void) { - pxa_gpio_mode(SPITZ_GPIO_ON_RESET | GPIO_OUT); - GPSR(SPITZ_GPIO_ON_RESET) = GPIO_bit(SPITZ_GPIO_ON_RESET); - - mdelay(1000); - arm_machine_restart('h'); + arm_machine_restart('g'); } static void spitz_restart(char mode) @@ -547,6 +544,7 @@ static void spitz_restart(char mode) static void __init common_init(void) { + init_gpio_reset(SPITZ_GPIO_ON_RESET); pm_power_off = spitz_poweroff; arm_pm_restart = spitz_restart; diff --git a/arch/arm/mach-pxa/tosa-bt.c b/arch/arm/mach-pxa/tosa-bt.c new file mode 100644 index 000000000000..7d8505466e54 --- /dev/null +++ b/arch/arm/mach-pxa/tosa-bt.c @@ -0,0 +1,150 @@ +/* + * Bluetooth built-in chip control + * + * Copyright (c) 2008 Dmitry Baryshkov + * + * 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/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/delay.h> +#include <linux/rfkill.h> + +#include <asm/arch/tosa_bt.h> + +static void tosa_bt_on(struct tosa_bt_data *data) +{ + gpio_set_value(data->gpio_reset, 0); + gpio_set_value(data->gpio_pwr, 1); + gpio_set_value(data->gpio_reset, 1); + mdelay(20); + gpio_set_value(data->gpio_reset, 0); +} + +static void tosa_bt_off(struct tosa_bt_data *data) +{ + gpio_set_value(data->gpio_reset, 1); + mdelay(10); + gpio_set_value(data->gpio_pwr, 0); + gpio_set_value(data->gpio_reset, 0); +} + +static int tosa_bt_toggle_radio(void *data, enum rfkill_state state) +{ + pr_info("BT_RADIO going: %s\n", + state == RFKILL_STATE_ON ? "on" : "off"); + + if (state == RFKILL_STATE_ON) { + pr_info("TOSA_BT: going ON\n"); + tosa_bt_on(data); + } else { + pr_info("TOSA_BT: going OFF\n"); + tosa_bt_off(data); + } + return 0; +} + +static int tosa_bt_probe(struct platform_device *dev) +{ + int rc; + struct rfkill *rfk; + + struct tosa_bt_data *data = dev->dev.platform_data; + + rc = gpio_request(data->gpio_reset, "Bluetooth reset"); + if (rc) + goto err_reset; + rc = gpio_direction_output(data->gpio_reset, 0); + if (rc) + goto err_reset_dir; + rc = gpio_request(data->gpio_pwr, "Bluetooth power"); + if (rc) + goto err_pwr; + rc = gpio_direction_output(data->gpio_pwr, 0); + if (rc) + goto err_pwr_dir; + + rfk = rfkill_allocate(&dev->dev, RFKILL_TYPE_BLUETOOTH); + if (!rfk) { + rc = -ENOMEM; + goto err_rfk_alloc; + } + + rfk->name = "tosa-bt"; + rfk->toggle_radio = tosa_bt_toggle_radio; + rfk->data = data; +#ifdef CONFIG_RFKILL_LEDS + rfk->led_trigger.name = "tosa-bt"; +#endif + + rc = rfkill_register(rfk); + if (rc) + goto err_rfkill; + + platform_set_drvdata(dev, rfk); + + return 0; + +err_rfkill: + if (rfk) + rfkill_free(rfk); + rfk = NULL; +err_rfk_alloc: + tosa_bt_off(data); +err_pwr_dir: + gpio_free(data->gpio_pwr); +err_pwr: +err_reset_dir: + gpio_free(data->gpio_reset); +err_reset: + return rc; +} + +static int __devexit tosa_bt_remove(struct platform_device *dev) +{ + struct tosa_bt_data *data = dev->dev.platform_data; + struct rfkill *rfk = platform_get_drvdata(dev); + + platform_set_drvdata(dev, NULL); + + if (rfk) + rfkill_unregister(rfk); + rfk = NULL; + + tosa_bt_off(data); + + gpio_free(data->gpio_pwr); + gpio_free(data->gpio_reset); + + return 0; +} + +static struct platform_driver tosa_bt_driver = { + .probe = tosa_bt_probe, + .remove = __devexit_p(tosa_bt_remove), + + .driver = { + .name = "tosa-bt", + .owner = THIS_MODULE, + }, +}; + + +static int __init tosa_bt_init(void) +{ + return platform_driver_register(&tosa_bt_driver); +} + +static void __exit tosa_bt_exit(void) +{ + platform_driver_unregister(&tosa_bt_driver); +} + +module_init(tosa_bt_init); +module_exit(tosa_bt_exit); diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index ab4a9f579913..2d49de572ba1 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -18,30 +18,31 @@ #include <linux/major.h> #include <linux/fs.h> #include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/fb.h> #include <linux/mmc/host.h> +#include <linux/mfd/tc6393xb.h> +#include <linux/mfd/tmio.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/partitions.h> #include <linux/pm.h> -#include <linux/delay.h> #include <linux/gpio_keys.h> #include <linux/input.h> #include <linux/gpio.h> +#include <linux/pda_power.h> +#include <linux/rfkill.h> #include <asm/setup.h> -#include <asm/memory.h> #include <asm/mach-types.h> -#include <asm/hardware.h> -#include <asm/irq.h> -#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> +#include <asm/arch/tosa_bt.h> #include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> #include <asm/arch/tosa.h> #include <asm/hardware/scoop.h> @@ -86,7 +87,7 @@ static unsigned long tosa_pin_config[] = { GPIO6_MMC_CLK, GPIO8_MMC_CS0, GPIO9_GPIO, /* Detect */ - // GPIO10 nSD_INT + GPIO10_GPIO, /* nSD_INT */ /* CF */ GPIO13_GPIO, /* CD_IRQ */ @@ -124,29 +125,25 @@ static unsigned long tosa_pin_config[] = { 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, + GPIO58_GPIO | MFP_LPM_DRIVE_LOW, + GPIO59_GPIO | MFP_LPM_DRIVE_LOW, + GPIO60_GPIO | MFP_LPM_DRIVE_LOW, + GPIO61_GPIO | MFP_LPM_DRIVE_LOW, + GPIO62_GPIO | MFP_LPM_DRIVE_LOW, + GPIO63_GPIO | MFP_LPM_DRIVE_LOW, + GPIO64_GPIO | MFP_LPM_DRIVE_LOW, + GPIO65_GPIO | MFP_LPM_DRIVE_LOW, + GPIO66_GPIO | MFP_LPM_DRIVE_LOW, + GPIO67_GPIO | MFP_LPM_DRIVE_LOW, + GPIO68_GPIO | MFP_LPM_DRIVE_LOW, + GPIO69_GPIO | MFP_LPM_DRIVE_LOW, + GPIO70_GPIO | MFP_LPM_DRIVE_LOW, + GPIO71_GPIO | MFP_LPM_DRIVE_LOW, + GPIO72_GPIO | MFP_LPM_DRIVE_LOW, + GPIO73_GPIO | MFP_LPM_DRIVE_LOW, + GPIO74_GPIO | MFP_LPM_DRIVE_LOW, + GPIO75_GPIO | MFP_LPM_DRIVE_LOW, /* SPI */ GPIO81_SSP2_CLK_OUT, @@ -154,6 +151,17 @@ static unsigned long tosa_pin_config[] = { GPIO83_SSP2_TXD, }; +static unsigned long tosa_pin_irda_off[] = { + GPIO46_STUART_RXD, + GPIO47_GPIO | MFP_LPM_DRIVE_LOW, +}; + +static unsigned long tosa_pin_irda_on[] = { + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, +}; + + /* * SCOOP Device */ @@ -249,6 +257,15 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250); + err = gpio_request(TOSA_GPIO_nSD_DETECT, "MMC/SD card detect"); + if (err) { + printk(KERN_ERR "tosa_mci_init: can't request nSD_DETECT gpio\n"); + goto err_gpio_detect; + } + err = gpio_direction_input(TOSA_GPIO_nSD_DETECT); + if (err) + goto err_gpio_detect_dir; + err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int, IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "MMC/SD card detect", data); @@ -257,7 +274,7 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void goto err_irq; } - err = gpio_request(TOSA_GPIO_SD_WP, "sd_wp"); + err = gpio_request(TOSA_GPIO_SD_WP, "SD Write Protect"); if (err) { printk(KERN_ERR "tosa_mci_init: can't request SD_WP gpio\n"); goto err_gpio_wp; @@ -266,7 +283,7 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void if (err) goto err_gpio_wp_dir; - err = gpio_request(TOSA_GPIO_PWR_ON, "sd_pwr"); + err = gpio_request(TOSA_GPIO_PWR_ON, "SD Power"); if (err) { printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n"); goto err_gpio_pwr; @@ -275,8 +292,20 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void if (err) goto err_gpio_pwr_dir; + err = gpio_request(TOSA_GPIO_nSD_INT, "SD Int"); + if (err) { + printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n"); + goto err_gpio_int; + } + err = gpio_direction_input(TOSA_GPIO_nSD_INT); + if (err) + goto err_gpio_int_dir; + return 0; +err_gpio_int_dir: + gpio_free(TOSA_GPIO_nSD_INT); +err_gpio_int: err_gpio_pwr_dir: gpio_free(TOSA_GPIO_PWR_ON); err_gpio_pwr: @@ -285,6 +314,9 @@ err_gpio_wp_dir: err_gpio_wp: free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data); err_irq: +err_gpio_detect_dir: + gpio_free(TOSA_GPIO_nSD_DETECT); +err_gpio_detect: return err; } @@ -306,9 +338,11 @@ static int tosa_mci_get_ro(struct device *dev) static void tosa_mci_exit(struct device *dev, void *data) { + gpio_free(TOSA_GPIO_nSD_INT); gpio_free(TOSA_GPIO_PWR_ON); gpio_free(TOSA_GPIO_SD_WP); free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data); + gpio_free(TOSA_GPIO_nSD_DETECT); } static struct pxamci_platform_data tosa_mci_platform_data = { @@ -322,29 +356,55 @@ static struct pxamci_platform_data tosa_mci_platform_data = { /* * Irda */ +static void tosa_irda_transceiver_mode(struct device *dev, int mode) +{ + if (mode & IR_OFF) { + gpio_set_value(TOSA_GPIO_IR_POWERDWN, 0); + pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_off)); + gpio_direction_output(TOSA_GPIO_IRDA_TX, 0); + } else { + pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_on)); + gpio_set_value(TOSA_GPIO_IR_POWERDWN, 1); + } +} + static int tosa_irda_startup(struct device *dev) { int ret; + ret = gpio_request(TOSA_GPIO_IRDA_TX, "IrDA TX"); + if (ret) + goto err_tx; + ret = gpio_direction_output(TOSA_GPIO_IRDA_TX, 0); + if (ret) + goto err_tx_dir; + ret = gpio_request(TOSA_GPIO_IR_POWERDWN, "IrDA powerdown"); if (ret) - return ret; + goto err_pwr; ret = gpio_direction_output(TOSA_GPIO_IR_POWERDWN, 0); if (ret) - gpio_free(TOSA_GPIO_IR_POWERDWN); + goto err_pwr_dir; - return ret; - } + tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF); -static void tosa_irda_shutdown(struct device *dev) -{ + return 0; + +err_pwr_dir: gpio_free(TOSA_GPIO_IR_POWERDWN); +err_pwr: +err_tx_dir: + gpio_free(TOSA_GPIO_IRDA_TX); +err_tx: + return ret; } -static void tosa_irda_transceiver_mode(struct device *dev, int mode) +static void tosa_irda_shutdown(struct device *dev) { - gpio_set_value(TOSA_GPIO_IR_POWERDWN, !(mode & IR_OFF)); + tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF); + gpio_free(TOSA_GPIO_IR_POWERDWN); + gpio_free(TOSA_GPIO_IRDA_TX); } static struct pxaficp_platform_data tosa_ficp_platform_data = { @@ -355,6 +415,70 @@ static struct pxaficp_platform_data tosa_ficp_platform_data = { }; /* + * Tosa AC IN + */ +static int tosa_power_init(struct device *dev) +{ + int ret = gpio_request(TOSA_GPIO_AC_IN, "ac in"); + if (ret) + goto err_gpio_req; + + ret = gpio_direction_input(TOSA_GPIO_AC_IN); + if (ret) + goto err_gpio_in; + + return 0; + +err_gpio_in: + gpio_free(TOSA_GPIO_AC_IN); +err_gpio_req: + return ret; +} + +static void tosa_power_exit(struct device *dev) +{ + gpio_free(TOSA_GPIO_AC_IN); +} + +static int tosa_power_ac_online(void) +{ + return gpio_get_value(TOSA_GPIO_AC_IN) == 0; +} + +static char *tosa_ac_supplied_to[] = { + "main-battery", + "backup-battery", + "jacket-battery", +}; + +static struct pda_power_pdata tosa_power_data = { + .init = tosa_power_init, + .is_ac_online = tosa_power_ac_online, + .exit = tosa_power_exit, + .supplied_to = tosa_ac_supplied_to, + .num_supplicants = ARRAY_SIZE(tosa_ac_supplied_to), +}; + +static struct resource tosa_power_resource[] = { + { + .name = "ac", + .start = gpio_to_irq(TOSA_GPIO_AC_IN), + .end = gpio_to_irq(TOSA_GPIO_AC_IN), + .flags = IORESOURCE_IRQ | + IORESOURCE_IRQ_HIGHEDGE | + IORESOURCE_IRQ_LOWEDGE, + }, +}; + +static struct platform_device tosa_power_device = { + .name = "pda-power", + .id = -1, + .dev.platform_data = &tosa_power_data, + .resource = tosa_power_resource, + .num_resources = ARRAY_SIZE(tosa_power_resource), +}; + +/* * Tosa Keyboard */ static struct platform_device tosakbd_device = { @@ -439,7 +563,7 @@ static struct gpio_led tosa_gpio_leds[] = { }, { .name = "tosa:blue:bluetooth", - .default_trigger = "none", + .default_trigger = "tosa-bt", .gpio = TOSA_GPIO_BT_LED, }, }; @@ -457,21 +581,184 @@ static struct platform_device tosaled_device = { }, }; +/* + * Toshiba Mobile IO Controller + */ +static struct resource tc6393xb_resources[] = { + [0] = { + .start = TOSA_LCDC_PHYS, + .end = TOSA_LCDC_PHYS + 0x3ffffff, + .flags = IORESOURCE_MEM, + }, + + [1] = { + .start = TOSA_IRQ_GPIO_TC6393XB_INT, + .end = TOSA_IRQ_GPIO_TC6393XB_INT, + .flags = IORESOURCE_IRQ, + }, +}; + + +static int tosa_tc6393xb_enable(struct platform_device *dev) +{ + int rc; + + rc = gpio_request(TOSA_GPIO_TC6393XB_REST_IN, "tc6393xb #pclr"); + if (rc) + goto err_req_pclr; + rc = gpio_request(TOSA_GPIO_TC6393XB_SUSPEND, "tc6393xb #suspend"); + if (rc) + goto err_req_suspend; + rc = gpio_request(TOSA_GPIO_TC6393XB_L3V_ON, "l3v"); + if (rc) + goto err_req_l3v; + rc = gpio_direction_output(TOSA_GPIO_TC6393XB_L3V_ON, 0); + if (rc) + goto err_dir_l3v; + rc = gpio_direction_output(TOSA_GPIO_TC6393XB_SUSPEND, 0); + if (rc) + goto err_dir_suspend; + rc = gpio_direction_output(TOSA_GPIO_TC6393XB_REST_IN, 0); + if (rc) + goto err_dir_pclr; + + mdelay(1); + + gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1); + + mdelay(10); + + gpio_set_value(TOSA_GPIO_TC6393XB_REST_IN, 1); + gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1); + + return 0; +err_dir_pclr: +err_dir_suspend: +err_dir_l3v: + gpio_free(TOSA_GPIO_TC6393XB_L3V_ON); +err_req_l3v: + gpio_free(TOSA_GPIO_TC6393XB_SUSPEND); +err_req_suspend: + gpio_free(TOSA_GPIO_TC6393XB_REST_IN); +err_req_pclr: + return rc; +} + +static int tosa_tc6393xb_disable(struct platform_device *dev) +{ + gpio_free(TOSA_GPIO_TC6393XB_L3V_ON); + gpio_free(TOSA_GPIO_TC6393XB_SUSPEND); + gpio_free(TOSA_GPIO_TC6393XB_REST_IN); + + return 0; +} + +static int tosa_tc6393xb_resume(struct platform_device *dev) +{ + gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1); + mdelay(10); + gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1); + mdelay(10); + + return 0; +} + +static int tosa_tc6393xb_suspend(struct platform_device *dev) +{ + gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 0); + gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 0); + return 0; +} + +static struct mtd_partition tosa_nand_partition[] = { + { + .name = "smf", + .offset = 0, + .size = 7 * 1024 * 1024, + }, + { + .name = "root", + .offset = MTDPART_OFS_APPEND, + .size = 28 * 1024 * 1024, + }, + { + .name = "home", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; + +static struct nand_bbt_descr tosa_tc6393xb_nand_bbt = { + .options = 0, + .offs = 4, + .len = 2, + .pattern = scan_ff_pattern +}; + +static struct tmio_nand_data tosa_tc6393xb_nand_config = { + .num_partitions = ARRAY_SIZE(tosa_nand_partition), + .partition = tosa_nand_partition, + .badblock_pattern = &tosa_tc6393xb_nand_bbt, +}; + +static struct tc6393xb_platform_data tosa_tc6393xb_setup = { + .scr_pll2cr = 0x0cc1, + .scr_gper = 0x3300, + .scr_gpo_dsr = + TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON), + .scr_gpo_doecr = + TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON), + + .irq_base = IRQ_BOARD_START, + .gpio_base = TOSA_TC6393XB_GPIO_BASE, + + .enable = tosa_tc6393xb_enable, + .disable = tosa_tc6393xb_disable, + .suspend = tosa_tc6393xb_suspend, + .resume = tosa_tc6393xb_resume, + + .nand_data = &tosa_tc6393xb_nand_config, +}; + + +static struct platform_device tc6393xb_device = { + .name = "tc6393xb", + .id = -1, + .dev = { + .platform_data = &tosa_tc6393xb_setup, + }, + .num_resources = ARRAY_SIZE(tc6393xb_resources), + .resource = tc6393xb_resources, +}; + +static struct tosa_bt_data tosa_bt_data = { + .gpio_pwr = TOSA_GPIO_BT_PWR_EN, + .gpio_reset = TOSA_GPIO_BT_RESET, +}; + +static struct platform_device tosa_bt_device = { + .name = "tosa-bt", + .id = -1, + .dev.platform_data = &tosa_bt_data, +}; + + static struct platform_device *devices[] __initdata = { &tosascoop_device, &tosascoop_jc_device, + &tc6393xb_device, + &tosa_power_device, &tosakbd_device, &tosa_gpio_keys_device, &tosaled_device, + &tosa_bt_device, }; static void tosa_poweroff(void) { - gpio_direction_output(TOSA_GPIO_ON_RESET, 0); - gpio_set_value(TOSA_GPIO_ON_RESET, 1); - - mdelay(1000); - arm_machine_restart('h'); + arm_machine_restart('g'); } static void tosa_restart(char mode) @@ -485,10 +772,15 @@ static void tosa_restart(char mode) static void __init tosa_init(void) { + int dummy; + pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_config)); + pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_off)); gpio_set_wake(MFP_PIN_GPIO1, 1); /* We can't pass to gpio-keys since it will drop the Reset altfunc */ + init_gpio_reset(TOSA_GPIO_ON_RESET); + pm_power_off = tosa_poweroff; arm_pm_restart = tosa_restart; @@ -497,6 +789,10 @@ static void __init tosa_init(void) /* enable batt_fault */ PMCR = 0x01; + dummy = gpiochip_reserve(TOSA_SCOOP_GPIO_BASE, 12); + dummy = gpiochip_reserve(TOSA_SCOOP_JC_GPIO_BASE, 12); + dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16); + pxa_set_mci_info(&tosa_mci_platform_data); pxa_set_udc_info(&udc_info); pxa_set_ficp_info(&tosa_ficp_platform_data); |