@ -8,7 +8,7 @@
# include <common.h>
# include <command.h>
# include <dm.h>
# include <asm/gpio.h>
# ifndef name_to_gpio
@ -22,25 +22,115 @@ enum gpio_cmd {
GPIO_TOGGLE ,
} ;
# if defined(CONFIG_DM_GPIO) && !defined(gpio_status)
static const char * const gpio_function [ ] = {
" input " ,
" output " ,
" unknown " ,
} ;
static void show_gpio ( struct device * dev , const char * bank_name , int offset )
{
struct dm_gpio_ops * ops = gpio_get_ops ( dev ) ;
char buf [ 80 ] ;
int ret ;
* buf = ' \0 ' ;
if ( ops - > get_state ) {
ret = ops - > get_state ( dev , offset , buf , sizeof ( buf ) ) ;
if ( ret ) {
puts ( " <unknown> " ) ;
return ;
}
} else {
int func = GPIOF_UNKNOWN ;
int ret ;
if ( ops - > get_function ) {
ret = ops - > get_function ( dev , offset ) ;
if ( ret > = 0 & & ret < ARRAY_SIZE ( gpio_function ) )
func = ret ;
}
sprintf ( buf , " %s%u: %8s %d " , bank_name , offset ,
gpio_function [ func ] , ops - > get_value ( dev , offset ) ) ;
}
puts ( buf ) ;
puts ( " \n " ) ;
}
static int do_gpio_status ( const char * gpio_name )
{
struct device * dev ;
int newline = 0 ;
int ret ;
if ( gpio_name & & ! * gpio_name )
gpio_name = NULL ;
for ( ret = uclass_first_device ( UCLASS_GPIO , & dev ) ;
dev ;
ret = uclass_next_device ( & dev ) ) {
const char * bank_name ;
int num_bits ;
bank_name = gpio_get_bank_info ( dev , & num_bits ) ;
if ( ! gpio_name | | ! bank_name | |
! strncmp ( gpio_name , bank_name , strlen ( bank_name ) ) ) {
const char * p = NULL ;
int offset ;
if ( bank_name ) {
if ( newline )
putc ( ' \n ' ) ;
printf ( " Bank %s: \n " , bank_name ) ;
}
newline = 1 ;
if ( gpio_name & & bank_name ) {
p = gpio_name + strlen ( bank_name ) ;
offset = simple_strtoul ( p , NULL , 10 ) ;
show_gpio ( dev , bank_name , offset ) ;
} else {
for ( offset = 0 ; offset < num_bits ; offset + + )
show_gpio ( dev , bank_name , offset ) ;
}
}
}
return ret ;
}
# endif
static int do_gpio ( cmd_tbl_t * cmdtp , int flag , int argc , char * const argv [ ] )
{
int gpio ;
unsigned int gpio ;
enum gpio_cmd sub_cmd ;
ulong value ;
const char * str_cmd , * str_gpio ;
const char * str_cmd , * str_gpio = NULL ;
# ifdef CONFIG_DM_GPIO
int ret ;
# endif
if ( argc < 2 )
show_usage :
return CMD_RET_USAGE ;
str_cmd = argv [ 1 ] ;
if ( argc > 2 )
str_gpio = argv [ 2 ] ;
if ( ! strcmp ( str_cmd , " status " ) ) {
/* Support deprecated gpio_status() */
# ifdef gpio_status
if ( argc = = 2 & & ! strcmp ( argv [ 1 ] , " status " ) ) {
gpio_status ( ) ;
return 0 ;
}
# elif defined(CONFIG_DM_GPIO)
return cmd_process_error ( cmdtp , do_gpio_status ( str_gpio ) ) ;
# else
goto show_usage ;
# endif
}
if ( argc ! = 3 )
show_usage :
return CMD_RET_USAGE ;
str_cmd = argv [ 1 ] ;
str_gpio = argv [ 2 ] ;
if ( ! str_gpio )
goto show_usage ;
/* parse the behavior */
switch ( * str_cmd ) {
@ -51,11 +141,23 @@ static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
default : goto show_usage ;
}
# if defined(CONFIG_DM_GPIO)
/*
* TODO ( sjg @ chromium . org ) : For now we must fit into the existing GPIO
* framework , so we look up the name here and convert it to a GPIO number .
* Once all GPIO drivers are converted to driver model , we can change the
* code here to use the GPIO uclass interface instead of the numbered
* GPIO compatibility layer .
*/
ret = gpio_lookup_name ( str_gpio , NULL , NULL , & gpio ) ;
if ( ret )
return cmd_process_error ( cmdtp , ret ) ;
# else
/* turn the gpio name into a gpio number */
gpio = name_to_gpio ( str_gpio ) ;
if ( gpio < 0 )
goto show_usage ;
# endif
/* grab the pin before we tweak it */
if ( gpio_request ( gpio , " cmd_gpio " ) ) {
printf ( " gpio: requesting pin %u failed \n " , gpio ) ;
@ -84,6 +186,7 @@ static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
U_BOOT_CMD ( gpio , 3 , 0 , do_gpio ,
" input/set/clear/toggle gpio pins" ,
" query and control gpio pins" ,
" <input|set|clear|toggle> <pin> \n "
" - input/set/clear/toggle the specified pin " ) ;
" - input/set/clear/toggle the specified pin \n "
" gpio status [<bank> | <pin>] " ) ;