Commit a63ae442 authored by Richard Purdie's avatar Richard Purdie Committed by Russell King

[ARM] 3093/1: SharpSL PCMCIA Updates for Cxx00 models

Patch from Richard Purdie

The Sharp SL-Cxx00 models have a combined power control for the SD
and CF slot 0. This patch adds hooks to the scoop driver to allow
machines to provide a custom control function for this and such a
function is added for spitz/akita/borzoi.

It also moves the gpio init code into the machine files as this
is machine dependent and differs between some models. A couple of
warnings when compiling for collie are also fixed.

Signed-off-by: Richard Purdie
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 1d23b65d
...@@ -19,12 +19,6 @@ ...@@ -19,12 +19,6 @@
#define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr))) #define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr)))
/* PCMCIA to Scoop linkage structures for pxa2xx_sharpsl.c
There is no easy way to link multiple scoop devices into one
single entity for the pxa2xx_pcmcia device */
int scoop_num;
struct scoop_pcmcia_dev *scoop_devs;
struct scoop_dev { struct scoop_dev {
void *base; void *base;
spinlock_t scoop_lock; spinlock_t scoop_lock;
......
...@@ -62,6 +62,37 @@ static struct scoop_config corgi_scoop_setup = { ...@@ -62,6 +62,37 @@ static struct scoop_config corgi_scoop_setup = {
.io_out = CORGI_SCOOP_IO_OUT, .io_out = CORGI_SCOOP_IO_OUT,
}; };
struct platform_device corgiscoop_device = {
.name = "sharp-scoop",
.id = -1,
.dev = {
.platform_data = &corgi_scoop_setup,
},
.num_resources = ARRAY_SIZE(corgi_scoop_resources),
.resource = corgi_scoop_resources,
};
static void corgi_pcmcia_init(void)
{
/* Setup default state of GPIO outputs
before we enable them as outputs. */
GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) |
GPIO_bit(GPIO53_nPCE_2);
pxa_gpio_mode(GPIO48_nPOE_MD);
pxa_gpio_mode(GPIO49_nPWE_MD);
pxa_gpio_mode(GPIO50_nPIOR_MD);
pxa_gpio_mode(GPIO51_nPIOW_MD);
pxa_gpio_mode(GPIO55_nPREG_MD);
pxa_gpio_mode(GPIO56_nPWAIT_MD);
pxa_gpio_mode(GPIO57_nIOIS16_MD);
pxa_gpio_mode(GPIO52_nPCE_1_MD);
pxa_gpio_mode(GPIO53_nPCE_2_MD);
pxa_gpio_mode(GPIO54_pSKTSEL_MD);
}
static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = { static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = {
{ {
.dev = &corgiscoop_device.dev, .dev = &corgiscoop_device.dev,
...@@ -71,16 +102,14 @@ static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = { ...@@ -71,16 +102,14 @@ static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = {
}, },
}; };
struct platform_device corgiscoop_device = { static struct scoop_pcmcia_config corgi_pcmcia_config = {
.name = "sharp-scoop", .devs = &corgi_pcmcia_scoop[0],
.id = -1, .num_devs = 1,
.dev = { .pcmcia_init = corgi_pcmcia_init,
.platform_data = &corgi_scoop_setup,
},
.num_resources = ARRAY_SIZE(corgi_scoop_resources),
.resource = corgi_scoop_resources,
}; };
EXPORT_SYMBOL(corgiscoop_device);
/* /*
* Corgi SSP Device * Corgi SSP Device
...@@ -294,8 +323,7 @@ static void __init corgi_init(void) ...@@ -294,8 +323,7 @@ static void __init corgi_init(void)
pxa_set_mci_info(&corgi_mci_platform_data); pxa_set_mci_info(&corgi_mci_platform_data);
pxa_set_ficp_info(&corgi_ficp_platform_data); pxa_set_ficp_info(&corgi_ficp_platform_data);
scoop_num = 1; platform_scoop_config = &corgi_pcmcia_config;
scoop_devs = &corgi_pcmcia_scoop[0];
platform_add_devices(devices, ARRAY_SIZE(devices)); platform_add_devices(devices, ARRAY_SIZE(devices));
} }
......
...@@ -65,6 +65,27 @@ struct platform_device poodle_scoop_device = { ...@@ -65,6 +65,27 @@ struct platform_device poodle_scoop_device = {
.resource = poodle_scoop_resources, .resource = poodle_scoop_resources,
}; };
static void poodle_pcmcia_init(void)
{
/* Setup default state of GPIO outputs
before we enable them as outputs. */
GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) |
GPIO_bit(GPIO53_nPCE_2);
pxa_gpio_mode(GPIO48_nPOE_MD);
pxa_gpio_mode(GPIO49_nPWE_MD);
pxa_gpio_mode(GPIO50_nPIOR_MD);
pxa_gpio_mode(GPIO51_nPIOW_MD);
pxa_gpio_mode(GPIO55_nPREG_MD);
pxa_gpio_mode(GPIO56_nPWAIT_MD);
pxa_gpio_mode(GPIO57_nIOIS16_MD);
pxa_gpio_mode(GPIO52_nPCE_1_MD);
pxa_gpio_mode(GPIO53_nPCE_2_MD);
pxa_gpio_mode(GPIO54_pSKTSEL_MD);
}
static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = { static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = {
{ {
.dev = &poodle_scoop_device.dev, .dev = &poodle_scoop_device.dev,
...@@ -74,6 +95,14 @@ static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = { ...@@ -74,6 +95,14 @@ static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = {
}, },
}; };
static struct scoop_pcmcia_config poodle_pcmcia_config = {
.devs = &poodle_pcmcia_scoop[0],
.num_devs = 1,
.pcmcia_init = poodle_pcmcia_init,
};
EXPORT_SYMBOL(poodle_scoop_device);
/* LoCoMo device */ /* LoCoMo device */
static struct resource locomo_resources[] = { static struct resource locomo_resources[] = {
...@@ -268,8 +297,7 @@ static void __init poodle_init(void) ...@@ -268,8 +297,7 @@ static void __init poodle_init(void)
pxa_set_mci_info(&poodle_mci_platform_data); pxa_set_mci_info(&poodle_mci_platform_data);
pxa_set_ficp_info(&poodle_ficp_platform_data); pxa_set_ficp_info(&poodle_ficp_platform_data);
scoop_num = 1; platform_scoop_config = &poodle_pcmcia_config;
scoop_devs = &poodle_pcmcia_scoop[0];
ret = platform_add_devices(devices, ARRAY_SIZE(devices)); ret = platform_add_devices(devices, ARRAY_SIZE(devices));
if (ret) { if (ret) {
......
...@@ -104,6 +104,66 @@ struct platform_device spitzscoop2_device = { ...@@ -104,6 +104,66 @@ struct platform_device spitzscoop2_device = {
.resource = spitz_scoop2_resources, .resource = spitz_scoop2_resources,
}; };
#define SPITZ_PWR_SD 0x01
#define SPITZ_PWR_CF 0x02
/* Power control is shared with between one of the CF slots and SD */
static void spitz_card_pwr_ctrl(int device, unsigned short new_cpr)
{
unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR);
if (new_cpr & 0x0007) {
set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
if (!(cpr & 0x0002) && !(cpr & 0x0004))
mdelay(5);
if (device == SPITZ_PWR_CF)
cpr |= 0x0002;
if (device == SPITZ_PWR_SD)
cpr |= 0x0004;
write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr);
} else {
if (device == SPITZ_PWR_CF)
cpr &= ~0x0002;
if (device == SPITZ_PWR_SD)
cpr &= ~0x0004;
write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr);
if (!(cpr & 0x0002) && !(cpr & 0x0004)) {
mdelay(1);
reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
}
}
}
static void spitz_pcmcia_init(void)
{
/* Setup default state of GPIO outputs
before we enable them as outputs. */
GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO54_nPCE_2);
GPSR(GPIO85_nPCE_1) = GPIO_bit(GPIO85_nPCE_1);
pxa_gpio_mode(GPIO48_nPOE_MD);
pxa_gpio_mode(GPIO49_nPWE_MD);
pxa_gpio_mode(GPIO50_nPIOR_MD);
pxa_gpio_mode(GPIO51_nPIOW_MD);
pxa_gpio_mode(GPIO55_nPREG_MD);
pxa_gpio_mode(GPIO56_nPWAIT_MD);
pxa_gpio_mode(GPIO57_nIOIS16_MD);
pxa_gpio_mode(GPIO85_nPCE_1_MD);
pxa_gpio_mode(GPIO54_nPCE_2_MD);
pxa_gpio_mode(GPIO104_pSKTSEL_MD);
}
static void spitz_pcmcia_pwr(struct device *scoop, unsigned short cpr, int nr)
{
/* Only need to override behaviour for slot 0 */
if (nr == 0)
spitz_card_pwr_ctrl(SPITZ_PWR_CF, cpr);
else
write_scoop_reg(scoop, SCOOP_CPR, cpr);
}
static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = { static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = {
{ {
.dev = &spitzscoop_device.dev, .dev = &spitzscoop_device.dev,
...@@ -117,6 +177,16 @@ static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = { ...@@ -117,6 +177,16 @@ static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = {
}, },
}; };
static struct scoop_pcmcia_config spitz_pcmcia_config = {
.devs = &spitz_pcmcia_scoop[0],
.num_devs = 2,
.pcmcia_init = spitz_pcmcia_init,
.power_ctrl = spitz_pcmcia_pwr,
};
EXPORT_SYMBOL(spitzscoop_device);
EXPORT_SYMBOL(spitzscoop2_device);
/* /*
* Spitz SSP Device * Spitz SSP Device
...@@ -235,27 +305,14 @@ static int spitz_mci_init(struct device *dev, irqreturn_t (*spitz_detect_int)(in ...@@ -235,27 +305,14 @@ static int spitz_mci_init(struct device *dev, irqreturn_t (*spitz_detect_int)(in
return 0; return 0;
} }
/* Power control is shared with one of the CF slots so we have a mess */
static void spitz_mci_setpower(struct device *dev, unsigned int vdd) static void spitz_mci_setpower(struct device *dev, unsigned int vdd)
{ {
struct pxamci_platform_data* p_d = dev->platform_data; struct pxamci_platform_data* p_d = dev->platform_data;
unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR); if (( 1 << vdd) & p_d->ocr_mask)
spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0004);
if (( 1 << vdd) & p_d->ocr_mask) { else
/* printk(KERN_DEBUG "%s: on\n", __FUNCTION__); */ spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0000);
set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
mdelay(2);
write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | 0x04);
} else {
/* printk(KERN_DEBUG "%s: off\n", __FUNCTION__); */
write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr & ~0x04);
if (!(cpr | 0x02)) {
mdelay(1);
reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
}
}
} }
static int spitz_mci_get_ro(struct device *dev) static int spitz_mci_get_ro(struct device *dev)
...@@ -351,8 +408,8 @@ static void __init common_init(void) ...@@ -351,8 +408,8 @@ static void __init common_init(void)
static void __init spitz_init(void) static void __init spitz_init(void)
{ {
scoop_num = 2; platform_scoop_config = &spitz_pcmcia_config;
scoop_devs = &spitz_pcmcia_scoop[0];
spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity; spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity;
common_init(); common_init();
......
...@@ -22,16 +22,20 @@ ...@@ -22,16 +22,20 @@
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/hardware/scoop.h> #include <asm/hardware/scoop.h>
#ifdef CONFIG_SA1100_COLLIE
#include <asm/arch-sa1100/collie.h>
#else
#include <asm/arch-pxa/pxa-regs.h>
#endif
#include "soc_common.h" #include "soc_common.h"
#define NO_KEEP_VS 0x0001 #define NO_KEEP_VS 0x0001
/* PCMCIA to Scoop linkage
There is no easy way to link multiple scoop devices into one
single entity for the pxa2xx_pcmcia device so this structure
is used which is setup by the platform code
*/
struct scoop_pcmcia_config *platform_scoop_config;
#define SCOOP_DEV platform_scoop_config->devs
static void sharpsl_pcmcia_init_reset(struct scoop_pcmcia_dev *scoopdev) static void sharpsl_pcmcia_init_reset(struct scoop_pcmcia_dev *scoopdev)
{ {
reset_scoop(scoopdev->dev); reset_scoop(scoopdev->dev);
...@@ -43,38 +47,16 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ...@@ -43,38 +47,16 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
int ret; int ret;
#ifndef CONFIG_SA1100_COLLIE if (platform_scoop_config->pcmcia_init)
/* platform_scoop_config->pcmcia_init();
* Setup default state of GPIO outputs
* before we enable them as outputs.
*/
GPSR(GPIO48_nPOE) =
GPIO_bit(GPIO48_nPOE) |
GPIO_bit(GPIO49_nPWE) |
GPIO_bit(GPIO50_nPIOR) |
GPIO_bit(GPIO51_nPIOW) |
GPIO_bit(GPIO52_nPCE_1) |
GPIO_bit(GPIO53_nPCE_2);
pxa_gpio_mode(GPIO48_nPOE_MD);
pxa_gpio_mode(GPIO49_nPWE_MD);
pxa_gpio_mode(GPIO50_nPIOR_MD);
pxa_gpio_mode(GPIO51_nPIOW_MD);
pxa_gpio_mode(GPIO52_nPCE_1_MD);
pxa_gpio_mode(GPIO53_nPCE_2_MD);
pxa_gpio_mode(GPIO54_pSKTSEL_MD);
pxa_gpio_mode(GPIO55_nPREG_MD);
pxa_gpio_mode(GPIO56_nPWAIT_MD);
pxa_gpio_mode(GPIO57_nIOIS16_MD);
#endif
/* Register interrupts */ /* Register interrupts */
if (scoop_devs[skt->nr].cd_irq >= 0) { if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
struct pcmcia_irqs cd_irq; struct pcmcia_irqs cd_irq;
cd_irq.sock = skt->nr; cd_irq.sock = skt->nr;
cd_irq.irq = scoop_devs[skt->nr].cd_irq; cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq;
cd_irq.str = scoop_devs[skt->nr].cd_irq_str; cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str;
ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1); ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1);
if (ret) { if (ret) {
...@@ -83,19 +65,19 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ...@@ -83,19 +65,19 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
} }
} }
skt->irq = scoop_devs[skt->nr].irq; skt->irq = SCOOP_DEV[skt->nr].irq;
return 0; return 0;
} }
static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{ {
if (scoop_devs[skt->nr].cd_irq >= 0) { if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
struct pcmcia_irqs cd_irq; struct pcmcia_irqs cd_irq;
cd_irq.sock = skt->nr; cd_irq.sock = skt->nr;
cd_irq.irq = scoop_devs[skt->nr].cd_irq; cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq;
cd_irq.str = scoop_devs[skt->nr].cd_irq_str; cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str;
soc_pcmcia_free_irqs(skt, &cd_irq, 1); soc_pcmcia_free_irqs(skt, &cd_irq, 1);
} }
} }
...@@ -105,9 +87,9 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, ...@@ -105,9 +87,9 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state) struct pcmcia_state *state)
{ {
unsigned short cpr, csr; unsigned short cpr, csr;
struct device *scoop = scoop_devs[skt->nr].dev; struct device *scoop = SCOOP_DEV[skt->nr].dev;
cpr = read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR); cpr = read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR);
write_scoop_reg(scoop, SCOOP_IRM, 0x00FF); write_scoop_reg(scoop, SCOOP_IRM, 0x00FF);
write_scoop_reg(scoop, SCOOP_ISR, 0x0000); write_scoop_reg(scoop, SCOOP_ISR, 0x0000);
...@@ -116,21 +98,25 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, ...@@ -116,21 +98,25 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
if (csr & 0x0004) { if (csr & 0x0004) {
/* card eject */ /* card eject */
write_scoop_reg(scoop, SCOOP_CDR, 0x0000); write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
scoop_devs[skt->nr].keep_vs = NO_KEEP_VS; SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS;
} }
else if (!(scoop_devs[skt->nr].keep_vs & NO_KEEP_VS)) { else if (!(SCOOP_DEV[skt->nr].keep_vs & NO_KEEP_VS)) {
/* keep vs1,vs2 */ /* keep vs1,vs2 */
write_scoop_reg(scoop, SCOOP_CDR, 0x0000); write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
csr |= scoop_devs[skt->nr].keep_vs; csr |= SCOOP_DEV[skt->nr].keep_vs;
} }
else if (cpr & 0x0003) { else if (cpr & 0x0003) {
/* power on */ /* power on */
write_scoop_reg(scoop, SCOOP_CDR, 0x0000); write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
scoop_devs[skt->nr].keep_vs = (csr & 0x00C0); SCOOP_DEV[skt->nr].keep_vs = (csr & 0x00C0);
} }
else { else {
/* card detect */ /* card detect */
write_scoop_reg(scoop, SCOOP_CDR, 0x0002); if ((machine_is_spitz() || machine_is_borzoi()) && skt->nr == 1) {
write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
} else {
write_scoop_reg(scoop, SCOOP_CDR, 0x0002);
}
} }
state->detect = (csr & 0x0004) ? 0 : 1; state->detect = (csr & 0x0004) ? 0 : 1;
...@@ -144,7 +130,6 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, ...@@ -144,7 +130,6 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) { if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) {
printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr); printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr);
} }
} }
...@@ -152,7 +137,7 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ...@@ -152,7 +137,7 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state) const socket_state_t *state)
{ {
unsigned long flags; unsigned long flags;
struct device *scoop = scoop_devs[skt->nr].dev; struct device *scoop = SCOOP_DEV[skt->nr].dev;
unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr; unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr;
...@@ -177,8 +162,13 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ...@@ -177,8 +162,13 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
nccr = (ccr = read_scoop_reg(scoop, SCOOP_CCR)) & ~0x0080; nccr = (ccr = read_scoop_reg(scoop, SCOOP_CCR)) & ~0x0080;
nimr = (imr = read_scoop_reg(scoop, SCOOP_IMR)) & ~0x003E; nimr = (imr = read_scoop_reg(scoop, SCOOP_IMR)) & ~0x003E;
ncpr |= (state->Vcc == 33) ? 0x0001 : if ((machine_is_spitz() || machine_is_borzoi() || machine_is_akita()) && skt->nr == 0) {
(state->Vcc == 50) ? 0x0002 : 0; ncpr |= (state->Vcc == 33) ? 0x0002 :
(state->Vcc == 50) ? 0x0002 : 0;
} else {
ncpr |= (state->Vcc == 33) ? 0x0001 :
(state->Vcc == 50) ? 0x0002 : 0;
}
nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0; nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0;
ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0; ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0;
nccr |= (state->flags&SS_RESET)? 0x0080: 0; nccr |= (state->flags&SS_RESET)? 0x0080: 0;
...@@ -190,18 +180,22 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ...@@ -190,18 +180,22 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
((skt->status&SS_WRPROT) ? 0x0008 : 0); ((skt->status&SS_WRPROT) ? 0x0008 : 0);
if (!(ncpr & 0x0003)) { if (!(ncpr & 0x0003)) {
scoop_devs[skt->nr].keep_rd = 0; SCOOP_DEV[skt->nr].keep_rd = 0;
} else if (!scoop_devs[skt->nr].keep_rd) { } else if (!SCOOP_DEV[skt->nr].keep_rd) {
if (nccr & 0x0080) if (nccr & 0x0080)
scoop_devs[skt->nr].keep_rd = 1; SCOOP_DEV[skt->nr].keep_rd = 1;
else else
nccr |= 0x0080; nccr |= 0x0080;
} }
if (mcr != nmcr) if (mcr != nmcr)
write_scoop_reg(scoop, SCOOP_MCR, nmcr); write_scoop_reg(scoop, SCOOP_MCR, nmcr);
if (cpr != ncpr) if (cpr != ncpr) {
write_scoop_reg(scoop, SCOOP_CPR, ncpr); if (platform_scoop_config->power_ctrl)
platform_scoop_config->power_ctrl(scoop, ncpr , skt->nr);
else
write_scoop_reg(scoop, SCOOP_CPR, ncpr);
}
if (ccr != nccr) if (ccr != nccr)
write_scoop_reg(scoop, SCOOP_CCR, nccr); write_scoop_reg(scoop, SCOOP_CCR, nccr);
if (imr != nimr) if (imr != nimr)
...@@ -214,43 +208,43 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ...@@ -214,43 +208,43 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt) static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{ {
sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]); sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
/* Enable interrupt */ /* Enable interrupt */
write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_IMR, 0x00C0); write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_IMR, 0x00C0);
write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_MCR, 0x0101); write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_MCR, 0x0101);
scoop_devs[skt->nr].keep_vs = NO_KEEP_VS; SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS;
if (machine_is_collie()) if (machine_is_collie())
/* We need to disable SS_OUTPUT_ENA here. */ /* We need to disable SS_OUTPUT_ENA here. */
write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080); write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080);
} }
static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{ {
/* CF_BUS_OFF */ /* CF_BUS_OFF */
sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]); sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
if (machine_is_collie()) if (machine_is_collie())
/* We need to disable SS_OUTPUT_ENA here. */ /* We need to disable SS_OUTPUT_ENA here. */
write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080); write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080);
} }
static struct pcmcia_low_level sharpsl_pcmcia_ops = { static struct pcmcia_low_level sharpsl_pcmcia_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.hw_init = sharpsl_pcmcia_hw_init, .hw_init = sharpsl_pcmcia_hw_init,
.hw_shutdown = sharpsl_pcmcia_hw_shutdown, .hw_shutdown = sharpsl_pcmcia_hw_shutdown,
.socket_state = sharpsl_pcmcia_socket_state, .socket_state = sharpsl_pcmcia_socket_state,
.configure_socket = sharpsl_pcmcia_configure_socket, .configure_socket = sharpsl_pcmcia_configure_socket,
.socket_init = sharpsl_pcmcia_socket_init, .socket_init = sharpsl_pcmcia_socket_init,
.socket_suspend = sharpsl_pcmcia_socket_suspend, .socket_suspend = sharpsl_pcmcia_socket_suspend,
.first = 0, .first = 0,
.nr = 0, .nr = 0,
}; };
static struct platform_device *sharpsl_pcmcia_device;
#ifdef CONFIG_SA1100_COLLIE #ifdef CONFIG_SA1100_COLLIE
#include "sa11xx_base.h"
int __init pcmcia_collie_init(struct device *dev) int __init pcmcia_collie_init(struct device *dev)
{ {
int ret = -ENODEV; int ret = -ENODEV;
...@@ -263,11 +257,13 @@ int __init pcmcia_collie_init(struct device *dev) ...@@ -263,11 +257,13 @@ int __init pcmcia_collie_init(struct device *dev)
#else #else
static struct platform_device *sharpsl_pcmcia_device;
static int __init sharpsl_pcmcia_init(void) static int __init sharpsl_pcmcia_init(void)
{ {
int ret; int ret;
sharpsl_pcmcia_ops.nr=scoop_num; sharpsl_pcmcia_ops.nr=platform_scoop_config->num_devs;
sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL); sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL);
if (!sharpsl_pcmcia_device) if (!sharpsl_pcmcia_device)
return -ENOMEM; return -ENOMEM;
...@@ -275,7 +271,7 @@ static int __init sharpsl_pcmcia_init(void) ...@@ -275,7 +271,7 @@ static int __init sharpsl_pcmcia_init(void)
memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device)); memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device));
sharpsl_pcmcia_device->name = "pxa2xx-pcmcia"; sharpsl_pcmcia_device->name = "pxa2xx-pcmcia";
sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;
sharpsl_pcmcia_device->dev.parent=scoop_devs[0].dev; sharpsl_pcmcia_device->dev.parent=platform_scoop_config->devs[0].dev;
ret = platform_device_register(sharpsl_pcmcia_device); ret = platform_device_register(sharpsl_pcmcia_device);
if (ret) if (ret)
......
...@@ -52,8 +52,14 @@ struct scoop_pcmcia_dev { ...@@ -52,8 +52,14 @@ struct scoop_pcmcia_dev {
unsigned char keep_rd; unsigned char keep_rd;
}; };
extern int scoop_num; struct scoop_pcmcia_config {
extern struct scoop_pcmcia_dev *scoop_devs; struct scoop_pcmcia_dev *devs;
int num_devs;
void (*pcmcia_init)(void);
void (*power_ctrl)(struct device *scoop, unsigned short cpr, int nr);
};
extern struct scoop_pcmcia_config *platform_scoop_config;
void reset_scoop(struct device *dev); void reset_scoop(struct device *dev);
unsigned short set_scoop_gpio(struct device *dev, unsigned short bit); unsigned short set_scoop_gpio(struct device *dev, unsigned short bit);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment