Merge branch 'pxa-tosa' into pxa
Conflicts: arch/arm/mach-pxa/Kconfig arch/arm/mach-pxa/tosa.c arch/arm/mach-pxa/spitz.c
This commit is contained in:
@@ -584,6 +584,8 @@ L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
|||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
ARM/TOSA MACHINE SUPPORT
|
ARM/TOSA MACHINE SUPPORT
|
||||||
|
P: Dmitry Baryshkov
|
||||||
|
M: dbaryshkov@gmail.com
|
||||||
P: Dirk Opfer
|
P: Dirk Opfer
|
||||||
M: dirk@opfer-online.de
|
M: dirk@opfer-online.de
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
@@ -310,4 +310,13 @@ config PXA_PWM
|
|||||||
default BACKLIGHT_PWM
|
default BACKLIGHT_PWM
|
||||||
help
|
help
|
||||||
Enable support for PXA2xx/PXA3xx PWM controllers
|
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
|
endif
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
# Common support (must be linked before board specific support)
|
# Common support (must be linked before board specific support)
|
||||||
obj-y += clock.o devices.o generic.o irq.o dma.o \
|
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_PM) += pm.o sleep.o standby.o
|
||||||
obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o
|
obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o
|
||||||
|
|
||||||
@@ -61,3 +61,5 @@ obj-$(CONFIG_LEDS) += $(led-y)
|
|||||||
ifeq ($(CONFIG_PCI),y)
|
ifeq ($(CONFIG_PCI),y)
|
||||||
obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o
|
obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
obj-$(CONFIG_TOSA_BT) += tosa-bt.o
|
||||||
|
96
arch/arm/mach-pxa/reset.c
Normal file
96
arch/arm/mach-pxa/reset.c
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -38,6 +38,7 @@
|
|||||||
#include <asm/arch/pxa-regs.h>
|
#include <asm/arch/pxa-regs.h>
|
||||||
#include <asm/arch/pxa2xx-regs.h>
|
#include <asm/arch/pxa2xx-regs.h>
|
||||||
#include <asm/arch/pxa2xx-gpio.h>
|
#include <asm/arch/pxa2xx-gpio.h>
|
||||||
|
#include <asm/arch/pxa27x-udc.h>
|
||||||
#include <asm/arch/irda.h>
|
#include <asm/arch/irda.h>
|
||||||
#include <asm/arch/mmc.h>
|
#include <asm/arch/mmc.h>
|
||||||
#include <asm/arch/ohci.h>
|
#include <asm/arch/ohci.h>
|
||||||
@@ -529,11 +530,7 @@ static struct platform_device *devices[] __initdata = {
|
|||||||
|
|
||||||
static void spitz_poweroff(void)
|
static void spitz_poweroff(void)
|
||||||
{
|
{
|
||||||
pxa_gpio_mode(SPITZ_GPIO_ON_RESET | GPIO_OUT);
|
arm_machine_restart('g');
|
||||||
GPSR(SPITZ_GPIO_ON_RESET) = GPIO_bit(SPITZ_GPIO_ON_RESET);
|
|
||||||
|
|
||||||
mdelay(1000);
|
|
||||||
arm_machine_restart('h');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void spitz_restart(char mode)
|
static void spitz_restart(char mode)
|
||||||
@@ -547,6 +544,7 @@ static void spitz_restart(char mode)
|
|||||||
|
|
||||||
static void __init common_init(void)
|
static void __init common_init(void)
|
||||||
{
|
{
|
||||||
|
init_gpio_reset(SPITZ_GPIO_ON_RESET);
|
||||||
pm_power_off = spitz_poweroff;
|
pm_power_off = spitz_poweroff;
|
||||||
arm_pm_restart = spitz_restart;
|
arm_pm_restart = spitz_restart;
|
||||||
|
|
||||||
|
150
arch/arm/mach-pxa/tosa-bt.c
Normal file
150
arch/arm/mach-pxa/tosa-bt.c
Normal file
@@ -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);
|
@@ -18,30 +18,31 @@
|
|||||||
#include <linux/major.h>
|
#include <linux/major.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/mmc/host.h>
|
|
||||||
#include <linux/pm.h>
|
|
||||||
#include <linux/delay.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/gpio_keys.h>
|
#include <linux/gpio_keys.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
|
#include <linux/pda_power.h>
|
||||||
|
#include <linux/rfkill.h>
|
||||||
|
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
#include <asm/memory.h>
|
|
||||||
#include <asm/mach-types.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/pxa2xx-regs.h>
|
||||||
#include <asm/arch/mfp-pxa25x.h>
|
#include <asm/arch/mfp-pxa25x.h>
|
||||||
#include <asm/arch/irda.h>
|
#include <asm/arch/irda.h>
|
||||||
#include <asm/arch/i2c.h>
|
#include <asm/arch/i2c.h>
|
||||||
#include <asm/arch/mmc.h>
|
#include <asm/arch/mmc.h>
|
||||||
#include <asm/arch/udc.h>
|
#include <asm/arch/udc.h>
|
||||||
|
#include <asm/arch/tosa_bt.h>
|
||||||
|
|
||||||
#include <asm/mach/arch.h>
|
#include <asm/mach/arch.h>
|
||||||
#include <asm/mach/map.h>
|
|
||||||
#include <asm/mach/irq.h>
|
|
||||||
#include <asm/arch/tosa.h>
|
#include <asm/arch/tosa.h>
|
||||||
|
|
||||||
#include <asm/hardware/scoop.h>
|
#include <asm/hardware/scoop.h>
|
||||||
@@ -86,7 +87,7 @@ static unsigned long tosa_pin_config[] = {
|
|||||||
GPIO6_MMC_CLK,
|
GPIO6_MMC_CLK,
|
||||||
GPIO8_MMC_CS0,
|
GPIO8_MMC_CS0,
|
||||||
GPIO9_GPIO, /* Detect */
|
GPIO9_GPIO, /* Detect */
|
||||||
// GPIO10 nSD_INT
|
GPIO10_GPIO, /* nSD_INT */
|
||||||
|
|
||||||
/* CF */
|
/* CF */
|
||||||
GPIO13_GPIO, /* CD_IRQ */
|
GPIO13_GPIO, /* CD_IRQ */
|
||||||
@@ -124,29 +125,25 @@ static unsigned long tosa_pin_config[] = {
|
|||||||
GPIO44_BTUART_CTS,
|
GPIO44_BTUART_CTS,
|
||||||
GPIO45_BTUART_RTS,
|
GPIO45_BTUART_RTS,
|
||||||
|
|
||||||
/* IrDA */
|
|
||||||
GPIO46_STUART_RXD,
|
|
||||||
GPIO47_STUART_TXD,
|
|
||||||
|
|
||||||
/* Keybd */
|
/* Keybd */
|
||||||
GPIO58_GPIO,
|
GPIO58_GPIO | MFP_LPM_DRIVE_LOW,
|
||||||
GPIO59_GPIO,
|
GPIO59_GPIO | MFP_LPM_DRIVE_LOW,
|
||||||
GPIO60_GPIO,
|
GPIO60_GPIO | MFP_LPM_DRIVE_LOW,
|
||||||
GPIO61_GPIO,
|
GPIO61_GPIO | MFP_LPM_DRIVE_LOW,
|
||||||
GPIO62_GPIO,
|
GPIO62_GPIO | MFP_LPM_DRIVE_LOW,
|
||||||
GPIO63_GPIO,
|
GPIO63_GPIO | MFP_LPM_DRIVE_LOW,
|
||||||
GPIO64_GPIO,
|
GPIO64_GPIO | MFP_LPM_DRIVE_LOW,
|
||||||
GPIO65_GPIO,
|
GPIO65_GPIO | MFP_LPM_DRIVE_LOW,
|
||||||
GPIO66_GPIO,
|
GPIO66_GPIO | MFP_LPM_DRIVE_LOW,
|
||||||
GPIO67_GPIO,
|
GPIO67_GPIO | MFP_LPM_DRIVE_LOW,
|
||||||
GPIO68_GPIO,
|
GPIO68_GPIO | MFP_LPM_DRIVE_LOW,
|
||||||
GPIO69_GPIO,
|
GPIO69_GPIO | MFP_LPM_DRIVE_LOW,
|
||||||
GPIO70_GPIO,
|
GPIO70_GPIO | MFP_LPM_DRIVE_LOW,
|
||||||
GPIO71_GPIO,
|
GPIO71_GPIO | MFP_LPM_DRIVE_LOW,
|
||||||
GPIO72_GPIO,
|
GPIO72_GPIO | MFP_LPM_DRIVE_LOW,
|
||||||
GPIO73_GPIO,
|
GPIO73_GPIO | MFP_LPM_DRIVE_LOW,
|
||||||
GPIO74_GPIO,
|
GPIO74_GPIO | MFP_LPM_DRIVE_LOW,
|
||||||
GPIO75_GPIO,
|
GPIO75_GPIO | MFP_LPM_DRIVE_LOW,
|
||||||
|
|
||||||
/* SPI */
|
/* SPI */
|
||||||
GPIO81_SSP2_CLK_OUT,
|
GPIO81_SSP2_CLK_OUT,
|
||||||
@@ -154,6 +151,17 @@ static unsigned long tosa_pin_config[] = {
|
|||||||
GPIO83_SSP2_TXD,
|
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
|
* 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);
|
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,
|
err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int,
|
||||||
IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
|
IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
|
||||||
"MMC/SD card detect", data);
|
"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;
|
goto err_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = gpio_request(TOSA_GPIO_SD_WP, "sd_wp");
|
err = gpio_request(TOSA_GPIO_SD_WP, "SD Write Protect");
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(KERN_ERR "tosa_mci_init: can't request SD_WP gpio\n");
|
printk(KERN_ERR "tosa_mci_init: can't request SD_WP gpio\n");
|
||||||
goto err_gpio_wp;
|
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)
|
if (err)
|
||||||
goto err_gpio_wp_dir;
|
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) {
|
if (err) {
|
||||||
printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n");
|
printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n");
|
||||||
goto err_gpio_pwr;
|
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)
|
if (err)
|
||||||
goto err_gpio_pwr_dir;
|
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;
|
return 0;
|
||||||
|
|
||||||
|
err_gpio_int_dir:
|
||||||
|
gpio_free(TOSA_GPIO_nSD_INT);
|
||||||
|
err_gpio_int:
|
||||||
err_gpio_pwr_dir:
|
err_gpio_pwr_dir:
|
||||||
gpio_free(TOSA_GPIO_PWR_ON);
|
gpio_free(TOSA_GPIO_PWR_ON);
|
||||||
err_gpio_pwr:
|
err_gpio_pwr:
|
||||||
@@ -285,6 +314,9 @@ err_gpio_wp_dir:
|
|||||||
err_gpio_wp:
|
err_gpio_wp:
|
||||||
free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data);
|
free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data);
|
||||||
err_irq:
|
err_irq:
|
||||||
|
err_gpio_detect_dir:
|
||||||
|
gpio_free(TOSA_GPIO_nSD_DETECT);
|
||||||
|
err_gpio_detect:
|
||||||
return err;
|
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)
|
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_PWR_ON);
|
||||||
gpio_free(TOSA_GPIO_SD_WP);
|
gpio_free(TOSA_GPIO_SD_WP);
|
||||||
free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data);
|
free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data);
|
||||||
|
gpio_free(TOSA_GPIO_nSD_DETECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pxamci_platform_data tosa_mci_platform_data = {
|
static struct pxamci_platform_data tosa_mci_platform_data = {
|
||||||
@@ -322,29 +356,55 @@ static struct pxamci_platform_data tosa_mci_platform_data = {
|
|||||||
/*
|
/*
|
||||||
* Irda
|
* 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)
|
static int tosa_irda_startup(struct device *dev)
|
||||||
{
|
{
|
||||||
int ret;
|
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");
|
ret = gpio_request(TOSA_GPIO_IR_POWERDWN, "IrDA powerdown");
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto err_pwr;
|
||||||
|
|
||||||
ret = gpio_direction_output(TOSA_GPIO_IR_POWERDWN, 0);
|
ret = gpio_direction_output(TOSA_GPIO_IR_POWERDWN, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
gpio_free(TOSA_GPIO_IR_POWERDWN);
|
goto err_pwr_dir;
|
||||||
|
|
||||||
|
tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF);
|
||||||
|
|
||||||
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tosa_irda_shutdown(struct device *dev)
|
static void tosa_irda_shutdown(struct device *dev)
|
||||||
{
|
{
|
||||||
|
tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF);
|
||||||
gpio_free(TOSA_GPIO_IR_POWERDWN);
|
gpio_free(TOSA_GPIO_IR_POWERDWN);
|
||||||
}
|
gpio_free(TOSA_GPIO_IRDA_TX);
|
||||||
|
|
||||||
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 = {
|
static struct pxaficp_platform_data tosa_ficp_platform_data = {
|
||||||
@@ -354,6 +414,70 @@ static struct pxaficp_platform_data tosa_ficp_platform_data = {
|
|||||||
.shutdown = tosa_irda_shutdown,
|
.shutdown = tosa_irda_shutdown,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
* Tosa Keyboard
|
||||||
*/
|
*/
|
||||||
@@ -439,7 +563,7 @@ static struct gpio_led tosa_gpio_leds[] = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "tosa:blue:bluetooth",
|
.name = "tosa:blue:bluetooth",
|
||||||
.default_trigger = "none",
|
.default_trigger = "tosa-bt",
|
||||||
.gpio = TOSA_GPIO_BT_LED,
|
.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 = {
|
static struct platform_device *devices[] __initdata = {
|
||||||
&tosascoop_device,
|
&tosascoop_device,
|
||||||
&tosascoop_jc_device,
|
&tosascoop_jc_device,
|
||||||
|
&tc6393xb_device,
|
||||||
|
&tosa_power_device,
|
||||||
&tosakbd_device,
|
&tosakbd_device,
|
||||||
&tosa_gpio_keys_device,
|
&tosa_gpio_keys_device,
|
||||||
&tosaled_device,
|
&tosaled_device,
|
||||||
|
&tosa_bt_device,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void tosa_poweroff(void)
|
static void tosa_poweroff(void)
|
||||||
{
|
{
|
||||||
gpio_direction_output(TOSA_GPIO_ON_RESET, 0);
|
arm_machine_restart('g');
|
||||||
gpio_set_value(TOSA_GPIO_ON_RESET, 1);
|
|
||||||
|
|
||||||
mdelay(1000);
|
|
||||||
arm_machine_restart('h');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tosa_restart(char mode)
|
static void tosa_restart(char mode)
|
||||||
@@ -485,10 +772,15 @@ static void tosa_restart(char mode)
|
|||||||
|
|
||||||
static void __init tosa_init(void)
|
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_config));
|
||||||
|
pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_off));
|
||||||
gpio_set_wake(MFP_PIN_GPIO1, 1);
|
gpio_set_wake(MFP_PIN_GPIO1, 1);
|
||||||
/* We can't pass to gpio-keys since it will drop the Reset altfunc */
|
/* 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;
|
pm_power_off = tosa_poweroff;
|
||||||
arm_pm_restart = tosa_restart;
|
arm_pm_restart = tosa_restart;
|
||||||
|
|
||||||
@@ -497,6 +789,10 @@ static void __init tosa_init(void)
|
|||||||
/* enable batt_fault */
|
/* enable batt_fault */
|
||||||
PMCR = 0x01;
|
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_mci_info(&tosa_mci_platform_data);
|
||||||
pxa_set_udc_info(&udc_info);
|
pxa_set_udc_info(&udc_info);
|
||||||
pxa_set_ficp_info(&tosa_ficp_platform_data);
|
pxa_set_ficp_info(&tosa_ficp_platform_data);
|
||||||
|
@@ -215,8 +215,6 @@ static int tosakbd_suspend(struct platform_device *dev, pm_message_t state)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&tosakbd->lock, flags);
|
spin_lock_irqsave(&tosakbd->lock, flags);
|
||||||
PGSR1 = (PGSR1 & ~TOSA_GPIO_LOW_STROBE_BIT);
|
|
||||||
PGSR2 = (PGSR2 & ~TOSA_GPIO_HIGH_STROBE_BIT);
|
|
||||||
tosakbd->suspended = 1;
|
tosakbd->suspended = 1;
|
||||||
spin_unlock_irqrestore(&tosakbd->lock, flags);
|
spin_unlock_irqrestore(&tosakbd->lock, flags);
|
||||||
|
|
||||||
|
@@ -5,6 +5,10 @@
|
|||||||
menu "Multifunction device drivers"
|
menu "Multifunction device drivers"
|
||||||
depends on HAS_IOMEM
|
depends on HAS_IOMEM
|
||||||
|
|
||||||
|
config MFD_CORE
|
||||||
|
tristate
|
||||||
|
default n
|
||||||
|
|
||||||
config MFD_SM501
|
config MFD_SM501
|
||||||
tristate "Support for Silicon Motion SM501"
|
tristate "Support for Silicon Motion SM501"
|
||||||
---help---
|
---help---
|
||||||
@@ -38,6 +42,13 @@ config HTC_PASIC3
|
|||||||
HTC Magician devices, respectively. Actual functionality is
|
HTC Magician devices, respectively. Actual functionality is
|
||||||
handled by the leds-pasic3 and ds1wm drivers.
|
handled by the leds-pasic3 and ds1wm drivers.
|
||||||
|
|
||||||
|
config MFD_TC6393XB
|
||||||
|
bool "Support Toshiba TC6393XB"
|
||||||
|
depends on HAVE_GPIO_LIB
|
||||||
|
select MFD_CORE
|
||||||
|
help
|
||||||
|
Support for Toshiba Mobile IO Controller TC6393XB
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "Multimedia Capabilities Port drivers"
|
menu "Multimedia Capabilities Port drivers"
|
||||||
|
@@ -8,6 +8,10 @@ obj-$(CONFIG_MFD_ASIC3) += asic3.o
|
|||||||
obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
|
obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
|
||||||
obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
|
obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_MFD_CORE) += mfd-core.o
|
||||||
|
|
||||||
obj-$(CONFIG_MCP) += mcp-core.o
|
obj-$(CONFIG_MCP) += mcp-core.o
|
||||||
obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o
|
obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o
|
||||||
obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
|
obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
|
||||||
|
114
drivers/mfd/mfd-core.c
Normal file
114
drivers/mfd/mfd-core.c
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* drivers/mfd/mfd-core.c
|
||||||
|
*
|
||||||
|
* core MFD support
|
||||||
|
* Copyright (c) 2006 Ian Molton
|
||||||
|
* Copyright (c) 2007,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/platform_device.h>
|
||||||
|
#include <linux/mfd/core.h>
|
||||||
|
|
||||||
|
static int mfd_add_device(struct platform_device *parent,
|
||||||
|
const struct mfd_cell *cell,
|
||||||
|
struct resource *mem_base,
|
||||||
|
int irq_base)
|
||||||
|
{
|
||||||
|
struct resource res[cell->num_resources];
|
||||||
|
struct platform_device *pdev;
|
||||||
|
int ret = -ENOMEM;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
pdev = platform_device_alloc(cell->name, parent->id);
|
||||||
|
if (!pdev)
|
||||||
|
goto fail_alloc;
|
||||||
|
|
||||||
|
pdev->dev.parent = &parent->dev;
|
||||||
|
|
||||||
|
ret = platform_device_add_data(pdev,
|
||||||
|
cell, sizeof(struct mfd_cell));
|
||||||
|
if (ret)
|
||||||
|
goto fail_device;
|
||||||
|
|
||||||
|
memzero(res, sizeof(res));
|
||||||
|
for (r = 0; r < cell->num_resources; r++) {
|
||||||
|
res[r].name = cell->resources[r].name;
|
||||||
|
res[r].flags = cell->resources[r].flags;
|
||||||
|
|
||||||
|
/* Find out base to use */
|
||||||
|
if (cell->resources[r].flags & IORESOURCE_MEM) {
|
||||||
|
res[r].parent = mem_base;
|
||||||
|
res[r].start = mem_base->start +
|
||||||
|
cell->resources[r].start;
|
||||||
|
res[r].end = mem_base->start +
|
||||||
|
cell->resources[r].end;
|
||||||
|
} else if (cell->resources[r].flags & IORESOURCE_IRQ) {
|
||||||
|
res[r].start = irq_base +
|
||||||
|
cell->resources[r].start;
|
||||||
|
res[r].end = irq_base +
|
||||||
|
cell->resources[r].end;
|
||||||
|
} else {
|
||||||
|
res[r].parent = cell->resources[r].parent;
|
||||||
|
res[r].start = cell->resources[r].start;
|
||||||
|
res[r].end = cell->resources[r].end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
platform_device_add_resources(pdev, res, cell->num_resources);
|
||||||
|
|
||||||
|
ret = platform_device_add(pdev);
|
||||||
|
if (ret)
|
||||||
|
goto fail_device;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* platform_device_del(pdev); */
|
||||||
|
fail_device:
|
||||||
|
platform_device_put(pdev);
|
||||||
|
fail_alloc:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mfd_add_devices(
|
||||||
|
struct platform_device *parent,
|
||||||
|
const struct mfd_cell *cells, int n_devs,
|
||||||
|
struct resource *mem_base,
|
||||||
|
int irq_base)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < n_devs; i++) {
|
||||||
|
ret = mfd_add_device(parent, cells + i, mem_base, irq_base);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
mfd_remove_devices(parent);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(mfd_add_devices);
|
||||||
|
|
||||||
|
static int mfd_remove_devices_fn(struct device *dev, void *unused)
|
||||||
|
{
|
||||||
|
platform_device_unregister(
|
||||||
|
container_of(dev, struct platform_device, dev));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mfd_remove_devices(struct platform_device *parent)
|
||||||
|
{
|
||||||
|
device_for_each_child(&parent->dev, NULL, mfd_remove_devices_fn);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(mfd_remove_devices);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov");
|
600
drivers/mfd/tc6393xb.c
Normal file
600
drivers/mfd/tc6393xb.c
Normal file
@@ -0,0 +1,600 @@
|
|||||||
|
/*
|
||||||
|
* Toshiba TC6393XB SoC support
|
||||||
|
*
|
||||||
|
* Copyright(c) 2005-2006 Chris Humbert
|
||||||
|
* Copyright(c) 2005 Dirk Opfer
|
||||||
|
* Copyright(c) 2005 Ian Molton <spyro@f2s.com>
|
||||||
|
* Copyright(c) 2007 Dmitry Baryshkov
|
||||||
|
*
|
||||||
|
* Based on code written by Sharp/Lineo for 2.4 kernels
|
||||||
|
* Based on locomo.c
|
||||||
|
*
|
||||||
|
* 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/io.h>
|
||||||
|
#include <linux/irq.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/fb.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
|
#include <linux/mfd/core.h>
|
||||||
|
#include <linux/mfd/tmio.h>
|
||||||
|
#include <linux/mfd/tc6393xb.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
|
||||||
|
#define SCR_REVID 0x08 /* b Revision ID */
|
||||||
|
#define SCR_ISR 0x50 /* b Interrupt Status */
|
||||||
|
#define SCR_IMR 0x52 /* b Interrupt Mask */
|
||||||
|
#define SCR_IRR 0x54 /* b Interrupt Routing */
|
||||||
|
#define SCR_GPER 0x60 /* w GP Enable */
|
||||||
|
#define SCR_GPI_SR(i) (0x64 + (i)) /* b3 GPI Status */
|
||||||
|
#define SCR_GPI_IMR(i) (0x68 + (i)) /* b3 GPI INT Mask */
|
||||||
|
#define SCR_GPI_EDER(i) (0x6c + (i)) /* b3 GPI Edge Detect Enable */
|
||||||
|
#define SCR_GPI_LIR(i) (0x70 + (i)) /* b3 GPI Level Invert */
|
||||||
|
#define SCR_GPO_DSR(i) (0x78 + (i)) /* b3 GPO Data Set */
|
||||||
|
#define SCR_GPO_DOECR(i) (0x7c + (i)) /* b3 GPO Data OE Control */
|
||||||
|
#define SCR_GP_IARCR(i) (0x80 + (i)) /* b3 GP Internal Active Register Control */
|
||||||
|
#define SCR_GP_IARLCR(i) (0x84 + (i)) /* b3 GP INTERNAL Active Register Level Control */
|
||||||
|
#define SCR_GPI_BCR(i) (0x88 + (i)) /* b3 GPI Buffer Control */
|
||||||
|
#define SCR_GPA_IARCR 0x8c /* w GPa Internal Active Register Control */
|
||||||
|
#define SCR_GPA_IARLCR 0x90 /* w GPa Internal Active Register Level Control */
|
||||||
|
#define SCR_GPA_BCR 0x94 /* w GPa Buffer Control */
|
||||||
|
#define SCR_CCR 0x98 /* w Clock Control */
|
||||||
|
#define SCR_PLL2CR 0x9a /* w PLL2 Control */
|
||||||
|
#define SCR_PLL1CR 0x9c /* l PLL1 Control */
|
||||||
|
#define SCR_DIARCR 0xa0 /* b Device Internal Active Register Control */
|
||||||
|
#define SCR_DBOCR 0xa1 /* b Device Buffer Off Control */
|
||||||
|
#define SCR_FER 0xe0 /* b Function Enable */
|
||||||
|
#define SCR_MCR 0xe4 /* w Mode Control */
|
||||||
|
#define SCR_CONFIG 0xfc /* b Configuration Control */
|
||||||
|
#define SCR_DEBUG 0xff /* b Debug */
|
||||||
|
|
||||||
|
#define SCR_CCR_CK32K BIT(0)
|
||||||
|
#define SCR_CCR_USBCK BIT(1)
|
||||||
|
#define SCR_CCR_UNK1 BIT(4)
|
||||||
|
#define SCR_CCR_MCLK_MASK (7 << 8)
|
||||||
|
#define SCR_CCR_MCLK_OFF (0 << 8)
|
||||||
|
#define SCR_CCR_MCLK_12 (1 << 8)
|
||||||
|
#define SCR_CCR_MCLK_24 (2 << 8)
|
||||||
|
#define SCR_CCR_MCLK_48 (3 << 8)
|
||||||
|
#define SCR_CCR_HCLK_MASK (3 << 12)
|
||||||
|
#define SCR_CCR_HCLK_24 (0 << 12)
|
||||||
|
#define SCR_CCR_HCLK_48 (1 << 12)
|
||||||
|
|
||||||
|
#define SCR_FER_USBEN BIT(0) /* USB host enable */
|
||||||
|
#define SCR_FER_LCDCVEN BIT(1) /* polysilicon TFT enable */
|
||||||
|
#define SCR_FER_SLCDEN BIT(2) /* SLCD enable */
|
||||||
|
|
||||||
|
#define SCR_MCR_RDY_MASK (3 << 0)
|
||||||
|
#define SCR_MCR_RDY_OPENDRAIN (0 << 0)
|
||||||
|
#define SCR_MCR_RDY_TRISTATE (1 << 0)
|
||||||
|
#define SCR_MCR_RDY_PUSHPULL (2 << 0)
|
||||||
|
#define SCR_MCR_RDY_UNK BIT(2)
|
||||||
|
#define SCR_MCR_RDY_EN BIT(3)
|
||||||
|
#define SCR_MCR_INT_MASK (3 << 4)
|
||||||
|
#define SCR_MCR_INT_OPENDRAIN (0 << 4)
|
||||||
|
#define SCR_MCR_INT_TRISTATE (1 << 4)
|
||||||
|
#define SCR_MCR_INT_PUSHPULL (2 << 4)
|
||||||
|
#define SCR_MCR_INT_UNK BIT(6)
|
||||||
|
#define SCR_MCR_INT_EN BIT(7)
|
||||||
|
/* bits 8 - 16 are unknown */
|
||||||
|
|
||||||
|
#define TC_GPIO_BIT(i) (1 << (i & 0x7))
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
struct tc6393xb {
|
||||||
|
void __iomem *scr;
|
||||||
|
|
||||||
|
struct gpio_chip gpio;
|
||||||
|
|
||||||
|
struct clk *clk; /* 3,6 Mhz */
|
||||||
|
|
||||||
|
spinlock_t lock; /* protects RMW cycles */
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u8 fer;
|
||||||
|
u16 ccr;
|
||||||
|
u8 gpi_bcr[3];
|
||||||
|
u8 gpo_dsr[3];
|
||||||
|
u8 gpo_doecr[3];
|
||||||
|
} suspend_state;
|
||||||
|
|
||||||
|
struct resource rscr;
|
||||||
|
struct resource *iomem;
|
||||||
|
int irq;
|
||||||
|
int irq_base;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TC6393XB_CELL_NAND,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static int tc6393xb_nand_enable(struct platform_device *nand)
|
||||||
|
{
|
||||||
|
struct platform_device *dev = to_platform_device(nand->dev.parent);
|
||||||
|
struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&tc6393xb->lock, flags);
|
||||||
|
|
||||||
|
/* SMD buffer on */
|
||||||
|
dev_dbg(&dev->dev, "SMD buffer on\n");
|
||||||
|
iowrite8(0xff, tc6393xb->scr + SCR_GPI_BCR(1));
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&tc6393xb->lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct resource __devinitdata tc6393xb_nand_resources[] = {
|
||||||
|
{
|
||||||
|
.name = TMIO_NAND_CONFIG,
|
||||||
|
.start = 0x0100,
|
||||||
|
.end = 0x01ff,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = TMIO_NAND_CONTROL,
|
||||||
|
.start = 0x1000,
|
||||||
|
.end = 0x1007,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = TMIO_NAND_IRQ,
|
||||||
|
.start = IRQ_TC6393_NAND,
|
||||||
|
.end = IRQ_TC6393_NAND,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct mfd_cell __devinitdata tc6393xb_cells[] = {
|
||||||
|
[TC6393XB_CELL_NAND] = {
|
||||||
|
.name = "tmio-nand",
|
||||||
|
.enable = tc6393xb_nand_enable,
|
||||||
|
.num_resources = ARRAY_SIZE(tc6393xb_nand_resources),
|
||||||
|
.resources = tc6393xb_nand_resources,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static int tc6393xb_gpio_get(struct gpio_chip *chip,
|
||||||
|
unsigned offset)
|
||||||
|
{
|
||||||
|
struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
|
||||||
|
|
||||||
|
/* XXX: does dsr also represent inputs? */
|
||||||
|
return ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8))
|
||||||
|
& TC_GPIO_BIT(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __tc6393xb_gpio_set(struct gpio_chip *chip,
|
||||||
|
unsigned offset, int value)
|
||||||
|
{
|
||||||
|
struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
|
||||||
|
u8 dsr;
|
||||||
|
|
||||||
|
dsr = ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8));
|
||||||
|
if (value)
|
||||||
|
dsr |= TC_GPIO_BIT(offset);
|
||||||
|
else
|
||||||
|
dsr &= ~TC_GPIO_BIT(offset);
|
||||||
|
|
||||||
|
iowrite8(dsr, tc6393xb->scr + SCR_GPO_DSR(offset / 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tc6393xb_gpio_set(struct gpio_chip *chip,
|
||||||
|
unsigned offset, int value)
|
||||||
|
{
|
||||||
|
struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&tc6393xb->lock, flags);
|
||||||
|
|
||||||
|
__tc6393xb_gpio_set(chip, offset, value);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&tc6393xb->lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tc6393xb_gpio_direction_input(struct gpio_chip *chip,
|
||||||
|
unsigned offset)
|
||||||
|
{
|
||||||
|
struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
|
||||||
|
unsigned long flags;
|
||||||
|
u8 doecr;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&tc6393xb->lock, flags);
|
||||||
|
|
||||||
|
doecr = ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
|
||||||
|
doecr &= ~TC_GPIO_BIT(offset);
|
||||||
|
iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&tc6393xb->lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tc6393xb_gpio_direction_output(struct gpio_chip *chip,
|
||||||
|
unsigned offset, int value)
|
||||||
|
{
|
||||||
|
struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
|
||||||
|
unsigned long flags;
|
||||||
|
u8 doecr;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&tc6393xb->lock, flags);
|
||||||
|
|
||||||
|
__tc6393xb_gpio_set(chip, offset, value);
|
||||||
|
|
||||||
|
doecr = ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
|
||||||
|
doecr |= TC_GPIO_BIT(offset);
|
||||||
|
iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&tc6393xb->lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tc6393xb_register_gpio(struct tc6393xb *tc6393xb, int gpio_base)
|
||||||
|
{
|
||||||
|
tc6393xb->gpio.label = "tc6393xb";
|
||||||
|
tc6393xb->gpio.base = gpio_base;
|
||||||
|
tc6393xb->gpio.ngpio = 16;
|
||||||
|
tc6393xb->gpio.set = tc6393xb_gpio_set;
|
||||||
|
tc6393xb->gpio.get = tc6393xb_gpio_get;
|
||||||
|
tc6393xb->gpio.direction_input = tc6393xb_gpio_direction_input;
|
||||||
|
tc6393xb->gpio.direction_output = tc6393xb_gpio_direction_output;
|
||||||
|
|
||||||
|
return gpiochip_add(&tc6393xb->gpio);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
tc6393xb_irq(unsigned int irq, struct irq_desc *desc)
|
||||||
|
{
|
||||||
|
struct tc6393xb *tc6393xb = get_irq_data(irq);
|
||||||
|
unsigned int isr;
|
||||||
|
unsigned int i, irq_base;
|
||||||
|
|
||||||
|
irq_base = tc6393xb->irq_base;
|
||||||
|
|
||||||
|
while ((isr = ioread8(tc6393xb->scr + SCR_ISR) &
|
||||||
|
~ioread8(tc6393xb->scr + SCR_IMR)))
|
||||||
|
for (i = 0; i < TC6393XB_NR_IRQS; i++) {
|
||||||
|
if (isr & (1 << i))
|
||||||
|
generic_handle_irq(irq_base + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tc6393xb_irq_ack(unsigned int irq)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tc6393xb_irq_mask(unsigned int irq)
|
||||||
|
{
|
||||||
|
struct tc6393xb *tc6393xb = get_irq_chip_data(irq);
|
||||||
|
unsigned long flags;
|
||||||
|
u8 imr;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&tc6393xb->lock, flags);
|
||||||
|
imr = ioread8(tc6393xb->scr + SCR_IMR);
|
||||||
|
imr |= 1 << (irq - tc6393xb->irq_base);
|
||||||
|
iowrite8(imr, tc6393xb->scr + SCR_IMR);
|
||||||
|
spin_unlock_irqrestore(&tc6393xb->lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tc6393xb_irq_unmask(unsigned int irq)
|
||||||
|
{
|
||||||
|
struct tc6393xb *tc6393xb = get_irq_chip_data(irq);
|
||||||
|
unsigned long flags;
|
||||||
|
u8 imr;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&tc6393xb->lock, flags);
|
||||||
|
imr = ioread8(tc6393xb->scr + SCR_IMR);
|
||||||
|
imr &= ~(1 << (irq - tc6393xb->irq_base));
|
||||||
|
iowrite8(imr, tc6393xb->scr + SCR_IMR);
|
||||||
|
spin_unlock_irqrestore(&tc6393xb->lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct irq_chip tc6393xb_chip = {
|
||||||
|
.name = "tc6393xb",
|
||||||
|
.ack = tc6393xb_irq_ack,
|
||||||
|
.mask = tc6393xb_irq_mask,
|
||||||
|
.unmask = tc6393xb_irq_unmask,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void tc6393xb_attach_irq(struct platform_device *dev)
|
||||||
|
{
|
||||||
|
struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
|
||||||
|
unsigned int irq, irq_base;
|
||||||
|
|
||||||
|
irq_base = tc6393xb->irq_base;
|
||||||
|
|
||||||
|
for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) {
|
||||||
|
set_irq_chip(irq, &tc6393xb_chip);
|
||||||
|
set_irq_chip_data(irq, tc6393xb);
|
||||||
|
set_irq_handler(irq, handle_edge_irq);
|
||||||
|
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
|
||||||
|
}
|
||||||
|
|
||||||
|
set_irq_type(tc6393xb->irq, IRQT_FALLING);
|
||||||
|
set_irq_data(tc6393xb->irq, tc6393xb);
|
||||||
|
set_irq_chained_handler(tc6393xb->irq, tc6393xb_irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tc6393xb_detach_irq(struct platform_device *dev)
|
||||||
|
{
|
||||||
|
struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
|
||||||
|
unsigned int irq, irq_base;
|
||||||
|
|
||||||
|
set_irq_chained_handler(tc6393xb->irq, NULL);
|
||||||
|
set_irq_data(tc6393xb->irq, NULL);
|
||||||
|
|
||||||
|
irq_base = tc6393xb->irq_base;
|
||||||
|
|
||||||
|
for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) {
|
||||||
|
set_irq_flags(irq, 0);
|
||||||
|
set_irq_chip(irq, NULL);
|
||||||
|
set_irq_chip_data(irq, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static int tc6393xb_hw_init(struct platform_device *dev)
|
||||||
|
{
|
||||||
|
struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
|
||||||
|
struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
iowrite8(tc6393xb->suspend_state.fer, tc6393xb->scr + SCR_FER);
|
||||||
|
iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR);
|
||||||
|
iowrite16(tc6393xb->suspend_state.ccr, tc6393xb->scr + SCR_CCR);
|
||||||
|
iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN |
|
||||||
|
SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN |
|
||||||
|
BIT(15), tc6393xb->scr + SCR_MCR);
|
||||||
|
iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER);
|
||||||
|
iowrite8(0, tc6393xb->scr + SCR_IRR);
|
||||||
|
iowrite8(0xbf, tc6393xb->scr + SCR_IMR);
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
iowrite8(tc6393xb->suspend_state.gpo_dsr[i],
|
||||||
|
tc6393xb->scr + SCR_GPO_DSR(i));
|
||||||
|
iowrite8(tc6393xb->suspend_state.gpo_doecr[i],
|
||||||
|
tc6393xb->scr + SCR_GPO_DOECR(i));
|
||||||
|
iowrite8(tc6393xb->suspend_state.gpi_bcr[i],
|
||||||
|
tc6393xb->scr + SCR_GPI_BCR(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __devinit tc6393xb_probe(struct platform_device *dev)
|
||||||
|
{
|
||||||
|
struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
|
||||||
|
struct tc6393xb *tc6393xb;
|
||||||
|
struct resource *iomem;
|
||||||
|
struct resource *rscr;
|
||||||
|
int retval, temp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
|
||||||
|
if (!iomem)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
tc6393xb = kzalloc(sizeof *tc6393xb, GFP_KERNEL);
|
||||||
|
if (!tc6393xb) {
|
||||||
|
retval = -ENOMEM;
|
||||||
|
goto err_kzalloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock_init(&tc6393xb->lock);
|
||||||
|
|
||||||
|
platform_set_drvdata(dev, tc6393xb);
|
||||||
|
tc6393xb->iomem = iomem;
|
||||||
|
tc6393xb->irq = platform_get_irq(dev, 0);
|
||||||
|
tc6393xb->irq_base = tcpd->irq_base;
|
||||||
|
|
||||||
|
tc6393xb->clk = clk_get(&dev->dev, "GPIO27_CLK" /* "CK3P6MI" */);
|
||||||
|
if (IS_ERR(tc6393xb->clk)) {
|
||||||
|
retval = PTR_ERR(tc6393xb->clk);
|
||||||
|
goto err_clk_get;
|
||||||
|
}
|
||||||
|
|
||||||
|
rscr = &tc6393xb->rscr;
|
||||||
|
rscr->name = "tc6393xb-core";
|
||||||
|
rscr->start = iomem->start;
|
||||||
|
rscr->end = iomem->start + 0xff;
|
||||||
|
rscr->flags = IORESOURCE_MEM;
|
||||||
|
|
||||||
|
retval = request_resource(iomem, rscr);
|
||||||
|
if (retval)
|
||||||
|
goto err_request_scr;
|
||||||
|
|
||||||
|
tc6393xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1);
|
||||||
|
if (!tc6393xb->scr) {
|
||||||
|
retval = -ENOMEM;
|
||||||
|
goto err_ioremap;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = clk_enable(tc6393xb->clk);
|
||||||
|
if (retval)
|
||||||
|
goto err_clk_enable;
|
||||||
|
|
||||||
|
retval = tcpd->enable(dev);
|
||||||
|
if (retval)
|
||||||
|
goto err_enable;
|
||||||
|
|
||||||
|
tc6393xb->suspend_state.fer = 0;
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
tc6393xb->suspend_state.gpo_dsr[i] =
|
||||||
|
(tcpd->scr_gpo_dsr >> (8 * i)) & 0xff;
|
||||||
|
tc6393xb->suspend_state.gpo_doecr[i] =
|
||||||
|
(tcpd->scr_gpo_doecr >> (8 * i)) & 0xff;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* It may be necessary to change this back to
|
||||||
|
* platform-dependant code
|
||||||
|
*/
|
||||||
|
tc6393xb->suspend_state.ccr = SCR_CCR_UNK1 |
|
||||||
|
SCR_CCR_HCLK_48;
|
||||||
|
|
||||||
|
retval = tc6393xb_hw_init(dev);
|
||||||
|
if (retval)
|
||||||
|
goto err_hw_init;
|
||||||
|
|
||||||
|
printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n",
|
||||||
|
ioread8(tc6393xb->scr + SCR_REVID),
|
||||||
|
(unsigned long) iomem->start, tc6393xb->irq);
|
||||||
|
|
||||||
|
tc6393xb->gpio.base = -1;
|
||||||
|
|
||||||
|
if (tcpd->gpio_base >= 0) {
|
||||||
|
retval = tc6393xb_register_gpio(tc6393xb, tcpd->gpio_base);
|
||||||
|
if (retval)
|
||||||
|
goto err_gpio_add;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tc6393xb->irq)
|
||||||
|
tc6393xb_attach_irq(dev);
|
||||||
|
|
||||||
|
tc6393xb_cells[TC6393XB_CELL_NAND].driver_data = tcpd->nand_data;
|
||||||
|
|
||||||
|
retval = mfd_add_devices(dev,
|
||||||
|
tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells),
|
||||||
|
iomem, tcpd->irq_base);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (tc6393xb->irq)
|
||||||
|
tc6393xb_detach_irq(dev);
|
||||||
|
|
||||||
|
err_gpio_add:
|
||||||
|
if (tc6393xb->gpio.base != -1)
|
||||||
|
temp = gpiochip_remove(&tc6393xb->gpio);
|
||||||
|
err_hw_init:
|
||||||
|
tcpd->disable(dev);
|
||||||
|
err_clk_enable:
|
||||||
|
clk_disable(tc6393xb->clk);
|
||||||
|
err_enable:
|
||||||
|
iounmap(tc6393xb->scr);
|
||||||
|
err_ioremap:
|
||||||
|
release_resource(&tc6393xb->rscr);
|
||||||
|
err_request_scr:
|
||||||
|
clk_put(tc6393xb->clk);
|
||||||
|
err_clk_get:
|
||||||
|
kfree(tc6393xb);
|
||||||
|
err_kzalloc:
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __devexit tc6393xb_remove(struct platform_device *dev)
|
||||||
|
{
|
||||||
|
struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
|
||||||
|
struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mfd_remove_devices(dev);
|
||||||
|
|
||||||
|
if (tc6393xb->irq)
|
||||||
|
tc6393xb_detach_irq(dev);
|
||||||
|
|
||||||
|
if (tc6393xb->gpio.base != -1) {
|
||||||
|
ret = gpiochip_remove(&tc6393xb->gpio);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&dev->dev, "Can't remove gpio chip: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = tcpd->disable(dev);
|
||||||
|
|
||||||
|
clk_disable(tc6393xb->clk);
|
||||||
|
|
||||||
|
iounmap(tc6393xb->scr);
|
||||||
|
|
||||||
|
release_resource(&tc6393xb->rscr);
|
||||||
|
|
||||||
|
platform_set_drvdata(dev, NULL);
|
||||||
|
|
||||||
|
clk_put(tc6393xb->clk);
|
||||||
|
|
||||||
|
kfree(tc6393xb);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state)
|
||||||
|
{
|
||||||
|
struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
|
||||||
|
struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
|
||||||
|
tc6393xb->suspend_state.ccr = ioread16(tc6393xb->scr + SCR_CCR);
|
||||||
|
tc6393xb->suspend_state.fer = ioread8(tc6393xb->scr + SCR_FER);
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
tc6393xb->suspend_state.gpo_dsr[i] =
|
||||||
|
ioread8(tc6393xb->scr + SCR_GPO_DSR(i));
|
||||||
|
tc6393xb->suspend_state.gpo_doecr[i] =
|
||||||
|
ioread8(tc6393xb->scr + SCR_GPO_DOECR(i));
|
||||||
|
tc6393xb->suspend_state.gpi_bcr[i] =
|
||||||
|
ioread8(tc6393xb->scr + SCR_GPI_BCR(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return tcpd->suspend(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tc6393xb_resume(struct platform_device *dev)
|
||||||
|
{
|
||||||
|
struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
|
||||||
|
int ret = tcpd->resume(dev);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return tc6393xb_hw_init(dev);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define tc6393xb_suspend NULL
|
||||||
|
#define tc6393xb_resume NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct platform_driver tc6393xb_driver = {
|
||||||
|
.probe = tc6393xb_probe,
|
||||||
|
.remove = __devexit_p(tc6393xb_remove),
|
||||||
|
.suspend = tc6393xb_suspend,
|
||||||
|
.resume = tc6393xb_resume,
|
||||||
|
|
||||||
|
.driver = {
|
||||||
|
.name = "tc6393xb",
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init tc6393xb_init(void)
|
||||||
|
{
|
||||||
|
return platform_driver_register(&tc6393xb_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit tc6393xb_exit(void)
|
||||||
|
{
|
||||||
|
platform_driver_unregister(&tc6393xb_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
subsys_initcall(tc6393xb_init);
|
||||||
|
module_exit(tc6393xb_exit);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer");
|
||||||
|
MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller");
|
||||||
|
MODULE_ALIAS("platform:tc6393xb");
|
@@ -208,6 +208,11 @@ extern void pxa_gpio_set_value(unsigned gpio, int value);
|
|||||||
*/
|
*/
|
||||||
extern unsigned int get_memclk_frequency_10khz(void);
|
extern unsigned int get_memclk_frequency_10khz(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* register GPIO as reset generator
|
||||||
|
*/
|
||||||
|
extern int init_gpio_reset(int gpio);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI)
|
#if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI)
|
||||||
|
@@ -180,6 +180,7 @@
|
|||||||
#define NR_IRQS (IRQ_LOCOMO_SPI_TEND + 1)
|
#define NR_IRQS (IRQ_LOCOMO_SPI_TEND + 1)
|
||||||
#elif defined(CONFIG_ARCH_LUBBOCK) || \
|
#elif defined(CONFIG_ARCH_LUBBOCK) || \
|
||||||
defined(CONFIG_MACH_LOGICPD_PXA270) || \
|
defined(CONFIG_MACH_LOGICPD_PXA270) || \
|
||||||
|
defined(CONFIG_MACH_TOSA) || \
|
||||||
defined(CONFIG_MACH_MAINSTONE) || \
|
defined(CONFIG_MACH_MAINSTONE) || \
|
||||||
defined(CONFIG_MACH_PCM027) || \
|
defined(CONFIG_MACH_PCM027) || \
|
||||||
defined(CONFIG_MACH_MAGICIAN)
|
defined(CONFIG_MACH_MAGICIAN)
|
||||||
|
@@ -21,19 +21,4 @@ static inline void arch_idle(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void arch_reset(char mode)
|
void arch_reset(char mode);
|
||||||
{
|
|
||||||
if (cpu_is_pxa2xx())
|
|
||||||
RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
|
|
||||||
|
|
||||||
if (mode == 's') {
|
|
||||||
/* Jump into ROM at address 0 */
|
|
||||||
cpu_reset(0);
|
|
||||||
} else {
|
|
||||||
/* Initialize the watchdog and let it fire */
|
|
||||||
OWER = OWER_WME;
|
|
||||||
OSSR = OSSR_M3;
|
|
||||||
OSMR3 = OSCR + 368640; /* ... in 100 ms */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@@ -25,21 +25,18 @@
|
|||||||
*/
|
*/
|
||||||
#define TOSA_SCOOP_GPIO_BASE NR_BUILTIN_GPIO
|
#define TOSA_SCOOP_GPIO_BASE NR_BUILTIN_GPIO
|
||||||
#define TOSA_SCOOP_PXA_VCORE1 SCOOP_GPCR_PA11
|
#define TOSA_SCOOP_PXA_VCORE1 SCOOP_GPCR_PA11
|
||||||
#define TOSA_SCOOP_TC6393_REST_IN SCOOP_GPCR_PA12
|
#define TOSA_GPIO_TC6393XB_REST_IN (TOSA_SCOOP_GPIO_BASE + 1)
|
||||||
#define TOSA_GPIO_IR_POWERDWN (TOSA_SCOOP_GPIO_BASE + 2)
|
#define TOSA_GPIO_IR_POWERDWN (TOSA_SCOOP_GPIO_BASE + 2)
|
||||||
#define TOSA_GPIO_SD_WP (TOSA_SCOOP_GPIO_BASE + 3)
|
#define TOSA_GPIO_SD_WP (TOSA_SCOOP_GPIO_BASE + 3)
|
||||||
#define TOSA_GPIO_PWR_ON (TOSA_SCOOP_GPIO_BASE + 4)
|
#define TOSA_GPIO_PWR_ON (TOSA_SCOOP_GPIO_BASE + 4)
|
||||||
#define TOSA_SCOOP_AUD_PWR_ON SCOOP_GPCR_PA16
|
#define TOSA_SCOOP_AUD_PWR_ON SCOOP_GPCR_PA16
|
||||||
#define TOSA_SCOOP_BT_RESET SCOOP_GPCR_PA17
|
#define TOSA_GPIO_BT_RESET (TOSA_SCOOP_GPIO_BASE + 6)
|
||||||
#define TOSA_SCOOP_BT_PWR_EN SCOOP_GPCR_PA18
|
#define TOSA_GPIO_BT_PWR_EN (TOSA_SCOOP_GPIO_BASE + 7)
|
||||||
#define TOSA_SCOOP_AC_IN_OL SCOOP_GPCR_PA19
|
#define TOSA_SCOOP_AC_IN_OL SCOOP_GPCR_PA19
|
||||||
|
|
||||||
/* GPIO Direction 1 : output mode / 0:input mode */
|
/* GPIO Direction 1 : output mode / 0:input mode */
|
||||||
#define TOSA_SCOOP_IO_DIR ( TOSA_SCOOP_PXA_VCORE1 | TOSA_SCOOP_TC6393_REST_IN | \
|
#define TOSA_SCOOP_IO_DIR (TOSA_SCOOP_PXA_VCORE1 | \
|
||||||
TOSA_SCOOP_AUD_PWR_ON |\
|
TOSA_SCOOP_AUD_PWR_ON)
|
||||||
TOSA_SCOOP_BT_RESET | TOSA_SCOOP_BT_PWR_EN )
|
|
||||||
/* GPIO out put level when init 1: Hi */
|
|
||||||
#define TOSA_SCOOP_IO_OUT ( TOSA_SCOOP_TC6393_REST_IN )
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SCOOP2 jacket GPIOs
|
* SCOOP2 jacket GPIOs
|
||||||
@@ -49,16 +46,34 @@
|
|||||||
#define TOSA_GPIO_NOTE_LED (TOSA_SCOOP_JC_GPIO_BASE + 1)
|
#define TOSA_GPIO_NOTE_LED (TOSA_SCOOP_JC_GPIO_BASE + 1)
|
||||||
#define TOSA_GPIO_CHRG_ERR_LED (TOSA_SCOOP_JC_GPIO_BASE + 2)
|
#define TOSA_GPIO_CHRG_ERR_LED (TOSA_SCOOP_JC_GPIO_BASE + 2)
|
||||||
#define TOSA_GPIO_USB_PULLUP (TOSA_SCOOP_JC_GPIO_BASE + 3)
|
#define TOSA_GPIO_USB_PULLUP (TOSA_SCOOP_JC_GPIO_BASE + 3)
|
||||||
#define TOSA_SCOOP_JC_TC6393_SUSPEND SCOOP_GPCR_PA15
|
#define TOSA_GPIO_TC6393XB_SUSPEND (TOSA_SCOOP_JC_GPIO_BASE + 4)
|
||||||
#define TOSA_SCOOP_JC_TC3693_L3V_ON SCOOP_GPCR_PA16
|
#define TOSA_GPIO_TC6393XB_L3V_ON (TOSA_SCOOP_JC_GPIO_BASE + 5)
|
||||||
#define TOSA_SCOOP_JC_WLAN_DETECT SCOOP_GPCR_PA17
|
#define TOSA_SCOOP_JC_WLAN_DETECT SCOOP_GPCR_PA17
|
||||||
#define TOSA_GPIO_WLAN_LED (TOSA_SCOOP_JC_GPIO_BASE + 7)
|
#define TOSA_GPIO_WLAN_LED (TOSA_SCOOP_JC_GPIO_BASE + 7)
|
||||||
#define TOSA_SCOOP_JC_CARD_LIMIT_SEL SCOOP_GPCR_PA19
|
#define TOSA_SCOOP_JC_CARD_LIMIT_SEL SCOOP_GPCR_PA19
|
||||||
|
|
||||||
/* GPIO Direction 1 : output mode / 0:input mode */
|
/* GPIO Direction 1 : output mode / 0:input mode */
|
||||||
#define TOSA_SCOOP_JC_IO_DIR ( \
|
#define TOSA_SCOOP_JC_IO_DIR (TOSA_SCOOP_JC_CARD_LIMIT_SEL)
|
||||||
TOSA_SCOOP_JC_TC6393_SUSPEND | TOSA_SCOOP_JC_TC3693_L3V_ON | \
|
|
||||||
TOSA_SCOOP_JC_CARD_LIMIT_SEL )
|
/*
|
||||||
|
* TC6393XB GPIOs
|
||||||
|
*/
|
||||||
|
#define TOSA_TC6393XB_GPIO_BASE (NR_BUILTIN_GPIO + 2 * 12)
|
||||||
|
#define TOSA_TC6393XB_GPIO(i) (TOSA_TC6393XB_GPIO_BASE + (i))
|
||||||
|
#define TOSA_TC6393XB_GPIO_BIT(gpio) (1 << (gpio - TOSA_TC6393XB_GPIO_BASE))
|
||||||
|
|
||||||
|
#define TOSA_GPIO_TG_ON (TOSA_TC6393XB_GPIO_BASE + 0)
|
||||||
|
#define TOSA_GPIO_L_MUTE (TOSA_TC6393XB_GPIO_BASE + 1)
|
||||||
|
#define TOSA_GPIO_BL_C20MA (TOSA_TC6393XB_GPIO_BASE + 3)
|
||||||
|
#define TOSA_GPIO_CARD_VCC_ON (TOSA_TC6393XB_GPIO_BASE + 4)
|
||||||
|
#define TOSA_GPIO_CHARGE_OFF (TOSA_TC6393XB_GPIO_BASE + 6)
|
||||||
|
#define TOSA_GPIO_CHARGE_OFF_JC (TOSA_TC6393XB_GPIO_BASE + 7)
|
||||||
|
#define TOSA_GPIO_BAT0_V_ON (TOSA_TC6393XB_GPIO_BASE + 9)
|
||||||
|
#define TOSA_GPIO_BAT1_V_ON (TOSA_TC6393XB_GPIO_BASE + 10)
|
||||||
|
#define TOSA_GPIO_BU_CHRG_ON (TOSA_TC6393XB_GPIO_BASE + 11)
|
||||||
|
#define TOSA_GPIO_BAT_SW_ON (TOSA_TC6393XB_GPIO_BASE + 12)
|
||||||
|
#define TOSA_GPIO_BAT0_TH_ON (TOSA_TC6393XB_GPIO_BASE + 14)
|
||||||
|
#define TOSA_GPIO_BAT1_TH_ON (TOSA_TC6393XB_GPIO_BASE + 15)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Timing Generator
|
* Timing Generator
|
||||||
@@ -84,13 +99,13 @@
|
|||||||
#define TOSA_GPIO_JACKET_DETECT (7)
|
#define TOSA_GPIO_JACKET_DETECT (7)
|
||||||
#define TOSA_GPIO_nSD_DETECT (9)
|
#define TOSA_GPIO_nSD_DETECT (9)
|
||||||
#define TOSA_GPIO_nSD_INT (10)
|
#define TOSA_GPIO_nSD_INT (10)
|
||||||
#define TOSA_GPIO_TC6393_CLK (11)
|
#define TOSA_GPIO_TC6393XB_CLK (11)
|
||||||
#define TOSA_GPIO_BAT1_CRG (12)
|
#define TOSA_GPIO_BAT1_CRG (12)
|
||||||
#define TOSA_GPIO_CF_CD (13)
|
#define TOSA_GPIO_CF_CD (13)
|
||||||
#define TOSA_GPIO_BAT0_CRG (14)
|
#define TOSA_GPIO_BAT0_CRG (14)
|
||||||
#define TOSA_GPIO_TC6393_INT (15)
|
#define TOSA_GPIO_TC6393XB_INT (15)
|
||||||
#define TOSA_GPIO_BAT0_LOW (17)
|
#define TOSA_GPIO_BAT0_LOW (17)
|
||||||
#define TOSA_GPIO_TC6393_RDY (18)
|
#define TOSA_GPIO_TC6393XB_RDY (18)
|
||||||
#define TOSA_GPIO_ON_RESET (19)
|
#define TOSA_GPIO_ON_RESET (19)
|
||||||
#define TOSA_GPIO_EAR_IN (20)
|
#define TOSA_GPIO_EAR_IN (20)
|
||||||
#define TOSA_GPIO_CF_IRQ (21) /* CF slot0 Ready */
|
#define TOSA_GPIO_CF_IRQ (21) /* CF slot0 Ready */
|
||||||
@@ -99,6 +114,7 @@
|
|||||||
#define TOSA_GPIO_TP_INT (32) /* Touch Panel pen down interrupt */
|
#define TOSA_GPIO_TP_INT (32) /* Touch Panel pen down interrupt */
|
||||||
#define TOSA_GPIO_JC_CF_IRQ (36) /* CF slot1 Ready */
|
#define TOSA_GPIO_JC_CF_IRQ (36) /* CF slot1 Ready */
|
||||||
#define TOSA_GPIO_BAT_LOCKED (38) /* Battery locked */
|
#define TOSA_GPIO_BAT_LOCKED (38) /* Battery locked */
|
||||||
|
#define TOSA_GPIO_IRDA_TX (47)
|
||||||
#define TOSA_GPIO_TG_SPI_SCLK (81)
|
#define TOSA_GPIO_TG_SPI_SCLK (81)
|
||||||
#define TOSA_GPIO_TG_SPI_CS (82)
|
#define TOSA_GPIO_TG_SPI_CS (82)
|
||||||
#define TOSA_GPIO_TG_SPI_MOSI (83)
|
#define TOSA_GPIO_TG_SPI_MOSI (83)
|
||||||
@@ -137,7 +153,7 @@
|
|||||||
#define TOSA_IRQ_GPIO_BAT1_CRG IRQ_GPIO(TOSA_GPIO_BAT1_CRG)
|
#define TOSA_IRQ_GPIO_BAT1_CRG IRQ_GPIO(TOSA_GPIO_BAT1_CRG)
|
||||||
#define TOSA_IRQ_GPIO_CF_CD IRQ_GPIO(TOSA_GPIO_CF_CD)
|
#define TOSA_IRQ_GPIO_CF_CD IRQ_GPIO(TOSA_GPIO_CF_CD)
|
||||||
#define TOSA_IRQ_GPIO_BAT0_CRG IRQ_GPIO(TOSA_GPIO_BAT0_CRG)
|
#define TOSA_IRQ_GPIO_BAT0_CRG IRQ_GPIO(TOSA_GPIO_BAT0_CRG)
|
||||||
#define TOSA_IRQ_GPIO_TC6393_INT IRQ_GPIO(TOSA_GPIO_TC6393_INT)
|
#define TOSA_IRQ_GPIO_TC6393XB_INT IRQ_GPIO(TOSA_GPIO_TC6393XB_INT)
|
||||||
#define TOSA_IRQ_GPIO_BAT0_LOW IRQ_GPIO(TOSA_GPIO_BAT0_LOW)
|
#define TOSA_IRQ_GPIO_BAT0_LOW IRQ_GPIO(TOSA_GPIO_BAT0_LOW)
|
||||||
#define TOSA_IRQ_GPIO_EAR_IN IRQ_GPIO(TOSA_GPIO_EAR_IN)
|
#define TOSA_IRQ_GPIO_EAR_IN IRQ_GPIO(TOSA_GPIO_EAR_IN)
|
||||||
#define TOSA_IRQ_GPIO_CF_IRQ IRQ_GPIO(TOSA_GPIO_CF_IRQ)
|
#define TOSA_IRQ_GPIO_CF_IRQ IRQ_GPIO(TOSA_GPIO_CF_IRQ)
|
||||||
|
22
include/asm-arm/arch-pxa/tosa_bt.h
Normal file
22
include/asm-arm/arch-pxa/tosa_bt.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Tosa bluetooth built-in chip control.
|
||||||
|
*
|
||||||
|
* Later it may be shared with some other platforms.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef TOSA_BT_H
|
||||||
|
#define TOSA_BT_H
|
||||||
|
|
||||||
|
struct tosa_bt_data {
|
||||||
|
int gpio_pwr;
|
||||||
|
int gpio_reset;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
55
include/linux/mfd/core.h
Normal file
55
include/linux/mfd/core.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#ifndef MFD_CORE_H
|
||||||
|
#define MFD_CORE_H
|
||||||
|
/*
|
||||||
|
* drivers/mfd/mfd-core.h
|
||||||
|
*
|
||||||
|
* core MFD support
|
||||||
|
* Copyright (c) 2006 Ian Molton
|
||||||
|
* Copyright (c) 2007 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/platform_device.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This struct describes the MFD part ("cell").
|
||||||
|
* After registration the copy of this structure will become the platform data
|
||||||
|
* of the resulting platform_device
|
||||||
|
*/
|
||||||
|
struct mfd_cell {
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
int (*enable)(struct platform_device *dev);
|
||||||
|
int (*disable)(struct platform_device *dev);
|
||||||
|
int (*suspend)(struct platform_device *dev);
|
||||||
|
int (*resume)(struct platform_device *dev);
|
||||||
|
|
||||||
|
void *driver_data; /* driver-specific data */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This resources can be specified relatievly to the parent device.
|
||||||
|
* For accessing device you should use resources from device
|
||||||
|
*/
|
||||||
|
int num_resources;
|
||||||
|
const struct resource *resources;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct mfd_cell *
|
||||||
|
mfd_get_cell(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
return (struct mfd_cell *)pdev->dev.platform_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int mfd_add_devices(
|
||||||
|
struct platform_device *parent,
|
||||||
|
const struct mfd_cell *cells, int n_devs,
|
||||||
|
struct resource *mem_base,
|
||||||
|
int irq_base);
|
||||||
|
|
||||||
|
extern void mfd_remove_devices(struct platform_device *parent);
|
||||||
|
|
||||||
|
#endif
|
49
include/linux/mfd/tc6393xb.h
Normal file
49
include/linux/mfd/tc6393xb.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Toshiba TC6393XB SoC support
|
||||||
|
*
|
||||||
|
* Copyright(c) 2005-2006 Chris Humbert
|
||||||
|
* Copyright(c) 2005 Dirk Opfer
|
||||||
|
* Copyright(c) 2005 Ian Molton <spyro@f2s.com>
|
||||||
|
* Copyright(c) 2007 Dmitry Baryshkov
|
||||||
|
*
|
||||||
|
* Based on code written by Sharp/Lineo for 2.4 kernels
|
||||||
|
* Based on locomo.c
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TC6393XB_H
|
||||||
|
#define TC6393XB_H
|
||||||
|
|
||||||
|
/* Also one should provide the CK3P6MI clock */
|
||||||
|
struct tc6393xb_platform_data {
|
||||||
|
u16 scr_pll2cr; /* PLL2 Control */
|
||||||
|
u16 scr_gper; /* GP Enable */
|
||||||
|
u32 scr_gpo_doecr; /* GPO Data OE Control */
|
||||||
|
u32 scr_gpo_dsr; /* GPO Data Set */
|
||||||
|
|
||||||
|
int (*enable)(struct platform_device *dev);
|
||||||
|
int (*disable)(struct platform_device *dev);
|
||||||
|
int (*suspend)(struct platform_device *dev);
|
||||||
|
int (*resume)(struct platform_device *dev);
|
||||||
|
|
||||||
|
int irq_base; /* a base for cascaded irq */
|
||||||
|
int gpio_base;
|
||||||
|
|
||||||
|
struct tmio_nand_data *nand_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Relative to irq_base
|
||||||
|
*/
|
||||||
|
#define IRQ_TC6393_NAND 0
|
||||||
|
#define IRQ_TC6393_MMC 1
|
||||||
|
#define IRQ_TC6393_OHCI 2
|
||||||
|
#define IRQ_TC6393_SERIAL 3
|
||||||
|
#define IRQ_TC6393_FB 4
|
||||||
|
|
||||||
|
#define TC6393XB_NR_IRQS 8
|
||||||
|
|
||||||
|
#endif
|
17
include/linux/mfd/tmio.h
Normal file
17
include/linux/mfd/tmio.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef MFD_TMIO_H
|
||||||
|
#define MFD_TMIO_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* data for the NAND controller
|
||||||
|
*/
|
||||||
|
struct tmio_nand_data {
|
||||||
|
struct nand_bbt_descr *badblock_pattern;
|
||||||
|
struct mtd_partition *partition;
|
||||||
|
unsigned int num_partitions;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TMIO_NAND_CONFIG "tmio-nand-config"
|
||||||
|
#define TMIO_NAND_CONTROL "tmio-nand-control"
|
||||||
|
#define TMIO_NAND_IRQ "tmio-nand"
|
||||||
|
|
||||||
|
#endif
|
@@ -48,6 +48,7 @@ config SND_PXA2XX_SOC_POODLE
|
|||||||
config SND_PXA2XX_SOC_TOSA
|
config SND_PXA2XX_SOC_TOSA
|
||||||
tristate "SoC AC97 Audio support for Tosa"
|
tristate "SoC AC97 Audio support for Tosa"
|
||||||
depends on SND_PXA2XX_SOC && MACH_TOSA
|
depends on SND_PXA2XX_SOC && MACH_TOSA
|
||||||
|
depends on MFD_TC6393XB
|
||||||
select SND_PXA2XX_SOC_AC97
|
select SND_PXA2XX_SOC_AC97
|
||||||
select SND_SOC_WM9712
|
select SND_SOC_WM9712
|
||||||
help
|
help
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/moduleparam.h>
|
#include <linux/moduleparam.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
|
||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
#include <sound/pcm.h>
|
#include <sound/pcm.h>
|
||||||
@@ -31,7 +32,7 @@
|
|||||||
#include <sound/soc-dapm.h>
|
#include <sound/soc-dapm.h>
|
||||||
|
|
||||||
#include <asm/mach-types.h>
|
#include <asm/mach-types.h>
|
||||||
#include <asm/hardware/tmio.h>
|
#include <asm/arch/tosa.h>
|
||||||
#include <asm/arch/pxa-regs.h>
|
#include <asm/arch/pxa-regs.h>
|
||||||
#include <asm/arch/hardware.h>
|
#include <asm/arch/hardware.h>
|
||||||
#include <asm/arch/audio.h>
|
#include <asm/arch/audio.h>
|
||||||
@@ -138,10 +139,7 @@ static int tosa_set_spk(struct snd_kcontrol *kcontrol,
|
|||||||
static int tosa_hp_event(struct snd_soc_dapm_widget *w,
|
static int tosa_hp_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *k, int event)
|
struct snd_kcontrol *k, int event)
|
||||||
{
|
{
|
||||||
if (SND_SOC_DAPM_EVENT_ON(event))
|
gpio_set_value(TOSA_GPIO_L_MUTE, SND_SOC_DAPM_EVENT_ON(event) ? 1 :0);
|
||||||
set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE);
|
|
||||||
else
|
|
||||||
reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,16 +259,28 @@ static int __init tosa_init(void)
|
|||||||
if (!machine_is_tosa())
|
if (!machine_is_tosa())
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
ret = gpio_request(TOSA_GPIO_L_MUTE, "Headphone Jack");
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
gpio_direction_output(TOSA_GPIO_L_MUTE, 0);
|
||||||
|
|
||||||
tosa_snd_device = platform_device_alloc("soc-audio", -1);
|
tosa_snd_device = platform_device_alloc("soc-audio", -1);
|
||||||
if (!tosa_snd_device)
|
if (!tosa_snd_device) {
|
||||||
return -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
goto err_alloc;
|
||||||
|
}
|
||||||
|
|
||||||
platform_set_drvdata(tosa_snd_device, &tosa_snd_devdata);
|
platform_set_drvdata(tosa_snd_device, &tosa_snd_devdata);
|
||||||
tosa_snd_devdata.dev = &tosa_snd_device->dev;
|
tosa_snd_devdata.dev = &tosa_snd_device->dev;
|
||||||
ret = platform_device_add(tosa_snd_device);
|
ret = platform_device_add(tosa_snd_device);
|
||||||
|
|
||||||
if (ret)
|
if (!ret)
|
||||||
platform_device_put(tosa_snd_device);
|
return 0;
|
||||||
|
|
||||||
|
platform_device_put(tosa_snd_device);
|
||||||
|
|
||||||
|
err_alloc:
|
||||||
|
gpio_free(TOSA_GPIO_L_MUTE);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -278,6 +288,7 @@ static int __init tosa_init(void)
|
|||||||
static void __exit tosa_exit(void)
|
static void __exit tosa_exit(void)
|
||||||
{
|
{
|
||||||
platform_device_unregister(tosa_snd_device);
|
platform_device_unregister(tosa_snd_device);
|
||||||
|
gpio_free(TOSA_GPIO_L_MUTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(tosa_init);
|
module_init(tosa_init);
|
||||||
|
Reference in New Issue
Block a user