@ -8,9 +8,11 @@
# include <common.h>
# include <cros_ec.h>
# include <dm.h>
# include <errno.h>
# include <fdtdec.h>
# include <input.h>
# include <keyboard.h>
# include <key_matrix.h>
# include <stdio_dev.h>
@ -22,31 +24,29 @@ enum {
KBC_REPEAT_DELAY_MS = 240 ,
} ;
static struct keyb {
struct cros_ec_dev * dev ; /* The CROS_EC device */
struct input_config input ; /* The input layer */
struct cros_ec_keyb_priv {
struct input_config * input ; /* The input layer */
struct key_matrix matrix ; /* The key matrix layer */
int key_rows ; /* Number of keyboard rows */
int key_cols ; /* Number of keyboard columns */
int ghost_filter ; /* 1 to enable ghost filter, else 0 */
int inited ; /* 1 if keyboard is ready */
} config ;
} ;
/**
* Check the keyboard controller and return a list of key matrix positions
* for which a key is pressed
*
* @ param config Keyboard config
* @ param dev Keyboard device
* @ param keys List of keys that we have detected
* @ param max_count Maximum number of keys to return
* @ param samep Set to true if this scan repeats the last , else false
* @ return number of pressed keys , 0 for none , - EIO on error
*/
static int check_for_keys ( struct keyb * config ,
struct key_matrix_key * keys , int max_count ,
bool * samep )
static int check_for_keys ( struct udevice * dev , struct key_matrix_key * keys ,
int max_count , bool * samep )
{
struct cros_ec_keyb_priv * priv = dev_get_priv ( dev ) ;
struct key_matrix_key * key ;
static struct mbkp_keyscan last_scan ;
static bool last_scan_valid ;
@ -54,7 +54,7 @@ static int check_for_keys(struct keyb *config,
unsigned int row , col , bit , data ;
int num_keys ;
if ( cros_ec_scan_keyboard ( config - > dev - > dev , & scan ) ) {
if ( cros_ec_scan_keyboard ( dev - > parent , & scan ) ) {
debug ( " %s: keyboard scan failed \n " , __func__ ) ;
return - EIO ;
}
@ -69,9 +69,9 @@ static int check_for_keys(struct keyb *config,
last_scan_valid = true ;
memcpy ( & last_scan , & scan , sizeof ( last_scan ) ) ;
for ( col = num_keys = bit = 0 ; col < config - > matrix . num_cols ;
for ( col = num_keys = bit = 0 ; col < priv - > matrix . num_cols ;
col + + ) {
for ( row = 0 ; row < config - > matrix . num_rows ; row + + ) {
for ( row = 0 ; row < priv - > matrix . num_rows ; row + + ) {
unsigned int mask = 1 < < ( bit & 7 ) ;
data = scan . data [ bit / 8 ] ;
@ -89,28 +89,6 @@ static int check_for_keys(struct keyb *config,
}
/**
* Test if keys are available to be read
*
* @ return 0 if no keys available , 1 if keys are available
*/
static int kbd_tstc ( struct stdio_dev * dev )
{
/* Just get input to do this for us */
return config . inited ? input_tstc ( & config . input ) : 0 ;
}
/**
* Read a key
*
* @ return ASCII key code , or 0 if no key , or - 1 if error
*/
static int kbd_getc ( struct stdio_dev * dev )
{
/* Just get input to do this for us */
return config . inited ? input_getc ( & config . input ) : 0 ;
}
/**
* Check the keyboard , and send any keys that are pressed .
*
* This is called by input_tstc ( ) and input_getc ( ) when they need more
@ -121,6 +99,8 @@ static int kbd_getc(struct stdio_dev *dev)
*/
int cros_ec_kbc_check ( struct input_config * input )
{
struct udevice * dev = input - > dev ;
struct cros_ec_keyb_priv * priv = dev_get_priv ( dev ) ;
static struct key_matrix_key last_keys [ KBC_MAX_KEYS ] ;
static int last_num_keys ;
struct key_matrix_key keys [ KBC_MAX_KEYS ] ;
@ -139,9 +119,9 @@ int cros_ec_kbc_check(struct input_config *input)
* may return 0 before all keys have been read from the EC .
*/
do {
irq_pending = cros_ec_interrupt_pending ( config . dev - > dev ) ;
irq_pending = cros_ec_interrupt_pending ( dev - > parent ) ;
if ( irq_pending ) {
num_keys = check_for_keys ( & config , keys , KBC_MAX_KEYS ,
num_keys = check_for_keys ( dev , keys , KBC_MAX_KEYS ,
& same ) ;
if ( num_keys < 0 )
return 0 ;
@ -158,7 +138,7 @@ int cros_ec_kbc_check(struct input_config *input)
if ( num_keys < 0 )
return - 1 ;
num_keycodes = key_matrix_decode ( & config . matrix , keys ,
num_keycodes = key_matrix_decode ( & priv - > matrix , keys ,
num_keys , keycodes , KBC_MAX_KEYS ) ;
sent = input_send_keycodes ( input , keycodes , num_keycodes ) ;
@ -182,7 +162,7 @@ int cros_ec_kbc_check(struct input_config *input)
* @ return 0 if ok , - 1 on error
*/
static int cros_ec_keyb_decode_fdt ( const void * blob , int node ,
struct keyb * config )
struct cros_ec_ keyb_priv * config )
{
/*
* Get keyboard rows and columns - at present we are limited to
@ -202,68 +182,56 @@ static int cros_ec_keyb_decode_fdt(const void *blob, int node,
return 0 ;
}
/**
* Set up the keyboard . This is called by the stdio device handler .
*
* We want to do this init when the keyboard is actually used rather than
* at start - up , since keyboard input may not currently be selected .
*
* @ return 0 if ok , - 1 on error
*/
static int cros_ec_init_keyboard ( struct stdio_dev * dev )
static int cros_ec_kbd_probe ( struct udevice * dev )
{
struct cros_ec_keyb_priv * priv = dev_get_priv ( dev ) ;
struct keyboard_priv * uc_priv = dev_get_uclass_priv ( dev ) ;
struct stdio_dev * sdev = & uc_priv - > sdev ;
struct input_config * input = & uc_priv - > input ;
const void * blob = gd - > fdt_blob ;
int node ;
int node = dev - > of_offset ;
int ret ;
config . dev = board_get_cros_ec_dev ( ) ;
if ( ! config . dev ) {
debug ( " %s: no cros_ec device: cannot init keyboard \n " ,
__func__ ) ;
if ( cros_ec_keyb_decode_fdt ( blob , node , priv ) )
return - 1 ;
}
node = fdtdec_next_compatible ( blob , 0 , COMPAT_GOOGLE_CROS_EC_KEYB ) ;
if ( node < 0 ) {
debug ( " %s: Node not found \n " , __func__ ) ;
return - 1 ;
}
if ( cros_ec_keyb_decode_fdt ( blob , node , & config ) )
return - 1 ;
input_set_delays ( & config . input , KBC_REPEAT_DELAY_MS ,
KBC_REPEAT_RATE_MS ) ;
if ( key_matrix_init ( & config . matrix , config . key_rows ,
config . key_cols , config . ghost_filter ) ) {
input_set_delays ( input , KBC_REPEAT_DELAY_MS , KBC_REPEAT_RATE_MS ) ;
ret = key_matrix_init ( & priv - > matrix , priv - > key_rows , priv - > key_cols ,
priv - > ghost_filter ) ;
if ( ret ) {
debug ( " %s: cannot init key matrix \n " , __func__ ) ;
return - 1 ;
return ret ;
}
if ( key_matrix_decode_fdt ( & config . matrix , gd - > fdt_blob , node ) ) {
ret = key_matrix_decode_fdt ( & priv - > matrix , gd - > fdt_blob , node ) ;
if ( ret ) {
debug ( " %s: Could not decode key matrix from fdt \n " , __func__ ) ;
return - 1 ;
return ret ;
}
config . inited = 1 ;
debug ( " %s: Matrix keyboard %dx%d ready \n " , __func__ , config . key_rows ,
config . key_cols ) ;
debug ( " %s: Matrix keyboard %dx%d ready \n " , __func__ , priv - > key_rows ,
priv - > key_cols ) ;
return 0 ;
}
priv - > input = input ;
input - > dev = dev ;
input_add_tables ( input ) ;
input - > read_keys = cros_ec_kbc_check ;
strcpy ( sdev - > name , " cros-ec-keyb " ) ;
int drv_keyboard_init ( void )
{
struct stdio_dev dev ;
/* Register the device. cros_ec_init_keyboard() will be called soon */
return input_stdio_register ( sdev ) ;
}
if ( input_init ( & config . input , 0 ) ) {
debug ( " %s: Cannot set up input \n " , __func__ ) ;
return - 1 ;
}
config . input . read_keys = cros_ec_kbc_check ;
input_add_tables ( & config . input ) ;
static const struct keyboard_ops cros_ec_kbd_ops = {
} ;
memset ( & dev , ' \0 ' , sizeof ( dev ) ) ;
strcpy ( dev . name , " cros-ec-keyb " ) ;
dev . flags = DEV_FLAGS_INPUT ;
dev . getc = kbd_getc ;
dev . tstc = kbd_tstc ;
dev . start = cros_ec_init_keyboard ;
static const struct udevice_id cros_ec_kbd_ids [ ] = {
{ . compatible = " google,cros-ec-keyb " } ,
{ }
} ;
/* Register the device. cros_ec_init_keyboard() will be called soon */
return input_stdio_register ( & dev ) ;
}
U_BOOT_DRIVER ( cros_ec_kbd ) = {
. name = " cros_ec_kbd " ,
. id = UCLASS_KEYBOARD ,
. of_match = cros_ec_kbd_ids ,
. probe = cros_ec_kbd_probe ,
. ops = & cros_ec_kbd_ops ,
. priv_auto_alloc_size = sizeof ( struct cros_ec_keyb_priv ) ,
} ;