summaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorStephen Barber <smbarber@chromium.org>2015-06-09 07:04:46 -0400
committerLee Jones <lee.jones@linaro.org>2015-06-15 08:18:22 -0400
commitd365407079d33106f76bd486a863de05eb5ae95d (patch)
tree46cc169453a614fee690d5ce9df51ed992222c4c /drivers/platform
parent2c7589af3c4dee844e6a4174f2aa8996cf837604 (diff)
mfd: cros_ec: add bus-specific proto v3 code
Add proto v3 support to the SPI, I2C, and LPC. Signed-off-by: Stephen Barber <smbarber@chromium.org> Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk> Tested-by: Heiko Stuebner <heiko@sntech.de> Reviewed-by: Gwendal Grignou <gwendal@chromium.org> Tested-by: Gwendal Grignou <gwendal@chromium.org> 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/platform')
-rw-r--r--drivers/platform/chrome/cros_ec_lpc.c73
1 files changed, 72 insertions, 1 deletions
diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c
index 05aeb559275f..cac24d356c91 100644
--- a/drivers/platform/chrome/cros_ec_lpc.c
+++ b/drivers/platform/chrome/cros_ec_lpc.c
@@ -46,6 +46,77 @@ static int ec_response_timed_out(void)
46 return 1; 46 return 1;
47} 47}
48 48
49static int cros_ec_pkt_xfer_lpc(struct cros_ec_device *ec,
50 struct cros_ec_command *msg)
51{
52 struct ec_host_request *request;
53 struct ec_host_response response;
54 u8 sum = 0;
55 int i;
56 int ret = 0;
57 u8 *dout;
58
59 ret = cros_ec_prepare_tx(ec, msg);
60
61 /* Write buffer */
62 for (i = 0; i < ret; i++)
63 outb(ec->dout[i], EC_LPC_ADDR_HOST_PACKET + i);
64
65 request = (struct ec_host_request *)ec->dout;
66
67 /* Here we go */
68 outb(EC_COMMAND_PROTOCOL_3, EC_LPC_ADDR_HOST_CMD);
69
70 if (ec_response_timed_out()) {
71 dev_warn(ec->dev, "EC responsed timed out\n");
72 ret = -EIO;
73 goto done;
74 }
75
76 /* Check result */
77 msg->result = inb(EC_LPC_ADDR_HOST_DATA);
78 ret = cros_ec_check_result(ec, msg);
79 if (ret)
80 goto done;
81
82 /* Read back response */
83 dout = (u8 *)&response;
84 for (i = 0; i < sizeof(response); i++) {
85 dout[i] = inb(EC_LPC_ADDR_HOST_PACKET + i);
86 sum += dout[i];
87 }
88
89 msg->result = response.result;
90
91 if (response.data_len > msg->insize) {
92 dev_err(ec->dev,
93 "packet too long (%d bytes, expected %d)",
94 response.data_len, msg->insize);
95 ret = -EMSGSIZE;
96 goto done;
97 }
98
99 /* Read response and process checksum */
100 for (i = 0; i < response.data_len; i++) {
101 msg->data[i] =
102 inb(EC_LPC_ADDR_HOST_PACKET + sizeof(response) + i);
103 sum += msg->data[i];
104 }
105
106 if (sum) {
107 dev_err(ec->dev,
108 "bad packet checksum %02x\n",
109 response.checksum);
110 ret = -EBADMSG;
111 goto done;
112 }
113
114 /* Return actual amount of data received */
115 ret = response.data_len;
116done:
117 return ret;
118}
119
49static int cros_ec_cmd_xfer_lpc(struct cros_ec_device *ec, 120static int cros_ec_cmd_xfer_lpc(struct cros_ec_device *ec,
50 struct cros_ec_command *msg) 121 struct cros_ec_command *msg)
51{ 122{
@@ -215,7 +286,7 @@ static int cros_ec_lpc_probe(struct platform_device *pdev)
215 ec_dev->ec_name = pdev->name; 286 ec_dev->ec_name = pdev->name;
216 ec_dev->phys_name = dev_name(dev); 287 ec_dev->phys_name = dev_name(dev);
217 ec_dev->cmd_xfer = cros_ec_cmd_xfer_lpc; 288 ec_dev->cmd_xfer = cros_ec_cmd_xfer_lpc;
218 ec_dev->pkt_xfer = NULL; 289 ec_dev->pkt_xfer = cros_ec_pkt_xfer_lpc;
219 ec_dev->cmd_readmem = cros_ec_lpc_readmem; 290 ec_dev->cmd_readmem = cros_ec_lpc_readmem;
220 ec_dev->din_size = sizeof(struct ec_host_response) + 291 ec_dev->din_size = sizeof(struct ec_host_response) +
221 sizeof(struct ec_response_get_protocol_info); 292 sizeof(struct ec_response_get_protocol_info);