xref: /openbmc/linux/drivers/staging/nvec/nvec.c (revision 6dca320c)
1 /*
2  * NVEC: NVIDIA compliant embedded controller interface
3  *
4  * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
5  *
6  * Authors:  Pierre-Hugues Husson <phhusson@free.fr>
7  *           Ilya Petrov <ilya.muromec@gmail.com>
8  *           Marc Dietrich <marvin24@gmx.de>
9  *
10  * This file is subject to the terms and conditions of the GNU General Public
11  * License.  See the file "COPYING" in the main directory of this archive
12  * for more details.
13  *
14  */
15 
16 /* #define DEBUG */
17 
18 #include <asm/irq.h>
19 
20 #include <linux/completion.h>
21 #include <linux/interrupt.h>
22 #include <linux/io.h>
23 #include <linux/irq.h>
24 #include <linux/slab.h>
25 #include <linux/gpio.h>
26 #include <linux/serio.h>
27 #include <linux/delay.h>
28 #include <linux/input.h>
29 #include <linux/workqueue.h>
30 #include <linux/clk.h>
31 
32 #include <linux/semaphore.h>
33 #include <linux/list.h>
34 #include <linux/notifier.h>
35 #include <linux/platform_device.h>
36 #include <linux/mfd/core.h>
37 
38 #include <mach/iomap.h>
39 #include <mach/clk.h>
40 
41 #include "nvec.h"
42 
43 static const unsigned char EC_DISABLE_EVENT_REPORTING[3] = "\x04\x00\x00";
44 static const unsigned char EC_ENABLE_EVENT_REPORTING[3]  = "\x04\x00\x01";
45 static const unsigned char EC_GET_FIRMWARE_VERSION[2]    = "\x07\x15";
46 
47 static struct nvec_chip *nvec_power_handle;
48 
49 static struct mfd_cell nvec_devices[] = {
50 	{
51 		.name = "nvec-kbd",
52 		.id = 1,
53 	},
54 	{
55 		.name = "nvec-mouse",
56 		.id = 1,
57 	},
58 	{
59 		.name = "nvec-power",
60 		.id = 1,
61 	},
62 	{
63 		.name = "nvec-power",
64 		.id = 2,
65 	},
66 };
67 
68 int nvec_register_notifier(struct nvec_chip *nvec, struct notifier_block *nb,
69 			   unsigned int events)
70 {
71 	return atomic_notifier_chain_register(&nvec->notifier_list, nb);
72 }
73 EXPORT_SYMBOL_GPL(nvec_register_notifier);
74 
75 static int nvec_status_notifier(struct notifier_block *nb,
76 				unsigned long event_type, void *data)
77 {
78 	unsigned char *msg = (unsigned char *)data;
79 
80 	if (event_type != NVEC_CNTL)
81 		return NOTIFY_DONE;
82 
83 	printk(KERN_WARNING "unhandled msg type %ld\n", event_type);
84 	print_hex_dump(KERN_WARNING, "payload: ", DUMP_PREFIX_NONE, 16, 1,
85 		msg, msg[1] + 2, true);
86 
87 	return NOTIFY_OK;
88 }
89 
90 void nvec_write_async(struct nvec_chip *nvec, const unsigned char *data,
91 			short size)
92 {
93 	struct nvec_msg *msg = kzalloc(sizeof(struct nvec_msg), GFP_NOWAIT);
94 
95 	msg->data = kzalloc(size, GFP_NOWAIT);
96 	msg->data[0] = size;
97 	memcpy(msg->data + 1, data, size);
98 	msg->size = size + 1;
99 	msg->pos = 0;
100 	INIT_LIST_HEAD(&msg->node);
101 
102 	list_add_tail(&msg->node, &nvec->tx_data);
103 
104 	gpio_set_value(nvec->gpio, 0);
105 }
106 EXPORT_SYMBOL(nvec_write_async);
107 
108 static void nvec_request_master(struct work_struct *work)
109 {
110 	struct nvec_chip *nvec = container_of(work, struct nvec_chip, tx_work);
111 
112 	if (!list_empty(&nvec->tx_data))
113 		gpio_set_value(nvec->gpio, 0);
114 }
115 
116 static int parse_msg(struct nvec_chip *nvec, struct nvec_msg *msg)
117 {
118 	if ((msg->data[0] & 1 << 7) == 0 && msg->data[3]) {
119 		dev_err(nvec->dev, "ec responded %02x %02x %02x %02x\n",
120 			msg->data[0], msg->data[1], msg->data[2], msg->data[3]);
121 		return -EINVAL;
122 	}
123 
124 	if ((msg->data[0] >> 7) == 1 && (msg->data[0] & 0x0f) == 5)
125 		print_hex_dump(KERN_WARNING, "ec system event ",
126 				DUMP_PREFIX_NONE, 16, 1, msg->data,
127 				msg->data[1] + 2, true);
128 
129 	atomic_notifier_call_chain(&nvec->notifier_list, msg->data[0] & 0x8f,
130 				   msg->data);
131 
132 	return 0;
133 }
134 
135 static struct nvec_msg *nvec_write_sync(struct nvec_chip *nvec,
136 					const unsigned char *data, short size)
137 {
138 	down(&nvec->sync_write_mutex);
139 
140 	nvec->sync_write_pending = (data[1] << 8) + data[0];
141 	nvec_write_async(nvec, data, size);
142 
143 	dev_dbg(nvec->dev, "nvec_sync_write: 0x%04x\n",
144 		nvec->sync_write_pending);
145 	wait_for_completion(&nvec->sync_write);
146 	dev_dbg(nvec->dev, "nvec_sync_write: pong!\n");
147 
148 	up(&nvec->sync_write_mutex);
149 
150 	return nvec->last_sync_msg;
151 }
152 
153 /* RX worker */
154 static void nvec_dispatch(struct work_struct *work)
155 {
156 	struct nvec_chip *nvec = container_of(work, struct nvec_chip, rx_work);
157 	struct nvec_msg *msg;
158 
159 	while (!list_empty(&nvec->rx_data)) {
160 		msg = list_first_entry(&nvec->rx_data, struct nvec_msg, node);
161 		list_del_init(&msg->node);
162 
163 		if (nvec->sync_write_pending ==
164 		    (msg->data[2] << 8) + msg->data[0]) {
165 			dev_dbg(nvec->dev, "sync write completed!\n");
166 			nvec->sync_write_pending = 0;
167 			nvec->last_sync_msg = msg;
168 			complete(&nvec->sync_write);
169 		} else {
170 			parse_msg(nvec, msg);
171 			if ((!msg) || (!msg->data))
172 				dev_warn(nvec->dev,
173 					"attempt access zero pointer\n");
174 			else {
175 				kfree(msg->data);
176 				kfree(msg);
177 			}
178 		}
179 	}
180 }
181 
182 static irqreturn_t nvec_interrupt(int irq, void *dev)
183 {
184 	unsigned long status;
185 	unsigned long received;
186 	unsigned char to_send;
187 	struct nvec_msg *msg;
188 	struct nvec_chip *nvec = (struct nvec_chip *)dev;
189 	void __iomem *base = nvec->base;
190 
191 	status = readl(base + I2C_SL_STATUS);
192 
193 	if (!(status & I2C_SL_IRQ)) {
194 		dev_warn(nvec->dev, "nvec Spurious IRQ\n");
195 		goto handled;
196 	}
197 	if (status & END_TRANS && !(status & RCVD)) {
198 		nvec->state = NVEC_WAIT;
199 		if (nvec->rx->size > 1) {
200 			list_add_tail(&nvec->rx->node, &nvec->rx_data);
201 			schedule_work(&nvec->rx_work);
202 		} else {
203 			kfree(nvec->rx->data);
204 			kfree(nvec->rx);
205 		}
206 		return IRQ_HANDLED;
207 	} else if (status & RNW) {
208 		if (status & RCVD)
209 			udelay(3);
210 
211 		if (status & RCVD)
212 			nvec->state = NVEC_WRITE;
213 
214 		if (list_empty(&nvec->tx_data)) {
215 			dev_err(nvec->dev, "nvec empty tx - sending no-op\n");
216 			to_send = 0x8a;
217 			nvec_write_async(nvec, "\x07\x02", 2);
218 		} else {
219 			msg =
220 			    list_first_entry(&nvec->tx_data, struct nvec_msg,
221 					     node);
222 			if (msg->pos < msg->size) {
223 				to_send = msg->data[msg->pos];
224 				msg->pos++;
225 			} else {
226 				dev_err(nvec->dev, "nvec crap! %d\n",
227 					msg->size);
228 				to_send = 0x01;
229 			}
230 
231 			if (msg->pos >= msg->size) {
232 				list_del_init(&msg->node);
233 				kfree(msg->data);
234 				kfree(msg);
235 				schedule_work(&nvec->tx_work);
236 				nvec->state = NVEC_WAIT;
237 			}
238 		}
239 		writel(to_send, base + I2C_SL_RCVD);
240 
241 		gpio_set_value(nvec->gpio, 1);
242 
243 		dev_dbg(nvec->dev, "nvec sent %x\n", to_send);
244 
245 		goto handled;
246 	} else {
247 		received = readl(base + I2C_SL_RCVD);
248 
249 		if (status & RCVD) {
250 			writel(0, base + I2C_SL_RCVD);
251 			goto handled;
252 		}
253 
254 		if (nvec->state == NVEC_WAIT) {
255 			nvec->state = NVEC_READ;
256 			msg = kzalloc(sizeof(struct nvec_msg), GFP_NOWAIT);
257 			msg->data = kzalloc(32, GFP_NOWAIT);
258 			INIT_LIST_HEAD(&msg->node);
259 			nvec->rx = msg;
260 		} else
261 			msg = nvec->rx;
262 
263 		BUG_ON(msg->pos > 32);
264 
265 		msg->data[msg->pos] = received;
266 		msg->pos++;
267 		msg->size = msg->pos;
268 		dev_dbg(nvec->dev, "Got %02lx from Master (pos: %d)!\n",
269 			received, msg->pos);
270 	}
271 handled:
272 	return IRQ_HANDLED;
273 }
274 
275 static void tegra_init_i2c_slave(struct nvec_chip *nvec)
276 {
277 	u32 val;
278 
279 	clk_enable(nvec->i2c_clk);
280 
281 	tegra_periph_reset_assert(nvec->i2c_clk);
282 	udelay(2);
283 	tegra_periph_reset_deassert(nvec->i2c_clk);
284 
285 	val = I2C_CNFG_NEW_MASTER_SFM | I2C_CNFG_PACKET_MODE_EN |
286 	    (0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT);
287 	writel(val, nvec->base + I2C_CNFG);
288 
289 	clk_set_rate(nvec->i2c_clk, 8 * 80000);
290 
291 	writel(I2C_SL_NEWL, nvec->base + I2C_SL_CNFG);
292 	writel(0x1E, nvec->base + I2C_SL_DELAY_COUNT);
293 
294 	writel(nvec->i2c_addr>>1, nvec->base + I2C_SL_ADDR1);
295 	writel(0, nvec->base + I2C_SL_ADDR2);
296 
297 	enable_irq(nvec->irq);
298 
299 	clk_disable(nvec->i2c_clk);
300 }
301 
302 static void nvec_disable_i2c_slave(struct nvec_chip *nvec)
303 {
304 	disable_irq(nvec->irq);
305 	writel(I2C_SL_NEWL | I2C_SL_NACK, nvec->base + I2C_SL_CNFG);
306 	clk_disable(nvec->i2c_clk);
307 }
308 
309 static void nvec_power_off(void)
310 {
311 	nvec_write_async(nvec_power_handle, EC_DISABLE_EVENT_REPORTING, 3);
312 	nvec_write_async(nvec_power_handle, "\x04\x01", 2);
313 }
314 
315 static int __devinit tegra_nvec_probe(struct platform_device *pdev)
316 {
317 	int err, ret;
318 	struct clk *i2c_clk;
319 	struct nvec_platform_data *pdata = pdev->dev.platform_data;
320 	struct nvec_chip *nvec;
321 	struct nvec_msg *msg;
322 	struct resource *res;
323 	struct resource *iomem;
324 	void __iomem *base;
325 
326 	nvec = kzalloc(sizeof(struct nvec_chip), GFP_KERNEL);
327 	if (nvec == NULL) {
328 		dev_err(&pdev->dev, "failed to reserve memory\n");
329 		return -ENOMEM;
330 	}
331 	platform_set_drvdata(pdev, nvec);
332 	nvec->dev = &pdev->dev;
333 	nvec->gpio = pdata->gpio;
334 	nvec->i2c_addr = pdata->i2c_addr;
335 
336 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
337 	if (!res) {
338 		dev_err(&pdev->dev, "no mem resource?\n");
339 		return -ENODEV;
340 	}
341 
342 	iomem = request_mem_region(res->start, resource_size(res), pdev->name);
343 	if (!iomem) {
344 		dev_err(&pdev->dev, "I2C region already claimed\n");
345 		return -EBUSY;
346 	}
347 
348 	base = ioremap(iomem->start, resource_size(iomem));
349 	if (!base) {
350 		dev_err(&pdev->dev, "Can't ioremap I2C region\n");
351 		return -ENOMEM;
352 	}
353 
354 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
355 	if (!res) {
356 		dev_err(&pdev->dev, "no irq resource?\n");
357 		ret = -ENODEV;
358 		goto err_iounmap;
359 	}
360 
361 	i2c_clk = clk_get_sys("tegra-i2c.2", NULL);
362 	if (IS_ERR(i2c_clk)) {
363 		dev_err(nvec->dev, "failed to get controller clock\n");
364 		goto err_iounmap;
365 	}
366 
367 	nvec->base = base;
368 	nvec->irq = res->start;
369 	nvec->i2c_clk = i2c_clk;
370 
371 	/* Set the gpio to low when we've got something to say */
372 	err = gpio_request(nvec->gpio, "nvec gpio");
373 	if (err < 0)
374 		dev_err(nvec->dev, "couldn't request gpio\n");
375 
376 	ATOMIC_INIT_NOTIFIER_HEAD(&nvec->notifier_list);
377 
378 	init_completion(&nvec->sync_write);
379 	sema_init(&nvec->sync_write_mutex, 1);
380 	INIT_LIST_HEAD(&nvec->tx_data);
381 	INIT_LIST_HEAD(&nvec->rx_data);
382 	INIT_WORK(&nvec->rx_work, nvec_dispatch);
383 	INIT_WORK(&nvec->tx_work, nvec_request_master);
384 
385 	err = request_irq(nvec->irq, nvec_interrupt, 0, "nvec", nvec);
386 	if (err) {
387 		dev_err(nvec->dev, "couldn't request irq\n");
388 		goto failed;
389 	}
390 	disable_irq(nvec->irq);
391 
392 	tegra_init_i2c_slave(nvec);
393 
394 	clk_enable(i2c_clk);
395 
396 	gpio_direction_output(nvec->gpio, 1);
397 	gpio_set_value(nvec->gpio, 1);
398 
399 	/* enable event reporting */
400 	nvec_write_async(nvec, EC_ENABLE_EVENT_REPORTING,
401 			 sizeof(EC_ENABLE_EVENT_REPORTING));
402 
403 	nvec->nvec_status_notifier.notifier_call = nvec_status_notifier;
404 	nvec_register_notifier(nvec, &nvec->nvec_status_notifier, 0);
405 
406 	nvec_power_handle = nvec;
407 	pm_power_off = nvec_power_off;
408 
409 	/* Get Firmware Version */
410 	msg = nvec_write_sync(nvec, EC_GET_FIRMWARE_VERSION,
411 			      sizeof(EC_GET_FIRMWARE_VERSION));
412 
413 	dev_warn(nvec->dev, "ec firmware version %02x.%02x.%02x / %02x\n",
414 		 msg->data[4], msg->data[5], msg->data[6], msg->data[7]);
415 
416 	kfree(msg->data);
417 	kfree(msg);
418 
419 	ret = mfd_add_devices(nvec->dev, -1, nvec_devices,
420 			      ARRAY_SIZE(nvec_devices), base, 0);
421 	if (ret)
422 		dev_err(nvec->dev, "error adding subdevices\n");
423 
424 	/* unmute speakers? */
425 	nvec_write_async(nvec, "\x0d\x10\x59\x95", 4);
426 
427 	/* enable lid switch event */
428 	nvec_write_async(nvec, "\x01\x01\x01\x00\x00\x02\x00", 7);
429 
430 	/* enable power button event */
431 	nvec_write_async(nvec, "\x01\x01\x01\x00\x00\x80\x00", 7);
432 
433 	return 0;
434 
435 err_iounmap:
436 	iounmap(base);
437 failed:
438 	kfree(nvec);
439 	return -ENOMEM;
440 }
441 
442 static int __devexit tegra_nvec_remove(struct platform_device *pdev)
443 {
444 	struct nvec_chip *nvec = platform_get_drvdata(pdev);
445 
446 	nvec_write_async(nvec, EC_DISABLE_EVENT_REPORTING, 3);
447 	mfd_remove_devices(nvec->dev);
448 	free_irq(nvec->irq, &nvec_interrupt);
449 	iounmap(nvec->base);
450 	gpio_free(nvec->gpio);
451 	kfree(nvec);
452 
453 	return 0;
454 }
455 
456 #ifdef CONFIG_PM
457 
458 static int tegra_nvec_suspend(struct platform_device *pdev, pm_message_t state)
459 {
460 	struct nvec_chip *nvec = platform_get_drvdata(pdev);
461 
462 	dev_dbg(nvec->dev, "suspending\n");
463 	nvec_write_async(nvec, EC_DISABLE_EVENT_REPORTING, 3);
464 	nvec_write_async(nvec, "\x04\x02", 2);
465 	nvec_disable_i2c_slave(nvec);
466 
467 	return 0;
468 }
469 
470 static int tegra_nvec_resume(struct platform_device *pdev)
471 {
472 	struct nvec_chip *nvec = platform_get_drvdata(pdev);
473 
474 	dev_dbg(nvec->dev, "resuming\n");
475 	tegra_init_i2c_slave(nvec);
476 	nvec_write_async(nvec, EC_ENABLE_EVENT_REPORTING, 3);
477 
478 	return 0;
479 }
480 
481 #else
482 #define tegra_nvec_suspend NULL
483 #define tegra_nvec_resume NULL
484 #endif
485 
486 static struct platform_driver nvec_device_driver = {
487 	.probe   = tegra_nvec_probe,
488 	.remove  = __devexit_p(tegra_nvec_remove),
489 	.suspend = tegra_nvec_suspend,
490 	.resume  = tegra_nvec_resume,
491 	.driver  = {
492 		.name = "nvec",
493 		.owner = THIS_MODULE,
494 	}
495 };
496 
497 static int __init tegra_nvec_init(void)
498 {
499 	return platform_driver_register(&nvec_device_driver);
500 }
501 
502 module_init(tegra_nvec_init);
503 
504 MODULE_ALIAS("platform:nvec");
505 MODULE_DESCRIPTION("NVIDIA compliant embedded controller interface");
506 MODULE_AUTHOR("Marc Dietrich <marvin24@gmx.de>");
507 MODULE_LICENSE("GPL");
508