2010-07-27 23:48:10 +04:00
/*
* linux / drivers / pcmcia / pxa2xx_balloon3 . c
*
* Balloon3 PCMCIA specific routines .
*
* Author : Nick Bane
* Created : June , 2006
* Copyright : Toby Churchill Ltd
* Derived from pxa2xx_mainstone . c , by Nico Pitre
*
* Various modification by 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/gpio.h>
# include <linux/errno.h>
# include <linux/interrupt.h>
# include <linux/platform_device.h>
# include <linux/irq.h>
# include <linux/io.h>
# include <mach/balloon3.h>
2011-04-01 13:28:45 +04:00
# include <asm/mach-types.h>
2010-07-27 23:48:10 +04:00
# include "soc_common.h"
static int balloon3_pcmcia_hw_init ( struct soc_pcmcia_socket * skt )
{
uint16_t ver ;
ver = __raw_readw ( BALLOON3_FPGA_VER ) ;
2010-10-19 18:19:32 +04:00
if ( ver < 0x4f08 )
pr_warn ( " The FPGA code, version 0x%04x, is too old. "
2010-07-27 23:48:10 +04:00
" PCMCIA/CF support might be broken in this version! " ,
ver ) ;
skt - > socket . pci_irq = BALLOON3_BP_CF_NRDY_IRQ ;
2012-01-14 02:56:32 +04:00
skt - > stat [ SOC_STAT_CD ] . gpio = BALLOON3_GPIO_S0_CD ;
skt - > stat [ SOC_STAT_CD ] . name = " PCMCIA0 CD " ;
skt - > stat [ SOC_STAT_BVD1 ] . irq = BALLOON3_BP_NSTSCHG_IRQ ;
skt - > stat [ SOC_STAT_BVD1 ] . name = " PCMCIA0 STSCHG " ;
2010-07-27 23:48:10 +04:00
2012-01-14 02:56:32 +04:00
return 0 ;
2010-07-27 23:48:10 +04:00
}
static unsigned long balloon3_pcmcia_status [ 2 ] = {
BALLOON3_CF_nSTSCHG_BVD1 ,
BALLOON3_CF_nSTSCHG_BVD1
} ;
static void balloon3_pcmcia_socket_state ( struct soc_pcmcia_socket * skt ,
struct pcmcia_state * state )
{
uint16_t status ;
int flip ;
/* This actually reads the STATUS register */
status = __raw_readw ( BALLOON3_CF_STATUS_REG ) ;
flip = ( status ^ balloon3_pcmcia_status [ skt - > nr ] )
& BALLOON3_CF_nSTSCHG_BVD1 ;
/*
* Workaround for STSCHG which can ' t be deasserted :
* We therefore disable / enable corresponding IRQs
* as needed to avoid IRQ locks .
*/
if ( flip ) {
balloon3_pcmcia_status [ skt - > nr ] = status ;
if ( status & BALLOON3_CF_nSTSCHG_BVD1 )
enable_irq ( BALLOON3_BP_NSTSCHG_IRQ ) ;
else
disable_irq ( BALLOON3_BP_NSTSCHG_IRQ ) ;
}
state - > ready = ! ! ( status & BALLOON3_CF_nIRQ ) ;
state - > bvd1 = ! ! ( status & BALLOON3_CF_nSTSCHG_BVD1 ) ;
state - > bvd2 = 0 ; /* not available */
state - > vs_3v = 1 ; /* Always true its a CF card */
state - > vs_Xv = 0 ; /* not available */
}
static int balloon3_pcmcia_configure_socket ( struct soc_pcmcia_socket * skt ,
const socket_state_t * state )
{
2011-10-02 00:03:45 +04:00
__raw_writew ( BALLOON3_CF_RESET , BALLOON3_CF_CONTROL_REG +
2010-10-19 18:19:32 +04:00
( ( state - > flags & SS_RESET ) ?
BALLOON3_FPGA_SETnCLR : 0 ) ) ;
2010-07-27 23:48:10 +04:00
return 0 ;
}
static struct pcmcia_low_level balloon3_pcmcia_ops = {
. owner = THIS_MODULE ,
. hw_init = balloon3_pcmcia_hw_init ,
. socket_state = balloon3_pcmcia_socket_state ,
. configure_socket = balloon3_pcmcia_configure_socket ,
. first = 0 ,
. nr = 1 ,
} ;
static struct platform_device * balloon3_pcmcia_device ;
static int __init balloon3_pcmcia_init ( void )
{
int ret ;
2011-04-01 13:28:45 +04:00
if ( ! machine_is_balloon3 ( ) )
return - ENODEV ;
2010-07-27 23:48:10 +04:00
balloon3_pcmcia_device = platform_device_alloc ( " pxa2xx-pcmcia " , - 1 ) ;
if ( ! balloon3_pcmcia_device )
return - ENOMEM ;
ret = platform_device_add_data ( balloon3_pcmcia_device ,
& balloon3_pcmcia_ops , sizeof ( balloon3_pcmcia_ops ) ) ;
if ( ! ret )
ret = platform_device_add ( balloon3_pcmcia_device ) ;
if ( ret )
platform_device_put ( balloon3_pcmcia_device ) ;
return ret ;
}
static void __exit balloon3_pcmcia_exit ( void )
{
platform_device_unregister ( balloon3_pcmcia_device ) ;
}
module_init ( balloon3_pcmcia_init ) ;
module_exit ( balloon3_pcmcia_exit ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_AUTHOR ( " Nick Bane <nick@cecomputing.co.uk> " ) ;
MODULE_ALIAS ( " platform:pxa2xx-pcmcia " ) ;
MODULE_DESCRIPTION ( " Balloon3 board CF/PCMCIA driver " ) ;