2019-01-29 10:38:18 +01:00
// SPDX-License-Identifier: GPL-2.0
// LPC interface for ChromeOS Embedded Controller
//
// Copyright (C) 2012-2015 Google, Inc
//
// This driver uses the ChromeOS EC byte-level message-based protocol for
// communicating the keyboard state (which keys are pressed) from a keyboard EC
// to the AP over some bus (such as i2c, lpc, spi). The EC does debouncing,
// but everything else (including deghosting) is done here. The main
// motivation for this is to keep the EC firmware as simple as possible, since
// it cannot be easily upgraded and EC flash/IRAM space is relatively
// expensive.
2015-02-02 12:26:24 +01:00
2017-05-16 17:46:48 +02:00
# include <linux/acpi.h>
2015-02-02 12:26:24 +01:00
# include <linux/dmi.h>
# include <linux/delay.h>
2015-02-27 06:37:48 +01:00
# include <linux/io.h>
2018-10-09 10:56:46 -07:00
# include <linux/interrupt.h>
2015-02-02 12:26:24 +01:00
# include <linux/module.h>
2019-09-02 11:53:05 +02:00
# include <linux/platform_data/cros_ec_commands.h>
# include <linux/platform_data/cros_ec_proto.h>
2015-02-02 12:26:24 +01:00
# include <linux/platform_device.h>
# include <linux/printk.h>
2018-02-22 13:21:17 -08:00
# include <linux/suspend.h>
2015-02-02 12:26:24 +01:00
platform/chrome: cros_ec: Match implementation with headers
The 'cros_ec' core driver is the common interface for the cros_ec
transport drivers to do the shared operations to register, unregister,
suspend, resume and handle_event. The interface is provided by including
the header 'include/linux/platform_data/cros_ec_proto.h', however, instead
of have the implementation of these functions in cros_ec_proto.c, it is in
'cros_ec.c', which is a different kernel module. Apart from being a bad
practice, this can induce confusions allowing the users of the cros_ec
protocol to call these functions.
The register, unregister, suspend, resume and handle_event functions
*should* only be called by the different transport drivers (i2c, spi, lpc,
etc.), so make this a bit less confusing by moving these functions from
the public in-kernel space to a private include in platform/chrome, and
then, the interface for cros_ec module and for the cros_ec_proto module is
clean.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Signed-off-by: Benson Leung <bleung@chromium.org>
2020-01-22 10:07:01 +01:00
# include "cros_ec.h"
2019-06-14 23:43:00 +02:00
# include "cros_ec_lpc_mec.h"
2018-07-18 18:09:55 +02:00
2017-05-16 17:46:48 +02:00
# define DRV_NAME "cros_ec_lpcs"
2017-05-16 17:46:48 +02:00
# define ACPI_DRV_NAME "GOOG0004"
2015-02-02 12:26:24 +01:00
2017-12-01 14:42:21 +01:00
/* True if ACPI device is present */
static bool cros_ec_lpc_acpi_device_found ;
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
/**
* struct lpc_driver_ops - LPC driver operations
* @ read : Copy length bytes from EC address offset into buffer dest . Returns
* the 8 - bit checksum of all bytes read .
* @ write : Copy length bytes from buffer msg into EC address offset . Returns
* the 8 - bit checksum of all bytes written .
*/
struct lpc_driver_ops {
u8 ( * read ) ( unsigned int offset , unsigned int length , u8 * dest ) ;
u8 ( * write ) ( unsigned int offset , unsigned int length , const u8 * msg ) ;
} ;
static struct lpc_driver_ops cros_ec_lpc_ops = { } ;
/*
* A generic instance of the read function of struct lpc_driver_ops , used for
* the LPC EC .
*/
static u8 cros_ec_lpc_read_bytes ( unsigned int offset , unsigned int length ,
u8 * dest )
2019-06-14 23:43:00 +02:00
{
int sum = 0 ;
int i ;
for ( i = 0 ; i < length ; + + i ) {
dest [ i ] = inb ( offset + i ) ;
sum + = dest [ i ] ;
}
/* Return checksum of all bytes read */
return sum ;
}
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
/*
* A generic instance of the write function of struct lpc_driver_ops , used for
* the LPC EC .
*/
static u8 cros_ec_lpc_write_bytes ( unsigned int offset , unsigned int length ,
const u8 * msg )
2019-06-14 23:43:00 +02:00
{
int sum = 0 ;
int i ;
for ( i = 0 ; i < length ; + + i ) {
outb ( msg [ i ] , offset + i ) ;
sum + = msg [ i ] ;
}
/* Return checksum of all bytes written */
return sum ;
}
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
/*
* An instance of the read function of struct lpc_driver_ops , used for the
* MEC variant of LPC EC .
*/
static u8 cros_ec_lpc_mec_read_bytes ( unsigned int offset , unsigned int length ,
u8 * dest )
2019-06-14 23:43:00 +02:00
{
int in_range = cros_ec_lpc_mec_in_range ( offset , length ) ;
if ( in_range < 0 )
return 0 ;
return in_range ?
cros_ec_lpc_io_bytes_mec ( MEC_IO_READ ,
offset - EC_HOST_CMD_REGION0 ,
length , dest ) :
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
cros_ec_lpc_read_bytes ( offset , length , dest ) ;
2019-06-14 23:43:00 +02:00
}
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
/*
* An instance of the write function of struct lpc_driver_ops , used for the
* MEC variant of LPC EC .
*/
static u8 cros_ec_lpc_mec_write_bytes ( unsigned int offset , unsigned int length ,
const u8 * msg )
2019-06-14 23:43:00 +02:00
{
int in_range = cros_ec_lpc_mec_in_range ( offset , length ) ;
if ( in_range < 0 )
return 0 ;
return in_range ?
cros_ec_lpc_io_bytes_mec ( MEC_IO_WRITE ,
offset - EC_HOST_CMD_REGION0 ,
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
length , ( u8 * ) msg ) :
cros_ec_lpc_write_bytes ( offset , length , msg ) ;
2019-06-14 23:43:00 +02:00
}
2015-02-02 12:26:24 +01:00
static int ec_response_timed_out ( void )
{
unsigned long one_second = jiffies + HZ ;
2017-05-16 17:46:48 +02:00
u8 data ;
2015-02-02 12:26:24 +01:00
usleep_range ( 200 , 300 ) ;
do {
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
if ( ! ( cros_ec_lpc_ops . read ( EC_LPC_ADDR_HOST_CMD , 1 , & data ) &
2017-05-16 17:46:48 +02:00
EC_LPC_STATUS_BUSY_MASK ) )
2015-02-02 12:26:24 +01:00
return 0 ;
usleep_range ( 100 , 200 ) ;
} while ( time_before ( jiffies , one_second ) ) ;
return 1 ;
}
2015-06-09 13:04:46 +02:00
static int cros_ec_pkt_xfer_lpc ( struct cros_ec_device * ec ,
struct cros_ec_command * msg )
{
struct ec_host_response response ;
2017-05-16 17:46:48 +02:00
u8 sum ;
2015-06-09 13:04:46 +02:00
int ret = 0 ;
u8 * dout ;
ret = cros_ec_prepare_tx ( ec , msg ) ;
/* Write buffer */
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
cros_ec_lpc_ops . write ( EC_LPC_ADDR_HOST_PACKET , ret , ec - > dout ) ;
2015-06-09 13:04:46 +02:00
/* Here we go */
2017-05-16 17:46:48 +02:00
sum = EC_COMMAND_PROTOCOL_3 ;
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
cros_ec_lpc_ops . write ( EC_LPC_ADDR_HOST_CMD , 1 , & sum ) ;
2015-06-09 13:04:46 +02:00
if ( ec_response_timed_out ( ) ) {
dev_warn ( ec - > dev , " EC responsed timed out \n " ) ;
ret = - EIO ;
goto done ;
}
/* Check result */
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
msg - > result = cros_ec_lpc_ops . read ( EC_LPC_ADDR_HOST_DATA , 1 , & sum ) ;
2015-06-09 13:04:46 +02:00
ret = cros_ec_check_result ( ec , msg ) ;
if ( ret )
goto done ;
/* Read back response */
dout = ( u8 * ) & response ;
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
sum = cros_ec_lpc_ops . read ( EC_LPC_ADDR_HOST_PACKET , sizeof ( response ) ,
dout ) ;
2015-06-09 13:04:46 +02:00
msg - > result = response . result ;
if ( response . data_len > msg - > insize ) {
dev_err ( ec - > dev ,
" packet too long (%d bytes, expected %d) " ,
response . data_len , msg - > insize ) ;
ret = - EMSGSIZE ;
goto done ;
}
/* Read response and process checksum */
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
sum + = cros_ec_lpc_ops . read ( EC_LPC_ADDR_HOST_PACKET +
sizeof ( response ) , response . data_len ,
msg - > data ) ;
2015-06-09 13:04:46 +02:00
if ( sum ) {
dev_err ( ec - > dev ,
" bad packet checksum %02x \n " ,
response . checksum ) ;
ret = - EBADMSG ;
goto done ;
}
/* Return actual amount of data received */
ret = response . data_len ;
done :
return ret ;
}
2015-02-02 12:26:24 +01:00
static int cros_ec_cmd_xfer_lpc ( struct cros_ec_device * ec ,
struct cros_ec_command * msg )
{
struct ec_lpc_host_args args ;
2017-05-16 17:46:48 +02:00
u8 sum ;
2015-02-02 12:26:24 +01:00
int ret = 0 ;
if ( msg - > outsize > EC_PROTO2_MAX_PARAM_SIZE | |
msg - > insize > EC_PROTO2_MAX_PARAM_SIZE ) {
dev_err ( ec - > dev ,
" invalid buffer sizes (out %d, in %d) \n " ,
msg - > outsize , msg - > insize ) ;
return - EINVAL ;
}
/* Now actually send the command to the EC and get the result */
args . flags = EC_HOST_ARGS_FLAG_FROM_HOST ;
args . command_version = msg - > version ;
args . data_size = msg - > outsize ;
/* Initialize checksum */
2017-05-16 17:46:48 +02:00
sum = msg - > command + args . flags + args . command_version + args . data_size ;
2015-02-02 12:26:24 +01:00
/* Copy data and update checksum */
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
sum + = cros_ec_lpc_ops . write ( EC_LPC_ADDR_HOST_PARAM , msg - > outsize ,
msg - > data ) ;
2015-02-02 12:26:24 +01:00
/* Finalize checksum and write args */
2017-05-16 17:46:48 +02:00
args . checksum = sum ;
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
cros_ec_lpc_ops . write ( EC_LPC_ADDR_HOST_ARGS , sizeof ( args ) ,
( u8 * ) & args ) ;
2015-02-02 12:26:24 +01:00
/* Here we go */
2017-05-16 17:46:48 +02:00
sum = msg - > command ;
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
cros_ec_lpc_ops . write ( EC_LPC_ADDR_HOST_CMD , 1 , & sum ) ;
2015-02-02 12:26:24 +01:00
if ( ec_response_timed_out ( ) ) {
dev_warn ( ec - > dev , " EC responsed timed out \n " ) ;
ret = - EIO ;
goto done ;
}
/* Check result */
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
msg - > result = cros_ec_lpc_ops . read ( EC_LPC_ADDR_HOST_DATA , 1 , & sum ) ;
2015-06-22 08:27:18 +02:00
ret = cros_ec_check_result ( ec , msg ) ;
if ( ret )
2015-02-02 12:26:24 +01:00
goto done ;
/* Read back args */
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
cros_ec_lpc_ops . read ( EC_LPC_ADDR_HOST_ARGS , sizeof ( args ) , ( u8 * ) & args ) ;
2015-02-02 12:26:24 +01:00
if ( args . data_size > msg - > insize ) {
dev_err ( ec - > dev ,
" packet too long (%d bytes, expected %d) " ,
args . data_size , msg - > insize ) ;
ret = - ENOSPC ;
goto done ;
}
/* Start calculating response checksum */
2017-05-16 17:46:48 +02:00
sum = msg - > command + args . flags + args . command_version + args . data_size ;
2015-02-02 12:26:24 +01:00
/* Read response and update checksum */
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
sum + = cros_ec_lpc_ops . read ( EC_LPC_ADDR_HOST_PARAM , args . data_size ,
msg - > data ) ;
2015-02-02 12:26:24 +01:00
/* Verify checksum */
2017-05-16 17:46:48 +02:00
if ( args . checksum ! = sum ) {
2015-02-02 12:26:24 +01:00
dev_err ( ec - > dev ,
" bad packet checksum, expected %02x, got %02x \n " ,
2017-05-16 17:46:48 +02:00
args . checksum , sum ) ;
2015-02-02 12:26:24 +01:00
ret = - EBADMSG ;
goto done ;
}
/* Return actual amount of data received */
ret = args . data_size ;
done :
return ret ;
}
/* Returns num bytes read, or negative on error. Doesn't need locking. */
static int cros_ec_lpc_readmem ( struct cros_ec_device * ec , unsigned int offset ,
unsigned int bytes , void * dest )
{
int i = offset ;
char * s = dest ;
int cnt = 0 ;
if ( offset > = EC_MEMMAP_SIZE - bytes )
return - EINVAL ;
/* fixed length */
if ( bytes ) {
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
cros_ec_lpc_ops . read ( EC_LPC_ADDR_MEMMAP + offset , bytes , s ) ;
2017-05-16 17:46:48 +02:00
return bytes ;
2015-02-02 12:26:24 +01:00
}
/* string */
for ( ; i < EC_MEMMAP_SIZE ; i + + , s + + ) {
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
cros_ec_lpc_ops . read ( EC_LPC_ADDR_MEMMAP + i , 1 , s ) ;
2015-02-02 12:26:24 +01:00
cnt + + ;
if ( ! * s )
break ;
}
return cnt ;
}
2017-05-16 17:46:48 +02:00
static void cros_ec_lpc_acpi_notify ( acpi_handle device , u32 value , void * data )
{
struct cros_ec_device * ec_dev = data ;
2019-11-19 13:45:46 +01:00
bool ec_has_more_events ;
int ret ;
2017-05-16 17:46:48 +02:00
2019-11-19 13:45:46 +01:00
ec_dev - > last_event_time = cros_ec_get_time_ns ( ) ;
2019-11-19 13:45:46 +01:00
if ( ec_dev - > mkbp_event_supported )
do {
ret = cros_ec_get_next_event ( ec_dev , NULL ,
& ec_has_more_events ) ;
if ( ret > 0 )
blocking_notifier_call_chain (
& ec_dev - > event_notifier , 0 ,
ec_dev ) ;
} while ( ec_has_more_events ) ;
2018-02-22 13:21:17 -08:00
if ( value = = ACPI_NOTIFY_DEVICE_WAKE )
pm_system_wakeup ( ) ;
2017-05-16 17:46:48 +02:00
}
2015-02-02 12:26:24 +01:00
static int cros_ec_lpc_probe ( struct platform_device * pdev )
{
struct device * dev = & pdev - > dev ;
2017-05-16 17:46:48 +02:00
struct acpi_device * adev ;
acpi_status status ;
2015-02-02 12:26:24 +01:00
struct cros_ec_device * ec_dev ;
2017-05-16 17:46:48 +02:00
u8 buf [ 2 ] ;
2018-10-09 10:56:46 -07:00
int irq , ret ;
2015-02-02 12:26:24 +01:00
if ( ! devm_request_region ( dev , EC_LPC_ADDR_MEMMAP , EC_MEMMAP_SIZE ,
dev_name ( dev ) ) ) {
dev_err ( dev , " couldn't reserve memmap region \n " ) ;
return - EBUSY ;
}
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
/*
* Read the mapped ID twice , the first one is assuming the
* EC is a Microchip Embedded Controller ( MEC ) variant , if the
* protocol fails , fallback to the non MEC variant and try to
* read again the ID .
*/
cros_ec_lpc_ops . read = cros_ec_lpc_mec_read_bytes ;
cros_ec_lpc_ops . write = cros_ec_lpc_mec_write_bytes ;
cros_ec_lpc_ops . read ( EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID , 2 , buf ) ;
2017-05-16 17:46:48 +02:00
if ( buf [ 0 ] ! = ' E ' | | buf [ 1 ] ! = ' C ' ) {
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
/* Re-assign read/write operations for the non MEC variant */
cros_ec_lpc_ops . read = cros_ec_lpc_read_bytes ;
cros_ec_lpc_ops . write = cros_ec_lpc_write_bytes ;
cros_ec_lpc_ops . read ( EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID , 2 ,
buf ) ;
if ( buf [ 0 ] ! = ' E ' | | buf [ 1 ] ! = ' C ' ) {
dev_err ( dev , " EC ID not detected \n " ) ;
return - ENODEV ;
}
2015-02-02 12:26:24 +01:00
}
if ( ! devm_request_region ( dev , EC_HOST_CMD_REGION0 ,
EC_HOST_CMD_REGION_SIZE , dev_name ( dev ) ) ) {
dev_err ( dev , " couldn't reserve region0 \n " ) ;
return - EBUSY ;
}
if ( ! devm_request_region ( dev , EC_HOST_CMD_REGION1 ,
EC_HOST_CMD_REGION_SIZE , dev_name ( dev ) ) ) {
dev_err ( dev , " couldn't reserve region1 \n " ) ;
return - EBUSY ;
}
ec_dev = devm_kzalloc ( dev , sizeof ( * ec_dev ) , GFP_KERNEL ) ;
if ( ! ec_dev )
return - ENOMEM ;
platform_set_drvdata ( pdev , ec_dev ) ;
ec_dev - > dev = dev ;
ec_dev - > phys_name = dev_name ( dev ) ;
ec_dev - > cmd_xfer = cros_ec_cmd_xfer_lpc ;
2015-06-09 13:04:46 +02:00
ec_dev - > pkt_xfer = cros_ec_pkt_xfer_lpc ;
2015-02-02 12:26:24 +01:00
ec_dev - > cmd_readmem = cros_ec_lpc_readmem ;
2015-06-09 13:04:45 +02:00
ec_dev - > din_size = sizeof ( struct ec_host_response ) +
sizeof ( struct ec_response_get_protocol_info ) ;
ec_dev - > dout_size = sizeof ( struct ec_host_request ) ;
2015-02-02 12:26:24 +01:00
2018-10-09 10:56:46 -07:00
/*
* Some boards do not have an IRQ allotted for cros_ec_lpc ,
* which makes ENXIO an expected ( and safe ) scenario .
*/
2019-11-29 11:22:54 +01:00
irq = platform_get_irq_optional ( pdev , 0 ) ;
2018-10-09 10:56:46 -07:00
if ( irq > 0 )
ec_dev - > irq = irq ;
else if ( irq ! = - ENXIO ) {
dev_err ( dev , " couldn't retrieve IRQ number (%d) \n " , irq ) ;
return irq ;
}
2015-02-02 12:26:24 +01:00
ret = cros_ec_register ( ec_dev ) ;
if ( ret ) {
dev_err ( dev , " couldn't register ec_dev (%d) \n " , ret ) ;
return ret ;
}
2017-05-16 17:46:48 +02:00
/*
* Connect a notify handler to process MKBP messages if we have a
* companion ACPI device .
*/
adev = ACPI_COMPANION ( dev ) ;
if ( adev ) {
status = acpi_install_notify_handler ( adev - > handle ,
ACPI_ALL_NOTIFY ,
cros_ec_lpc_acpi_notify ,
ec_dev ) ;
if ( ACPI_FAILURE ( status ) )
dev_warn ( dev , " Failed to register notifier %08x \n " ,
status ) ;
}
2015-02-02 12:26:24 +01:00
return 0 ;
}
static int cros_ec_lpc_remove ( struct platform_device * pdev )
{
2019-09-02 11:53:00 +02:00
struct cros_ec_device * ec_dev = platform_get_drvdata ( pdev ) ;
2017-05-16 17:46:48 +02:00
struct acpi_device * adev ;
adev = ACPI_COMPANION ( & pdev - > dev ) ;
if ( adev )
acpi_remove_notify_handler ( adev - > handle , ACPI_ALL_NOTIFY ,
cros_ec_lpc_acpi_notify ) ;
2015-02-02 12:26:24 +01:00
2019-09-02 11:53:00 +02:00
return cros_ec_unregister ( ec_dev ) ;
2015-02-02 12:26:24 +01:00
}
2017-05-16 17:46:48 +02:00
static const struct acpi_device_id cros_ec_lpc_acpi_device_ids [ ] = {
{ ACPI_DRV_NAME , 0 } ,
{ }
} ;
MODULE_DEVICE_TABLE ( acpi , cros_ec_lpc_acpi_device_ids ) ;
2017-09-14 11:59:30 +02:00
static const struct dmi_system_id cros_ec_lpc_dmi_table [ ] __initconst = {
2015-02-02 12:26:24 +01:00
{
/*
* Today all Chromebooks / boxes ship with Google_ * as version and
* coreboot as bios vendor . No other systems with this
* combination are known to date .
*/
. matches = {
DMI_MATCH ( DMI_BIOS_VENDOR , " coreboot " ) ,
DMI_MATCH ( DMI_BIOS_VERSION , " Google_ " ) ,
} ,
} ,
2018-03-07 14:56:43 +01:00
{
/*
* If the box is running custom coreboot firmware then the
* DMI BIOS version string will not be matched by " Google_ " ,
* but the system vendor string will still be matched by
* " GOOGLE " .
*/
. matches = {
DMI_MATCH ( DMI_BIOS_VENDOR , " coreboot " ) ,
DMI_MATCH ( DMI_SYS_VENDOR , " GOOGLE " ) ,
} ,
} ,
2015-02-02 12:26:24 +01:00
{
/* x86-link, the Chromebook Pixel. */
. matches = {
DMI_MATCH ( DMI_SYS_VENDOR , " GOOGLE " ) ,
DMI_MATCH ( DMI_PRODUCT_NAME , " Link " ) ,
} ,
} ,
2015-06-22 08:27:19 +02:00
{
/* x86-samus, the Chromebook Pixel 2. */
. matches = {
DMI_MATCH ( DMI_SYS_VENDOR , " GOOGLE " ) ,
DMI_MATCH ( DMI_PRODUCT_NAME , " Samus " ) ,
} ,
} ,
2015-02-02 12:26:24 +01:00
{
/* x86-peppy, the Acer C720 Chromebook. */
. matches = {
DMI_MATCH ( DMI_SYS_VENDOR , " Acer " ) ,
DMI_MATCH ( DMI_PRODUCT_NAME , " Peppy " ) ,
} ,
} ,
2017-12-01 14:42:22 +01:00
{
/* x86-glimmer, the Lenovo Thinkpad Yoga 11e. */
. matches = {
DMI_MATCH ( DMI_SYS_VENDOR , " GOOGLE " ) ,
DMI_MATCH ( DMI_PRODUCT_NAME , " Glimmer " ) ,
} ,
} ,
2015-02-02 12:26:24 +01:00
{ /* sentinel */ }
} ;
MODULE_DEVICE_TABLE ( dmi , cros_ec_lpc_dmi_table ) ;
2017-05-16 17:46:48 +02:00
# ifdef CONFIG_PM_SLEEP
static int cros_ec_lpc_suspend ( struct device * dev )
{
struct cros_ec_device * ec_dev = dev_get_drvdata ( dev ) ;
return cros_ec_suspend ( ec_dev ) ;
}
static int cros_ec_lpc_resume ( struct device * dev )
{
struct cros_ec_device * ec_dev = dev_get_drvdata ( dev ) ;
return cros_ec_resume ( ec_dev ) ;
}
# endif
2019-05-30 16:49:32 +08:00
static const struct dev_pm_ops cros_ec_lpc_pm_ops = {
2017-05-16 17:46:48 +02:00
SET_LATE_SYSTEM_SLEEP_PM_OPS ( cros_ec_lpc_suspend , cros_ec_lpc_resume )
} ;
2015-02-02 12:26:24 +01:00
static struct platform_driver cros_ec_lpc_driver = {
. driver = {
. name = DRV_NAME ,
2017-05-16 17:46:48 +02:00
. acpi_match_table = cros_ec_lpc_acpi_device_ids ,
2017-05-16 17:46:48 +02:00
. pm = & cros_ec_lpc_pm_ops ,
2015-02-02 12:26:24 +01:00
} ,
. probe = cros_ec_lpc_probe ,
. remove = cros_ec_lpc_remove ,
} ;
2017-12-01 14:42:21 +01:00
static struct platform_device cros_ec_lpc_device = {
. name = DRV_NAME
} ;
static acpi_status cros_ec_lpc_parse_device ( acpi_handle handle , u32 level ,
void * context , void * * retval )
{
* ( bool * ) context = true ;
return AE_CTRL_TERMINATE ;
}
2015-02-02 12:26:24 +01:00
static int __init cros_ec_lpc_init ( void )
{
int ret ;
2017-12-01 14:42:21 +01:00
acpi_status status ;
2015-02-02 12:26:24 +01:00
2018-05-22 16:08:41 -07:00
status = acpi_get_devices ( ACPI_DRV_NAME , cros_ec_lpc_parse_device ,
& cros_ec_lpc_acpi_device_found , NULL ) ;
if ( ACPI_FAILURE ( status ) )
pr_warn ( DRV_NAME " : Looking for %s failed \n " , ACPI_DRV_NAME ) ;
if ( ! cros_ec_lpc_acpi_device_found & &
! dmi_check_system ( cros_ec_lpc_dmi_table ) ) {
2015-02-02 12:26:24 +01:00
pr_err ( DRV_NAME " : unsupported system. \n " ) ;
return - ENODEV ;
}
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
cros_ec_lpc_mec_init ( EC_HOST_CMD_REGION0 ,
EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SIZE ) ;
2017-05-16 17:46:48 +02:00
2015-02-02 12:26:24 +01:00
/* Register the driver */
ret = platform_driver_register ( & cros_ec_lpc_driver ) ;
if ( ret ) {
pr_err ( DRV_NAME " : can't register driver: %d \n " , ret ) ;
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
cros_ec_lpc_mec_destroy ( ) ;
2015-02-02 12:26:24 +01:00
return ret ;
}
2017-12-01 14:42:21 +01:00
if ( ! cros_ec_lpc_acpi_device_found ) {
/* Register the device, and it'll get hooked up automatically */
ret = platform_device_register ( & cros_ec_lpc_device ) ;
if ( ret ) {
pr_err ( DRV_NAME " : can't register device: %d \n " , ret ) ;
platform_driver_unregister ( & cros_ec_lpc_driver ) ;
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
cros_ec_lpc_mec_destroy ( ) ;
2017-12-01 14:42:21 +01:00
}
}
return ret ;
2015-02-02 12:26:24 +01:00
}
static void __exit cros_ec_lpc_exit ( void )
{
2017-12-01 14:42:21 +01:00
if ( ! cros_ec_lpc_acpi_device_found )
platform_device_unregister ( & cros_ec_lpc_device ) ;
2015-02-02 12:26:24 +01:00
platform_driver_unregister ( & cros_ec_lpc_driver ) ;
platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime
On many boards, communication between the kernel and the Embedded
Controller happens over an LPC bus. In these cases, the kernel config
CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
Microchip Embedded Controller (MEC) that is different from the regular
EC. On these devices, the same LPC bus is used, but the protocol is
a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
config is enabled. Currently, the kernel decides at compile-time whether
or not to use the MEC variant, and, when that kernel option is selected
it breaks the other boards. We would like a kind of runtime detection to
avoid this.
This patch adds that detection mechanism by probing the protocol at
runtime, first we assume that a MEC variant is connected, and if the
protocol fails it fallbacks to the regular EC. This adds a bit of
overload because we try to read twice on those LPC boards that doesn't
contain a MEC variant, but is a better solution than having to select the
EC variant at compile-time.
While here also fix the alignment in Kconfig file for this config option
replacing the spaces by tabs.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Nick Crews <ncrews@chromium.org>
Reviewed-by: Nick Crews <ncrews@chromium.org>
2019-06-14 23:43:01 +02:00
cros_ec_lpc_mec_destroy ( ) ;
2015-02-02 12:26:24 +01:00
}
module_init ( cros_ec_lpc_init ) ;
module_exit ( cros_ec_lpc_exit ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_DESCRIPTION ( " ChromeOS EC LPC driver " ) ;