1 /*
2  * cros_ec_lpc_mec - LPC variant I/O for Microchip EC
3  *
4  * Copyright (C) 2016 Google, Inc
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * This driver uses the Chrome OS EC byte-level message-based protocol for
16  * communicating the keyboard state (which keys are pressed) from a keyboard EC
17  * to the AP over some bus (such as i2c, lpc, spi).  The EC does debouncing,
18  * but everything else (including deghosting) is done here.  The main
19  * motivation for this is to keep the EC firmware as simple as possible, since
20  * it cannot be easily upgraded and EC flash/IRAM space is relatively
21  * expensive.
22  */
23 
24 #ifndef __CROS_EC_LPC_MEC_H
25 #define __CROS_EC_LPC_MEC_H
26 
27 #include <linux/mfd/cros_ec_commands.h>
28 
29 enum cros_ec_lpc_mec_emi_access_mode {
30 	/* 8-bit access */
31 	ACCESS_TYPE_BYTE = 0x0,
32 	/* 16-bit access */
33 	ACCESS_TYPE_WORD = 0x1,
34 	/* 32-bit access */
35 	ACCESS_TYPE_LONG = 0x2,
36 	/*
37 	 * 32-bit access, read or write of MEC_EMI_EC_DATA_B3 causes the
38 	 * EC data register to be incremented.
39 	 */
40 	ACCESS_TYPE_LONG_AUTO_INCREMENT = 0x3,
41 };
42 
43 enum cros_ec_lpc_mec_io_type {
44 	MEC_IO_READ,
45 	MEC_IO_WRITE,
46 };
47 
48 /* Access IO ranges 0x800 thru 0x9ff using EMI interface instead of LPC */
49 #define MEC_EMI_RANGE_START EC_HOST_CMD_REGION0
50 #define MEC_EMI_RANGE_END   (EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SIZE)
51 
52 /* EMI registers are relative to base */
53 #define MEC_EMI_BASE 0x800
54 #define MEC_EMI_HOST_TO_EC (MEC_EMI_BASE + 0)
55 #define MEC_EMI_EC_TO_HOST (MEC_EMI_BASE + 1)
56 #define MEC_EMI_EC_ADDRESS_B0 (MEC_EMI_BASE + 2)
57 #define MEC_EMI_EC_ADDRESS_B1 (MEC_EMI_BASE + 3)
58 #define MEC_EMI_EC_DATA_B0 (MEC_EMI_BASE + 4)
59 #define MEC_EMI_EC_DATA_B1 (MEC_EMI_BASE + 5)
60 #define MEC_EMI_EC_DATA_B2 (MEC_EMI_BASE + 6)
61 #define MEC_EMI_EC_DATA_B3 (MEC_EMI_BASE + 7)
62 
63 /*
64  * cros_ec_lpc_mec_init
65  *
66  * Initialize MEC I/O.
67  */
68 void cros_ec_lpc_mec_init(void);
69 
70 /*
71  * cros_ec_lpc_mec_destroy
72  *
73  * Cleanup MEC I/O.
74  */
75 void cros_ec_lpc_mec_destroy(void);
76 
77 /**
78  * cros_ec_lpc_io_bytes_mec - Read / write bytes to MEC EMI port
79  *
80  * @io_type: MEC_IO_READ or MEC_IO_WRITE, depending on request
81  * @offset:  Base read / write address
82  * @length:  Number of bytes to read / write
83  * @buf:     Destination / source buffer
84  *
85  * @return 8-bit checksum of all bytes read / written
86  */
87 u8 cros_ec_lpc_io_bytes_mec(enum cros_ec_lpc_mec_io_type io_type,
88 			    unsigned int offset, unsigned int length, u8 *buf);
89 
90 #endif /* __CROS_EC_LPC_MEC_H */
91