2005-04-17 02:20:36 +04:00
/*
* linux / drivers / pcmcia / sa1100_badge4 . c
*
* BadgePAD 4 PCMCIA specific routines
*
* Christopher Hoover < ch @ hpl . hp . com >
*
* Copyright ( C ) 2002 Hewlett - Packard Company
*
* 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/kernel.h>
# include <linux/device.h>
# include <linux/errno.h>
# include <linux/init.h>
2008-08-05 19:14:15 +04:00
# include <mach/hardware.h>
2005-04-17 02:20:36 +04:00
# include <asm/mach-types.h>
2008-08-05 19:14:15 +04:00
# include <mach/badge4.h>
2005-04-17 02:20:36 +04:00
# include <asm/hardware/sa1111.h>
# include "sa1111_generic.h"
/*
* BadgePAD 4 Details
*
* PCM Vcc :
*
* PCM Vcc on BadgePAD 4 can be jumpered for 3 v3 ( short pins 1 and 3
* on JP6 ) or 5 v0 ( short pins 3 and 5 on JP6 ) .
*
* PCM Vpp :
*
* PCM Vpp on BadgePAD 4 can be jumpered for 12 v0 ( short pins 4 and 6
* on JP6 ) or tied to PCM Vcc ( short pins 2 and 4 on JP6 ) . N . B . ,
* 12 v0 operation requires that the power supply actually supply 12 v0
* via pin 7 of JP7 .
*
* CF Vcc :
*
* CF Vcc on BadgePAD 4 can be jumpered either for 3 v3 ( short pins 1
* and 2 on JP10 ) or 5 v0 ( short pins 2 and 3 on JP10 ) .
*
* Unfortunately there ' s no way programmatically to determine how a
* given board is jumpered . This code assumes a default jumpering
* as described below .
*
* If the defaults aren ' t correct , you may override them with a pcmv
* setup argument : pcmv = < pcm vcc > , < pcm vpp > , < cf vcc > . The units are
* tenths of volts ; e . g . pcmv = 33 , 120 , 50 indicates 3 v3 PCM Vcc , 12 v0
* PCM Vpp , and 5 v0 CF Vcc .
*
*/
static int badge4_pcmvcc = 50 ; /* pins 3 and 5 jumpered on JP6 */
static int badge4_pcmvpp = 50 ; /* pins 2 and 4 jumpered on JP6 */
static int badge4_cfvcc = 33 ; /* pins 1 and 2 jumpered on JP10 */
static void complain_about_jumpering ( const char * whom ,
const char * supply ,
int given , int wanted )
{
printk ( KERN_ERR
" %s: %s %d.%dV wanted but board is jumpered for %s %d.%dV operation "
" ; re-jumper the board and/or use pcmv=xx,xx,xx \n " ,
whom , supply ,
wanted / 10 , wanted % 10 ,
supply ,
given / 10 , given % 10 ) ;
}
static int
badge4_pcmcia_configure_socket ( struct soc_pcmcia_socket * skt , const socket_state_t * state )
{
int ret ;
switch ( skt - > nr ) {
case 0 :
if ( ( state - > Vcc ! = 0 ) & &
( state - > Vcc ! = badge4_pcmvcc ) ) {
2008-05-01 15:34:54 +04:00
complain_about_jumpering ( __func__ , " pcmvcc " ,
2005-04-17 02:20:36 +04:00
badge4_pcmvcc , state - > Vcc ) ;
// Apply power regardless of the jumpering.
// return -1;
}
if ( ( state - > Vpp ! = 0 ) & &
( state - > Vpp ! = badge4_pcmvpp ) ) {
2008-05-01 15:34:54 +04:00
complain_about_jumpering ( __func__ , " pcmvpp " ,
2005-04-17 02:20:36 +04:00
badge4_pcmvpp , state - > Vpp ) ;
return - 1 ;
}
break ;
case 1 :
if ( ( state - > Vcc ! = 0 ) & &
( state - > Vcc ! = badge4_cfvcc ) ) {
2008-05-01 15:34:54 +04:00
complain_about_jumpering ( __func__ , " cfvcc " ,
2005-04-17 02:20:36 +04:00
badge4_cfvcc , state - > Vcc ) ;
return - 1 ;
}
break ;
default :
return - 1 ;
}
ret = sa1111_pcmcia_configure_socket ( skt , state ) ;
if ( ret = = 0 ) {
unsigned long flags ;
int need5V ;
local_irq_save ( flags ) ;
need5V = ( ( state - > Vcc = = 50 ) | | ( state - > Vpp = = 50 ) ) ;
badge4_set_5V ( BADGE4_5V_PCMCIA_SOCK ( skt - > nr ) , need5V ) ;
local_irq_restore ( flags ) ;
}
2012-01-16 13:27:33 +04:00
return ret ;
2005-04-17 02:20:36 +04:00
}
static struct pcmcia_low_level badge4_pcmcia_ops = {
. owner = THIS_MODULE ,
. configure_socket = badge4_pcmcia_configure_socket ,
2009-03-29 22:42:44 +04:00
. first = 0 ,
. nr = 2 ,
2005-04-17 02:20:36 +04:00
} ;
2014-10-21 00:29:23 +04:00
int pcmcia_badge4_init ( struct sa1111_dev * dev )
2005-04-17 02:20:36 +04:00
{
int ret = - ENODEV ;
if ( machine_is_badge4 ( ) ) {
printk ( KERN_INFO
" %s: badge4_pcmvcc=%d, badge4_pcmvpp=%d, badge4_cfvcc=%d \n " ,
2008-05-01 15:34:54 +04:00
__func__ ,
2005-04-17 02:20:36 +04:00
badge4_pcmvcc , badge4_pcmvpp , badge4_cfvcc ) ;
2009-03-29 22:42:44 +04:00
sa11xx_drv_pcmcia_ops ( & badge4_pcmcia_ops ) ;
ret = sa1111_pcmcia_add ( dev , & badge4_pcmcia_ops ,
sa11xx_drv_pcmcia_add_one ) ;
2005-04-17 02:20:36 +04:00
}
return ret ;
}
static int __init pcmv_setup ( char * s )
{
int v [ 4 ] ;
s = get_options ( s , ARRAY_SIZE ( v ) , v ) ;
if ( v [ 0 ] > = 1 ) badge4_pcmvcc = v [ 1 ] ;
if ( v [ 0 ] > = 2 ) badge4_pcmvpp = v [ 2 ] ;
if ( v [ 0 ] > = 3 ) badge4_cfvcc = v [ 3 ] ;
return 1 ;
}
__setup ( " pcmv= " , pcmv_setup ) ;