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