2019-05-19 13:08:20 +01:00
// SPDX-License-Identifier: GPL-2.0-only
2009-03-04 23:27:15 -08:00
/*
* Support for the S1 button on Routerboard 532
*
* Copyright ( C ) 2009 Phil Sutter < n0 - 1 @ freewrt . org >
*/
2019-10-29 17:04:33 -07:00
# include <linux/input.h>
2009-03-04 23:27:15 -08:00
# include <linux/module.h>
# include <linux/platform_device.h>
2015-08-02 18:30:11 +02:00
# include <linux/gpio.h>
2009-03-04 23:27:15 -08:00
# include <asm/mach-rc32434/gpio.h>
# include <asm/mach-rc32434/rb.h>
# define DRV_NAME "rb532-button"
# define RB532_BTN_RATE 100 /* msec */
# define RB532_BTN_KSYM BTN_0
/* The S1 button state is provided by GPIO pin 1. But as this
* pin is also used for uart input as alternate function , the
* operational modes must be switched first :
* 1 ) disable uart using set_latch_u5 ( )
* 2 ) turn off alternate function implicitly through
* gpio_direction_input ( )
* 3 ) read the GPIO ' s current value
* 4 ) undo step 2 by enabling alternate function ( in this
* mode the GPIO direction is fixed , so no change needed )
* 5 ) turn on uart again
* The GPIO value occurs to be inverted , so pin high means
* button is not pressed .
*/
static bool rb532_button_pressed ( void )
{
int val ;
set_latch_u5 ( 0 , LO_FOFF ) ;
gpio_direction_input ( GPIO_BTN_S1 ) ;
val = gpio_get_value ( GPIO_BTN_S1 ) ;
rb532_gpio_set_func ( GPIO_BTN_S1 ) ;
set_latch_u5 ( LO_FOFF , 0 ) ;
return ! val ;
}
2019-10-29 17:04:33 -07:00
static void rb532_button_poll ( struct input_dev * input )
2009-03-04 23:27:15 -08:00
{
2019-10-29 17:04:33 -07:00
input_report_key ( input , RB532_BTN_KSYM , rb532_button_pressed ( ) ) ;
input_sync ( input ) ;
2009-03-04 23:27:15 -08:00
}
2012-11-23 21:38:25 -08:00
static int rb532_button_probe ( struct platform_device * pdev )
2009-03-04 23:27:15 -08:00
{
2019-10-29 17:04:33 -07:00
struct input_dev * input ;
2009-03-04 23:27:15 -08:00
int error ;
2019-10-29 17:04:33 -07:00
input = devm_input_allocate_device ( & pdev - > dev ) ;
if ( ! input )
2009-03-04 23:27:15 -08:00
return - ENOMEM ;
2019-10-29 17:04:33 -07:00
input - > name = " rb532 button " ;
input - > phys = " rb532/button0 " ;
input - > id . bustype = BUS_HOST ;
2009-03-04 23:27:15 -08:00
2019-10-29 17:04:33 -07:00
input_set_capability ( input , EV_KEY , RB532_BTN_KSYM ) ;
2009-03-04 23:27:15 -08:00
2019-10-29 17:04:33 -07:00
error = input_setup_polling ( input , rb532_button_poll ) ;
if ( error )
return error ;
input_set_poll_interval ( input , RB532_BTN_RATE ) ;
2009-03-04 23:27:15 -08:00
2019-10-29 17:04:33 -07:00
error = input_register_device ( input ) ;
2019-10-29 17:04:25 -07:00
if ( error )
2009-03-04 23:27:15 -08:00
return error ;
return 0 ;
}
static struct platform_driver rb532_button_driver = {
. probe = rb532_button_probe ,
. driver = {
. name = DRV_NAME ,
} ,
} ;
2011-11-29 11:08:40 -08:00
module_platform_driver ( rb532_button_driver ) ;
2009-03-04 23:27:15 -08:00
MODULE_AUTHOR ( " Phil Sutter <n0-1@freewrt.org> " ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_DESCRIPTION ( " Support for S1 button on Routerboard 532 " ) ;
MODULE_ALIAS ( " platform: " DRV_NAME ) ;