2019-06-04 11:11:33 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2005-04-17 02:20:36 +04:00
/*
* linux / drivers / pcmcia / pxa2xx_mainstone . c
*
* Mainstone PCMCIA specific routines .
*
* Created : May 12 , 2004
* Author : Nicolas Pitre
* Copyright : MontaVista Software Inc .
*/
2018-11-28 16:57:23 +03:00
# include <linux/gpio/consumer.h>
2005-04-17 02:20:36 +04:00
# include <linux/module.h>
# include <linux/init.h>
2018-11-28 16:57:23 +03:00
# include <linux/interrupt.h>
2005-04-17 02:20:36 +04:00
# include <linux/kernel.h>
# include <linux/errno.h>
2005-10-29 22:07:23 +04:00
# include <linux/platform_device.h>
2005-04-17 02:20:36 +04:00
# include <pcmcia/ss.h>
2008-04-24 18:23:25 +04:00
# include <asm/mach-types.h>
2005-04-17 02:20:36 +04:00
# include "soc_common.h"
2018-11-28 16:57:23 +03:00
# include "max1600.h"
2005-04-17 02:20:36 +04:00
static int mst_pcmcia_hw_init ( struct soc_pcmcia_socket * skt )
{
2018-11-28 16:57:23 +03:00
struct device * dev = skt - > socket . dev . parent ;
struct max1600 * m ;
int ret ;
skt - > stat [ SOC_STAT_CD ] . name = skt - > nr ? " bdetect " : " adetect " ;
skt - > stat [ SOC_STAT_BVD1 ] . name = skt - > nr ? " bbvd1 " : " abvd1 " ;
skt - > stat [ SOC_STAT_BVD2 ] . name = skt - > nr ? " bbvd2 " : " abvd2 " ;
skt - > stat [ SOC_STAT_RDY ] . name = skt - > nr ? " bready " : " aready " ;
skt - > stat [ SOC_STAT_VS1 ] . name = skt - > nr ? " bvs1 " : " avs1 " ;
skt - > stat [ SOC_STAT_VS2 ] . name = skt - > nr ? " bvs2 " : " avs2 " ;
skt - > gpio_reset = devm_gpiod_get ( dev , skt - > nr ? " breset " : " areset " ,
GPIOD_OUT_HIGH ) ;
if ( IS_ERR ( skt - > gpio_reset ) )
return PTR_ERR ( skt - > gpio_reset ) ;
ret = max1600_init ( dev , & m , skt - > nr ? MAX1600_CHAN_B : MAX1600_CHAN_A ,
MAX1600_CODE_HIGH ) ;
if ( ret )
return ret ;
skt - > driver_data = m ;
return soc_pcmcia_request_gpiods ( skt ) ;
2005-04-17 02:20:36 +04:00
}
2018-11-28 16:57:23 +03:00
static unsigned int mst_pcmcia_bvd1_status [ 2 ] ;
2005-04-17 02:20:36 +04:00
static void mst_pcmcia_socket_state ( struct soc_pcmcia_socket * skt ,
struct pcmcia_state * state )
{
2018-11-28 16:57:23 +03:00
unsigned int flip = mst_pcmcia_bvd1_status [ skt - > nr ] ^ state - > bvd1 ;
2005-04-17 02:20:36 +04:00
/*
* Workaround for STSCHG which can ' t be deasserted :
* We therefore disable / enable corresponding IRQs
* as needed to avoid IRQ locks .
*/
if ( flip ) {
2018-11-28 16:57:23 +03:00
mst_pcmcia_bvd1_status [ skt - > nr ] = state - > bvd1 ;
if ( state - > bvd1 )
enable_irq ( skt - > stat [ SOC_STAT_BVD1 ] . irq ) ;
2005-04-17 02:20:36 +04:00
else
2018-11-28 16:57:23 +03:00
disable_irq ( skt - > stat [ SOC_STAT_BVD2 ] . irq ) ;
2005-04-17 02:20:36 +04:00
}
}
static int mst_pcmcia_configure_socket ( struct soc_pcmcia_socket * skt ,
const socket_state_t * state )
{
2018-11-28 16:57:23 +03:00
return max1600_configure ( skt - > driver_data , state - > Vcc , state - > Vpp ) ;
2005-04-17 02:20:36 +04:00
}
2008-04-24 18:28:11 +04:00
static struct pcmcia_low_level mst_pcmcia_ops __initdata = {
2005-04-17 02:20:36 +04:00
. owner = THIS_MODULE ,
. hw_init = mst_pcmcia_hw_init ,
. socket_state = mst_pcmcia_socket_state ,
. configure_socket = mst_pcmcia_configure_socket ,
. nr = 2 ,
} ;
static struct platform_device * mst_pcmcia_device ;
static int __init mst_pcmcia_init ( void )
{
int ret ;
2008-04-24 18:23:25 +04:00
if ( ! machine_is_mainstone ( ) )
return - ENODEV ;
2006-01-10 20:16:12 +03:00
mst_pcmcia_device = platform_device_alloc ( " pxa2xx-pcmcia " , - 1 ) ;
2005-04-17 02:20:36 +04:00
if ( ! mst_pcmcia_device )
return - ENOMEM ;
2006-01-10 20:16:12 +03:00
2008-04-24 18:28:11 +04:00
ret = platform_device_add_data ( mst_pcmcia_device , & mst_pcmcia_ops ,
sizeof ( mst_pcmcia_ops ) ) ;
if ( ret = = 0 )
ret = platform_device_add ( mst_pcmcia_device ) ;
2006-01-10 20:16:12 +03:00
2005-04-17 02:20:36 +04:00
if ( ret )
2006-01-10 20:16:12 +03:00
platform_device_put ( mst_pcmcia_device ) ;
2005-04-17 02:20:36 +04:00
return ret ;
}
static void __exit mst_pcmcia_exit ( void )
{
platform_device_unregister ( mst_pcmcia_device ) ;
}
2005-09-03 22:39:25 +04:00
fs_initcall ( mst_pcmcia_init ) ;
2005-04-17 02:20:36 +04:00
module_exit ( mst_pcmcia_exit ) ;
MODULE_LICENSE ( " GPL " ) ;
2007-08-18 06:40:39 +04:00
MODULE_ALIAS ( " platform:pxa2xx-pcmcia " ) ;