1 /*
2  * Support for OLPC XO-1 System Control Interrupts (SCI)
3  *
4  * Copyright (C) 2010 One Laptop per Child
5  * Copyright (C) 2006 Red Hat, Inc.
6  * Copyright (C) 2006 Advanced Micro Devices, Inc.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  */
13 
14 #include <linux/cs5535.h>
15 #include <linux/device.h>
16 #include <linux/gpio.h>
17 #include <linux/input.h>
18 #include <linux/interrupt.h>
19 #include <linux/platform_device.h>
20 #include <linux/pm.h>
21 #include <linux/mfd/core.h>
22 #include <linux/suspend.h>
23 #include <linux/workqueue.h>
24 
25 #include <asm/io.h>
26 #include <asm/msr.h>
27 #include <asm/olpc.h>
28 
29 #define DRV_NAME	"olpc-xo1-sci"
30 #define PFX		DRV_NAME ": "
31 
32 static unsigned long acpi_base;
33 static struct input_dev *power_button_idev;
34 static struct input_dev *ebook_switch_idev;
35 
36 static int sci_irq;
37 
38 /* Report current ebook switch state through input layer */
39 static void send_ebook_state(void)
40 {
41 	unsigned char state;
42 
43 	if (olpc_ec_cmd(EC_READ_EB_MODE, NULL, 0, &state, 1)) {
44 		pr_err(PFX "failed to get ebook state\n");
45 		return;
46 	}
47 
48 	input_report_switch(ebook_switch_idev, SW_TABLET_MODE, state);
49 	input_sync(ebook_switch_idev);
50 }
51 
52 /*
53  * Process all items in the EC's SCI queue.
54  *
55  * This is handled in a workqueue because olpc_ec_cmd can be slow (and
56  * can even timeout).
57  *
58  * If propagate_events is false, the queue is drained without events being
59  * generated for the interrupts.
60  */
61 static void process_sci_queue(bool propagate_events)
62 {
63 	int r;
64 	u16 data;
65 
66 	do {
67 		r = olpc_ec_sci_query(&data);
68 		if (r || !data)
69 			break;
70 
71 		pr_debug(PFX "SCI 0x%x received\n", data);
72 
73 		if (data == EC_SCI_SRC_EBOOK && propagate_events)
74 			send_ebook_state();
75 	} while (data);
76 
77 	if (r)
78 		pr_err(PFX "Failed to clear SCI queue");
79 }
80 
81 static void process_sci_queue_work(struct work_struct *work)
82 {
83 	process_sci_queue(true);
84 }
85 
86 static DECLARE_WORK(sci_work, process_sci_queue_work);
87 
88 static irqreturn_t xo1_sci_intr(int irq, void *dev_id)
89 {
90 	struct platform_device *pdev = dev_id;
91 	u32 sts;
92 	u32 gpe;
93 
94 	sts = inl(acpi_base + CS5536_PM1_STS);
95 	outl(sts | 0xffff, acpi_base + CS5536_PM1_STS);
96 
97 	gpe = inl(acpi_base + CS5536_PM_GPE0_STS);
98 	outl(0xffffffff, acpi_base + CS5536_PM_GPE0_STS);
99 
100 	dev_dbg(&pdev->dev, "sts %x gpe %x\n", sts, gpe);
101 
102 	if (sts & CS5536_PWRBTN_FLAG && !(sts & CS5536_WAK_FLAG)) {
103 		input_report_key(power_button_idev, KEY_POWER, 1);
104 		input_sync(power_button_idev);
105 		input_report_key(power_button_idev, KEY_POWER, 0);
106 		input_sync(power_button_idev);
107 	}
108 
109 	if (gpe & CS5536_GPIOM7_PME_FLAG) { /* EC GPIO */
110 		cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_NEGATIVE_EDGE_STS);
111 		schedule_work(&sci_work);
112 	}
113 
114 	return IRQ_HANDLED;
115 }
116 
117 static int xo1_sci_suspend(struct platform_device *pdev, pm_message_t state)
118 {
119 	if (device_may_wakeup(&power_button_idev->dev))
120 		olpc_xo1_pm_wakeup_set(CS5536_PM_PWRBTN);
121 	else
122 		olpc_xo1_pm_wakeup_clear(CS5536_PM_PWRBTN);
123 
124 	if (device_may_wakeup(&ebook_switch_idev->dev))
125 		olpc_ec_wakeup_set(EC_SCI_SRC_EBOOK);
126 	else
127 		olpc_ec_wakeup_clear(EC_SCI_SRC_EBOOK);
128 
129 	return 0;
130 }
131 
132 static int xo1_sci_resume(struct platform_device *pdev)
133 {
134 	/* Enable all EC events */
135 	olpc_ec_mask_write(EC_SCI_SRC_ALL);
136 	return 0;
137 }
138 
139 static int __devinit setup_sci_interrupt(struct platform_device *pdev)
140 {
141 	u32 lo, hi;
142 	u32 sts;
143 	int r;
144 
145 	rdmsr(0x51400020, lo, hi);
146 	sci_irq = (lo >> 20) & 15;
147 
148 	if (sci_irq) {
149 		dev_info(&pdev->dev, "SCI is mapped to IRQ %d\n", sci_irq);
150 	} else {
151 		/* Zero means masked */
152 		dev_info(&pdev->dev, "SCI unmapped. Mapping to IRQ 3\n");
153 		sci_irq = 3;
154 		lo |= 0x00300000;
155 		wrmsrl(0x51400020, lo);
156 	}
157 
158 	/* Select level triggered in PIC */
159 	if (sci_irq < 8) {
160 		lo = inb(CS5536_PIC_INT_SEL1);
161 		lo |= 1 << sci_irq;
162 		outb(lo, CS5536_PIC_INT_SEL1);
163 	} else {
164 		lo = inb(CS5536_PIC_INT_SEL2);
165 		lo |= 1 << (sci_irq - 8);
166 		outb(lo, CS5536_PIC_INT_SEL2);
167 	}
168 
169 	/* Enable SCI from power button, and clear pending interrupts */
170 	sts = inl(acpi_base + CS5536_PM1_STS);
171 	outl((CS5536_PM_PWRBTN << 16) | 0xffff, acpi_base + CS5536_PM1_STS);
172 
173 	r = request_irq(sci_irq, xo1_sci_intr, 0, DRV_NAME, pdev);
174 	if (r)
175 		dev_err(&pdev->dev, "can't request interrupt\n");
176 
177 	return r;
178 }
179 
180 static int __devinit setup_ec_sci(void)
181 {
182 	int r;
183 
184 	r = gpio_request(OLPC_GPIO_ECSCI, "OLPC-ECSCI");
185 	if (r)
186 		return r;
187 
188 	gpio_direction_input(OLPC_GPIO_ECSCI);
189 
190 	/* Clear pending EC SCI events */
191 	cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_NEGATIVE_EDGE_STS);
192 	cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_POSITIVE_EDGE_STS);
193 
194 	/*
195 	 * Enable EC SCI events, and map them to both a PME and the SCI
196 	 * interrupt.
197 	 *
198 	 * Ordinarily, in addition to functioning as GPIOs, Geode GPIOs can
199 	 * be mapped to regular interrupts *or* Geode-specific Power
200 	 * Management Events (PMEs) - events that bring the system out of
201 	 * suspend. In this case, we want both of those things - the system
202 	 * wakeup, *and* the ability to get an interrupt when an event occurs.
203 	 *
204 	 * To achieve this, we map the GPIO to a PME, and then we use one
205 	 * of the many generic knobs on the CS5535 PIC to additionally map the
206 	 * PME to the regular SCI interrupt line.
207 	 */
208 	cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_EVENTS_ENABLE);
209 
210 	/* Set the SCI to cause a PME event on group 7 */
211 	cs5535_gpio_setup_event(OLPC_GPIO_ECSCI, 7, 1);
212 
213 	/* And have group 7 also fire the SCI interrupt */
214 	cs5535_pic_unreqz_select_high(7, sci_irq);
215 
216 	return 0;
217 }
218 
219 static void free_ec_sci(void)
220 {
221 	gpio_free(OLPC_GPIO_ECSCI);
222 }
223 
224 static int __devinit setup_power_button(struct platform_device *pdev)
225 {
226 	int r;
227 
228 	power_button_idev = input_allocate_device();
229 	if (!power_button_idev)
230 		return -ENOMEM;
231 
232 	power_button_idev->name = "Power Button";
233 	power_button_idev->phys = DRV_NAME "/input0";
234 	set_bit(EV_KEY, power_button_idev->evbit);
235 	set_bit(KEY_POWER, power_button_idev->keybit);
236 
237 	power_button_idev->dev.parent = &pdev->dev;
238 	device_init_wakeup(&power_button_idev->dev, 1);
239 
240 	r = input_register_device(power_button_idev);
241 	if (r) {
242 		dev_err(&pdev->dev, "failed to register power button: %d\n", r);
243 		input_free_device(power_button_idev);
244 	}
245 
246 	return r;
247 }
248 
249 static void free_power_button(void)
250 {
251 	input_unregister_device(power_button_idev);
252 	input_free_device(power_button_idev);
253 }
254 
255 static int __devinit setup_ebook_switch(struct platform_device *pdev)
256 {
257 	int r;
258 
259 	ebook_switch_idev = input_allocate_device();
260 	if (!ebook_switch_idev)
261 		return -ENOMEM;
262 
263 	ebook_switch_idev->name = "EBook Switch";
264 	ebook_switch_idev->phys = DRV_NAME "/input1";
265 	set_bit(EV_SW, ebook_switch_idev->evbit);
266 	set_bit(SW_TABLET_MODE, ebook_switch_idev->swbit);
267 
268 	ebook_switch_idev->dev.parent = &pdev->dev;
269 	device_set_wakeup_capable(&ebook_switch_idev->dev, true);
270 
271 	r = input_register_device(ebook_switch_idev);
272 	if (r) {
273 		dev_err(&pdev->dev, "failed to register ebook switch: %d\n", r);
274 		input_free_device(ebook_switch_idev);
275 	}
276 
277 	return r;
278 }
279 
280 static void free_ebook_switch(void)
281 {
282 	input_unregister_device(ebook_switch_idev);
283 	input_free_device(ebook_switch_idev);
284 }
285 
286 static int __devinit xo1_sci_probe(struct platform_device *pdev)
287 {
288 	struct resource *res;
289 	int r;
290 
291 	/* don't run on non-XOs */
292 	if (!machine_is_olpc())
293 		return -ENODEV;
294 
295 	r = mfd_cell_enable(pdev);
296 	if (r)
297 		return r;
298 
299 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
300 	if (!res) {
301 		dev_err(&pdev->dev, "can't fetch device resource info\n");
302 		return -EIO;
303 	}
304 	acpi_base = res->start;
305 
306 	r = setup_power_button(pdev);
307 	if (r)
308 		return r;
309 
310 	r = setup_ebook_switch(pdev);
311 	if (r)
312 		goto err_ebook;
313 
314 	r = setup_ec_sci();
315 	if (r)
316 		goto err_ecsci;
317 
318 	/* Enable PME generation for EC-generated events */
319 	outl(CS5536_GPIOM7_PME_EN, acpi_base + CS5536_PM_GPE0_EN);
320 
321 	/* Clear pending events */
322 	outl(0xffffffff, acpi_base + CS5536_PM_GPE0_STS);
323 	process_sci_queue(false);
324 
325 	/* Initial sync */
326 	send_ebook_state();
327 
328 	r = setup_sci_interrupt(pdev);
329 	if (r)
330 		goto err_sci;
331 
332 	/* Enable all EC events */
333 	olpc_ec_mask_write(EC_SCI_SRC_ALL);
334 
335 	return r;
336 
337 err_sci:
338 	free_ec_sci();
339 err_ecsci:
340 	free_ebook_switch();
341 err_ebook:
342 	free_power_button();
343 	return r;
344 }
345 
346 static int __devexit xo1_sci_remove(struct platform_device *pdev)
347 {
348 	mfd_cell_disable(pdev);
349 	free_irq(sci_irq, pdev);
350 	cancel_work_sync(&sci_work);
351 	free_ec_sci();
352 	free_ebook_switch();
353 	free_power_button();
354 	acpi_base = 0;
355 	return 0;
356 }
357 
358 static struct platform_driver xo1_sci_driver = {
359 	.driver = {
360 		.name = "olpc-xo1-sci-acpi",
361 	},
362 	.probe = xo1_sci_probe,
363 	.remove = __devexit_p(xo1_sci_remove),
364 	.suspend = xo1_sci_suspend,
365 	.resume = xo1_sci_resume,
366 };
367 
368 static int __init xo1_sci_init(void)
369 {
370 	return platform_driver_register(&xo1_sci_driver);
371 }
372 arch_initcall(xo1_sci_init);
373