/*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ #include #include #include "boardparms.h" #include "bcm_gpio.h" #include "mach/avm_gpio.h" #include "pushbutton.h" extern spinlock_t bcm_gpio_spinlock; #define BUTTON_INT_MASK 3 unsigned int virtToRealPin(unsigned int virtPin) { return( (virtPin <= BUTTON_INT_MASK) ? (BP_GPIO_32_AH ^ virtPin) : virtPin ); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int brcm_gpio_init(void) { return GPIO_OK; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int brcm_gpio_ctrl(unsigned int gpio_pin, enum _hw_gpio_function pin_mode, enum _hw_gpio_direction pin_dir) { unsigned long flags; int result = GPIO_FAIL; spin_lock_irqsave(&bcm_gpio_spinlock, flags); /*--- TODO: Function Flag auswerten ---*/ bcm_gpio_set_dir(virtToRealPin(gpio_pin), (unsigned int)pin_dir); result = (bcm_gpio_get_dir(virtToRealPin(gpio_pin)) == (unsigned int)pin_dir) ? GPIO_OK : GPIO_FAIL; spin_unlock_irqrestore(&bcm_gpio_spinlock, flags); return result; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ typedef int (*buttonCallback_t)(unsigned int); static buttonCallback_t buttonCallback[BUTTON_INT_MASK + 1]; void pbNotifyHook( unsigned long timeInMs, void *param ) { if( buttonCallback[((unsigned long)param & BUTTON_INT_MASK)] != NULL ) (buttonCallback[((unsigned long)param & BUTTON_INT_MASK)])(1 << ((unsigned long)param & BUTTON_INT_MASK)); } int maskToIndex(unsigned int mask) { int i; for( i = 0; mask != 0; i++ ) mask = mask >> 1; return (i - 1); } int brcm_button_request_callback(unsigned int mask, enum _hw_gpio_polarity mode, enum _hw_gpio_sensitivity edge, int (*handle_func)(unsigned int)) { int index; unsigned long pin; index = maskToIndex(mask); if( index < 0 ) { printk(KERN_ERR "%s: MASK MUST NOT BE ZERO! \n", __FUNCTION__); return -1; } index = index & BUTTON_INT_MASK; pin = (unsigned long)virtToRealPin(index); printk(KERN_ERR "%s: pin=%lx, mode=%d, edge=%d, func_p=%p\n", __FUNCTION__, pin, mode, edge, handle_func); if( edge == 0 ) { printk(KERN_ERR "%s: LEVEL SENSIVITY NOT SUPPORTED! PIN: %lx\n", __FUNCTION__, pin); return -1; } if( registerPushButtonPressNotifyHook( (PB_BUTTON_ID)index, pbNotifyHook, (void *)pin ) ) { printk(KERN_ERR "%s: PRESS HOOK REGISTRATION FAILED! PIN: %lx\n", __FUNCTION__, pin); return -1; } if( edge > 1 ) { if( registerPushButtonReleaseNotifyHook( (PB_BUTTON_ID)index, pbNotifyHook, 100UL, (void *)pin ) ) { printk(KERN_ERR "%s: RELEASE HOOK REGISTRATION FAILED! PIN: %lx\n", __FUNCTION__, pin); return -1; } } buttonCallback[index] = handle_func; return index; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ void brcm_button_disable_callback(int index) { if( index == -1 ) return; (void)deregisterPushButtonPressNotifyHook( (PB_BUTTON_ID)index, pbNotifyHook ); (void)deregisterPushButtonReleaseNotifyHook( (PB_BUTTON_ID)index, pbNotifyHook, 100UL ); buttonCallback[index] = NULL; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int brcm_gpio_out_bit(unsigned int gpio_pin, int value) { unsigned long flags; int result = GPIO_FAIL; spin_lock_irqsave(&bcm_gpio_spinlock, flags); bcm_gpio_set_data(gpio_pin, (unsigned int)value); result = (bcm_gpio_get_data(gpio_pin) == (unsigned int)value) ? GPIO_OK : GPIO_FAIL; spin_unlock_irqrestore(&bcm_gpio_spinlock, flags); return result; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int brcm_gpio_out_bit_no_sched(unsigned int gpio_pin, int value) { return( brcm_gpio_out_bit(gpio_pin, value) ); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int brcm_gpio_in_bit(unsigned int gpio_pin) { unsigned long flags; int result = GPIO_FAIL; spin_lock_irqsave(&bcm_gpio_spinlock, flags); result = (int)bcm_gpio_get_data(virtToRealPin(gpio_pin)); spin_unlock_irqrestore(&bcm_gpio_spinlock, flags); return result; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ void brcm_gpio_set_bitmask(uint64_t mask, uint64_t value) { unsigned long flags; spin_lock_irqsave(&bcm_gpio_spinlock, flags); bcm_gpio_set_bitmask(mask, value); spin_unlock_irqrestore(&bcm_gpio_spinlock, flags); return; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ EXPORT_SYMBOL(brcm_gpio_ctrl); EXPORT_SYMBOL(brcm_button_request_callback); EXPORT_SYMBOL(brcm_button_disable_callback); EXPORT_SYMBOL(brcm_gpio_out_bit); EXPORT_SYMBOL(brcm_gpio_out_bit_no_sched); EXPORT_SYMBOL(brcm_gpio_in_bit); EXPORT_SYMBOL(brcm_gpio_set_bitmask);