@ -20,9 +20,13 @@
*/
# include <common.h>
# include <dm.h>
# include <fdtdec.h>
# include <asm/gpio.h>
# include <asm/io.h>
# include <asm/errno.h>
# include <malloc.h>
DECLARE_GLOBAL_DATA_PTR ;
# define OMAP_GPIO_DIR_OUT 0
# define OMAP_GPIO_DIR_IN 1
@ -34,7 +38,6 @@
struct gpio_bank {
/* TODO(sjg@chromium.org): Can we use a struct here? */
void * base ; /* address of registers in physical memory */
enum gpio_method method ;
} ;
# endif
@ -55,13 +58,8 @@ static void _set_gpio_direction(const struct gpio_bank *bank, int gpio,
void * reg = bank - > base ;
u32 l ;
switch ( bank - > method ) {
case METHOD_GPIO_24XX :
reg + = OMAP_GPIO_OE ;
break ;
default :
return ;
}
reg + = OMAP_GPIO_OE ;
l = __raw_readl ( reg ) ;
if ( is_input )
l | = 1 < < gpio ;
@ -79,13 +77,7 @@ static int _get_gpio_direction(const struct gpio_bank *bank, int gpio)
void * reg = bank - > base ;
u32 v ;
switch ( bank - > method ) {
case METHOD_GPIO_24XX :
reg + = OMAP_GPIO_OE ;
break ;
default :
return - 1 ;
}
reg + = OMAP_GPIO_OE ;
v = __raw_readl ( reg ) ;
@ -101,19 +93,12 @@ static void _set_gpio_dataout(const struct gpio_bank *bank, int gpio,
void * reg = bank - > base ;
u32 l = 0 ;
switch ( bank - > method ) {
case METHOD_GPIO_24XX :
if ( enable )
reg + = OMAP_GPIO_SETDATAOUT ;
else
reg + = OMAP_GPIO_CLEARDATAOUT ;
l = 1 < < gpio ;
break ;
default :
printf ( " omap3-gpio unknown bank method %s %d \n " ,
__FILE__ , __LINE__ ) ;
return ;
}
if ( enable )
reg + = OMAP_GPIO_SETDATAOUT ;
else
reg + = OMAP_GPIO_CLEARDATAOUT ;
l = 1 < < gpio ;
__raw_writel ( l , reg ) ;
}
@ -122,19 +107,13 @@ static int _get_gpio_value(const struct gpio_bank *bank, int gpio)
void * reg = bank - > base ;
int input ;
switch ( bank - > method ) {
case METHOD_GPIO_24XX :
input = _get_gpio_direction ( bank , gpio ) ;
switch ( input ) {
case OMAP_GPIO_DIR_IN :
reg + = OMAP_GPIO_DATAIN ;
break ;
case OMAP_GPIO_DIR_OUT :
reg + = OMAP_GPIO_DATAOUT ;
break ;
default :
return - 1 ;
}
input = _get_gpio_direction ( bank , gpio ) ;
switch ( input ) {
case OMAP_GPIO_DIR_IN :
reg + = OMAP_GPIO_DATAIN ;
break ;
case OMAP_GPIO_DIR_OUT :
reg + = OMAP_GPIO_DATAOUT ;
break ;
default :
return - 1 ;
@ -310,24 +289,56 @@ static int omap_gpio_probe(struct udevice *dev)
struct gpio_bank * bank = dev_get_priv ( dev ) ;
struct omap_gpio_platdata * plat = dev_get_platdata ( dev ) ;
struct gpio_dev_priv * uc_priv = dev_get_uclass_priv ( dev ) ;
char name [ 18 ] , * str ;
sprintf ( name , " GPIO%d_ " , plat - > bank_index ) ;
str = strdup ( name ) ;
if ( ! str )
return - ENOMEM ;
uc_priv - > bank_name = str ;
uc_priv - > bank_name = plat - > port_name ;
uc_priv - > gpio_count = GPIO_PER_BANK ;
bank - > base = ( void * ) plat - > base ;
bank - > method = plat - > method ;
return 0 ;
}
static int omap_gpio_bind ( struct udevice * dev )
{
struct omap_gpio_platdata * plat = dev - > platdata ;
fdt_addr_t base_addr ;
if ( plat )
return 0 ;
base_addr = dev_get_addr ( dev ) ;
if ( base_addr = = FDT_ADDR_T_NONE )
return - ENODEV ;
/*
* TODO :
* When every board is converted to driver model and DT is
* supported , this can be done by auto - alloc feature , but
* not using calloc to alloc memory for platdata .
*/
plat = calloc ( 1 , sizeof ( * plat ) ) ;
if ( ! plat )
return - ENOMEM ;
plat - > base = base_addr ;
plat - > port_name = fdt_get_name ( gd - > fdt_blob , dev - > of_offset , NULL ) ;
dev - > platdata = plat ;
return 0 ;
}
static const struct udevice_id omap_gpio_ids [ ] = {
{ . compatible = " ti,omap3-gpio " } ,
{ . compatible = " ti,omap4-gpio " } ,
{ . compatible = " ti,am4372-gpio " } ,
{ }
} ;
U_BOOT_DRIVER ( gpio_omap ) = {
. name = " gpio_omap " ,
. id = UCLASS_GPIO ,
. ops = & gpio_omap_ops ,
. of_match = omap_gpio_ids ,
. bind = omap_gpio_bind ,
. probe = omap_gpio_probe ,
. priv_auto_alloc_size = sizeof ( struct gpio_bank ) ,
} ;