summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJavier Martinez Canillas <javier.martinez@collabora.co.uk>2015-06-09 07:04:44 -0400
committerLee Jones <lee.jones@linaro.org>2015-06-15 08:18:20 -0400
commit062476f24aa7cf714169342cc50626fd9bbb93da (patch)
tree5af8fcb6bacea36579c79929a57b572d14982691 /drivers
parent256ab950bdaa8797b7bac8fc11a567030d486304 (diff)
mfd: cros_ec: Move protocol helpers out of the MFD driver
The MFD driver should only have the logic to instantiate its child devices and setup any shared resources that will be used by the subdevices drivers. The cros_ec MFD is more complex than expected since it also has helpers to communicate with the EC. So the driver will only get more bigger as other protocols are supported in the future. So move the communication protocol helpers to its own driver as drivers/platform/chrome/cros_ec_proto.c. Suggested-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk> Tested-by: Heiko Stuebner <heiko@sntech.de> Acked-by: Lee Jones <lee.jones@linaro.org> Acked-by: Olof Johansson <olof@lixom.net> Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/i2c/busses/Kconfig2
-rw-r--r--drivers/input/keyboard/Kconfig2
-rw-r--r--drivers/mfd/Kconfig6
-rw-r--r--drivers/mfd/cros_ec.c96
-rw-r--r--drivers/platform/chrome/Kconfig9
-rw-r--r--drivers/platform/chrome/Makefile1
-rw-r--r--drivers/platform/chrome/cros_ec_proto.c115
7 files changed, 129 insertions, 102 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 2255af23b9c7..5f1c1c4f5d87 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -1103,7 +1103,7 @@ config I2C_SIBYTE
1103 1103
1104config I2C_CROS_EC_TUNNEL 1104config I2C_CROS_EC_TUNNEL
1105 tristate "ChromeOS EC tunnel I2C bus" 1105 tristate "ChromeOS EC tunnel I2C bus"
1106 depends on MFD_CROS_EC 1106 depends on CROS_EC_PROTO
1107 help 1107 help
1108 If you say yes here you get an I2C bus that will tunnel i2c commands 1108 If you say yes here you get an I2C bus that will tunnel i2c commands
1109 through to the other side of the ChromeOS EC to the i2c bus 1109 through to the other side of the ChromeOS EC to the i2c bus
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 106fbac7f8c5..e8eb60c6d83e 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -677,7 +677,7 @@ config KEYBOARD_W90P910
677config KEYBOARD_CROS_EC 677config KEYBOARD_CROS_EC
678 tristate "ChromeOS EC keyboard" 678 tristate "ChromeOS EC keyboard"
679 select INPUT_MATRIXKMAP 679 select INPUT_MATRIXKMAP
680 depends on MFD_CROS_EC 680 depends on CROS_EC_PROTO
681 help 681 help
682 Say Y here to enable the matrix keyboard used by ChromeOS devices 682 Say Y here to enable the matrix keyboard used by ChromeOS devices
683 and implemented on the ChromeOS EC. You must enable one bus option 683 and implemented on the ChromeOS EC. You must enable one bus option
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index d5ad04dad081..cf3b86d441f7 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -94,6 +94,8 @@ config MFD_AXP20X
94config MFD_CROS_EC 94config MFD_CROS_EC
95 tristate "ChromeOS Embedded Controller" 95 tristate "ChromeOS Embedded Controller"
96 select MFD_CORE 96 select MFD_CORE
97 select CHROME_PLATFORMS
98 select CROS_EC_PROTO
97 help 99 help
98 If you say Y here you get support for the ChromeOS Embedded 100 If you say Y here you get support for the ChromeOS Embedded
99 Controller (EC) providing keyboard, battery and power services. 101 Controller (EC) providing keyboard, battery and power services.
@@ -102,7 +104,7 @@ config MFD_CROS_EC
102 104
103config MFD_CROS_EC_I2C 105config MFD_CROS_EC_I2C
104 tristate "ChromeOS Embedded Controller (I2C)" 106 tristate "ChromeOS Embedded Controller (I2C)"
105 depends on MFD_CROS_EC && I2C 107 depends on MFD_CROS_EC && CROS_EC_PROTO && I2C
106 108
107 help 109 help
108 If you say Y here, you get support for talking to the ChromeOS 110 If you say Y here, you get support for talking to the ChromeOS
@@ -112,7 +114,7 @@ config MFD_CROS_EC_I2C
112 114
113config MFD_CROS_EC_SPI 115config MFD_CROS_EC_SPI
114 tristate "ChromeOS Embedded Controller (SPI)" 116 tristate "ChromeOS Embedded Controller (SPI)"
115 depends on MFD_CROS_EC && SPI && OF 117 depends on MFD_CROS_EC && CROS_EC_PROTO && SPI && OF
116 118
117 ---help--- 119 ---help---
118 If you say Y here, you get support for talking to the ChromeOS EC 120 If you say Y here, you get support for talking to the ChromeOS EC
diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c
index 4a0f6dfcd376..d857f6a2b57b 100644
--- a/drivers/mfd/cros_ec.c
+++ b/drivers/mfd/cros_ec.c
@@ -23,102 +23,6 @@
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/mfd/core.h> 24#include <linux/mfd/core.h>
25#include <linux/mfd/cros_ec.h> 25#include <linux/mfd/cros_ec.h>
26#include <linux/mfd/cros_ec_commands.h>
27#include <linux/delay.h>
28
29#define EC_COMMAND_RETRIES 50
30
31int cros_ec_prepare_tx(struct cros_ec_device *ec_dev,
32 struct cros_ec_command *msg)
33{
34 uint8_t *out;
35 int csum, i;
36
37 BUG_ON(msg->outsize > EC_PROTO2_MAX_PARAM_SIZE);
38 out = ec_dev->dout;
39 out[0] = EC_CMD_VERSION0 + msg->version;
40 out[1] = msg->command;
41 out[2] = msg->outsize;
42 csum = out[0] + out[1] + out[2];
43 for (i = 0; i < msg->outsize; i++)
44 csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->data[i];
45 out[EC_MSG_TX_HEADER_BYTES + msg->outsize] = (uint8_t)(csum & 0xff);
46
47 return EC_MSG_TX_PROTO_BYTES + msg->outsize;
48}
49EXPORT_SYMBOL(cros_ec_prepare_tx);
50
51int cros_ec_check_result(struct cros_ec_device *ec_dev,
52 struct cros_ec_command *msg)
53{
54 switch (msg->result) {
55 case EC_RES_SUCCESS:
56 return 0;
57 case EC_RES_IN_PROGRESS:
58 dev_dbg(ec_dev->dev, "command 0x%02x in progress\n",
59 msg->command);
60 return -EAGAIN;
61 default:
62 dev_dbg(ec_dev->dev, "command 0x%02x returned %d\n",
63 msg->command, msg->result);
64 return 0;
65 }
66}
67EXPORT_SYMBOL(cros_ec_check_result);
68
69int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev,
70 struct cros_ec_command *msg)
71{
72 int ret;
73
74 mutex_lock(&ec_dev->lock);
75 ret = ec_dev->cmd_xfer(ec_dev, msg);
76 if (msg->result == EC_RES_IN_PROGRESS) {
77 int i;
78 struct cros_ec_command *status_msg;
79 struct ec_response_get_comms_status *status;
80
81 status_msg = kmalloc(sizeof(*status_msg) + sizeof(*status),
82 GFP_KERNEL);
83 if (!status_msg) {
84 ret = -ENOMEM;
85 goto exit;
86 }
87
88 status_msg->version = 0;
89 status_msg->command = EC_CMD_GET_COMMS_STATUS;
90 status_msg->insize = sizeof(*status);
91 status_msg->outsize = 0;
92
93 /*
94 * Query the EC's status until it's no longer busy or
95 * we encounter an error.
96 */
97 for (i = 0; i < EC_COMMAND_RETRIES; i++) {
98 usleep_range(10000, 11000);
99
100 ret = ec_dev->cmd_xfer(ec_dev, status_msg);
101 if (ret < 0)
102 break;
103
104 msg->result = status_msg->result;
105 if (status_msg->result != EC_RES_SUCCESS)
106 break;
107
108 status = (struct ec_response_get_comms_status *)
109 status_msg->data;
110 if (!(status->flags & EC_COMMS_STATUS_PROCESSING))
111 break;
112 }
113
114 kfree(status_msg);
115 }
116exit:
117 mutex_unlock(&ec_dev->lock);
118
119 return ret;
120}
121EXPORT_SYMBOL(cros_ec_cmd_xfer);
122 26
123static const struct mfd_cell cros_devs[] = { 27static const struct mfd_cell cros_devs[] = {
124 { 28 {
diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
index 2a6531a5fde8..cb1329919527 100644
--- a/drivers/platform/chrome/Kconfig
+++ b/drivers/platform/chrome/Kconfig
@@ -40,7 +40,7 @@ config CHROMEOS_PSTORE
40 40
41config CROS_EC_CHARDEV 41config CROS_EC_CHARDEV
42 tristate "Chrome OS Embedded Controller userspace device interface" 42 tristate "Chrome OS Embedded Controller userspace device interface"
43 depends on MFD_CROS_EC 43 depends on CROS_EC_PROTO
44 ---help--- 44 ---help---
45 This driver adds support to talk with the ChromeOS EC from userspace. 45 This driver adds support to talk with the ChromeOS EC from userspace.
46 46
@@ -49,7 +49,7 @@ config CROS_EC_CHARDEV
49 49
50config CROS_EC_LPC 50config CROS_EC_LPC
51 tristate "ChromeOS Embedded Controller (LPC)" 51 tristate "ChromeOS Embedded Controller (LPC)"
52 depends on MFD_CROS_EC && (X86 || COMPILE_TEST) 52 depends on MFD_CROS_EC && CROS_EC_PROTO && (X86 || COMPILE_TEST)
53 help 53 help
54 If you say Y here, you get support for talking to the ChromeOS EC 54 If you say Y here, you get support for talking to the ChromeOS EC
55 over an LPC bus. This uses a simple byte-level protocol with a 55 over an LPC bus. This uses a simple byte-level protocol with a
@@ -59,4 +59,9 @@ config CROS_EC_LPC
59 To compile this driver as a module, choose M here: the 59 To compile this driver as a module, choose M here: the
60 module will be called cros_ec_lpc. 60 module will be called cros_ec_lpc.
61 61
62config CROS_EC_PROTO
63 bool
64 help
65 ChromeOS EC communication protocol helpers.
66
62endif # CHROMEOS_PLATFORMS 67endif # CHROMEOS_PLATFORMS
diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile
index bd8d8601e875..4a11b010f5d8 100644
--- a/drivers/platform/chrome/Makefile
+++ b/drivers/platform/chrome/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o
4cros_ec_devs-objs := cros_ec_dev.o cros_ec_sysfs.o cros_ec_lightbar.o 4cros_ec_devs-objs := cros_ec_dev.o cros_ec_sysfs.o cros_ec_lightbar.o
5obj-$(CONFIG_CROS_EC_CHARDEV) += cros_ec_devs.o 5obj-$(CONFIG_CROS_EC_CHARDEV) += cros_ec_devs.o
6obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpc.o 6obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpc.o
7obj-$(CONFIG_CROS_EC_PROTO) += cros_ec_proto.o
diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c
new file mode 100644
index 000000000000..58e98a24fd08
--- /dev/null
+++ b/drivers/platform/chrome/cros_ec_proto.c
@@ -0,0 +1,115 @@
1/*
2 * ChromeOS EC communication protocol helper functions
3 *
4 * Copyright (C) 2015 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 */
16
17#include <linux/mfd/cros_ec.h>
18#include <linux/delay.h>
19#include <linux/device.h>
20#include <linux/module.h>
21#include <linux/slab.h>
22
23#define EC_COMMAND_RETRIES 50
24
25int cros_ec_prepare_tx(struct cros_ec_device *ec_dev,
26 struct cros_ec_command *msg)
27{
28 uint8_t *out;
29 int csum, i;
30
31 BUG_ON(msg->outsize > EC_PROTO2_MAX_PARAM_SIZE);
32 out = ec_dev->dout;
33 out[0] = EC_CMD_VERSION0 + msg->version;
34 out[1] = msg->command;
35 out[2] = msg->outsize;
36 csum = out[0] + out[1] + out[2];
37 for (i = 0; i < msg->outsize; i++)
38 csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->data[i];
39 out[EC_MSG_TX_HEADER_BYTES + msg->outsize] = (uint8_t)(csum & 0xff);
40
41 return EC_MSG_TX_PROTO_BYTES + msg->outsize;
42}
43EXPORT_SYMBOL(cros_ec_prepare_tx);
44
45int cros_ec_check_result(struct cros_ec_device *ec_dev,
46 struct cros_ec_command *msg)
47{
48 switch (msg->result) {
49 case EC_RES_SUCCESS:
50 return 0;
51 case EC_RES_IN_PROGRESS:
52 dev_dbg(ec_dev->dev, "command 0x%02x in progress\n",
53 msg->command);
54 return -EAGAIN;
55 default:
56 dev_dbg(ec_dev->dev, "command 0x%02x returned %d\n",
57 msg->command, msg->result);
58 return 0;
59 }
60}
61EXPORT_SYMBOL(cros_ec_check_result);
62
63int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev,
64 struct cros_ec_command *msg)
65{
66 int ret;
67
68 mutex_lock(&ec_dev->lock);
69 ret = ec_dev->cmd_xfer(ec_dev, msg);
70 if (msg->result == EC_RES_IN_PROGRESS) {
71 int i;
72 struct cros_ec_command *status_msg;
73 struct ec_response_get_comms_status *status;
74
75 status_msg = kmalloc(sizeof(*status_msg) + sizeof(*status),
76 GFP_KERNEL);
77 if (!status_msg) {
78 ret = -ENOMEM;
79 goto exit;
80 }
81
82 status_msg->version = 0;
83 status_msg->command = EC_CMD_GET_COMMS_STATUS;
84 status_msg->insize = sizeof(*status);
85 status_msg->outsize = 0;
86
87 /*
88 * Query the EC's status until it's no longer busy or
89 * we encounter an error.
90 */
91 for (i = 0; i < EC_COMMAND_RETRIES; i++) {
92 usleep_range(10000, 11000);
93
94 ret = ec_dev->cmd_xfer(ec_dev, status_msg);
95 if (ret < 0)
96 break;
97
98 msg->result = status_msg->result;
99 if (status_msg->result != EC_RES_SUCCESS)
100 break;
101
102 status = (struct ec_response_get_comms_status *)
103 status_msg->data;
104 if (!(status->flags & EC_COMMS_STATUS_PROCESSING))
105 break;
106 }
107
108 kfree(status_msg);
109 }
110exit:
111 mutex_unlock(&ec_dev->lock);
112
113 return ret;
114}
115EXPORT_SYMBOL(cros_ec_cmd_xfer);