UPSTREAM: USB: option: Updated Huawei K4605 has better id
[cascardo/linux.git] / drivers / mfd / chromeos_ec.c
1 /*
2  *  Copyright (C) 2012 Google, Inc
3  *
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.
8  *
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.
13  *
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
17  *
18  *
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.
22  */
23
24 #include <linux/interrupt.h>
25 #include <linux/slab.h>
26 #include <linux/mfd/core.h>
27 #include <linux/mfd/chromeos_ec.h>
28 #include <linux/mfd/chromeos_ec_commands.h>
29 #include <linux/of_platform.h>
30
31 int cros_ec_prepare_tx(struct chromeos_ec_device *ec_dev,
32                        struct chromeos_ec_msg *msg)
33 {
34         uint8_t *out;
35         int csum, i;
36
37         BUG_ON(msg->out_len > EC_HOST_PARAM_SIZE);
38         out = ec_dev->dout;
39         out[0] = EC_CMD_VERSION0 + msg->version;
40         out[1] = msg->cmd;
41         out[2] = msg->out_len;
42         csum = out[0] + out[1] + out[2];
43         for (i = 0; i < msg->out_len; i++)
44                 csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->out_buf[i];
45         out[EC_MSG_TX_HEADER_BYTES + msg->out_len] = (uint8_t)(csum & 0xff);
46
47         return EC_MSG_TX_PROTO_BYTES + msg->out_len;
48 }
49
50 static int cros_ec_command_sendrecv(struct chromeos_ec_device *ec_dev,
51                 uint16_t cmd, void *out_buf, int out_len,
52                 void *in_buf, int in_len)
53 {
54         struct chromeos_ec_msg msg;
55
56         msg.version = cmd >> 8;
57         msg.cmd = cmd & 0xff;
58         msg.out_buf = out_buf;
59         msg.out_len = out_len;
60         msg.in_buf = in_buf;
61         msg.in_len = in_len;
62
63         return ec_dev->command_xfer(ec_dev, &msg);
64 }
65
66 static int cros_ec_command_recv(struct chromeos_ec_device *ec_dev,
67                 uint16_t cmd, void *buf, int buf_len)
68 {
69         return cros_ec_command_sendrecv(ec_dev, cmd, NULL, 0, buf, buf_len);
70 }
71
72 static int cros_ec_command_send(struct chromeos_ec_device *ec_dev,
73                 uint16_t cmd, void *buf, int buf_len)
74 {
75         return cros_ec_command_sendrecv(ec_dev, cmd, buf, buf_len, NULL, 0);
76 }
77
78 struct chromeos_ec_device *__devinit cros_ec_alloc(const char *name)
79 {
80         struct chromeos_ec_device *ec_dev;
81
82         ec_dev = kzalloc(sizeof(*ec_dev), GFP_KERNEL);
83         if (ec_dev == NULL) {
84                 dev_err(ec_dev->dev, "cannot allocate\n");
85                 return NULL;
86         }
87         ec_dev->name = name;
88
89         return ec_dev;
90 }
91
92 void cros_ec_free(struct chromeos_ec_device *ec)
93 {
94         kfree(ec);
95 }
96
97 static irqreturn_t ec_irq_thread(int irq, void *data)
98 {
99         struct chromeos_ec_device *ec_dev = data;
100
101         if (device_may_wakeup(ec_dev->dev))
102                 pm_wakeup_event(ec_dev->dev, 0);
103
104         blocking_notifier_call_chain(&ec_dev->event_notifier, 1, ec_dev);
105
106         return IRQ_HANDLED;
107 }
108
109 static int __devinit check_protocol_version(struct chromeos_ec_device *ec)
110 {
111         int ret;
112         struct ec_response_proto_version data;
113
114         ret = ec->command_recv(ec, EC_CMD_PROTO_VERSION, &data, sizeof(data));
115         if (ret < 0)
116                 return ret;
117         dev_info(ec->dev, "protocol version: %d\n", data.version);
118         if (data.version != EC_PROTO_VERSION)
119                 return -EPROTONOSUPPORT;
120
121         return 0;
122 }
123
124 static struct mfd_cell cros_devs[] = {
125         {
126                 .name = "mkbp",
127                 .id = 1,
128         },
129         {
130                 .name = "cros_ec-fw",
131                 .id = 2,
132         },
133 };
134
135 int __devinit cros_ec_register(struct chromeos_ec_device *ec_dev)
136 {
137         struct device *dev = ec_dev->dev;
138         int err = 0;
139         struct device_node *node;
140         int id = 0;
141
142         BLOCKING_INIT_NOTIFIER_HEAD(&ec_dev->event_notifier);
143         BLOCKING_INIT_NOTIFIER_HEAD(&ec_dev->wake_notifier);
144
145         ec_dev->command_send = cros_ec_command_send;
146         ec_dev->command_recv = cros_ec_command_recv;
147         ec_dev->command_sendrecv = cros_ec_command_sendrecv;
148
149         if (ec_dev->din_size) {
150                 ec_dev->din = kmalloc(ec_dev->din_size, GFP_KERNEL);
151                 if (!ec_dev->din) {
152                         err = -ENOMEM;
153                         dev_err(dev, "cannot allocate din\n");
154                         goto fail_din;
155                 }
156         }
157         if (ec_dev->dout_size) {
158                 ec_dev->dout = kmalloc(ec_dev->dout_size, GFP_KERNEL);
159                 if (!ec_dev->dout) {
160                         err = -ENOMEM;
161                         dev_err(dev, "cannot allocate dout\n");
162                         goto fail_dout;
163                 }
164         }
165
166         if (!ec_dev->irq) {
167                 dev_dbg(dev, "no valid IRQ: %d\n", ec_dev->irq);
168                 goto fail_irq;
169         }
170
171         err = request_threaded_irq(ec_dev->irq, NULL, ec_irq_thread,
172                                    IRQF_TRIGGER_LOW | IRQF_ONESHOT,
173                                    "chromeos-ec", ec_dev);
174         if (err) {
175                 dev_err(dev, "request irq %d: error %d\n", ec_dev->irq, err);
176                 goto fail_irq;
177         }
178
179         err = check_protocol_version(ec_dev);
180         if (err < 0) {
181                 dev_err(dev, "protocol version check failed: %d\n", err);
182                 goto fail_proto;
183         }
184
185         err = mfd_add_devices(dev, 0, cros_devs,
186                               ARRAY_SIZE(cros_devs),
187                               NULL, ec_dev->irq);
188         if (err)
189                 goto fail_mfd;
190
191         /* adding sub-devices declared in the device tree */
192         for_each_child_of_node(dev->of_node, node) {
193                 char name[128];
194                 struct mfd_cell cell = {
195                         .id = id++,
196                         .name = name,
197                 };
198
199                 dev_dbg(dev, "adding MFD sub-device %s\n", node->name);
200                 if (of_modalias_node(node, name, sizeof(name)) < 0) {
201                         dev_err(dev, "modalias failure on %s\n",
202                                 node->full_name);
203                         continue;
204                 }
205
206                 err = mfd_add_devices(dev, 0x10, &cell, 1, NULL, 0);
207                 if (err)
208                         dev_err(dev, "fail to add %s\n", node->full_name);
209         }
210
211         dev_info(dev, "Chrome EC (%s)\n", ec_dev->name);
212
213         return 0;
214
215 fail_mfd:
216 fail_proto:
217         free_irq(ec_dev->irq, ec_dev);
218 fail_irq:
219         kfree(ec_dev->dout);
220 fail_dout:
221         kfree(ec_dev->din);
222 fail_din:
223         return err;
224 }
225
226 int __devinit cros_ec_remove(struct chromeos_ec_device *ec_dev)
227 {
228         mfd_remove_devices(ec_dev->dev);
229         free_irq(ec_dev->irq, ec_dev);
230         kfree(ec_dev->dout);
231         kfree(ec_dev->din);
232
233         return 0;
234 }
235
236 #ifdef CONFIG_PM_SLEEP
237 int cros_ec_suspend(struct chromeos_ec_device *ec_dev)
238 {
239         struct device *dev = ec_dev->dev;
240
241         if (device_may_wakeup(dev))
242                 ec_dev->wake_enabled = !enable_irq_wake(ec_dev->irq);
243
244         disable_irq(ec_dev->irq);
245
246         return 0;
247 }
248
249 int cros_ec_resume(struct chromeos_ec_device *ec_dev)
250 {
251         /*
252          * When the EC is not a wake source, then it could not have caused the
253          * resume, so we should do the resume processing. This may clear the
254          * EC's key scan buffer, for example. If the EC is a wake source (e.g.
255          * the lid is open and the user might press a key to wake) then we
256          * don't want to do resume processing (key scan buffer should be
257          * preserved).
258          */
259         if (!ec_dev->wake_enabled)
260                 blocking_notifier_call_chain(&ec_dev->wake_notifier, 1, ec_dev);
261         enable_irq(ec_dev->irq);
262
263         if (ec_dev->wake_enabled) {
264                 disable_irq_wake(ec_dev->irq);
265                 ec_dev->wake_enabled = 0;
266         }
267
268         return 0;
269 }
270 #endif