2007-11-29 17:11:23 +01:00
/*
* Helper functions for I / O pins .
*
* Copyright ( c ) 2005 - 2007 Axis Communications AB .
*/
# include <linux/types.h>
# include <linux/errno.h>
# include <linux/init.h>
# include <linux/string.h>
# include <linux/ctype.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <asm/io.h>
2008-10-21 17:45:58 +02:00
# include <mach/pinmux.h>
2007-11-29 17:11:23 +01:00
# include <hwregs/gio_defs.h>
struct crisv32_ioport crisv32_ioports [ ] = {
{
( unsigned long * ) REG_ADDR ( gio , regi_gio , rw_pa_oe ) ,
( unsigned long * ) REG_ADDR ( gio , regi_gio , rw_pa_dout ) ,
( unsigned long * ) REG_ADDR ( gio , regi_gio , r_pa_din ) ,
32
} ,
{
( unsigned long * ) REG_ADDR ( gio , regi_gio , rw_pb_oe ) ,
( unsigned long * ) REG_ADDR ( gio , regi_gio , rw_pb_dout ) ,
( unsigned long * ) REG_ADDR ( gio , regi_gio , r_pb_din ) ,
32
} ,
{
( unsigned long * ) REG_ADDR ( gio , regi_gio , rw_pc_oe ) ,
( unsigned long * ) REG_ADDR ( gio , regi_gio , rw_pc_dout ) ,
( unsigned long * ) REG_ADDR ( gio , regi_gio , r_pc_din ) ,
16
} ,
} ;
# define NBR_OF_PORTS sizeof(crisv32_ioports) / sizeof(struct crisv32_ioport)
struct crisv32_iopin crisv32_led_net0_green ;
struct crisv32_iopin crisv32_led_net0_red ;
struct crisv32_iopin crisv32_led2_green ;
struct crisv32_iopin crisv32_led2_red ;
struct crisv32_iopin crisv32_led3_green ;
struct crisv32_iopin crisv32_led3_red ;
/* Dummy port used when green LED and red LED is on the same bit */
static unsigned long io_dummy ;
static struct crisv32_ioport dummy_port = {
& io_dummy ,
& io_dummy ,
& io_dummy ,
32
} ;
static struct crisv32_iopin dummy_led = {
& dummy_port ,
0
} ;
static int __init crisv32_io_init ( void )
{
int ret = 0 ;
u32 i ;
/* Locks *should* be dynamically initialized. */
for ( i = 0 ; i < ARRAY_SIZE ( crisv32_ioports ) ; i + + )
spin_lock_init ( & crisv32_ioports [ i ] . lock ) ;
spin_lock_init ( & dummy_port . lock ) ;
/* Initialize LEDs */
# if (defined(CONFIG_ETRAX_NBR_LED_GRP_ONE) || defined(CONFIG_ETRAX_NBR_LED_GRP_TWO))
ret + = crisv32_io_get_name ( & crisv32_led_net0_green ,
CONFIG_ETRAX_LED_G_NET0 ) ;
crisv32_io_set_dir ( & crisv32_led_net0_green , crisv32_io_dir_out ) ;
if ( strcmp ( CONFIG_ETRAX_LED_G_NET0 , CONFIG_ETRAX_LED_R_NET0 ) ) {
ret + = crisv32_io_get_name ( & crisv32_led_net0_red ,
CONFIG_ETRAX_LED_R_NET0 ) ;
crisv32_io_set_dir ( & crisv32_led_net0_red , crisv32_io_dir_out ) ;
} else
crisv32_led_net0_red = dummy_led ;
# endif
ret + = crisv32_io_get_name ( & crisv32_led2_green , CONFIG_ETRAX_V32_LED2G ) ;
ret + = crisv32_io_get_name ( & crisv32_led2_red , CONFIG_ETRAX_V32_LED2R ) ;
ret + = crisv32_io_get_name ( & crisv32_led3_green , CONFIG_ETRAX_V32_LED3G ) ;
ret + = crisv32_io_get_name ( & crisv32_led3_red , CONFIG_ETRAX_V32_LED3R ) ;
crisv32_io_set_dir ( & crisv32_led2_green , crisv32_io_dir_out ) ;
crisv32_io_set_dir ( & crisv32_led2_red , crisv32_io_dir_out ) ;
crisv32_io_set_dir ( & crisv32_led3_green , crisv32_io_dir_out ) ;
crisv32_io_set_dir ( & crisv32_led3_red , crisv32_io_dir_out ) ;
return ret ;
}
__initcall ( crisv32_io_init ) ;
int crisv32_io_get ( struct crisv32_iopin * iopin ,
unsigned int port , unsigned int pin )
{
if ( port > NBR_OF_PORTS )
return - EINVAL ;
if ( port > crisv32_ioports [ port ] . pin_count )
return - EINVAL ;
iopin - > bit = 1 < < pin ;
iopin - > port = & crisv32_ioports [ port ] ;
if ( crisv32_pinmux_alloc ( port , pin , pin , pinmux_gpio ) )
return - EIO ;
return 0 ;
}
2008-01-29 18:54:55 +01:00
int crisv32_io_get_name ( struct crisv32_iopin * iopin , const char * name )
2007-11-29 17:11:23 +01:00
{
int port ;
int pin ;
if ( toupper ( * name ) = = ' P ' )
name + + ;
if ( toupper ( * name ) < ' A ' | | toupper ( * name ) > ' E ' )
return - EINVAL ;
port = toupper ( * name ) - ' A ' ;
name + + ;
pin = simple_strtoul ( name , NULL , 10 ) ;
if ( pin < 0 | | pin > crisv32_ioports [ port ] . pin_count )
return - EINVAL ;
iopin - > bit = 1 < < pin ;
iopin - > port = & crisv32_ioports [ port ] ;
if ( crisv32_pinmux_alloc ( port , pin , pin , pinmux_gpio ) )
return - EIO ;
return 0 ;
}
# ifdef CONFIG_PCI
/* PCI I/O access stuff */
struct cris_io_operations * cris_iops = NULL ;
EXPORT_SYMBOL ( cris_iops ) ;
# endif