2005-04-17 02:20:36 +04:00
/*
* drivers / pcmcia / sa1100_assabet . c
*
* PCMCIA implementation routines for Assabet
*
*/
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/errno.h>
# include <linux/interrupt.h>
# include <linux/device.h>
# include <linux/init.h>
2012-01-14 03:02:15 +04:00
# include <linux/gpio.h>
2005-04-17 02:20:36 +04:00
# include <asm/mach-types.h>
2008-08-05 19:14:15 +04:00
# include <mach/assabet.h>
2005-04-17 02:20:36 +04:00
# include "sa1100_generic.h"
static int assabet_pcmcia_hw_init ( struct soc_pcmcia_socket * skt )
{
2012-01-14 03:02:15 +04:00
skt - > stat [ SOC_STAT_CD ] . gpio = ASSABET_GPIO_CF_CD ;
skt - > stat [ SOC_STAT_CD ] . name = " CF CD " ;
skt - > stat [ SOC_STAT_BVD1 ] . gpio = ASSABET_GPIO_CF_BVD1 ;
skt - > stat [ SOC_STAT_BVD1 ] . name = " CF BVD1 " ;
skt - > stat [ SOC_STAT_BVD2 ] . gpio = ASSABET_GPIO_CF_BVD2 ;
skt - > stat [ SOC_STAT_BVD2 ] . name = " CF BVD2 " ;
skt - > stat [ SOC_STAT_RDY ] . gpio = ASSABET_GPIO_CF_IRQ ;
skt - > stat [ SOC_STAT_RDY ] . name = " CF RDY " ;
2005-04-17 02:20:36 +04:00
2012-01-14 03:02:15 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
static int
assabet_pcmcia_configure_socket ( struct soc_pcmcia_socket * skt , const socket_state_t * state )
{
unsigned int mask ;
switch ( state - > Vcc ) {
case 0 :
mask = 0 ;
break ;
case 50 :
printk ( KERN_WARNING " %s(): CS asked for 5V, applying 3.3V... \n " ,
2008-05-01 15:34:54 +04:00
__func__ ) ;
2005-04-17 02:20:36 +04:00
case 33 : /* Can only apply 3.3V to the CF slot. */
mask = ASSABET_BCR_CF_PWR ;
break ;
default :
2008-05-01 15:34:54 +04:00
printk ( KERN_ERR " %s(): unrecognized Vcc %u \n " , __func__ ,
2005-04-17 02:20:36 +04:00
state - > Vcc ) ;
return - 1 ;
}
2012-01-14 03:02:15 +04:00
/* Silently ignore Vpp, speaker enable. */
2005-04-17 02:20:36 +04:00
if ( state - > flags & SS_RESET )
mask | = ASSABET_BCR_CF_RST ;
2012-01-14 03:02:15 +04:00
if ( ! ( state - > flags & SS_OUTPUT_ENA ) )
mask | = ASSABET_BCR_CF_BUS_OFF ;
2005-04-17 02:20:36 +04:00
2012-01-14 03:02:15 +04:00
ASSABET_BCR_frob ( ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR |
ASSABET_BCR_CF_BUS_OFF , mask ) ;
2005-04-17 02:20:36 +04:00
return 0 ;
}
/*
* Disable card status IRQs on suspend .
*/
static void assabet_pcmcia_socket_suspend ( struct soc_pcmcia_socket * skt )
{
/*
* Tristate the CF bus signals . Also assert CF
* reset as per user guide page 4 - 11.
*/
ASSABET_BCR_set ( ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_CF_RST ) ;
}
static struct pcmcia_low_level assabet_pcmcia_ops = {
. owner = THIS_MODULE ,
. hw_init = assabet_pcmcia_hw_init ,
2016-08-31 10:49:46 +03:00
. socket_state = soc_common_cf_socket_state ,
2005-04-17 02:20:36 +04:00
. configure_socket = assabet_pcmcia_configure_socket ,
. socket_suspend = assabet_pcmcia_socket_suspend ,
} ;
2012-11-19 22:23:12 +04:00
int pcmcia_assabet_init ( struct device * dev )
2005-04-17 02:20:36 +04:00
{
int ret = - ENODEV ;
if ( machine_is_assabet ( ) & & ! machine_has_neponset ( ) )
ret = sa11xx_drv_pcmcia_probe ( dev , & assabet_pcmcia_ops , 1 , 1 ) ;
return ret ;
}