mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (236 commits)
[ARM] 5300/1: fixup spitz reset during boot
[ARM] 5295/1: make ZONE_DMA optional
[ARM] 5239/1: Palm Zire 72 power management support
[ARM] 5298/1: Drop desc_handle_irq()
[ARM] 5297/1: [KS8695] Fix two compile-time warnings
[ARM] 5296/1: [KS8695] Replace macro's with trailing underscores.
[ARM] pxa: allow multi-machine PCMCIA builds
[ARM] pxa: add preliminary CPUFREQ support for PXA3xx
[ARM] pxa: add missing ACCR bit definitions to pxa3xx-regs.h
[ARM] pxa: rename cpu-pxa.c to cpufreq-pxa2xx.c
[ARM] pxa/zylonite: add support for USB OHCI
[ARM] ohci-pxa27x: use ioremap() and offset for register access
[ARM] ohci-pxa27x: introduce pxa27x_clear_otgph()
[ARM] ohci-pxa27x: use platform_get_{irq,resource} for the resource
[ARM] ohci-pxa27x: move OHCI controller specific registers into the driver
[ARM] ohci-pxa27x: introduce flags to avoid direct access to OHCI registers
[ARM] pxa: move I2S register and bit definitions into pxa2xx-i2s.c
[ARM] pxa: simplify DMA register definitions
[ARM] pxa: make additional DCSR bits valid for PXA3xx
[ARM] pxa: move i2c register and bit definitions into i2c-pxa.c
...
Fixed up conflicts in
arch/arm/mach-versatile/core.c
sound/soc/pxa/pxa2xx-ac97.c
sound/soc/pxa/pxa2xx-i2s.c
manually.
This commit is contained in:
commit
7cc4e87f91
733 changed files with 24195 additions and 8548 deletions
|
|
@ -220,7 +220,8 @@ config PCMCIA_PXA2XX
|
|||
tristate "PXA2xx support"
|
||||
depends on ARM && ARCH_PXA && PCMCIA
|
||||
depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \
|
||||
|| MACH_ARMCORE || ARCH_PXA_PALM)
|
||||
|| MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \
|
||||
|| ARCH_VIPER)
|
||||
help
|
||||
Say Y here to include support for the PXA2xx PCMCIA controller
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o
|
|||
obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o
|
||||
obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o
|
||||
obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o
|
||||
obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_core.o pxa2xx_cs.o
|
||||
obj-$(CONFIG_M32R_PCC) += m32r_pcc.o
|
||||
obj-$(CONFIG_M32R_CFC) += m32r_cfc.o
|
||||
obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o
|
||||
|
|
@ -68,9 +67,14 @@ sa1100_cs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o
|
|||
sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o
|
||||
sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
|
||||
|
||||
pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock.o sa1111_generic.o
|
||||
pxa2xx_cs-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o
|
||||
pxa2xx_cs-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o
|
||||
pxa2xx_cs-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x270.o
|
||||
pxa2xx_cs-$(CONFIG_MACH_PALMTX) += pxa2xx_palmtx.o
|
||||
pxa2xx_lubbock_cs-y += pxa2xx_lubbock.o sa1111_generic.o
|
||||
pxa2xx-obj-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock_cs.o
|
||||
pxa2xx-obj-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o
|
||||
pxa2xx-obj-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o
|
||||
pxa2xx-obj-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o
|
||||
pxa2xx-obj-$(CONFIG_ARCH_VIPER) += pxa2xx_viper.o
|
||||
pxa2xx-obj-$(CONFIG_TRIZEPS_PCMCIA) += pxa2xx_trizeps.o
|
||||
pxa2xx-obj-$(CONFIG_MACH_PALMTX) += pxa2xx_palmtx.o
|
||||
pxa2xx-obj-$(CONFIG_MACH_PALMLD) += pxa2xx_palmld.o
|
||||
|
||||
obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_core.o $(pxa2xx-obj-y)
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include <asm/system.h>
|
||||
#include <mach/pxa-regs.h>
|
||||
#include <mach/pxa2xx-regs.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <pcmcia/cs_types.h>
|
||||
#include <pcmcia/ss.h>
|
||||
|
|
@ -166,18 +167,32 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt,
|
|||
}
|
||||
#endif
|
||||
|
||||
static void pxa2xx_configure_sockets(struct device *dev)
|
||||
{
|
||||
struct pcmcia_low_level *ops = dev->platform_data;
|
||||
|
||||
/*
|
||||
* We have at least one socket, so set MECR:CIT
|
||||
* (Card Is There)
|
||||
*/
|
||||
MECR |= MECR_CIT;
|
||||
|
||||
/* Set MECR:NOS (Number Of Sockets) */
|
||||
if (ops->nr > 1 || machine_is_viper())
|
||||
MECR |= MECR_NOS;
|
||||
else
|
||||
MECR &= ~MECR_NOS;
|
||||
}
|
||||
|
||||
int __pxa2xx_drv_pcmcia_probe(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
struct pcmcia_low_level *ops;
|
||||
int first, nr;
|
||||
|
||||
if (!dev || !dev->platform_data)
|
||||
return -ENODEV;
|
||||
|
||||
ops = (struct pcmcia_low_level *)dev->platform_data;
|
||||
first = ops->first;
|
||||
nr = ops->nr;
|
||||
|
||||
/* Provide our PXA2xx specific timing routines. */
|
||||
ops->set_timing = pxa2xx_pcmcia_set_timing;
|
||||
|
|
@ -185,21 +200,10 @@ int __pxa2xx_drv_pcmcia_probe(struct device *dev)
|
|||
ops->frequency_change = pxa2xx_pcmcia_frequency_change;
|
||||
#endif
|
||||
|
||||
ret = soc_common_drv_pcmcia_probe(dev, ops, first, nr);
|
||||
ret = soc_common_drv_pcmcia_probe(dev, ops, ops->first, ops->nr);
|
||||
|
||||
if (ret == 0) {
|
||||
/*
|
||||
* We have at least one socket, so set MECR:CIT
|
||||
* (Card Is There)
|
||||
*/
|
||||
MECR |= MECR_CIT;
|
||||
|
||||
/* Set MECR:NOS (Number Of Sockets) */
|
||||
if (nr > 1)
|
||||
MECR |= MECR_NOS;
|
||||
else
|
||||
MECR &= ~MECR_NOS;
|
||||
}
|
||||
if (!ret)
|
||||
pxa2xx_configure_sockets(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -223,11 +227,7 @@ static int pxa2xx_drv_pcmcia_suspend(struct platform_device *dev, pm_message_t s
|
|||
|
||||
static int pxa2xx_drv_pcmcia_resume(struct platform_device *dev)
|
||||
{
|
||||
struct pcmcia_low_level *ops = dev->dev.platform_data;
|
||||
int nr = ops ? ops->nr : 0;
|
||||
|
||||
MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0);
|
||||
|
||||
pxa2xx_configure_sockets(&dev->dev);
|
||||
return pcmcia_socket_dev_resume(&dev->dev);
|
||||
}
|
||||
|
||||
|
|
|
|||
154
drivers/pcmcia/pxa2xx_cm_x255.c
Normal file
154
drivers/pcmcia/pxa2xx_cm_x255.c
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* linux/drivers/pcmcia/pxa/pxa_cm_x255.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.
|
||||
*
|
||||
* Compulab Ltd., 2003, 2007, 2008
|
||||
* Mike Rapoport <mike@compulab.co.il>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <mach/pxa-regs.h>
|
||||
|
||||
#include "soc_common.h"
|
||||
|
||||
#define GPIO_PCMCIA_SKTSEL (54)
|
||||
#define GPIO_PCMCIA_S0_CD_VALID (16)
|
||||
#define GPIO_PCMCIA_S1_CD_VALID (17)
|
||||
#define GPIO_PCMCIA_S0_RDYINT (6)
|
||||
#define GPIO_PCMCIA_S1_RDYINT (8)
|
||||
#define GPIO_PCMCIA_RESET (9)
|
||||
|
||||
#define PCMCIA_S0_CD_VALID IRQ_GPIO(GPIO_PCMCIA_S0_CD_VALID)
|
||||
#define PCMCIA_S1_CD_VALID IRQ_GPIO(GPIO_PCMCIA_S1_CD_VALID)
|
||||
#define PCMCIA_S0_RDYINT IRQ_GPIO(GPIO_PCMCIA_S0_RDYINT)
|
||||
#define PCMCIA_S1_RDYINT IRQ_GPIO(GPIO_PCMCIA_S1_RDYINT)
|
||||
|
||||
|
||||
static struct pcmcia_irqs irqs[] = {
|
||||
{ 0, PCMCIA_S0_CD_VALID, "PCMCIA0 CD" },
|
||||
{ 1, PCMCIA_S1_CD_VALID, "PCMCIA1 CD" },
|
||||
};
|
||||
|
||||
static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
||||
{
|
||||
int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
|
||||
if (ret)
|
||||
return ret;
|
||||
gpio_direction_output(GPIO_PCMCIA_RESET, 0);
|
||||
|
||||
skt->irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT;
|
||||
ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
||||
if (!ret)
|
||||
gpio_free(GPIO_PCMCIA_RESET);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
|
||||
{
|
||||
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
||||
gpio_free(GPIO_PCMCIA_RESET);
|
||||
}
|
||||
|
||||
|
||||
static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
|
||||
struct pcmcia_state *state)
|
||||
{
|
||||
int cd = skt->nr ? GPIO_PCMCIA_S1_CD_VALID : GPIO_PCMCIA_S0_CD_VALID;
|
||||
int rdy = skt->nr ? GPIO_PCMCIA_S0_RDYINT : GPIO_PCMCIA_S1_RDYINT;
|
||||
|
||||
state->detect = !gpio_get_value(cd);
|
||||
state->ready = !!gpio_get_value(rdy);
|
||||
state->bvd1 = 1;
|
||||
state->bvd2 = 1;
|
||||
state->vs_3v = 0;
|
||||
state->vs_Xv = 0;
|
||||
state->wrprot = 0; /* not available */
|
||||
}
|
||||
|
||||
|
||||
static int cmx255_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
|
||||
const socket_state_t *state)
|
||||
{
|
||||
switch (skt->nr) {
|
||||
case 0:
|
||||
if (state->flags & SS_RESET) {
|
||||
gpio_set_value(GPIO_PCMCIA_SKTSEL, 0);
|
||||
udelay(1);
|
||||
gpio_set_value(GPIO_PCMCIA_RESET, 1);
|
||||
udelay(10);
|
||||
gpio_set_value(GPIO_PCMCIA_RESET, 0);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (state->flags & SS_RESET) {
|
||||
gpio_set_value(GPIO_PCMCIA_SKTSEL, 1);
|
||||
udelay(1);
|
||||
gpio_set_value(GPIO_PCMCIA_RESET, 1);
|
||||
udelay(10);
|
||||
gpio_set_value(GPIO_PCMCIA_RESET, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cmx255_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
|
||||
{
|
||||
}
|
||||
|
||||
static void cmx255_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static struct pcmcia_low_level cmx255_pcmcia_ops __initdata = {
|
||||
.owner = THIS_MODULE,
|
||||
.hw_init = cmx255_pcmcia_hw_init,
|
||||
.hw_shutdown = cmx255_pcmcia_shutdown,
|
||||
.socket_state = cmx255_pcmcia_socket_state,
|
||||
.configure_socket = cmx255_pcmcia_configure_socket,
|
||||
.socket_init = cmx255_pcmcia_socket_init,
|
||||
.socket_suspend = cmx255_pcmcia_socket_suspend,
|
||||
.nr = 1,
|
||||
};
|
||||
|
||||
static struct platform_device *cmx255_pcmcia_device;
|
||||
|
||||
int __init cmx255_pcmcia_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cmx255_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
|
||||
|
||||
if (!cmx255_pcmcia_device)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = platform_device_add_data(cmx255_pcmcia_device, &cmx255_pcmcia_ops,
|
||||
sizeof(cmx255_pcmcia_ops));
|
||||
|
||||
if (ret == 0) {
|
||||
printk(KERN_INFO "Registering cm-x255 PCMCIA interface.\n");
|
||||
ret = platform_device_add(cmx255_pcmcia_device);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
platform_device_put(cmx255_pcmcia_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __exit cmx255_pcmcia_exit(void)
|
||||
{
|
||||
platform_device_unregister(cmx255_pcmcia_device);
|
||||
}
|
||||
|
|
@ -105,13 +105,10 @@ static struct pcmcia_low_level cmx270_pcmcia_ops __initdata = {
|
|||
|
||||
static struct platform_device *cmx270_pcmcia_device;
|
||||
|
||||
static int __init cmx270_pcmcia_init(void)
|
||||
int __init cmx270_pcmcia_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!machine_is_armcore())
|
||||
return -ENODEV;
|
||||
|
||||
cmx270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
|
||||
|
||||
if (!cmx270_pcmcia_device)
|
||||
|
|
@ -131,14 +128,7 @@ static int __init cmx270_pcmcia_init(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void __exit cmx270_pcmcia_exit(void)
|
||||
void __exit cmx270_pcmcia_exit(void)
|
||||
{
|
||||
platform_device_unregister(cmx270_pcmcia_device);
|
||||
}
|
||||
|
||||
module_init(cmx270_pcmcia_init);
|
||||
module_exit(cmx270_pcmcia_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mike Rapoport <[email protected]>");
|
||||
MODULE_DESCRIPTION("CM-x270 PCMCIA driver");
|
||||
|
|
|
|||
49
drivers/pcmcia/pxa2xx_cm_x2xx.c
Normal file
49
drivers/pcmcia/pxa2xx_cm_x2xx.c
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* linux/drivers/pcmcia/pxa/pxa_cm_x2xx.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.
|
||||
*
|
||||
* Compulab Ltd., 2003, 2007, 2008
|
||||
* Mike Rapoport <mike@compulab.co.il>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <mach/system.h>
|
||||
|
||||
int cmx255_pcmcia_init(void);
|
||||
int cmx270_pcmcia_init(void);
|
||||
void cmx255_pcmcia_exit(void);
|
||||
void cmx270_pcmcia_exit(void);
|
||||
|
||||
static int __init cmx2xx_pcmcia_init(void)
|
||||
{
|
||||
int ret = -ENODEV;
|
||||
|
||||
if (machine_is_armcore() && cpu_is_pxa25x())
|
||||
ret = cmx255_pcmcia_init();
|
||||
else if (machine_is_armcore() && cpu_is_pxa27x())
|
||||
ret = cmx270_pcmcia_init();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit cmx2xx_pcmcia_exit(void)
|
||||
{
|
||||
if (machine_is_armcore() && cpu_is_pxa25x())
|
||||
cmx255_pcmcia_exit();
|
||||
else if (machine_is_armcore() && cpu_is_pxa27x())
|
||||
cmx270_pcmcia_exit();
|
||||
}
|
||||
|
||||
module_init(cmx2xx_pcmcia_init);
|
||||
module_exit(cmx2xx_pcmcia_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mike Rapoport <[email protected]>");
|
||||
MODULE_DESCRIPTION("CM-x2xx PCMCIA driver");
|
||||
151
drivers/pcmcia/pxa2xx_palmld.c
Normal file
151
drivers/pcmcia/pxa2xx_palmld.c
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* linux/drivers/pcmcia/pxa2xx_palmld.c
|
||||
*
|
||||
* Driver for Palm LifeDrive PCMCIA
|
||||
*
|
||||
* Copyright (C) 2006 Alex Osborne <ato@meshy.org>
|
||||
* Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com>
|
||||
*
|
||||
* 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/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <mach/palmld.h>
|
||||
#include "soc_common.h"
|
||||
|
||||
static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_POWER, "PCMCIA PWR");
|
||||
if (ret)
|
||||
goto err1;
|
||||
ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_POWER, 0);
|
||||
if (ret)
|
||||
goto err2;
|
||||
|
||||
ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_RESET, "PCMCIA RST");
|
||||
if (ret)
|
||||
goto err2;
|
||||
ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_RESET, 1);
|
||||
if (ret)
|
||||
goto err3;
|
||||
|
||||
ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_READY, "PCMCIA RDY");
|
||||
if (ret)
|
||||
goto err3;
|
||||
ret = gpio_direction_input(GPIO_NR_PALMLD_PCMCIA_READY);
|
||||
if (ret)
|
||||
goto err4;
|
||||
|
||||
skt->irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY);
|
||||
return 0;
|
||||
|
||||
err4:
|
||||
gpio_free(GPIO_NR_PALMLD_PCMCIA_READY);
|
||||
err3:
|
||||
gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET);
|
||||
err2:
|
||||
gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER);
|
||||
err1:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void palmld_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
|
||||
{
|
||||
gpio_free(GPIO_NR_PALMLD_PCMCIA_READY);
|
||||
gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET);
|
||||
gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER);
|
||||
}
|
||||
|
||||
static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
|
||||
struct pcmcia_state *state)
|
||||
{
|
||||
state->detect = 1; /* always inserted */
|
||||
state->ready = !!gpio_get_value(GPIO_NR_PALMLD_PCMCIA_READY);
|
||||
state->bvd1 = 1;
|
||||
state->bvd2 = 1;
|
||||
state->wrprot = 0;
|
||||
state->vs_3v = 1;
|
||||
state->vs_Xv = 0;
|
||||
}
|
||||
|
||||
static int palmld_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
|
||||
const socket_state_t *state)
|
||||
{
|
||||
gpio_set_value(GPIO_NR_PALMLD_PCMCIA_POWER, 1);
|
||||
gpio_set_value(GPIO_NR_PALMLD_PCMCIA_RESET,
|
||||
!!(state->flags & SS_RESET));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void palmld_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
|
||||
{
|
||||
}
|
||||
|
||||
static void palmld_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
|
||||
{
|
||||
}
|
||||
|
||||
static struct pcmcia_low_level palmld_pcmcia_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
|
||||
.first = 0,
|
||||
.nr = 2,
|
||||
|
||||
.hw_init = palmld_pcmcia_hw_init,
|
||||
.hw_shutdown = palmld_pcmcia_hw_shutdown,
|
||||
|
||||
.socket_state = palmld_pcmcia_socket_state,
|
||||
.configure_socket = palmld_pcmcia_configure_socket,
|
||||
|
||||
.socket_init = palmld_pcmcia_socket_init,
|
||||
.socket_suspend = palmld_pcmcia_socket_suspend,
|
||||
};
|
||||
|
||||
static struct platform_device *palmld_pcmcia_device;
|
||||
|
||||
static int __init palmld_pcmcia_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!machine_is_palmld())
|
||||
return -ENODEV;
|
||||
|
||||
palmld_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
|
||||
if (!palmld_pcmcia_device)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = platform_device_add_data(palmld_pcmcia_device, &palmld_pcmcia_ops,
|
||||
sizeof(palmld_pcmcia_ops));
|
||||
|
||||
if (!ret)
|
||||
ret = platform_device_add(palmld_pcmcia_device);
|
||||
|
||||
if (ret)
|
||||
platform_device_put(palmld_pcmcia_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit palmld_pcmcia_exit(void)
|
||||
{
|
||||
platform_device_unregister(palmld_pcmcia_device);
|
||||
}
|
||||
|
||||
module_init(palmld_pcmcia_init);
|
||||
module_exit(palmld_pcmcia_exit);
|
||||
|
||||
MODULE_AUTHOR("Alex Osborne <[email protected]>,"
|
||||
" Marek Vasut <[email protected]>");
|
||||
MODULE_DESCRIPTION("PCMCIA support for Palm LifeDrive");
|
||||
MODULE_ALIAS("platform:pxa2xx-pcmcia");
|
||||
MODULE_LICENSE("GPL");
|
||||
256
drivers/pcmcia/pxa2xx_trizeps4.c
Normal file
256
drivers/pcmcia/pxa2xx_trizeps4.c
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* linux/drivers/pcmcia/pxa2xx_trizeps4.c
|
||||
*
|
||||
* TRIZEPS PCMCIA specific routines.
|
||||
*
|
||||
* Author: Jürgen Schindele
|
||||
* Created: 20 02, 2006
|
||||
* Copyright: Jürgen Schindele
|
||||
*
|
||||
* 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/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/pxa-regs.h>
|
||||
#include <mach/trizeps4.h>
|
||||
|
||||
#include "soc_common.h"
|
||||
|
||||
extern void board_pcmcia_power(int power);
|
||||
|
||||
static struct pcmcia_irqs irqs[] = {
|
||||
{ 0, IRQ_GPIO(GPIO_PCD), "cs0_cd" }
|
||||
/* on other baseboards we can have more inputs */
|
||||
};
|
||||
|
||||
static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
||||
{
|
||||
int ret, i;
|
||||
/* we dont have voltage/card/ready detection
|
||||
* so we dont need interrupts for it
|
||||
*/
|
||||
switch (skt->nr) {
|
||||
case 0:
|
||||
if (gpio_request(GPIO_PRDY, "cf_irq") < 0) {
|
||||
pr_err("%s: sock %d unable to request gpio %d\n", __func__,
|
||||
skt->nr, GPIO_PRDY);
|
||||
return -EBUSY;
|
||||
}
|
||||
if (gpio_direction_input(GPIO_PRDY) < 0) {
|
||||
pr_err("%s: sock %d unable to set input gpio %d\n", __func__,
|
||||
skt->nr, GPIO_PRDY);
|
||||
gpio_free(GPIO_PRDY);
|
||||
return -EINVAL;
|
||||
}
|
||||
skt->irq = IRQ_GPIO(GPIO_PRDY);
|
||||
break;
|
||||
|
||||
#ifndef CONFIG_MACH_TRIZEPS_CONXS
|
||||
case 1:
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* release the reset of this card */
|
||||
pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->irq);
|
||||
|
||||
/* supplementory irqs for the socket */
|
||||
for (i = 0; i < ARRAY_SIZE(irqs); i++) {
|
||||
if (irqs[i].sock != skt->nr)
|
||||
continue;
|
||||
if (gpio_request(IRQ_TO_GPIO(irqs[i].irq), irqs[i].str) < 0) {
|
||||
pr_err("%s: sock %d unable to request gpio %d\n",
|
||||
__func__, skt->nr, IRQ_TO_GPIO(irqs[i].irq));
|
||||
ret = -EBUSY;
|
||||
goto error;
|
||||
}
|
||||
if (gpio_direction_input(IRQ_TO_GPIO(irqs[i].irq)) < 0) {
|
||||
pr_err("%s: sock %d unable to set input gpio %d\n",
|
||||
__func__, skt->nr, IRQ_TO_GPIO(irqs[i].irq));
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
||||
|
||||
error:
|
||||
for (; i >= 0; i--) {
|
||||
gpio_free(IRQ_TO_GPIO(irqs[i].irq));
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void trizeps_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
|
||||
{
|
||||
int i;
|
||||
/* free allocated gpio's */
|
||||
gpio_free(GPIO_PRDY);
|
||||
for (i = 0; i < ARRAY_SIZE(irqs); i++)
|
||||
gpio_free(IRQ_TO_GPIO(irqs[i].irq));
|
||||
}
|
||||
|
||||
static unsigned long trizeps_pcmcia_status[2];
|
||||
|
||||
static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
|
||||
struct pcmcia_state *state)
|
||||
{
|
||||
unsigned short status = 0, change;
|
||||
status = CFSR_readw();
|
||||
change = (status ^ trizeps_pcmcia_status[skt->nr]) &
|
||||
ConXS_CFSR_BVD_MASK;
|
||||
if (change) {
|
||||
trizeps_pcmcia_status[skt->nr] = status;
|
||||
if (status & ConXS_CFSR_BVD1) {
|
||||
/* enable_irq empty */
|
||||
} else {
|
||||
/* disable_irq empty */
|
||||
}
|
||||
}
|
||||
|
||||
switch (skt->nr) {
|
||||
case 0:
|
||||
/* just fill in fix states */
|
||||
state->detect = gpio_get_value(GPIO_PCD) ? 0 : 1;
|
||||
state->ready = gpio_get_value(GPIO_PRDY) ? 1 : 0;
|
||||
state->bvd1 = (status & ConXS_CFSR_BVD1) ? 1 : 0;
|
||||
state->bvd2 = (status & ConXS_CFSR_BVD2) ? 1 : 0;
|
||||
state->vs_3v = (status & ConXS_CFSR_VS1) ? 0 : 1;
|
||||
state->vs_Xv = (status & ConXS_CFSR_VS2) ? 0 : 1;
|
||||
state->wrprot = 0; /* not available */
|
||||
break;
|
||||
|
||||
#ifndef CONFIG_MACH_TRIZEPS_CONXS
|
||||
/* on ConXS we only have one slot. Second is inactive */
|
||||
case 1:
|
||||
state->detect = 0;
|
||||
state->ready = 0;
|
||||
state->bvd1 = 0;
|
||||
state->bvd2 = 0;
|
||||
state->vs_3v = 0;
|
||||
state->vs_Xv = 0;
|
||||
state->wrprot = 0;
|
||||
break;
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static int trizeps_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
|
||||
const socket_state_t *state)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned short power = 0;
|
||||
|
||||
/* we do nothing here just check a bit */
|
||||
switch (state->Vcc) {
|
||||
case 0: power &= 0xfc; break;
|
||||
case 33: power |= ConXS_BCR_S0_VCC_3V3; break;
|
||||
case 50:
|
||||
pr_err("%s(): Vcc 5V not supported in socket\n", __func__);
|
||||
break;
|
||||
default:
|
||||
pr_err("%s(): bad Vcc %u\n", __func__, state->Vcc);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
switch (state->Vpp) {
|
||||
case 0: power &= 0xf3; break;
|
||||
case 33: power |= ConXS_BCR_S0_VPP_3V3; break;
|
||||
case 120:
|
||||
pr_err("%s(): Vpp 12V not supported in socket\n", __func__);
|
||||
break;
|
||||
default:
|
||||
if (state->Vpp != state->Vcc) {
|
||||
pr_err("%s(): bad Vpp %u\n", __func__, state->Vpp);
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
switch (skt->nr) {
|
||||
case 0: /* we only have 3.3V */
|
||||
board_pcmcia_power(power);
|
||||
break;
|
||||
|
||||
#ifndef CONFIG_MACH_TRIZEPS_CONXS
|
||||
/* on ConXS we only have one slot. Second is inactive */
|
||||
case 1:
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void trizeps_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
|
||||
{
|
||||
/* default is on */
|
||||
board_pcmcia_power(0x9);
|
||||
}
|
||||
|
||||
static void trizeps_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
|
||||
{
|
||||
board_pcmcia_power(0x0);
|
||||
}
|
||||
|
||||
static struct pcmcia_low_level trizeps_pcmcia_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.hw_init = trizeps_pcmcia_hw_init,
|
||||
.hw_shutdown = trizeps_pcmcia_hw_shutdown,
|
||||
.socket_state = trizeps_pcmcia_socket_state,
|
||||
.configure_socket = trizeps_pcmcia_configure_socket,
|
||||
.socket_init = trizeps_pcmcia_socket_init,
|
||||
.socket_suspend = trizeps_pcmcia_socket_suspend,
|
||||
#ifdef CONFIG_MACH_TRIZEPS_CONXS
|
||||
.nr = 1,
|
||||
#else
|
||||
.nr = 2,
|
||||
#endif
|
||||
.first = 0,
|
||||
};
|
||||
|
||||
static struct platform_device *trizeps_pcmcia_device;
|
||||
|
||||
static int __init trizeps_pcmcia_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
trizeps_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
|
||||
if (!trizeps_pcmcia_device)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = platform_device_add_data(trizeps_pcmcia_device,
|
||||
&trizeps_pcmcia_ops, sizeof(trizeps_pcmcia_ops));
|
||||
|
||||
if (ret == 0)
|
||||
ret = platform_device_add(trizeps_pcmcia_device);
|
||||
|
||||
if (ret)
|
||||
platform_device_put(trizeps_pcmcia_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit trizeps_pcmcia_exit(void)
|
||||
{
|
||||
platform_device_unregister(trizeps_pcmcia_device);
|
||||
}
|
||||
|
||||
fs_initcall(trizeps_pcmcia_init);
|
||||
module_exit(trizeps_pcmcia_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Juergen Schindele");
|
||||
MODULE_ALIAS("platform:pxa2xx-pcmcia");
|
||||
179
drivers/pcmcia/pxa2xx_viper.c
Normal file
179
drivers/pcmcia/pxa2xx_viper.c
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* VIPER PCMCIA support
|
||||
* Copyright 2004 Arcom Control Systems
|
||||
*
|
||||
* Maintained by Marc Zyngier <maz@misterjones.org>
|
||||
* <marc.zyngier@altran.com>
|
||||
*
|
||||
* Based on:
|
||||
* iPAQ h2200 PCMCIA support
|
||||
* Copyright 2004 Koen Kooi <koen@vestingbar.nl>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file COPYING in the main directory of this archive for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <pcmcia/ss.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include <mach/pxa-regs.h>
|
||||
#include <mach/viper.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include "soc_common.h"
|
||||
#include "pxa2xx_base.h"
|
||||
|
||||
static struct pcmcia_irqs irqs[] = {
|
||||
{ 0, gpio_to_irq(VIPER_CF_CD_GPIO), "PCMCIA_CD" }
|
||||
};
|
||||
|
||||
static int viper_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
skt->irq = gpio_to_irq(VIPER_CF_RDY_GPIO);
|
||||
|
||||
if (gpio_request(VIPER_CF_CD_GPIO, "CF detect"))
|
||||
goto err_request_cd;
|
||||
|
||||
if (gpio_request(VIPER_CF_RDY_GPIO, "CF ready"))
|
||||
goto err_request_rdy;
|
||||
|
||||
if (gpio_request(VIPER_CF_POWER_GPIO, "CF power"))
|
||||
goto err_request_pwr;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
/* GPIO 82 is the CF power enable line. initially off */
|
||||
if (gpio_direction_output(VIPER_CF_POWER_GPIO, 0) ||
|
||||
gpio_direction_input(VIPER_CF_CD_GPIO) ||
|
||||
gpio_direction_input(VIPER_CF_RDY_GPIO)) {
|
||||
local_irq_restore(flags);
|
||||
goto err_dir;
|
||||
}
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
||||
|
||||
err_dir:
|
||||
gpio_free(VIPER_CF_POWER_GPIO);
|
||||
err_request_pwr:
|
||||
gpio_free(VIPER_CF_RDY_GPIO);
|
||||
err_request_rdy:
|
||||
gpio_free(VIPER_CF_CD_GPIO);
|
||||
err_request_cd:
|
||||
printk(KERN_ERR "viper: Failed to setup PCMCIA GPIOs\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release all resources.
|
||||
*/
|
||||
static void viper_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
|
||||
{
|
||||
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
||||
gpio_free(VIPER_CF_POWER_GPIO);
|
||||
gpio_free(VIPER_CF_RDY_GPIO);
|
||||
gpio_free(VIPER_CF_CD_GPIO);
|
||||
}
|
||||
|
||||
static void viper_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
|
||||
struct pcmcia_state *state)
|
||||
{
|
||||
state->detect = gpio_get_value(VIPER_CF_CD_GPIO) ? 0 : 1;
|
||||
state->ready = gpio_get_value(VIPER_CF_RDY_GPIO) ? 1 : 0;
|
||||
state->bvd1 = 1;
|
||||
state->bvd2 = 1;
|
||||
state->wrprot = 0;
|
||||
state->vs_3v = 1; /* Can only apply 3.3V */
|
||||
state->vs_Xv = 0;
|
||||
}
|
||||
|
||||
static int viper_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
|
||||
const socket_state_t *state)
|
||||
{
|
||||
/* Silently ignore Vpp, output enable, speaker enable. */
|
||||
viper_cf_rst(state->flags & SS_RESET);
|
||||
|
||||
/* Apply socket voltage */
|
||||
switch (state->Vcc) {
|
||||
case 0:
|
||||
gpio_set_value(VIPER_CF_POWER_GPIO, 0);
|
||||
break;
|
||||
case 33:
|
||||
gpio_set_value(VIPER_CF_POWER_GPIO, 1);
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "%s: Unsupported Vcc:%d\n",
|
||||
__func__, state->Vcc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void viper_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
|
||||
{
|
||||
}
|
||||
|
||||
static void viper_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
|
||||
{
|
||||
}
|
||||
|
||||
static struct pcmcia_low_level viper_pcmcia_ops __initdata = {
|
||||
.owner = THIS_MODULE,
|
||||
.hw_init = viper_pcmcia_hw_init,
|
||||
.hw_shutdown = viper_pcmcia_hw_shutdown,
|
||||
.socket_state = viper_pcmcia_socket_state,
|
||||
.configure_socket = viper_pcmcia_configure_socket,
|
||||
.socket_init = viper_pcmcia_socket_init,
|
||||
.socket_suspend = viper_pcmcia_socket_suspend,
|
||||
.nr = 1,
|
||||
};
|
||||
|
||||
static struct platform_device *viper_pcmcia_device;
|
||||
|
||||
static int __init viper_pcmcia_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!machine_is_viper())
|
||||
return -ENODEV;
|
||||
|
||||
viper_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
|
||||
if (!viper_pcmcia_device)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = platform_device_add_data(viper_pcmcia_device,
|
||||
&viper_pcmcia_ops,
|
||||
sizeof(viper_pcmcia_ops));
|
||||
|
||||
if (!ret)
|
||||
ret = platform_device_add(viper_pcmcia_device);
|
||||
|
||||
if (ret)
|
||||
platform_device_put(viper_pcmcia_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit viper_pcmcia_exit(void)
|
||||
{
|
||||
platform_device_unregister(viper_pcmcia_device);
|
||||
}
|
||||
|
||||
module_init(viper_pcmcia_init);
|
||||
module_exit(viper_pcmcia_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
Loading…
Reference in a new issue