2 * Copyright (C) 2012 Google, Inc
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * The ChromeOS EC multi function device is used to mux all the requests
20 * to the EC device for its multiple features : keyboard controller,
21 * battery charging and regulator control, firmware update.
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/i2c.h>
27 #include <linux/interrupt.h>
28 #include <linux/mfd/core.h>
29 #include <linux/mfd/chromeos_ec.h>
30 #include <linux/platform_device.h>
31 #include <linux/slab.h>
34 #define MKBP_MAX_TRIES 3
36 /* Send a one-byte command to the keyboard and receive a response of length
37 * BUF_LEN. Return BUF_LEN, or a negative error code.
39 static int mkbp_command_noretry(struct chromeos_ec_device *ec_dev,
40 char cmd, uint8_t *buf, int buf_len)
48 /* allocate larger packet (one extra byte for checksum) */
49 packet_len = buf_len + MKBP_MSG_PROTO_BYTES;
50 packet = kzalloc(packet_len, GFP_KERNEL);
54 /* send command to EC */
55 ret = i2c_master_send(ec_dev->client, &cmd, 1);
57 dev_err(ec_dev->dev, "i2c send failed: %d\n", ret);
60 /* receive response */
61 ret = i2c_master_recv(ec_dev->client, packet, packet_len);
63 dev_err(ec_dev->dev, "i2c receive failed: %d\n", ret);
65 } else if (ret != packet_len) {
66 dev_err(ec_dev->dev, "expected %d bytes, got %d\n",
71 /* copy response packet payload and compute checksum */
72 for (i = 0, sum = 0; i < buf_len; i++) {
77 dev_dbg(ec_dev->dev, "packet: ");
78 for (i = 0; i < packet_len; i++) {
79 printk(" %02x", packet[i]);
81 printk(", sum = %02x\n", sum);
83 if (sum != packet[packet_len - 1]) {
84 dev_err(ec_dev->dev, "bad keyboard packet checksum\n");
94 static int mkbp_command(struct chromeos_ec_device *ec_dev,
95 char cmd, uint8_t *buf, int buf_len)
100 * Try the command a few times in case there are transmission errors.
101 * It is possible that this is overkill, but we don't completely trust
104 for (try = 0; try < MKBP_MAX_TRIES; try++) {
105 ret = mkbp_command_noretry(ec_dev, cmd, buf, buf_len);
109 dev_err(ec_dev->dev, "mkbp_command failed with %d (%d tries)\n",
114 static irqreturn_t ec_irq_thread(int irq, void *data)
116 struct chromeos_ec_device *ec = data;
118 blocking_notifier_call_chain(&ec->event_notifier, 1, ec);
123 static int __devinit mkbp_check_protocol_version(struct chromeos_ec_device *ec)
127 static char expected_version[4] = {1, 0, 0, 0};
130 ret = mkbp_command(ec, MKBP_CMDC_PROTO_VER, buf, sizeof(buf));
133 for (i = 0; i < sizeof(expected_version); i++) {
134 if (buf[i] != expected_version[i])
135 return -EPROTONOSUPPORT;
140 static struct mfd_cell cros_devs[] = {
147 static int __devinit cros_ec_probe(struct i2c_client *client,
148 const struct i2c_device_id *dev_id)
150 struct device *dev = &client->dev;
151 struct chromeos_ec_device *ec_dev = NULL;
154 dev_dbg(dev, "probing\n");
156 ec_dev = kzalloc(sizeof(*ec_dev), GFP_KERNEL);
157 if (ec_dev == NULL) {
159 dev_err(dev, "cannot allocate\n");
163 ec_dev->client = client;
165 i2c_set_clientdata(client, ec_dev);
166 ec_dev->irq = client->irq;
167 ec_dev->send_command = mkbp_command;
169 BLOCKING_INIT_NOTIFIER_HEAD(&ec_dev->event_notifier);
171 err = request_threaded_irq(ec_dev->irq, NULL, ec_irq_thread,
172 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
173 "chromeos-ec", ec_dev);
175 dev_err(dev, "request irq %d: error %d\n", ec_dev->irq, err);
179 err = mkbp_check_protocol_version(ec_dev);
181 dev_err(dev, "protocol version check failed: %d\n", err);
185 err = mfd_add_devices(dev, 0, cros_devs, ARRAY_SIZE(cros_devs),
192 free_irq(ec_dev->irq, ec_dev);
198 #ifdef CONFIG_PM_SLEEP
199 static int cros_ec_suspend(struct device *dev)
204 static int cros_ec_resume(struct device *dev)
210 static SIMPLE_DEV_PM_OPS(cros_ec_pm_ops, cros_ec_suspend, cros_ec_resume);
212 static const struct i2c_device_id cros_ec_i2c_id[] = {
213 { "chromeos-ec", 0 },
216 MODULE_DEVICE_TABLE(i2c, mkbp_i2c_id);
218 static struct i2c_driver cros_ec_driver = {
220 .name = "chromeos-ec",
221 .owner = THIS_MODULE,
222 .pm = &cros_ec_pm_ops,
224 .probe = cros_ec_probe,
225 .id_table = cros_ec_i2c_id,
228 module_i2c_driver(cros_ec_driver);
230 MODULE_LICENSE("GPL");
231 MODULE_DESCRIPTION("ChromeOS EC multi function device");