Line 141... |
Line 141... |
/* Wishbone read */
|
/* Wishbone read */
|
unsigned long gpio_read32( unsigned long addr )
|
unsigned long gpio_read32( unsigned long addr )
|
{
|
{
|
struct gpio_device *gpio;
|
struct gpio_device *gpio;
|
if ( !gpio_find_device( addr, &gpio, &addr ) ) {
|
if ( !gpio_find_device( addr, &gpio, &addr ) ) {
|
printf( "gpio_read32( 0x%08lX ): Not in registered range(s)\n", addr );
|
debug( 2, "gpio_read32( 0x%08lX ): Not in registered range(s)\n", addr );
|
return 0;
|
return 0;
|
}
|
}
|
|
|
switch( addr ) {
|
switch( addr ) {
|
case RGPIO_IN:
|
case RGPIO_IN:
|
Line 164... |
Line 164... |
/* Wishbone write */
|
/* Wishbone write */
|
void gpio_write32( unsigned long addr, unsigned long value )
|
void gpio_write32( unsigned long addr, unsigned long value )
|
{
|
{
|
struct gpio_device *gpio;
|
struct gpio_device *gpio;
|
if ( !gpio_find_device( addr, &gpio, &addr ) ) {
|
if ( !gpio_find_device( addr, &gpio, &addr ) ) {
|
printf( "gpio_write32( 0x%08lX ): Not in registered range(s)\n", addr );
|
debug( 2, "gpio_write32( 0x%08lX ): Not in registered range(s)\n", addr );
|
return;
|
return;
|
}
|
}
|
|
|
switch( addr ) {
|
switch( addr ) {
|
case RGPIO_IN: debug( 2, "GPIO: Cannot write to RGPIO_IN\n" ); break;
|
case RGPIO_IN: debug( 5, "GPIO: Cannot write to RGPIO_IN\n" ); break;
|
case RGPIO_OUT: gpio->next.out = value; break;
|
case RGPIO_OUT: gpio->next.out = value; break;
|
case RGPIO_OE: gpio->next.oe = value; break;
|
case RGPIO_OE: gpio->next.oe = value; break;
|
case RGPIO_INTE: gpio->next.inte = value; break;
|
case RGPIO_INTE: gpio->next.inte = value; break;
|
case RGPIO_PTRIG: gpio->next.ptrig = value; break;
|
case RGPIO_PTRIG: gpio->next.ptrig = value; break;
|
case RGPIO_AUX: gpio->next.aux = value; break;
|
case RGPIO_AUX: gpio->next.aux = value; break;
|
Line 195... |
Line 195... |
return;
|
return;
|
}
|
}
|
|
|
switch( which ) {
|
switch( which ) {
|
case GPIO_VAPI_DATA:
|
case GPIO_VAPI_DATA:
|
debug( 3, "GPIO: Next input from VAPI = 0x%08x\n", data );
|
debug( 4, "GPIO: Next input from VAPI = 0x%08x (RGPIO_OE = 0x%08x)\n", data, gpio->next.oe );
|
gpio->next.in = data;
|
gpio->next.in = data;
|
break;
|
break;
|
case GPIO_VAPI_AUX:
|
case GPIO_VAPI_AUX:
|
gpio->auxiliary_inputs = data;
|
gpio->auxiliary_inputs = data;
|
break;
|
break;
|
Line 265... |
Line 265... |
gpio->next.out = (gpio->next.out & ~gpio->next.aux) | (gpio->auxiliary_inputs & gpio->next.aux);
|
gpio->next.out = (gpio->next.out & ~gpio->next.aux) | (gpio->auxiliary_inputs & gpio->next.aux);
|
gpio->next.out &= gpio->next.oe; /* Only output-enabled bits */
|
gpio->next.out &= gpio->next.oe; /* Only output-enabled bits */
|
|
|
/* If any outputs changed, notify the world (i.e. vapi) */
|
/* If any outputs changed, notify the world (i.e. vapi) */
|
if ( gpio->next.out != gpio->curr.out ) {
|
if ( gpio->next.out != gpio->curr.out ) {
|
debug( 3, "GPIO: New output 0x%08x\n", gpio->next.out );
|
debug( 4, "GPIO: New output 0x%08x, RGPIO_OE = 0x%08x\n", gpio->next.out, gpio->next.oe );
|
if ( gpio->base_vapi_id )
|
if ( gpio->base_vapi_id )
|
vapi_send( gpio->base_vapi_id + GPIO_VAPI_DATA, gpio->next.out );
|
vapi_send( gpio->base_vapi_id + GPIO_VAPI_DATA, gpio->next.out );
|
}
|
}
|
|
|
/* If any inputs changed and interrupt enabled, generate interrupt */
|
/* If any inputs changed and interrupt enabled, generate interrupt */
|
if ( gpio->next.in != gpio->curr.in ) {
|
if ( gpio->next.in != gpio->curr.in ) {
|
debug( 3, "GPIO: New input 0x%08x\n", gpio->next.out );
|
debug( 4, "GPIO: New input 0x%08x\n", gpio->next.in );
|
|
|
if ( gpio->next.ctrl & RGPIO_CTRL_INTE ) {
|
if ( gpio->next.ctrl & RGPIO_CTRL_INTE ) {
|
unsigned changed_bits = gpio->next.in ^ gpio->curr.in; /* inputs that have changed */
|
unsigned changed_bits = gpio->next.in ^ gpio->curr.in; /* inputs that have changed */
|
unsigned set_bits = changed_bits & gpio->next.in; /* inputs that have been set */
|
unsigned set_bits = changed_bits & gpio->next.in; /* inputs that have been set */
|
unsigned cleared_bits = changed_bits & gpio->curr.in; /* inputs that have been cleared */
|
unsigned cleared_bits = changed_bits & gpio->curr.in; /* inputs that have been cleared */
|
unsigned relevant_bits = (gpio->next.ptrig & set_bits) | (~gpio->next.ptrig & cleared_bits);
|
unsigned relevant_bits = (gpio->next.ptrig & set_bits) | (~gpio->next.ptrig & cleared_bits);
|
|
|
if ( relevant_bits & gpio->next.inte ) {
|
if ( relevant_bits & gpio->next.inte ) {
|
|
debug( 3, "GPIO: Interrupt %d\n", gpio->irq );
|
report_interrupt( gpio->irq );
|
report_interrupt( gpio->irq );
|
gpio->next.ctrl |= RGPIO_CTRL_INT;
|
gpio->next.ctrl |= RGPIO_CTRL_INT;
|
}
|
}
|
}
|
}
|
}
|
}
|