Root/target/linux/omap24xx/patches-2.6.38/500-cbus.patch

1---
2 arch/arm/Kconfig | 4
3 drivers/Makefile | 2
4 drivers/cbus/Kconfig | 89 ++++
5 drivers/cbus/Makefile | 14
6 drivers/cbus/cbus.c | 309 ++++++++++++++++
7 drivers/cbus/cbus.h | 36 +
8 drivers/cbus/retu-headset.c | 356 ++++++++++++++++++
9 drivers/cbus/retu-pwrbutton.c | 118 ++++++
10 drivers/cbus/retu-rtc.c | 477 ++++++++++++++++++++++++
11 drivers/cbus/retu-user.c | 424 ++++++++++++++++++++++
12 drivers/cbus/retu-wdt.c | 387 ++++++++++++++++++++
13 drivers/cbus/retu.c | 468 ++++++++++++++++++++++++
14 drivers/cbus/retu.h | 77 ++++
15 drivers/cbus/tahvo-usb.c | 788 +++++++++++++++++++++++++++++++++++++++++
16 drivers/cbus/tahvo-user.c | 406 +++++++++++++++++++++
17 drivers/cbus/tahvo.c | 443 +++++++++++++++++++++++
18 drivers/cbus/tahvo.h | 61 +++
19 drivers/cbus/user_retu_tahvo.h | 75 +++
20 18 files changed, 4533 insertions(+), 1 deletion(-)
21
22--- /dev/null
23+++ b/drivers/cbus/cbus.c
24@@ -0,0 +1,332 @@
25+/*
26+ * drivers/cbus/cbus.c
27+ *
28+ * Support functions for CBUS serial protocol
29+ *
30+ * Copyright (C) 2004-2010 Nokia Corporation
31+ * Contact: Felipe Balbi <felipe.balbi@nokia.com>
32+ *
33+ * Written by Juha Yrjölä <juha.yrjola@nokia.com>,
34+ * David Weinehall <david.weinehall@nokia.com>, and
35+ * Mikko Ylinen <mikko.k.ylinen@nokia.com>
36+ *
37+ * Several updates and cleanups by Felipe Balbi <felipe.balbi@nokia.com>
38+ *
39+ * This file is subject to the terms and conditions of the GNU General
40+ * Public License. See the file "COPYING" in the main directory of this
41+ * archive for more details.
42+ *
43+ * This program is distributed in the hope that it will be useful,
44+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
45+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46+ * GNU General Public License for more details.
47+ *
48+ * You should have received a copy of the GNU General Public License
49+ * along with this program; if not, write to the Free Software
50+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
51+ */
52+
53+#include <linux/device.h>
54+#include <linux/init.h>
55+#include <linux/kernel.h>
56+#include <linux/slab.h>
57+#include <linux/spinlock.h>
58+#include <linux/gpio.h>
59+#include <linux/platform_device.h>
60+
61+#include <plat/cbus.h>
62+
63+#include "cbus.h"
64+
65+#define CBUS_XFER_READ 1
66+#define CBUS_XFER_WRITE 0
67+
68+struct cbus_host {
69+ /* host lock */
70+ spinlock_t lock;
71+
72+ struct device *dev;
73+
74+ int clk_gpio;
75+ int dat_gpio;
76+ int sel_gpio;
77+};
78+
79+static struct cbus_host *cbus_host;
80+
81+/**
82+ * cbus_send_bit - sends one bit over the bus
83+ * @host: the host we're using
84+ * @bit: one bit of information to send
85+ * @input: whether to set data pin as input after sending
86+ */
87+static int cbus_send_bit(struct cbus_host *host, unsigned bit,
88+ unsigned input)
89+{
90+ int ret = 0;
91+
92+ gpio_set_value(host->dat_gpio, bit ? 1 : 0);
93+ gpio_set_value(host->clk_gpio, 1);
94+
95+ /* The data bit is read on the rising edge of CLK */
96+ if (input)
97+ ret = gpio_direction_input(host->dat_gpio);
98+
99+ gpio_set_value(host->clk_gpio, 0);
100+
101+ return ret;
102+}
103+
104+/**
105+ * cbus_send_data - sends @len amount of data over the bus
106+ * @host: the host we're using
107+ * @data: the data to send
108+ * @len: size of the transfer
109+ * @input: whether to set data pin as input after sending
110+ */
111+static int cbus_send_data(struct cbus_host *host, unsigned data, unsigned len,
112+ unsigned input)
113+{
114+ int ret = 0;
115+ int i;
116+
117+ for (i = len; i > 0; i--) {
118+ ret = cbus_send_bit(host, data & (1 << (i - 1)),
119+ input && (i == 1));
120+ if (ret < 0)
121+ goto out;
122+ }
123+
124+out:
125+ return ret;
126+}
127+
128+/**
129+ * cbus_receive_bit - receives one bit from the bus
130+ * @host: the host we're using
131+ */
132+static int cbus_receive_bit(struct cbus_host *host)
133+{
134+ int ret;
135+
136+ gpio_set_value(host->clk_gpio, 1);
137+ ret = gpio_get_value(host->dat_gpio);
138+ if (ret < 0)
139+ goto out;
140+ gpio_set_value(host->clk_gpio, 0);
141+
142+out:
143+ return ret;
144+}
145+
146+/**
147+ * cbus_receive_data - receives @len data from the bus
148+ * @host: the host we're using
149+ * @len: the length of data to receive
150+ */
151+static int cbus_receive_data(struct cbus_host *host, unsigned len)
152+{
153+ int ret = 0;
154+ int i;
155+
156+ for (i = 16; i > 0; i--) {
157+ int bit = cbus_receive_bit(host);
158+
159+ if (bit < 0)
160+ goto out;
161+
162+ if (bit)
163+ ret |= 1 << (i - 1);
164+ }
165+
166+out:
167+ return ret;
168+}
169+
170+/**
171+ * cbus_transfer - transfers data over the bus
172+ * @host: the host we're using
173+ * @rw: read/write flag
174+ * @dev: device address
175+ * @reg: register address
176+ * @data: if @rw == 0 data to send otherwise 0
177+ */
178+static int cbus_transfer(struct cbus_host *host, unsigned rw, unsigned dev,
179+ unsigned reg, unsigned data)
180+{
181+ unsigned long flags;
182+ int input = 0;
183+ int ret = 0;
184+
185+ /* We don't want interrupts disturbing our transfer */
186+ spin_lock_irqsave(&host->lock, flags);
187+
188+ /* Reset state and start of transfer, SEL stays down during transfer */
189+ gpio_set_value(host->sel_gpio, 0);
190+
191+ /* Set the DAT pin to output */
192+ gpio_direction_output(host->dat_gpio, 1);
193+
194+ /* Send the device address */
195+ ret = cbus_send_data(host, dev, 3, 0);
196+ if (ret < 0) {
197+ dev_dbg(host->dev, "failed sending device addr\n");
198+ goto out;
199+ }
200+
201+ /* Send the rw flag */
202+ ret = cbus_send_bit(host, rw, 0);
203+ if (ret < 0) {
204+ dev_dbg(host->dev, "failed sending read/write flag\n");
205+ goto out;
206+ }
207+
208+ /* Send the register address */
209+ if (rw)
210+ input = true;
211+
212+ ret = cbus_send_data(host, reg, 5, input);
213+ if (ret < 0) {
214+ dev_dbg(host->dev, "failed sending register addr\n");
215+ goto out;
216+ }
217+
218+ if (!rw) {
219+ ret = cbus_send_data(host, data, 16, 0);
220+ if (ret < 0) {
221+ dev_dbg(host->dev, "failed sending data\n");
222+ goto out;
223+ }
224+ } else {
225+ gpio_set_value(host->clk_gpio, 1);
226+
227+ ret = cbus_receive_data(host, 16);
228+ if (ret < 0) {
229+ dev_dbg(host->dev, "failed receiving data\n");
230+ goto out;
231+ }
232+ }
233+
234+ /* Indicate end of transfer, SEL goes up until next transfer */
235+ gpio_set_value(host->sel_gpio, 1);
236+ gpio_set_value(host->clk_gpio, 1);
237+ gpio_set_value(host->clk_gpio, 0);
238+
239+out:
240+ spin_unlock_irqrestore(&host->lock, flags);
241+
242+ return ret;
243+}
244+
245+/**
246+ * cbus_read_reg - reads a given register from the device
247+ * @dev: device address
248+ * @reg: register address
249+ */
250+int cbus_read_reg(unsigned dev, unsigned reg)
251+{
252+ return cbus_transfer(cbus_host, CBUS_XFER_READ, dev, reg, 0);
253+}
254+EXPORT_SYMBOL(cbus_read_reg);
255+
256+/**
257+ * cbus_write_reg - writes to a given register of the device
258+ * @dev: device address
259+ * @reg: register address
260+ * @val: data to be written to @reg
261+ */
262+int cbus_write_reg(unsigned dev, unsigned reg, unsigned val)
263+{
264+ return cbus_transfer(cbus_host, CBUS_XFER_WRITE, dev, reg, val);
265+}
266+EXPORT_SYMBOL(cbus_write_reg);
267+
268+static int __init cbus_bus_probe(struct platform_device *pdev)
269+{
270+ struct cbus_host *chost;
271+ struct cbus_host_platform_data *pdata = pdev->dev.platform_data;
272+ int ret;
273+
274+ chost = kzalloc(sizeof(*chost), GFP_KERNEL);
275+ if (chost == NULL)
276+ return -ENOMEM;
277+
278+ spin_lock_init(&chost->lock);
279+
280+ chost->clk_gpio = pdata->clk_gpio;
281+ chost->dat_gpio = pdata->dat_gpio;
282+ chost->sel_gpio = pdata->sel_gpio;
283+ chost->dev = &pdev->dev;
284+
285+ ret = gpio_request(chost->clk_gpio, "CBUS clk");
286+ if (ret < 0)
287+ goto exit1;
288+
289+ ret = gpio_request(chost->dat_gpio, "CBUS data");
290+ if (ret < 0)
291+ goto exit2;
292+
293+ ret = gpio_request(chost->sel_gpio, "CBUS sel");
294+ if (ret < 0)
295+ goto exit3;
296+
297+ gpio_direction_output(chost->clk_gpio, 0);
298+ gpio_direction_input(chost->dat_gpio);
299+ gpio_direction_output(chost->sel_gpio, 1);
300+
301+ gpio_set_value(chost->clk_gpio, 1);
302+ gpio_set_value(chost->clk_gpio, 0);
303+
304+ platform_set_drvdata(pdev, chost);
305+
306+ cbus_host = chost;
307+
308+ return 0;
309+exit3:
310+ gpio_free(chost->dat_gpio);
311+exit2:
312+ gpio_free(chost->clk_gpio);
313+exit1:
314+ kfree(chost);
315+
316+ return ret;
317+}
318+
319+static void __exit cbus_bus_remove(struct platform_device *pdev)
320+{
321+ struct cbus_host *chost = platform_get_drvdata(pdev);
322+
323+ gpio_free(chost->sel_gpio);
324+ gpio_free(chost->dat_gpio);
325+ gpio_free(chost->clk_gpio);
326+
327+ kfree(chost);
328+ cbus_host = NULL;
329+}
330+
331+static struct platform_driver cbus_driver = {
332+ .remove = __exit_p(cbus_bus_remove),
333+ .driver = {
334+ .name = "cbus",
335+ },
336+};
337+
338+static int __init cbus_bus_init(void)
339+{
340+ return platform_driver_probe(&cbus_driver, cbus_bus_probe);
341+}
342+subsys_initcall(cbus_bus_init);
343+
344+static void __exit cbus_bus_exit(void)
345+{
346+ platform_driver_unregister(&cbus_driver);
347+}
348+module_exit(cbus_bus_exit);
349+
350+MODULE_DESCRIPTION("CBUS serial protocol");
351+MODULE_LICENSE("GPL");
352+MODULE_AUTHOR("Juha Yrjölä");
353+MODULE_AUTHOR("David Weinehall");
354+MODULE_AUTHOR("Mikko Ylinen");
355+MODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>");
356+
357--- /dev/null
358+++ b/drivers/cbus/cbus.h
359@@ -0,0 +1,29 @@
360+/*
361+ * drivers/cbus/cbus.h
362+ *
363+ * Copyright (C) 2004, 2005 Nokia Corporation
364+ *
365+ * Written by Juha Yrjölä <juha.yrjola@nokia.com> and
366+ * David Weinehall <david.weinehall@nokia.com>
367+ *
368+ * This file is subject to the terms and conditions of the GNU General
369+ * Public License. See the file "COPYING" in the main directory of this
370+ * archive for more details.
371+ *
372+ * This program is distributed in the hope that it will be useful,
373+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
374+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
375+ * GNU General Public License for more details.
376+ *
377+ * You should have received a copy of the GNU General Public License
378+ * along with this program; if not, write to the Free Software
379+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
380+ */
381+
382+#ifndef __DRIVERS_CBUS_CBUS_H
383+#define __DRIVERS_CBUS_CBUS_H
384+
385+extern int cbus_read_reg(unsigned dev, unsigned reg);
386+extern int cbus_write_reg(unsigned dev, unsigned reg, unsigned val);
387+
388+#endif /* __DRIVERS_CBUS_CBUS_H */
389--- /dev/null
390+++ b/drivers/cbus/Kconfig
391@@ -0,0 +1,75 @@
392+#
393+# CBUS device configuration
394+#
395+
396+menu "CBUS support"
397+
398+config CBUS
399+ depends on ARCH_OMAP
400+ bool "CBUS support on OMAP"
401+ ---help---
402+ CBUS is a proprietary serial protocol by Nokia. It is mainly
403+ used for accessing Energy Management auxiliary chips.
404+
405+ If you want CBUS support, you should say Y here.
406+
407+config CBUS_TAHVO
408+ depends on CBUS
409+ bool "Support for Tahvo"
410+ ---help---
411+ Tahvo is a mixed signal ASIC with some system features
412+
413+ If you want Tahvo support, you should say Y here.
414+
415+config CBUS_TAHVO_USB
416+ depends on CBUS_TAHVO && USB
417+ tristate "Support for Tahvo USB transceiver"
418+ ---help---
419+ If you want Tahvo support for USB transceiver, say Y or M here.
420+
421+config CBUS_TAHVO_USB_HOST_BY_DEFAULT
422+ depends on CBUS_TAHVO_USB && USB_OTG
423+ boolean "Device in USB host mode by default"
424+ ---help---
425+ Say Y here, if you want the device to enter USB host mode
426+ by default on bootup.
427+
428+config CBUS_RETU
429+ depends on CBUS
430+ bool "Support for Retu"
431+ ---help---
432+ Retu is a mixed signal ASIC with some system features
433+
434+ If you want Retu support, you should say Y here.
435+
436+config CBUS_RETU_POWERBUTTON
437+ depends on CBUS_RETU
438+ bool "Support for Retu power button"
439+ ---help---
440+ The power button on Nokia 770 is connected to the Retu ASIC.
441+
442+ If you want support for the Retu power button, you should say Y here.
443+
444+config CBUS_RETU_RTC
445+ depends on CBUS_RETU && RTC_CLASS
446+ tristate "Support for Retu pseudo-RTC"
447+ ---help---
448+ Say Y here if you want support for the device that alleges to be an
449+ RTC in Retu. This will expose a sysfs interface for it.
450+
451+config CBUS_RETU_WDT
452+ depends on CBUS_RETU && SYSFS && WATCHDOG
453+ tristate "Support for Retu watchdog timer"
454+ ---help---
455+ Say Y here if you want support for the watchdog in Retu. This will
456+ expose a sysfs interface to grok it.
457+
458+config CBUS_RETU_HEADSET
459+ depends on CBUS_RETU && SYSFS
460+ tristate "Support for headset detection with Retu/Vilma"
461+ ---help---
462+ Say Y here if you want support detecting a headset that's connected
463+ to Retu/Vilma. Detection state and events are exposed through
464+ sysfs.
465+
466+endmenu
467--- /dev/null
468+++ b/drivers/cbus/Makefile
469@@ -0,0 +1,13 @@
470+#
471+# Makefile for CBUS.
472+#
473+
474+obj-$(CONFIG_CBUS) += cbus.o
475+obj-$(CONFIG_CBUS_TAHVO) += tahvo.o
476+obj-$(CONFIG_CBUS_RETU) += retu.o
477+obj-$(CONFIG_CBUS_TAHVO_USB) += tahvo-usb.o
478+
479+obj-$(CONFIG_CBUS_RETU_POWERBUTTON) += retu-pwrbutton.o
480+obj-$(CONFIG_CBUS_RETU_RTC) += retu-rtc.o
481+obj-$(CONFIG_CBUS_RETU_WDT) += retu-wdt.o
482+obj-$(CONFIG_CBUS_RETU_HEADSET) += retu-headset.o
483--- /dev/null
484+++ b/drivers/cbus/retu.c
485@@ -0,0 +1,544 @@
486+/**
487+ * drivers/cbus/retu.c
488+ *
489+ * Support functions for Retu ASIC
490+ *
491+ * Copyright (C) 2004, 2005 Nokia Corporation
492+ *
493+ * Written by Juha Yrjölä <juha.yrjola@nokia.com>,
494+ * David Weinehall <david.weinehall@nokia.com>, and
495+ * Mikko Ylinen <mikko.k.ylinen@nokia.com>
496+ *
497+ * This file is subject to the terms and conditions of the GNU General
498+ * Public License. See the file "COPYING" in the main directory of this
499+ * archive for more details.
500+ *
501+ * This program is distributed in the hope that it will be useful,
502+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
503+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
504+ * GNU General Public License for more details.
505+ *
506+ * You should have received a copy of the GNU General Public License
507+ * along with this program; if not, write to the Free Software
508+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
509+ */
510+
511+#include <linux/module.h>
512+#include <linux/init.h>
513+
514+#include <linux/slab.h>
515+#include <linux/kernel.h>
516+#include <linux/errno.h>
517+#include <linux/device.h>
518+#include <linux/miscdevice.h>
519+#include <linux/poll.h>
520+#include <linux/fs.h>
521+#include <linux/mutex.h>
522+#include <linux/irq.h>
523+#include <linux/interrupt.h>
524+#include <linux/platform_device.h>
525+#include <linux/gpio.h>
526+
527+#include <asm/uaccess.h>
528+#include <asm/mach-types.h>
529+
530+#include <plat/mux.h>
531+#include <plat/board.h>
532+#include <plat/cbus.h>
533+
534+#include "cbus.h"
535+#include "retu.h"
536+
537+struct retu {
538+ /* Device lock */
539+ struct mutex mutex;
540+ struct device *dev;
541+
542+ int devid;
543+
544+ int irq_base;
545+ int irq_end;
546+
547+ int irq;
548+
549+ int ack;
550+ bool ack_pending;
551+
552+ int mask;
553+ bool mask_pending;
554+
555+ bool is_vilma;
556+};
557+
558+static struct retu *the_retu;
559+
560+/**
561+ * __retu_read_reg - Read a value from a register in Retu
562+ * @retu: pointer to retu structure
563+ * @reg: the register address to read from
564+ */
565+static int __retu_read_reg(struct retu *retu, unsigned reg)
566+{
567+ return cbus_read_reg(retu->devid, reg);
568+}
569+
570+/**
571+ * __retu_write_reg - Writes a value to a register in Retu
572+ * @retu: pointer to retu structure
573+ * @reg: the register address to write to
574+ * @val: the value to write to the register
575+ */
576+static void __retu_write_reg(struct retu *retu, unsigned reg, u16 val)
577+{
578+ cbus_write_reg(retu->devid, reg, val);
579+}
580+
581+/**
582+ * retu_read_reg - Read a value from a register in Retu
583+ * @child: device pointer for the calling child
584+ * @reg: the register to read from
585+ *
586+ * This function returns the contents of the specified register
587+ */
588+int retu_read_reg(struct device *child, unsigned reg)
589+{
590+ struct retu *retu = dev_get_drvdata(child->parent);
591+
592+ return __retu_read_reg(retu, reg);
593+}
594+EXPORT_SYMBOL_GPL(retu_read_reg);
595+
596+/**
597+ * retu_write_reg - Write a value to a register in Retu
598+ * @child: the pointer to our calling child
599+ * @reg: the register to write to
600+ * @val: the value to write to the register
601+ *
602+ * This function writes a value to the specified register
603+ */
604+void retu_write_reg(struct device *child, unsigned reg, u16 val)
605+{
606+ struct retu *retu = dev_get_drvdata(child->parent);
607+
608+ __retu_write_reg(retu, reg, val);
609+}
610+EXPORT_SYMBOL_GPL(retu_write_reg);
611+
612+/**
613+ * retu_set_clear_reg_bits - helper function to read/set/clear bits
614+ * @child: device pointer to calling child
615+ * @reg: the register address
616+ * @set: mask for setting bits
617+ * @clear: mask for clearing bits
618+ */
619+void retu_set_clear_reg_bits(struct device *child, unsigned reg, u16 set,
620+ u16 clear)
621+{
622+ struct retu *retu = dev_get_drvdata(child->parent);
623+ u16 w;
624+
625+ mutex_lock(&retu->mutex);
626+ w = __retu_read_reg(retu, reg);
627+ w &= ~clear;
628+ w |= set;
629+ __retu_write_reg(retu, reg, w);
630+ mutex_unlock(&retu->mutex);
631+}
632+EXPORT_SYMBOL_GPL(retu_set_clear_reg_bits);
633+
634+#define ADC_MAX_CHAN_NUMBER 13
635+
636+/**
637+ * retu_read_adc - Reads AD conversion result
638+ * @child: device pointer to calling child
639+ * @channel: the ADC channel to read from
640+ */
641+int retu_read_adc(struct device *child, int channel)
642+{
643+ struct retu *retu = dev_get_drvdata(child->parent);
644+ int res;
645+
646+ if (!retu)
647+ return -ENODEV;
648+
649+ if (channel < 0 || channel > ADC_MAX_CHAN_NUMBER)
650+ return -EINVAL;
651+
652+ mutex_lock(&retu->mutex);
653+
654+ if ((channel == 8) && retu->is_vilma) {
655+ int scr = __retu_read_reg(retu, RETU_REG_ADCSCR);
656+ int ch = (__retu_read_reg(retu, RETU_REG_ADCR) >> 10) & 0xf;
657+ if (((scr & 0xff) != 0) && (ch != 8))
658+ __retu_write_reg(retu, RETU_REG_ADCSCR, (scr & ~0xff));
659+ }
660+
661+ /* Select the channel and read result */
662+ __retu_write_reg(retu, RETU_REG_ADCR, channel << 10);
663+ res = __retu_read_reg(retu, RETU_REG_ADCR) & 0x3ff;
664+
665+ if (retu->is_vilma)
666+ __retu_write_reg(retu, RETU_REG_ADCR, (1 << 13));
667+
668+ /* Unlock retu */
669+ mutex_unlock(&retu->mutex);
670+
671+ return res;
672+}
673+EXPORT_SYMBOL_GPL(retu_read_adc);
674+
675+static irqreturn_t retu_irq_handler(int irq, void *_retu)
676+{
677+ struct retu *retu = _retu;
678+
679+ int i;
680+
681+ u16 idr;
682+ u16 imr;
683+
684+ idr = __retu_read_reg(retu, RETU_REG_IDR);
685+ imr = __retu_read_reg(retu, RETU_REG_IMR);
686+ idr &= ~imr;
687+
688+ if (!idr) {
689+ dev_vdbg(retu->dev, "No IRQ, spurious?\n");
690+ return IRQ_NONE;
691+ }
692+
693+ for (i = 0; idr != 0; i++, idr >>= 1) {
694+ if (!(idr & 1))
695+ continue;
696+
697+ handle_nested_irq(i);
698+ }
699+
700+ return IRQ_HANDLED;
701+}
702+
703+/* -------------------------------------------------------------------------- */
704+
705+static void retu_irq_mask(struct irq_data *data)
706+{
707+ struct retu *retu = irq_data_get_irq_chip_data(data);
708+ int irq = data->irq;
709+
710+ retu->mask |= (1 << (irq - retu->irq_base));
711+ retu->mask_pending = true;
712+}
713+
714+static void retu_irq_unmask(struct irq_data *data)
715+{
716+ struct retu *retu = irq_data_get_irq_chip_data(data);
717+ int irq = data->irq;
718+
719+ retu->mask &= ~(1 << (irq - retu->irq_base));
720+ retu->mask_pending = true;
721+
722+}
723+
724+static void retu_irq_ack(struct irq_data *data)
725+{
726+ struct retu *retu = irq_data_get_irq_chip_data(data);
727+ int irq = data->irq;
728+
729+ retu->ack |= (1 << (irq - retu->irq_base));
730+ retu->ack_pending = true;
731+}
732+
733+static void retu_bus_lock(struct irq_data *data)
734+{
735+ struct retu *retu = irq_data_get_irq_chip_data(data);
736+
737+ mutex_lock(&retu->mutex);
738+}
739+
740+static void retu_bus_sync_unlock(struct irq_data *data)
741+{
742+ struct retu *retu = irq_data_get_irq_chip_data(data);
743+
744+ if (retu->mask_pending) {
745+ __retu_write_reg(retu, RETU_REG_IMR, retu->mask);
746+ retu->mask_pending = false;
747+ }
748+
749+ if (retu->ack_pending) {
750+ __retu_write_reg(retu, RETU_REG_IDR, retu->ack);
751+ retu->ack_pending = false;
752+ }
753+
754+ mutex_unlock(&retu->mutex);
755+}
756+
757+static struct irq_chip retu_irq_chip = {
758+ .name = "retu",
759+ .irq_bus_lock = retu_bus_lock,
760+ .irq_bus_sync_unlock = retu_bus_sync_unlock,
761+ .irq_mask = retu_irq_mask,
762+ .irq_unmask = retu_irq_unmask,
763+ .irq_ack = retu_irq_ack,
764+};
765+
766+static inline void retu_irq_setup(int irq)
767+{
768+#ifdef CONFIG_ARM
769+ set_irq_flags(irq, IRQF_VALID);
770+#else
771+ set_irq_noprobe(irq);
772+#endif
773+}
774+
775+static void retu_irq_init(struct retu *retu)
776+{
777+ int base = retu->irq_base;
778+ int end = retu->irq_end;
779+ int irq;
780+
781+ for (irq = base; irq < end; irq++) {
782+ set_irq_chip_data(irq, retu);
783+ set_irq_chip_and_handler(irq, &retu_irq_chip,
784+ handle_simple_irq);
785+ set_irq_nested_thread(irq, 1);
786+ retu_irq_setup(irq);
787+ }
788+}
789+
790+static void retu_irq_exit(struct retu *retu)
791+{
792+ int base = retu->irq_base;
793+ int end = retu->irq_end;
794+ int irq;
795+
796+ for (irq = base; irq < end; irq++) {
797+#ifdef CONFIG_ARM
798+ set_irq_flags(irq, 0);
799+#endif
800+ set_irq_chip_and_handler(irq, NULL, NULL);
801+ set_irq_chip_data(irq, NULL);
802+ }
803+}
804+
805+/* -------------------------------------------------------------------------- */
806+
807+/**
808+ * retu_power_off - Shut down power to system
809+ *
810+ * This function puts the system in power off state
811+ */
812+static void retu_power_off(void)
813+{
814+ struct retu *retu = the_retu;
815+ unsigned reg;
816+
817+ reg = __retu_read_reg(retu, RETU_REG_CC1);
818+
819+ /* Ignore power button state */
820+ __retu_write_reg(retu, RETU_REG_CC1, reg | 2);
821+ /* Expire watchdog immediately */
822+ __retu_write_reg(retu, RETU_REG_WATCHDOG, 0);
823+ /* Wait for poweroff*/
824+ for (;;);
825+}
826+
827+static struct resource generic_resources[] = {
828+ {
829+ .start = -EINVAL, /* fixed later */
830+ .flags = IORESOURCE_IRQ,
831+ },
832+ {
833+ .start = -EINVAL, /* fixed later */
834+ .flags = IORESOURCE_IRQ,
835+ },
836+};
837+
838+/**
839+ * retu_allocate_child - Allocates one Retu child
840+ * @name: name of new child
841+ * @parent: parent device for this child
842+ */
843+static struct device *retu_allocate_child(char *name, struct device *parent,
844+ int irq_base, int irq1, int irq2, int num)
845+{
846+ struct platform_device *pdev;
847+ int status;
848+
849+ pdev = platform_device_alloc(name, -1);
850+ if (!pdev) {
851+ dev_dbg(parent, "can't allocate %s\n", name);
852+ goto err;
853+ }
854+
855+ pdev->dev.parent = parent;
856+
857+ if (num) {
858+ generic_resources[0].start = irq_base + irq1;
859+ generic_resources[1].start = irq_base + irq2;
860+
861+ status = platform_device_add_resources(pdev,
862+ generic_resources, num);
863+ if (status < 0) {
864+ dev_dbg(parent, "can't add resources to %s\n", name);
865+ goto err;
866+ }
867+ }
868+
869+ status = platform_device_add(pdev);
870+ if (status < 0) {
871+ dev_dbg(parent, "can't add %s\n", name);
872+ goto err;
873+ }
874+
875+ return &pdev->dev;
876+
877+err:
878+ platform_device_put(pdev);
879+
880+ return NULL;
881+}
882+
883+/**
884+ * retu_allocate_children - Allocates Retu's children
885+ */
886+static int retu_allocate_children(struct device *parent, int irq_base)
887+{
888+ struct device *child;
889+
890+ child = retu_allocate_child("retu-pwrbutton", parent, irq_base,
891+ RETU_INT_PWR, -1, 1);
892+ if (!child)
893+ return -ENOMEM;
894+
895+ child = retu_allocate_child("retu-headset", parent, irq_base,
896+ RETU_INT_HOOK, -1, 1);
897+ if (!child)
898+ return -ENOMEM;
899+
900+ child = retu_allocate_child("retu-rtc", parent, irq_base,
901+ RETU_INT_RTCS, RETU_INT_RTCA, 2);
902+ if (!child)
903+ return -ENOMEM;
904+
905+ child = retu_allocate_child("retu-wdt", parent, -1, -1, -1, 0);
906+ if (!child)
907+ return -ENOMEM;
908+
909+ return 0;
910+}
911+
912+/**
913+ * retu_probe - Probe for Retu ASIC
914+ * @dev: the Retu device
915+ *
916+ * Probe for the Retu ASIC and allocate memory
917+ * for its device-struct if found
918+ */
919+static int __init retu_probe(struct platform_device *pdev)
920+{
921+ struct retu *retu;
922+ struct cbus_retu_platform_data *pdata = pdev->dev.platform_data;
923+
924+ int ret = -ENOMEM;
925+ int rev;
926+
927+ retu = kzalloc(sizeof(*retu), GFP_KERNEL);
928+ if (!retu) {
929+ dev_err(&pdev->dev, "not enough memory\n");
930+ goto err0;
931+ }
932+
933+ platform_set_drvdata(pdev, retu);
934+
935+ retu->irq = platform_get_irq(pdev, 0);
936+ retu->irq_base = pdata->irq_base;
937+ retu->irq_end = pdata->irq_end;
938+ retu->devid = pdata->devid;
939+ the_retu = retu;
940+
941+ mutex_init(&retu->mutex);
942+
943+ retu_irq_init(retu);
944+
945+ rev = __retu_read_reg(retu, RETU_REG_ASICR) & 0xff;
946+ if (rev & (1 << 7))
947+ retu->is_vilma = true;
948+
949+ dev_info(&pdev->dev, "%s v%d.%d found\n",
950+ retu->is_vilma ? "Vilma" : "Retu",
951+ (rev >> 4) & 0x07, rev & 0x0f);
952+
953+ /* Mask all RETU interrupts */
954+ __retu_write_reg(retu, RETU_REG_IMR, 0xffff);
955+
956+ ret = request_threaded_irq(retu->irq, NULL, retu_irq_handler, 0,
957+ "retu", retu);
958+ if (ret < 0) {
959+ dev_err(&pdev->dev, "Unable to register IRQ handler\n");
960+ goto err1;
961+ }
962+
963+ set_irq_wake(retu->irq, 1);
964+
965+ /* Register power off function */
966+ pm_power_off = retu_power_off;
967+
968+ ret = retu_allocate_children(&pdev->dev, retu->irq_base);
969+ if (ret < 0) {
970+ dev_err(&pdev->dev, "Unable to allocate Retu children\n");
971+ goto err2;
972+ }
973+
974+ return 0;
975+
976+err2:
977+ pm_power_off = NULL;
978+ __retu_write_reg(retu, RETU_REG_IMR, 0xffff);
979+ free_irq(retu->irq, retu);
980+
981+err1:
982+ kfree(retu);
983+ the_retu = NULL;
984+
985+err0:
986+ return ret;
987+}
988+
989+static int __exit retu_remove(struct platform_device *pdev)
990+{
991+ struct retu *retu = platform_get_drvdata(pdev);
992+
993+ pm_power_off = NULL;
994+ the_retu = NULL;
995+
996+ /* Mask all RETU interrupts */
997+ __retu_write_reg(retu, RETU_REG_IMR, 0xffff);
998+
999+ free_irq(retu->irq, retu);
1000+ retu_irq_exit(retu);
1001+ kfree(retu);
1002+
1003+ return 0;
1004+}
1005+
1006+static struct platform_driver retu_driver = {
1007+ .remove = __exit_p(retu_remove),
1008+ .driver = {
1009+ .name = "retu",
1010+ },
1011+};
1012+
1013+static int __init retu_init(void)
1014+{
1015+ return platform_driver_probe(&retu_driver, retu_probe);
1016+}
1017+subsys_initcall(retu_init);
1018+
1019+static void __exit retu_exit(void)
1020+{
1021+ platform_driver_unregister(&retu_driver);
1022+}
1023+module_exit(retu_exit);
1024+
1025+MODULE_DESCRIPTION("Retu ASIC control");
1026+MODULE_LICENSE("GPL");
1027+MODULE_AUTHOR("Juha Yrjölä");
1028+MODULE_AUTHOR("David Weinehall");
1029+MODULE_AUTHOR("Mikko Ylinen");
1030--- /dev/null
1031+++ b/drivers/cbus/retu.h
1032@@ -0,0 +1,66 @@
1033+/**
1034+ * drivers/cbus/retu.h
1035+ *
1036+ * Copyright (C) 2004, 2005 Nokia Corporation
1037+ *
1038+ * Written by Juha Yrjölä <juha.yrjola@nokia.com> and
1039+ * David Weinehall <david.weinehall@nokia.com>
1040+ *
1041+ * This file is subject to the terms and conditions of the GNU General
1042+ * Public License. See the file "COPYING" in the main directory of this
1043+ * archive for more details.
1044+ *
1045+ * This program is distributed in the hope that it will be useful,
1046+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1047+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1048+ * GNU General Public License for more details.
1049+
1050+ * You should have received a copy of the GNU General Public License
1051+ * along with this program; if not, write to the Free Software
1052+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1053+ */
1054+
1055+#ifndef __DRIVERS_CBUS_RETU_H
1056+#define __DRIVERS_CBUS_RETU_H
1057+
1058+#include <linux/types.h>
1059+
1060+/* Registers */
1061+#define RETU_REG_ASICR 0x00 /* ASIC ID & revision */
1062+#define RETU_REG_IDR 0x01 /* Interrupt ID */
1063+#define RETU_REG_IMR 0x02 /* Interrupt mask */
1064+#define RETU_REG_RTCDSR 0x03 /* RTC seconds register */
1065+#define RETU_REG_RTCHMR 0x04 /* RTC hours and minutes register */
1066+#define RETU_REG_RTCHMAR 0x05 /* RTC hours and minutes alarm and time set register */
1067+#define RETU_REG_RTCCALR 0x06 /* RTC calibration register */
1068+#define RETU_REG_ADCR 0x08 /* ADC result */
1069+#define RETU_REG_ADCSCR 0x09 /* ADC sample ctrl */
1070+#define RETU_REG_CC1 0x0d /* Common control register 1 */
1071+#define RETU_REG_CC2 0x0e /* Common control register 2 */
1072+#define RETU_REG_CTRL_CLR 0x0f /* Regulator clear register */
1073+#define RETU_REG_CTRL_SET 0x10 /* Regulator set register */
1074+#define RETU_REG_STATUS 0x16 /* Status register */
1075+#define RETU_REG_WATCHDOG 0x17 /* Watchdog register */
1076+#define RETU_REG_AUDTXR 0x18 /* Audio Codec Tx register */
1077+#define RETU_REG_MAX 0x1f
1078+
1079+/* Interrupt sources */
1080+#define RETU_INT_PWR 0
1081+#define RETU_INT_CHAR 1
1082+#define RETU_INT_RTCS 2
1083+#define RETU_INT_RTCM 3
1084+#define RETU_INT_RTCD 4
1085+#define RETU_INT_RTCA 5
1086+#define RETU_INT_HOOK 6
1087+#define RETU_INT_HEAD 7
1088+#define RETU_INT_ADCS 8
1089+
1090+#define MAX_RETU_IRQ_HANDLERS 16
1091+
1092+int retu_read_reg(struct device *child, unsigned reg);
1093+void retu_write_reg(struct device *child, unsigned reg, u16 val);
1094+void retu_set_clear_reg_bits(struct device *child, unsigned reg, u16 set,
1095+ u16 clear);
1096+int retu_read_adc(struct device *child, int channel);
1097+
1098+#endif /* __DRIVERS_CBUS_RETU_H */
1099--- /dev/null
1100+++ b/drivers/cbus/retu-headset.c
1101@@ -0,0 +1,359 @@
1102+/**
1103+ * Retu/Vilma headset detection
1104+ *
1105+ * Copyright (C) 2006 Nokia Corporation
1106+ *
1107+ * Written by Juha Yrjölä
1108+ *
1109+ * This file is subject to the terms and conditions of the GNU General
1110+ * Public License. See the file "COPYING" in the main directory of this
1111+ * archive for more details.
1112+ *
1113+ * This program is distributed in the hope that it will be useful,
1114+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1115+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1116+ * GNU General Public License for more details.
1117+ *
1118+ * You should have received a copy of the GNU General Public License
1119+ * along with this program; if not, write to the Free Software
1120+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1121+ */
1122+
1123+#include <linux/module.h>
1124+#include <linux/init.h>
1125+#include <linux/kernel.h>
1126+#include <linux/irq.h>
1127+#include <linux/interrupt.h>
1128+#include <linux/slab.h>
1129+#include <linux/delay.h>
1130+#include <linux/input.h>
1131+#include <linux/platform_device.h>
1132+
1133+#include "retu.h"
1134+
1135+#define RETU_ADC_CHANNEL_HOOKDET 0x05
1136+
1137+#define RETU_HEADSET_KEY KEY_PHONE
1138+
1139+struct retu_headset {
1140+ spinlock_t lock;
1141+ struct mutex mutex;
1142+ struct device *dev;
1143+ struct input_dev *idev;
1144+ unsigned bias_enabled;
1145+ unsigned detection_enabled;
1146+ unsigned pressed;
1147+ struct timer_list enable_timer;
1148+ struct timer_list detect_timer;
1149+ int irq;
1150+};
1151+
1152+static void retu_headset_set_bias(struct retu_headset *hs, int enable)
1153+{
1154+ if (enable) {
1155+ retu_set_clear_reg_bits(hs->dev, RETU_REG_AUDTXR,
1156+ (1 << 0) | (1 << 1), 0);
1157+ msleep(2);
1158+ retu_set_clear_reg_bits(hs->dev, RETU_REG_AUDTXR,
1159+ 1 << 3, 0);
1160+ } else {
1161+ retu_set_clear_reg_bits(hs->dev, RETU_REG_AUDTXR, 0,
1162+ (1 << 0) | (1 << 1) | (1 << 3));
1163+ }
1164+}
1165+
1166+static void retu_headset_enable(struct retu_headset *hs)
1167+{
1168+ mutex_lock(&hs->mutex);
1169+ if (!hs->bias_enabled) {
1170+ hs->bias_enabled = 1;
1171+ retu_headset_set_bias(hs, 1);
1172+ }
1173+ mutex_unlock(&hs->mutex);
1174+}
1175+
1176+static void retu_headset_disable(struct retu_headset *hs)
1177+{
1178+ mutex_lock(&hs->mutex);
1179+ if (hs->bias_enabled) {
1180+ hs->bias_enabled = 0;
1181+ retu_headset_set_bias(hs, 0);
1182+ }
1183+ mutex_unlock(&hs->mutex);
1184+}
1185+
1186+static void retu_headset_det_enable(struct retu_headset *hs)
1187+{
1188+ mutex_lock(&hs->mutex);
1189+ if (!hs->detection_enabled) {
1190+ hs->detection_enabled = 1;
1191+ retu_set_clear_reg_bits(hs->dev, RETU_REG_CC1,
1192+ (1 << 10) | (1 << 8), 0);
1193+ }
1194+ mutex_unlock(&hs->mutex);
1195+}
1196+
1197+static void retu_headset_det_disable(struct retu_headset *hs)
1198+{
1199+ unsigned long flags;
1200+
1201+ mutex_lock(&hs->mutex);
1202+ if (hs->detection_enabled) {
1203+ hs->detection_enabled = 0;
1204+ del_timer_sync(&hs->enable_timer);
1205+ del_timer_sync(&hs->detect_timer);
1206+ spin_lock_irqsave(&hs->lock, flags);
1207+ if (hs->pressed)
1208+ input_report_key(hs->idev, RETU_HEADSET_KEY, 0);
1209+ spin_unlock_irqrestore(&hs->lock, flags);
1210+ retu_set_clear_reg_bits(hs->dev, RETU_REG_CC1, 0,
1211+ (1 << 10) | (1 << 8));
1212+ }
1213+ mutex_unlock(&hs->mutex);
1214+}
1215+
1216+static ssize_t retu_headset_hookdet_show(struct device *dev,
1217+ struct device_attribute *attr,
1218+ char *buf)
1219+{
1220+ int val;
1221+
1222+ val = retu_read_adc(dev, RETU_ADC_CHANNEL_HOOKDET);
1223+ return sprintf(buf, "%d\n", val);
1224+}
1225+
1226+static DEVICE_ATTR(hookdet, S_IRUGO, retu_headset_hookdet_show, NULL);
1227+
1228+static ssize_t retu_headset_enable_show(struct device *dev,
1229+ struct device_attribute *attr,
1230+ char *buf)
1231+{
1232+ struct retu_headset *hs = dev_get_drvdata(dev);
1233+
1234+ return sprintf(buf, "%u\n", hs->bias_enabled);
1235+}
1236+
1237+static ssize_t retu_headset_enable_store(struct device *dev,
1238+ struct device_attribute *attr,
1239+ const char *buf, size_t count)
1240+{
1241+ struct retu_headset *hs = dev_get_drvdata(dev);
1242+ int enable;
1243+
1244+ if (sscanf(buf, "%u", &enable) != 1)
1245+ return -EINVAL;
1246+ if (enable)
1247+ retu_headset_enable(hs);
1248+ else
1249+ retu_headset_disable(hs);
1250+ return count;
1251+}
1252+
1253+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
1254+ retu_headset_enable_show, retu_headset_enable_store);
1255+
1256+static ssize_t retu_headset_enable_det_show(struct device *dev,
1257+ struct device_attribute *attr,
1258+ char *buf)
1259+{
1260+ struct retu_headset *hs = dev_get_drvdata(dev);
1261+
1262+ return sprintf(buf, "%u\n", hs->detection_enabled);
1263+}
1264+
1265+static ssize_t retu_headset_enable_det_store(struct device *dev,
1266+ struct device_attribute *attr,
1267+ const char *buf, size_t count)
1268+{
1269+ struct retu_headset *hs = dev_get_drvdata(dev);
1270+ int enable;
1271+
1272+ if (sscanf(buf, "%u", &enable) != 1)
1273+ return -EINVAL;
1274+ if (enable)
1275+ retu_headset_det_enable(hs);
1276+ else
1277+ retu_headset_det_disable(hs);
1278+ return count;
1279+}
1280+
1281+static DEVICE_ATTR(enable_det, S_IRUGO | S_IWUSR | S_IWGRP,
1282+ retu_headset_enable_det_show,
1283+ retu_headset_enable_det_store);
1284+
1285+static irqreturn_t retu_headset_hook_interrupt(int irq, void *_hs)
1286+{
1287+ struct retu_headset *hs = _hs;
1288+ unsigned long flags;
1289+
1290+ spin_lock_irqsave(&hs->lock, flags);
1291+ if (!hs->pressed) {
1292+ /* Headset button was just pressed down. */
1293+ hs->pressed = 1;
1294+ input_report_key(hs->idev, RETU_HEADSET_KEY, 1);
1295+ }
1296+ spin_unlock_irqrestore(&hs->lock, flags);
1297+ retu_set_clear_reg_bits(hs->dev, RETU_REG_CC1, 0,
1298+ (1 << 10) | (1 << 8));
1299+ mod_timer(&hs->enable_timer, jiffies + msecs_to_jiffies(50));
1300+
1301+ return IRQ_HANDLED;
1302+}
1303+
1304+static void retu_headset_enable_timer(unsigned long arg)
1305+{
1306+ struct retu_headset *hs = (struct retu_headset *) arg;
1307+
1308+ retu_set_clear_reg_bits(hs->dev, RETU_REG_CC1,
1309+ (1 << 10) | (1 << 8), 0);
1310+ mod_timer(&hs->detect_timer, jiffies + msecs_to_jiffies(350));
1311+}
1312+
1313+static void retu_headset_detect_timer(unsigned long arg)
1314+{
1315+ struct retu_headset *hs = (struct retu_headset *) arg;
1316+ unsigned long flags;
1317+
1318+ spin_lock_irqsave(&hs->lock, flags);
1319+ if (hs->pressed) {
1320+ hs->pressed = 0;
1321+ input_report_key(hs->idev, RETU_HEADSET_KEY, 0);
1322+ }
1323+ spin_unlock_irqrestore(&hs->lock, flags);
1324+}
1325+
1326+static int __init retu_headset_probe(struct platform_device *pdev)
1327+{
1328+ struct retu_headset *hs;
1329+ int irq;
1330+ int r;
1331+
1332+ hs = kzalloc(sizeof(*hs), GFP_KERNEL);
1333+ if (hs == NULL)
1334+ return -ENOMEM;
1335+
1336+ hs->dev = &pdev->dev;
1337+
1338+ hs->idev = input_allocate_device();
1339+ if (hs->idev == NULL) {
1340+ r = -ENOMEM;
1341+ goto err1;
1342+ }
1343+ hs->idev->name = "retu-headset";
1344+ hs->idev->dev.parent = &pdev->dev;
1345+ set_bit(EV_KEY, hs->idev->evbit);
1346+ set_bit(RETU_HEADSET_KEY, hs->idev->keybit);
1347+ r = input_register_device(hs->idev);
1348+ if (r < 0)
1349+ goto err2;
1350+
1351+ r = device_create_file(&pdev->dev, &dev_attr_hookdet);
1352+ if (r < 0)
1353+ goto err3;
1354+ r = device_create_file(&pdev->dev, &dev_attr_enable);
1355+ if (r < 0)
1356+ goto err4;
1357+ r = device_create_file(&pdev->dev, &dev_attr_enable_det);
1358+ if (r < 0)
1359+ goto err5;
1360+ platform_set_drvdata(pdev, hs);
1361+
1362+ spin_lock_init(&hs->lock);
1363+ mutex_init(&hs->mutex);
1364+ setup_timer(&hs->enable_timer, retu_headset_enable_timer,
1365+ (unsigned long) hs);
1366+ setup_timer(&hs->detect_timer, retu_headset_detect_timer,
1367+ (unsigned long) hs);
1368+
1369+ irq = platform_get_irq(pdev, 0);
1370+ hs->irq = irq;
1371+
1372+ r = request_threaded_irq(irq, NULL, retu_headset_hook_interrupt, 0,
1373+ "hookdet", hs);
1374+ if (r != 0) {
1375+ dev_err(&pdev->dev, "hookdet IRQ not available\n");
1376+ goto err6;
1377+ }
1378+
1379+ return 0;
1380+err6:
1381+ device_remove_file(&pdev->dev, &dev_attr_enable_det);
1382+err5:
1383+ device_remove_file(&pdev->dev, &dev_attr_enable);
1384+err4:
1385+ device_remove_file(&pdev->dev, &dev_attr_hookdet);
1386+err3:
1387+ input_unregister_device(hs->idev);
1388+err2:
1389+ input_free_device(hs->idev);
1390+err1:
1391+ kfree(hs);
1392+ return r;
1393+}
1394+
1395+static int retu_headset_remove(struct platform_device *pdev)
1396+{
1397+ struct retu_headset *hs = platform_get_drvdata(pdev);
1398+
1399+ device_remove_file(&pdev->dev, &dev_attr_hookdet);
1400+ device_remove_file(&pdev->dev, &dev_attr_enable);
1401+ device_remove_file(&pdev->dev, &dev_attr_enable_det);
1402+ retu_headset_disable(hs);
1403+ retu_headset_det_disable(hs);
1404+ free_irq(hs->irq, hs);
1405+ input_unregister_device(hs->idev);
1406+ input_free_device(hs->idev);
1407+
1408+ return 0;
1409+}
1410+
1411+static int retu_headset_suspend(struct platform_device *pdev,
1412+ pm_message_t mesg)
1413+{
1414+ struct retu_headset *hs = platform_get_drvdata(pdev);
1415+
1416+ mutex_lock(&hs->mutex);
1417+ if (hs->bias_enabled)
1418+ retu_headset_set_bias(hs, 0);
1419+ mutex_unlock(&hs->mutex);
1420+
1421+ return 0;
1422+}
1423+
1424+static int retu_headset_resume(struct platform_device *pdev)
1425+{
1426+ struct retu_headset *hs = platform_get_drvdata(pdev);
1427+
1428+ mutex_lock(&hs->mutex);
1429+ if (hs->bias_enabled)
1430+ retu_headset_set_bias(hs, 1);
1431+ mutex_unlock(&hs->mutex);
1432+
1433+ return 0;
1434+}
1435+
1436+static struct platform_driver retu_headset_driver = {
1437+ .remove = retu_headset_remove,
1438+ .suspend = retu_headset_suspend,
1439+ .resume = retu_headset_resume,
1440+ .driver = {
1441+ .name = "retu-headset",
1442+ },
1443+};
1444+
1445+static int __init retu_headset_init(void)
1446+{
1447+ return platform_driver_probe(&retu_headset_driver, retu_headset_probe);
1448+}
1449+
1450+static void __exit retu_headset_exit(void)
1451+{
1452+ platform_driver_unregister(&retu_headset_driver);
1453+}
1454+
1455+module_init(retu_headset_init);
1456+module_exit(retu_headset_exit);
1457+
1458+MODULE_DESCRIPTION("Retu/Vilma headset detection");
1459+MODULE_LICENSE("GPL");
1460+MODULE_AUTHOR("Juha Yrjölä");
1461--- /dev/null
1462+++ b/drivers/cbus/retu-pwrbutton.c
1463@@ -0,0 +1,165 @@
1464+/**
1465+ * drivers/cbus/retu-pwrbutton.c
1466+ *
1467+ * Driver for sending retu power button event to input-layer
1468+ *
1469+ * Copyright (C) 2004-2010 Nokia Corporation
1470+ *
1471+ * Written by
1472+ * Ari Saastamoinen <ari.saastamoinen@elektrobit.com>
1473+ * Juha Yrjola <juha.yrjola@solidboot.com>
1474+ *
1475+ * Contact: Felipe Balbi <felipe.balbi@nokia.com>
1476+ *
1477+ * This file is subject to the terms and conditions of the GNU General
1478+ * Public License. See the file "COPYING" in the main directory of this
1479+ * archive for more details.
1480+ *
1481+ * This program is distributed in the hope that it will be useful,
1482+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1483+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1484+ * GNU General Public License for more details.
1485+ *
1486+ * You should have received a copy of the GNU General Public License
1487+ * along with this program; if not, write to the Free Software
1488+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1489+ */
1490+
1491+#include <linux/module.h>
1492+#include <linux/init.h>
1493+#include <linux/kernel.h>
1494+#include <linux/errno.h>
1495+#include <linux/input.h>
1496+#include <linux/jiffies.h>
1497+#include <linux/bitops.h>
1498+#include <linux/irq.h>
1499+#include <linux/interrupt.h>
1500+#include <linux/platform_device.h>
1501+#include <linux/slab.h>
1502+
1503+#include "retu.h"
1504+
1505+#define RETU_STATUS_PWRONX (1 << 5)
1506+
1507+#define PWRBTN_DELAY 20
1508+#define PWRBTN_UP 0
1509+#define PWRBTN_PRESSED 1
1510+
1511+struct retu_pwrbutton {
1512+ struct input_dev *idev;
1513+ struct device *dev;
1514+
1515+ int state;
1516+ int irq;
1517+};
1518+
1519+static irqreturn_t retubutton_irq(int irq, void *_pwr)
1520+{
1521+ struct retu_pwrbutton *pwr = _pwr;
1522+ int state;
1523+
1524+ if (retu_read_reg(pwr->dev, RETU_REG_STATUS) & RETU_STATUS_PWRONX)
1525+ state = PWRBTN_UP;
1526+ else
1527+ state = PWRBTN_PRESSED;
1528+
1529+ if (pwr->state != state) {
1530+ input_report_key(pwr->idev, KEY_POWER, state);
1531+ input_sync(pwr->idev);
1532+ pwr->state = state;
1533+ }
1534+
1535+ return IRQ_HANDLED;
1536+}
1537+
1538+static int __init retubutton_probe(struct platform_device *pdev)
1539+{
1540+ struct retu_pwrbutton *pwr;
1541+ int ret = 0;
1542+
1543+ pwr = kzalloc(sizeof(*pwr), GFP_KERNEL);
1544+ if (!pwr) {
1545+ dev_err(&pdev->dev, "not enough memory\n");
1546+ ret = -ENOMEM;
1547+ goto err0;
1548+ }
1549+
1550+ pwr->dev = &pdev->dev;
1551+ pwr->irq = platform_get_irq(pdev, 0);
1552+ platform_set_drvdata(pdev, pwr);
1553+
1554+ ret = request_threaded_irq(pwr->irq, NULL, retubutton_irq, 0,
1555+ "retu-pwrbutton", pwr);
1556+ if (ret < 0) {
1557+ dev_err(&pdev->dev, "Cannot allocate irq\n");
1558+ goto err1;
1559+ }
1560+
1561+ pwr->idev = input_allocate_device();
1562+ if (!pwr->idev) {
1563+ dev_err(&pdev->dev, "can't allocate input device\n");
1564+ ret = -ENOMEM;
1565+ goto err2;
1566+ }
1567+
1568+ pwr->idev->evbit[0] = BIT_MASK(EV_KEY);
1569+ pwr->idev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
1570+ pwr->idev->name = "retu-pwrbutton";
1571+
1572+ ret = input_register_device(pwr->idev);
1573+ if (ret < 0) {
1574+ dev_err(&pdev->dev, "failed to register input device\n");
1575+ goto err3;
1576+ }
1577+
1578+ return 0;
1579+
1580+err3:
1581+ input_free_device(pwr->idev);
1582+
1583+err2:
1584+ free_irq(pwr->irq, pwr);
1585+
1586+err1:
1587+ kfree(pwr);
1588+
1589+err0:
1590+ return ret;
1591+}
1592+
1593+static int __exit retubutton_remove(struct platform_device *pdev)
1594+{
1595+ struct retu_pwrbutton *pwr = platform_get_drvdata(pdev);
1596+
1597+ free_irq(pwr->irq, pwr);
1598+ input_unregister_device(pwr->idev);
1599+ input_free_device(pwr->idev);
1600+ kfree(pwr);
1601+
1602+ return 0;
1603+}
1604+
1605+static struct platform_driver retu_pwrbutton_driver = {
1606+ .remove = __exit_p(retubutton_remove),
1607+ .driver = {
1608+ .name = "retu-pwrbutton",
1609+ },
1610+};
1611+
1612+static int __init retubutton_init(void)
1613+{
1614+ return platform_driver_probe(&retu_pwrbutton_driver, retubutton_probe);
1615+}
1616+module_init(retubutton_init);
1617+
1618+static void __exit retubutton_exit(void)
1619+{
1620+ platform_driver_unregister(&retu_pwrbutton_driver);
1621+}
1622+module_exit(retubutton_exit);
1623+
1624+MODULE_DESCRIPTION("Retu Power Button");
1625+MODULE_LICENSE("GPL");
1626+MODULE_AUTHOR("Ari Saastamoinen");
1627+MODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>");
1628+
1629--- /dev/null
1630+++ b/drivers/cbus/retu-rtc.c
1631@@ -0,0 +1,287 @@
1632+/**
1633+ * drivers/cbus/retu-rtc.c
1634+ *
1635+ * Support for Retu RTC
1636+ *
1637+ * Copyright (C) 2004, 2005 Nokia Corporation
1638+ *
1639+ * Written by Paul Mundt <paul.mundt@nokia.com> and
1640+ * Igor Stoppa <igor.stoppa@nokia.com>
1641+ *
1642+ * The Retu RTC is essentially a partial read-only RTC that gives us Retu's
1643+ * idea of what time actually is. It's left as a userspace excercise to map
1644+ * this back to time in the real world and ensure that calibration settings
1645+ * are sane to compensate for any horrible drift (on account of not being able
1646+ * to set the clock to anything).
1647+ *
1648+ * Days are semi-writeable. Namely, Retu will only track 255 days for us
1649+ * consecutively, after which the counter is explicitly stuck at 255 until
1650+ * someone comes along and clears it with a write. In the event that no one
1651+ * comes along and clears it, we no longer have any idea what day it is.
1652+ *
1653+ * This file is subject to the terms and conditions of the GNU General
1654+ * Public License. See the file "COPYING" in the main directory of this
1655+ * archive for more details.
1656+ *
1657+ * This program is distributed in the hope that it will be useful,
1658+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1659+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1660+ * GNU General Public License for more details.
1661+ *
1662+ * You should have received a copy of the GNU General Public License
1663+ * along with this program; if not, write to the Free Software
1664+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1665+ */
1666+
1667+#include <linux/device.h>
1668+#include <linux/init.h>
1669+#include <linux/kernel.h>
1670+#include <linux/slab.h>
1671+#include <linux/module.h>
1672+#include <linux/platform_device.h>
1673+#include <linux/mutex.h>
1674+#include <linux/rtc.h>
1675+
1676+#include "cbus.h"
1677+#include "retu.h"
1678+
1679+struct retu_rtc {
1680+ /* device lock */
1681+ struct mutex mutex;
1682+ struct device *dev;
1683+ struct rtc_device *rtc;
1684+
1685+ u16 alarm_expired;
1686+ int irq_rtcs;
1687+ int irq_rtca;
1688+};
1689+
1690+static void retu_rtc_do_reset(struct retu_rtc *rtc)
1691+{
1692+ u16 ccr1;
1693+
1694+ ccr1 = retu_read_reg(rtc->dev, RETU_REG_CC1);
1695+ /* RTC in reset */
1696+ retu_write_reg(rtc->dev, RETU_REG_CC1, ccr1 | 0x0001);
1697+ /* RTC in normal operating mode */
1698+ retu_write_reg(rtc->dev, RETU_REG_CC1, ccr1 & ~0x0001);
1699+
1700+ /* Disable alarm and RTC WD */
1701+ retu_write_reg(rtc->dev, RETU_REG_RTCHMAR, 0x7f3f);
1702+ /* Set Calibration register to default value */
1703+ retu_write_reg(rtc->dev, RETU_REG_RTCCALR, 0x00c0);
1704+
1705+ rtc->alarm_expired = 0;
1706+}
1707+
1708+static irqreturn_t retu_rtc_interrupt(int irq, void *_rtc)
1709+{
1710+ struct retu_rtc *rtc = _rtc;
1711+
1712+ mutex_lock(&rtc->mutex);
1713+ rtc->alarm_expired = 1;
1714+ retu_write_reg(rtc->dev, RETU_REG_RTCHMAR, (24 << 8) | 60);
1715+ mutex_unlock(&rtc->mutex);
1716+
1717+ return IRQ_HANDLED;
1718+}
1719+
1720+static int retu_rtc_init_irq(struct retu_rtc *rtc)
1721+{
1722+ int irq;
1723+ int ret;
1724+
1725+ irq = platform_get_irq(to_platform_device(rtc->dev), 0);
1726+ rtc->irq_rtcs = irq;
1727+
1728+ irq = platform_get_irq(to_platform_device(rtc->dev), 1);
1729+ rtc->irq_rtca = irq;
1730+
1731+ ret = request_threaded_irq(rtc->irq_rtcs, NULL, retu_rtc_interrupt,
1732+ 0, "RTCS", rtc);
1733+ if (ret != 0)
1734+ return ret;
1735+
1736+ ret = request_threaded_irq(rtc->irq_rtca, NULL, retu_rtc_interrupt,
1737+ 0, "RTCA", rtc);
1738+ if (ret != 0) {
1739+ free_irq(rtc->irq_rtcs, rtc);
1740+ return ret;
1741+ }
1742+
1743+ return 0;
1744+}
1745+
1746+static int retu_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
1747+{
1748+ struct retu_rtc *rtc = dev_get_drvdata(dev);
1749+ u16 chmar;
1750+
1751+ mutex_lock(&rtc->mutex);
1752+
1753+ chmar = ((alm->time.tm_hour & 0x1f) << 8) | (alm->time.tm_min & 0x3f);
1754+ retu_write_reg(rtc->dev, RETU_REG_RTCHMAR, chmar);
1755+
1756+ mutex_unlock(&rtc->mutex);
1757+
1758+ return 0;
1759+}
1760+
1761+static int retu_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
1762+{
1763+ struct retu_rtc *rtc = dev_get_drvdata(dev);
1764+ u16 chmar;
1765+
1766+ mutex_lock(&rtc->mutex);
1767+
1768+ chmar = retu_read_reg(rtc->dev, RETU_REG_RTCHMAR);
1769+
1770+ alm->time.tm_hour = (chmar >> 8) & 0x1f;
1771+ alm->time.tm_min = chmar & 0x3f;
1772+ alm->enabled = !!rtc->alarm_expired;
1773+
1774+ mutex_unlock(&rtc->mutex);
1775+
1776+ return 0;
1777+}
1778+
1779+static int retu_rtc_set_time(struct device *dev, struct rtc_time *tm)
1780+{
1781+ struct retu_rtc *rtc = dev_get_drvdata(dev);
1782+ u16 dsr;
1783+ u16 hmr;
1784+
1785+ dsr = ((tm->tm_mday & 0xff) << 8) | (tm->tm_hour & 0xff);
1786+ hmr = ((tm->tm_min & 0xff) << 8) | (tm->tm_sec & 0xff);
1787+
1788+ mutex_lock(&rtc->mutex);
1789+
1790+ retu_write_reg(rtc->dev, RETU_REG_RTCDSR, dsr);
1791+ retu_write_reg(rtc->dev, RETU_REG_RTCHMR, hmr);
1792+
1793+ mutex_unlock(&rtc->mutex);
1794+
1795+ return 0;
1796+}
1797+
1798+static int retu_rtc_read_time(struct device *dev, struct rtc_time *tm)
1799+{
1800+ struct retu_rtc *rtc = dev_get_drvdata(dev);
1801+ u16 dsr;
1802+ u16 hmr;
1803+
1804+ /*
1805+ * DSR holds days and hours
1806+ * HMR hols minutes and seconds
1807+ *
1808+ * both are 16 bit registers with 8-bit for each field.
1809+ */
1810+
1811+ mutex_lock(&rtc->mutex);
1812+
1813+ dsr = retu_read_reg(rtc->dev, RETU_REG_RTCDSR);
1814+ hmr = retu_read_reg(rtc->dev, RETU_REG_RTCHMR);
1815+
1816+ tm->tm_sec = hmr & 0xff;
1817+ tm->tm_min = hmr >> 8;
1818+ tm->tm_hour = dsr & 0xff;
1819+ tm->tm_mday = dsr >> 8;
1820+
1821+ mutex_unlock(&rtc->mutex);
1822+
1823+ return 0;
1824+}
1825+
1826+static struct rtc_class_ops retu_rtc_ops = {
1827+ .read_time = retu_rtc_read_time,
1828+ .set_time = retu_rtc_set_time,
1829+ .read_alarm = retu_rtc_read_alarm,
1830+ .set_alarm = retu_rtc_set_alarm,
1831+};
1832+
1833+static int __init retu_rtc_probe(struct platform_device *pdev)
1834+{
1835+ struct retu_rtc *rtc;
1836+ int r;
1837+
1838+ rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
1839+ if (!rtc) {
1840+ dev_err(&pdev->dev, "not enough memory\n");
1841+ r = -ENOMEM;
1842+ goto err0;
1843+ }
1844+
1845+ rtc->dev = &pdev->dev;
1846+ platform_set_drvdata(pdev, rtc);
1847+ mutex_init(&rtc->mutex);
1848+
1849+ rtc->alarm_expired = retu_read_reg(rtc->dev, RETU_REG_IDR) &
1850+ (0x1 << RETU_INT_RTCA);
1851+
1852+ r = retu_rtc_init_irq(rtc);
1853+ if (r < 0) {
1854+ dev_err(&pdev->dev, "failed to request retu irq\n");
1855+ goto err1;
1856+ }
1857+
1858+ /* If the calibration register is zero, we've probably lost power */
1859+ if (!(retu_read_reg(rtc->dev, RETU_REG_RTCCALR) & 0x00ff))
1860+ retu_rtc_do_reset(rtc);
1861+
1862+ rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &
1863+ retu_rtc_ops, THIS_MODULE);
1864+ if (IS_ERR(rtc->rtc)) {
1865+ dev_err(&pdev->dev, "can't register RTC device\n");
1866+ goto err2;
1867+ }
1868+
1869+ return 0;
1870+
1871+err2:
1872+ free_irq(rtc->irq_rtcs, rtc);
1873+ free_irq(rtc->irq_rtca, rtc);
1874+
1875+err1:
1876+ kfree(rtc);
1877+
1878+err0:
1879+ return r;
1880+}
1881+
1882+static int __devexit retu_rtc_remove(struct platform_device *pdev)
1883+{
1884+ struct retu_rtc *rtc = platform_get_drvdata(pdev);
1885+
1886+ free_irq(rtc->irq_rtcs, rtc);
1887+ free_irq(rtc->irq_rtca, rtc);
1888+ rtc_device_unregister(rtc->rtc);
1889+ kfree(rtc);
1890+
1891+ return 0;
1892+}
1893+
1894+static struct platform_driver retu_rtc_driver = {
1895+ .remove = __exit_p(retu_rtc_remove),
1896+ .driver = {
1897+ .name = "retu-rtc",
1898+ },
1899+};
1900+
1901+static int __init retu_rtc_init(void)
1902+{
1903+ return platform_driver_probe(&retu_rtc_driver, retu_rtc_probe);
1904+}
1905+module_init(retu_rtc_init);
1906+
1907+static void __exit retu_rtc_exit(void)
1908+{
1909+ platform_driver_unregister(&retu_rtc_driver);
1910+}
1911+module_exit(retu_rtc_exit);
1912+
1913+MODULE_DESCRIPTION("Retu RTC");
1914+MODULE_LICENSE("GPL");
1915+MODULE_AUTHOR("Paul Mundt");
1916+MODULE_AUTHOR("Igor Stoppa");
1917+MODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>");
1918+
1919--- /dev/null
1920+++ b/drivers/cbus/retu-wdt.c
1921@@ -0,0 +1,358 @@
1922+/**
1923+ * drivers/cbus/retu-wdt.c
1924+ *
1925+ * Driver for Retu watchdog
1926+ *
1927+ * Copyright (C) 2004, 2005 Nokia Corporation
1928+ *
1929+ * Written by Amit Kucheria <amit.kucheria@nokia.com>
1930+ *
1931+ * This file is subject to the terms and conditions of the GNU General
1932+ * Public License. See the file "COPYING" in the main directory of this
1933+ * archive for more details.
1934+ *
1935+ * This program is distributed in the hope that it will be useful,
1936+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1937+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1938+ * GNU General Public License for more details.
1939+ *
1940+ * You should have received a copy of the GNU General Public License
1941+ * along with this program; if not, write to the Free Software
1942+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1943+ */
1944+
1945+#include <linux/kernel.h>
1946+#include <linux/slab.h>
1947+#include <linux/module.h>
1948+#include <linux/device.h>
1949+#include <linux/init.h>
1950+#include <linux/fs.h>
1951+#include <linux/io.h>
1952+#include <linux/platform_device.h>
1953+
1954+#include <linux/completion.h>
1955+#include <linux/errno.h>
1956+#include <linux/moduleparam.h>
1957+#include <linux/miscdevice.h>
1958+#include <linux/watchdog.h>
1959+
1960+#include <asm/uaccess.h>
1961+
1962+#include <plat/prcm.h>
1963+
1964+#include "cbus.h"
1965+#include "retu.h"
1966+
1967+/* Watchdog timeout in seconds */
1968+#define RETU_WDT_MIN_TIMER 0
1969+#define RETU_WDT_DEFAULT_TIMER 32
1970+#define RETU_WDT_MAX_TIMER 63
1971+
1972+static DEFINE_MUTEX(retu_wdt_mutex);
1973+
1974+/* Current period of watchdog */
1975+static unsigned int period_val = RETU_WDT_DEFAULT_TIMER;
1976+static int counter_param = RETU_WDT_MAX_TIMER;
1977+
1978+struct retu_wdt_dev {
1979+ struct device *dev;
1980+ int users;
1981+ struct miscdevice retu_wdt_miscdev;
1982+ struct timer_list ping_timer;
1983+};
1984+
1985+static struct retu_wdt_dev *retu_wdt;
1986+
1987+static void retu_wdt_set_ping_timer(unsigned long enable);
1988+
1989+static int _retu_modify_counter(unsigned int new)
1990+{
1991+ if (retu_wdt)
1992+ retu_write_reg(retu_wdt->dev, RETU_REG_WATCHDOG, (u16)new);
1993+
1994+ return 0;
1995+}
1996+
1997+static int retu_modify_counter(unsigned int new)
1998+{
1999+ if (new < RETU_WDT_MIN_TIMER || new > RETU_WDT_MAX_TIMER)
2000+ return -EINVAL;
2001+
2002+ mutex_lock(&retu_wdt_mutex);
2003+ period_val = new;
2004+ _retu_modify_counter(period_val);
2005+ mutex_unlock(&retu_wdt_mutex);
2006+
2007+ return 0;
2008+}
2009+
2010+static ssize_t retu_wdt_period_show(struct device *dev,
2011+ struct device_attribute *attr, char *buf)
2012+{
2013+ /* Show current max counter */
2014+ return sprintf(buf, "%u\n", (u16)period_val);
2015+}
2016+
2017+/*
2018+ * Note: This inteface is non-standard and likely to disappear!
2019+ * Use /dev/watchdog instead, that's the standard.
2020+ */
2021+static ssize_t retu_wdt_period_store(struct device *dev,
2022+ struct device_attribute *attr,
2023+ const char *buf, size_t count)
2024+{
2025+ unsigned int new_period;
2026+ int ret;
2027+
2028+#ifdef CONFIG_WATCHDOG_NOWAYOUT
2029+ retu_wdt_set_ping_timer(0);
2030+#endif
2031+
2032+ if (sscanf(buf, "%u", &new_period) != 1) {
2033+ printk(KERN_ALERT "retu_wdt_period_store: Invalid input\n");
2034+ return -EINVAL;
2035+ }
2036+
2037+ ret = retu_modify_counter(new_period);
2038+ if (ret < 0)
2039+ return ret;
2040+
2041+ return strnlen(buf, count);
2042+}
2043+
2044+static ssize_t retu_wdt_counter_show(struct device *dev,
2045+ struct device_attribute *attr, char *buf)
2046+{
2047+ u16 counter;
2048+
2049+ /* Show current value in watchdog counter */
2050+ counter = retu_read_reg(dev, RETU_REG_WATCHDOG);
2051+
2052+ /* Only the 5 LSB are important */
2053+ return snprintf(buf, PAGE_SIZE, "%u\n", (counter & 0x3F));
2054+}
2055+
2056+static DEVICE_ATTR(period, S_IRUGO | S_IWUSR, retu_wdt_period_show, \
2057+ retu_wdt_period_store);
2058+static DEVICE_ATTR(counter, S_IRUGO, retu_wdt_counter_show, NULL);
2059+
2060+/*----------------------------------------------------------------------------*/
2061+
2062+/*
2063+ * Since retu watchdog cannot be disabled in hardware, we must kick it
2064+ * with a timer until userspace watchdog software takes over. Do this
2065+ * unless /dev/watchdog is open or CONFIG_WATCHDOG_NOWAYOUT is set.
2066+ */
2067+static void retu_wdt_set_ping_timer(unsigned long enable)
2068+{
2069+ _retu_modify_counter(RETU_WDT_MAX_TIMER);
2070+ if (enable)
2071+ mod_timer(&retu_wdt->ping_timer,
2072+ jiffies + RETU_WDT_DEFAULT_TIMER * HZ);
2073+ else
2074+ del_timer_sync(&retu_wdt->ping_timer);
2075+}
2076+
2077+static int retu_wdt_open(struct inode *inode, struct file *file)
2078+{
2079+ if (test_and_set_bit(1, (unsigned long *)&(retu_wdt->users)))
2080+ return -EBUSY;
2081+
2082+ file->private_data = (void *)retu_wdt;
2083+ retu_wdt_set_ping_timer(0);
2084+
2085+ return nonseekable_open(inode, file);
2086+}
2087+
2088+static int retu_wdt_release(struct inode *inode, struct file *file)
2089+{
2090+ struct retu_wdt_dev *wdev = file->private_data;
2091+
2092+#ifndef CONFIG_WATCHDOG_NOWAYOUT
2093+ retu_wdt_set_ping_timer(1);
2094+#endif
2095+ wdev->users = 0;
2096+
2097+ return 0;
2098+}
2099+
2100+static ssize_t retu_wdt_write(struct file *file, const char __user *data,
2101+ size_t len, loff_t *ppos)
2102+{
2103+ if (len)
2104+ retu_modify_counter(RETU_WDT_MAX_TIMER);
2105+
2106+ return len;
2107+}
2108+
2109+static long retu_wdt_ioctl(struct file *file, unsigned int cmd,
2110+ unsigned long arg)
2111+{
2112+ int new_margin;
2113+
2114+ static struct watchdog_info ident = {
2115+ .identity = "Retu Watchdog",
2116+ .options = WDIOF_SETTIMEOUT,
2117+ .firmware_version = 0,
2118+ };
2119+
2120+ switch (cmd) {
2121+ default:
2122+ return -ENOTTY;
2123+ case WDIOC_GETSUPPORT:
2124+ return copy_to_user((struct watchdog_info __user *)arg, &ident,
2125+ sizeof(ident));
2126+ case WDIOC_GETSTATUS:
2127+ return put_user(0, (int __user *)arg);
2128+ case WDIOC_GETBOOTSTATUS:
2129+ if (cpu_is_omap16xx())
2130+ return put_user(omap_readw(ARM_SYSST),
2131+ (int __user *)arg);
2132+ if (cpu_is_omap24xx())
2133+ return put_user(omap_prcm_get_reset_sources(),
2134+ (int __user *)arg);
2135+ case WDIOC_KEEPALIVE:
2136+ retu_modify_counter(RETU_WDT_MAX_TIMER);
2137+ break;
2138+ case WDIOC_SETTIMEOUT:
2139+ if (get_user(new_margin, (int __user *)arg))
2140+ return -EFAULT;
2141+ retu_modify_counter(new_margin);
2142+ /* Fall through */
2143+ case WDIOC_GETTIMEOUT:
2144+ return put_user(period_val, (int __user *)arg);
2145+ }
2146+
2147+ return 0;
2148+}
2149+
2150+/* Start kicking retu watchdog until user space starts doing the kicking */
2151+static int __devinit retu_wdt_ping(void)
2152+{
2153+#ifdef CONFIG_WATCHDOG_NOWAYOUT
2154+ retu_modify_counter(RETU_WDT_MAX_TIMER);
2155+#else
2156+ retu_wdt_set_ping_timer(1);
2157+#endif
2158+
2159+ return 0;
2160+}
2161+
2162+static const struct file_operations retu_wdt_fops = {
2163+ .owner = THIS_MODULE,
2164+ .write = retu_wdt_write,
2165+ .unlocked_ioctl = retu_wdt_ioctl,
2166+ .open = retu_wdt_open,
2167+ .release = retu_wdt_release,
2168+};
2169+
2170+/*----------------------------------------------------------------------------*/
2171+
2172+static int __init retu_wdt_probe(struct platform_device *pdev)
2173+{
2174+ struct retu_wdt_dev *wdev;
2175+ int ret;
2176+
2177+ wdev = kzalloc(sizeof(struct retu_wdt_dev), GFP_KERNEL);
2178+ if (!wdev)
2179+ return -ENOMEM;
2180+
2181+ wdev->dev = &pdev->dev;
2182+ wdev->users = 0;
2183+
2184+ ret = device_create_file(&pdev->dev, &dev_attr_period);
2185+ if (ret) {
2186+ dev_err(&pdev->dev, "Error creating sysfs period\n");
2187+ goto free1;
2188+ }
2189+
2190+ ret = device_create_file(&pdev->dev, &dev_attr_counter);
2191+ if (ret) {
2192+ dev_err(&pdev->dev, "Error creating sysfs counter\n");
2193+ goto free2;
2194+ }
2195+
2196+ platform_set_drvdata(pdev, wdev);
2197+ retu_wdt = wdev;
2198+ wdev->retu_wdt_miscdev.parent = &pdev->dev;
2199+ wdev->retu_wdt_miscdev.minor = WATCHDOG_MINOR;
2200+ wdev->retu_wdt_miscdev.name = "watchdog";
2201+ wdev->retu_wdt_miscdev.fops = &retu_wdt_fops;
2202+
2203+ ret = misc_register(&(wdev->retu_wdt_miscdev));
2204+ if (ret)
2205+ goto free3;
2206+
2207+ setup_timer(&wdev->ping_timer, retu_wdt_set_ping_timer, 1);
2208+
2209+ /* passed as module parameter? */
2210+ ret = retu_modify_counter(counter_param);
2211+ if (ret == -EINVAL) {
2212+ ret = retu_modify_counter(RETU_WDT_DEFAULT_TIMER);
2213+ dev_dbg(&pdev->dev, "Initializing to default value\n");
2214+ }
2215+
2216+ /* Kick the watchdog for kernel booting to finish */
2217+ retu_modify_counter(RETU_WDT_MAX_TIMER);
2218+
2219+ ret = retu_wdt_ping();
2220+ if (ret < 0) {
2221+ dev_err(&pdev->dev, "Failed to ping\n");
2222+ goto free4;
2223+ }
2224+
2225+ return 0;
2226+
2227+free4:
2228+ misc_deregister(&wdev->retu_wdt_miscdev);
2229+
2230+free3:
2231+ device_remove_file(&pdev->dev, &dev_attr_counter);
2232+
2233+free2:
2234+ device_remove_file(&pdev->dev, &dev_attr_period);
2235+
2236+free1:
2237+ kfree(wdev);
2238+
2239+ return ret;
2240+}
2241+
2242+static int __devexit retu_wdt_remove(struct platform_device *pdev)
2243+{
2244+ struct retu_wdt_dev *wdev;
2245+
2246+ wdev = platform_get_drvdata(pdev);
2247+ misc_deregister(&wdev->retu_wdt_miscdev);
2248+ device_remove_file(&pdev->dev, &dev_attr_period);
2249+ device_remove_file(&pdev->dev, &dev_attr_counter);
2250+ kfree(wdev);
2251+
2252+ return 0;
2253+}
2254+
2255+static struct platform_driver retu_wdt_driver = {
2256+ .remove = __exit_p(retu_wdt_remove),
2257+ .driver = {
2258+ .name = "retu-wdt",
2259+ },
2260+};
2261+
2262+static int __init retu_wdt_init(void)
2263+{
2264+ return platform_driver_probe(&retu_wdt_driver, retu_wdt_probe);
2265+}
2266+
2267+static void __exit retu_wdt_exit(void)
2268+{
2269+ platform_driver_unregister(&retu_wdt_driver);
2270+}
2271+
2272+module_init(retu_wdt_init);
2273+module_exit(retu_wdt_exit);
2274+module_param(counter_param, int, 0);
2275+
2276+MODULE_DESCRIPTION("Retu WatchDog");
2277+MODULE_AUTHOR("Amit Kucheria");
2278+MODULE_LICENSE("GPL");
2279+
2280--- /dev/null
2281+++ b/drivers/cbus/tahvo.c
2282@@ -0,0 +1,391 @@
2283+/**
2284+ * drivers/cbus/tahvo.c
2285+ *
2286+ * Support functions for Tahvo ASIC
2287+ *
2288+ * Copyright (C) 2004, 2005 Nokia Corporation
2289+ *
2290+ * Written by Juha Yrjölä <juha.yrjola@nokia.com>,
2291+ * David Weinehall <david.weinehall@nokia.com>, and
2292+ * Mikko Ylinen <mikko.k.ylinen@nokia.com>
2293+ *
2294+ * This file is subject to the terms and conditions of the GNU General
2295+ * Public License. See the file "COPYING" in the main directory of this
2296+ * archive for more details.
2297+ *
2298+ * This program is distributed in the hope that it will be useful,
2299+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2300+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2301+ * GNU General Public License for more details.
2302+ *
2303+ * You should have received a copy of the GNU General Public License
2304+ * along with this program; if not, write to the Free Software
2305+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2306+ */
2307+
2308+#include <linux/module.h>
2309+#include <linux/init.h>
2310+
2311+#include <linux/kernel.h>
2312+#include <linux/errno.h>
2313+#include <linux/device.h>
2314+#include <linux/miscdevice.h>
2315+#include <linux/poll.h>
2316+#include <linux/fs.h>
2317+#include <linux/irq.h>
2318+#include <linux/interrupt.h>
2319+#include <linux/platform_device.h>
2320+#include <linux/gpio.h>
2321+
2322+#include <asm/uaccess.h>
2323+#include <asm/mach-types.h>
2324+
2325+#include <plat/mux.h>
2326+#include <plat/board.h>
2327+
2328+#include "cbus.h"
2329+#include "tahvo.h"
2330+
2331+#define TAHVO_ID 0x02
2332+#define PFX "tahvo: "
2333+
2334+static int tahvo_initialized;
2335+static int tahvo_is_betty;
2336+
2337+static struct tasklet_struct tahvo_tasklet;
2338+spinlock_t tahvo_lock = SPIN_LOCK_UNLOCKED;
2339+
2340+struct tahvo_irq_handler_desc {
2341+ int (*func)(unsigned long);
2342+ unsigned long arg;
2343+ char name[8];
2344+};
2345+
2346+static struct tahvo_irq_handler_desc tahvo_irq_handlers[MAX_TAHVO_IRQ_HANDLERS];
2347+
2348+int tahvo_get_status(void)
2349+{
2350+ return tahvo_initialized;
2351+}
2352+EXPORT_SYMBOL(tahvo_get_status);
2353+
2354+/**
2355+ * tahvo_read_reg - Read a value from a register in Tahvo
2356+ * @reg: the register to read from
2357+ *
2358+ * This function returns the contents of the specified register
2359+ */
2360+int tahvo_read_reg(unsigned reg)
2361+{
2362+ BUG_ON(!tahvo_initialized);
2363+ return cbus_read_reg(TAHVO_ID, reg);
2364+}
2365+EXPORT_SYMBOL(tahvo_read_reg);
2366+
2367+/**
2368+ * tahvo_write_reg - Write a value to a register in Tahvo
2369+ * @reg: the register to write to
2370+ * @reg: the value to write to the register
2371+ *
2372+ * This function writes a value to the specified register
2373+ */
2374+void tahvo_write_reg(unsigned reg, u16 val)
2375+{
2376+ BUG_ON(!tahvo_initialized);
2377+ cbus_write_reg(TAHVO_ID, reg, val);
2378+}
2379+EXPORT_SYMBOL(tahvo_write_reg);
2380+
2381+/**
2382+ * tahvo_set_clear_reg_bits - set and clear register bits atomically
2383+ * @reg: the register to write to
2384+ * @bits: the bits to set
2385+ *
2386+ * This function sets and clears the specified Tahvo register bits atomically
2387+ */
2388+void tahvo_set_clear_reg_bits(unsigned reg, u16 set, u16 clear)
2389+{
2390+ unsigned long flags;
2391+ u16 w;
2392+
2393+ spin_lock_irqsave(&tahvo_lock, flags);
2394+ w = tahvo_read_reg(reg);
2395+ w &= ~clear;
2396+ w |= set;
2397+ tahvo_write_reg(reg, w);
2398+ spin_unlock_irqrestore(&tahvo_lock, flags);
2399+}
2400+
2401+/*
2402+ * Disable given TAHVO interrupt
2403+ */
2404+void tahvo_disable_irq(int id)
2405+{
2406+ unsigned long flags;
2407+ u16 mask;
2408+
2409+ spin_lock_irqsave(&tahvo_lock, flags);
2410+ mask = tahvo_read_reg(TAHVO_REG_IMR);
2411+ mask |= 1 << id;
2412+ tahvo_write_reg(TAHVO_REG_IMR, mask);
2413+ spin_unlock_irqrestore(&tahvo_lock, flags);
2414+}
2415+EXPORT_SYMBOL(tahvo_disable_irq);
2416+
2417+/*
2418+ * Enable given TAHVO interrupt
2419+ */
2420+void tahvo_enable_irq(int id)
2421+{
2422+ unsigned long flags;
2423+ u16 mask;
2424+
2425+ spin_lock_irqsave(&tahvo_lock, flags);
2426+ mask = tahvo_read_reg(TAHVO_REG_IMR);
2427+ mask &= ~(1 << id);
2428+ tahvo_write_reg(TAHVO_REG_IMR, mask);
2429+ spin_unlock_irqrestore(&tahvo_lock, flags);
2430+}
2431+EXPORT_SYMBOL(tahvo_enable_irq);
2432+
2433+/*
2434+ * Acknowledge given TAHVO interrupt
2435+ */
2436+void tahvo_ack_irq(int id)
2437+{
2438+ tahvo_write_reg(TAHVO_REG_IDR, 1 << id);
2439+}
2440+EXPORT_SYMBOL(tahvo_ack_irq);
2441+
2442+static int tahvo_7bit_backlight;
2443+
2444+int tahvo_get_backlight_level(void)
2445+{
2446+ int mask;
2447+
2448+ if (tahvo_7bit_backlight)
2449+ mask = 0x7f;
2450+ else
2451+ mask = 0x0f;
2452+ return tahvo_read_reg(TAHVO_REG_LEDPWMR) & mask;
2453+}
2454+EXPORT_SYMBOL(tahvo_get_backlight_level);
2455+
2456+int tahvo_get_max_backlight_level(void)
2457+{
2458+ if (tahvo_7bit_backlight)
2459+ return 0x7f;
2460+ else
2461+ return 0x0f;
2462+}
2463+EXPORT_SYMBOL(tahvo_get_max_backlight_level);
2464+
2465+void tahvo_set_backlight_level(int level)
2466+{
2467+ int max_level;
2468+
2469+ max_level = tahvo_get_max_backlight_level();
2470+ if (level > max_level)
2471+ level = max_level;
2472+ tahvo_write_reg(TAHVO_REG_LEDPWMR, level);
2473+}
2474+EXPORT_SYMBOL(tahvo_set_backlight_level);
2475+
2476+/*
2477+ * TAHVO interrupt handler. Only schedules the tasklet.
2478+ */
2479+static irqreturn_t tahvo_irq_handler(int irq, void *dev_id)
2480+{
2481+ tasklet_schedule(&tahvo_tasklet);
2482+ return IRQ_HANDLED;
2483+}
2484+
2485+/*
2486+ * Tasklet handler
2487+ */
2488+static void tahvo_tasklet_handler(unsigned long data)
2489+{
2490+ struct tahvo_irq_handler_desc *hnd;
2491+ u16 id;
2492+ u16 im;
2493+ int i;
2494+
2495+ for (;;) {
2496+ id = tahvo_read_reg(TAHVO_REG_IDR);
2497+ im = ~tahvo_read_reg(TAHVO_REG_IMR);
2498+ id &= im;
2499+
2500+ if (!id)
2501+ break;
2502+
2503+ for (i = 0; id != 0; i++, id >>= 1) {
2504+ if (!(id & 1))
2505+ continue;
2506+ hnd = &tahvo_irq_handlers[i];
2507+ if (hnd->func == NULL) {
2508+ /* Spurious tahvo interrupt - just ack it */
2509+ printk(KERN_INFO "Spurious Tahvo interrupt "
2510+ "(id %d)\n", i);
2511+ tahvo_disable_irq(i);
2512+ tahvo_ack_irq(i);
2513+ continue;
2514+ }
2515+ hnd->func(hnd->arg);
2516+ /*
2517+ * Don't acknowledge the interrupt here
2518+ * It must be done explicitly
2519+ */
2520+ }
2521+ }
2522+}
2523+
2524+/*
2525+ * Register the handler for a given TAHVO interrupt source.
2526+ */
2527+int tahvo_request_irq(int id, void *irq_handler, unsigned long arg, char *name)
2528+{
2529+ struct tahvo_irq_handler_desc *hnd;
2530+
2531+ if (irq_handler == NULL || id >= MAX_TAHVO_IRQ_HANDLERS ||
2532+ name == NULL) {
2533+ printk(KERN_ERR PFX "Invalid arguments to %s\n",
2534+ __FUNCTION__);
2535+ return -EINVAL;
2536+ }
2537+ hnd = &tahvo_irq_handlers[id];
2538+ if (hnd->func != NULL) {
2539+ printk(KERN_ERR PFX "IRQ %d already reserved\n", id);
2540+ return -EBUSY;
2541+ }
2542+ printk(KERN_INFO PFX "Registering interrupt %d for device %s\n",
2543+ id, name);
2544+ hnd->func = irq_handler;
2545+ hnd->arg = arg;
2546+ strlcpy(hnd->name, name, sizeof(hnd->name));
2547+
2548+ tahvo_ack_irq(id);
2549+ tahvo_enable_irq(id);
2550+
2551+ return 0;
2552+}
2553+EXPORT_SYMBOL(tahvo_request_irq);
2554+
2555+/*
2556+ * Unregister the handler for a given TAHVO interrupt source.
2557+ */
2558+void tahvo_free_irq(int id)
2559+{
2560+ struct tahvo_irq_handler_desc *hnd;
2561+
2562+ if (id >= MAX_TAHVO_IRQ_HANDLERS) {
2563+ printk(KERN_ERR PFX "Invalid argument to %s\n",
2564+ __FUNCTION__);
2565+ return;
2566+ }
2567+ hnd = &tahvo_irq_handlers[id];
2568+ if (hnd->func == NULL) {
2569+ printk(KERN_ERR PFX "IRQ %d already freed\n", id);
2570+ return;
2571+ }
2572+
2573+ tahvo_disable_irq(id);
2574+ hnd->func = NULL;
2575+}
2576+EXPORT_SYMBOL(tahvo_free_irq);
2577+
2578+/**
2579+ * tahvo_probe - Probe for Tahvo ASIC
2580+ * @dev: the Tahvo device
2581+ *
2582+ * Probe for the Tahvo ASIC and allocate memory
2583+ * for its device-struct if found
2584+ */
2585+static int __init tahvo_probe(struct platform_device *pdev)
2586+{
2587+ int rev, id, ret;
2588+ int irq;
2589+
2590+ /* Prepare tasklet */
2591+ tasklet_init(&tahvo_tasklet, tahvo_tasklet_handler, 0);
2592+
2593+ tahvo_initialized = 1;
2594+
2595+ rev = tahvo_read_reg(TAHVO_REG_ASICR);
2596+
2597+ id = (rev >> 8) & 0xff;
2598+ if (id == 0x03) {
2599+ if ((rev & 0xff) >= 0x50)
2600+ tahvo_7bit_backlight = 1;
2601+ } else if (id == 0x0b) {
2602+ tahvo_is_betty = 1;
2603+ tahvo_7bit_backlight = 1;
2604+ } else {
2605+ dev_err(&pdev->dev, "Tahvo/Betty chip not found");
2606+ return -ENODEV;
2607+ }
2608+
2609+ dev_err(&pdev->dev, "%s v%d.%d found\n", tahvo_is_betty ? "Betty" : "Tahvo",
2610+ (rev >> 4) & 0x0f, rev & 0x0f);
2611+
2612+ irq = platform_get_irq(pdev, 0);
2613+
2614+ /* Mask all TAHVO interrupts */
2615+ tahvo_write_reg(TAHVO_REG_IMR, 0xffff);
2616+
2617+ ret = request_irq(irq, tahvo_irq_handler, IRQF_TRIGGER_RISING,
2618+ "tahvo", 0);
2619+ if (ret < 0) {
2620+ dev_err(&pdev->dev, "Unable to register IRQ handler\n");
2621+ return ret;
2622+ }
2623+ return 0;
2624+}
2625+
2626+static int __exit tahvo_remove(struct platform_device *pdev)
2627+{
2628+ int irq;
2629+
2630+ irq = platform_get_irq(pdev, 0);
2631+
2632+ /* Mask all TAHVO interrupts */
2633+ tahvo_write_reg(TAHVO_REG_IMR, 0xffff);
2634+ free_irq(irq, 0);
2635+ tasklet_kill(&tahvo_tasklet);
2636+
2637+ return 0;
2638+}
2639+
2640+static struct platform_driver tahvo_driver = {
2641+ .remove = __exit_p(tahvo_remove),
2642+ .driver = {
2643+ .name = "tahvo",
2644+ },
2645+};
2646+
2647+/**
2648+ * tahvo_init - initialise Tahvo driver
2649+ *
2650+ * Initialise the Tahvo driver and return 0 if everything worked ok
2651+ */
2652+static int __init tahvo_init(void)
2653+{
2654+ return platform_driver_probe(&tahvo_driver, tahvo_probe);
2655+}
2656+
2657+/*
2658+ * Cleanup
2659+ */
2660+static void __exit tahvo_exit(void)
2661+{
2662+ platform_driver_unregister(&tahvo_driver);
2663+}
2664+
2665+subsys_initcall(tahvo_init);
2666+module_exit(tahvo_exit);
2667+
2668+MODULE_DESCRIPTION("Tahvo ASIC control");
2669+MODULE_LICENSE("GPL");
2670+MODULE_AUTHOR("Juha Yrjölä");
2671+MODULE_AUTHOR("David Weinehall");
2672+MODULE_AUTHOR("Mikko Ylinen");
2673+
2674--- /dev/null
2675+++ b/drivers/cbus/tahvo.h
2676@@ -0,0 +1,57 @@
2677+/*
2678+ * drivers/cbus/tahvo.h
2679+ *
2680+ * Copyright (C) 2004, 2005 Nokia Corporation
2681+ *
2682+ * Written by Juha Yrjölä <juha.yrjola@nokia.com> and
2683+ * David Weinehall <david.weinehall@nokia.com>
2684+ *
2685+ * This file is subject to the terms and conditions of the GNU General
2686+ * Public License. See the file "COPYING" in the main directory of this
2687+ * archive for more details.
2688+ *
2689+ * This program is distributed in the hope that it will be useful,
2690+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2691+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2692+ * GNU General Public License for more details.
2693+
2694+ * You should have received a copy of the GNU General Public License
2695+ * along with this program; if not, write to the Free Software
2696+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2697+ */
2698+
2699+#ifndef __DRIVERS_CBUS_TAHVO_H
2700+#define __DRIVERS_CBUS_TAHVO_H
2701+
2702+#include <linux/types.h>
2703+
2704+/* Registers */
2705+#define TAHVO_REG_ASICR 0x00 /* ASIC ID & revision */
2706+#define TAHVO_REG_IDR 0x01 /* Interrupt ID */
2707+#define TAHVO_REG_IDSR 0x02 /* Interrupt status */
2708+#define TAHVO_REG_IMR 0x03 /* Interrupt mask */
2709+#define TAHVO_REG_LEDPWMR 0x05 /* LED PWM */
2710+#define TAHVO_REG_USBR 0x06 /* USB control */
2711+#define TAHVO_REG_MAX 0x0d
2712+
2713+/* Interrupt sources */
2714+#define TAHVO_INT_VBUSON 0
2715+
2716+#define MAX_TAHVO_IRQ_HANDLERS 8
2717+
2718+int tahvo_get_status(void);
2719+int tahvo_read_reg(unsigned reg);
2720+void tahvo_write_reg(unsigned reg, u16 val);
2721+void tahvo_set_clear_reg_bits(unsigned reg, u16 set, u16 clear);
2722+int tahvo_request_irq(int id, void *irq_handler, unsigned long arg, char *name);
2723+void tahvo_free_irq(int id);
2724+void tahvo_enable_irq(int id);
2725+void tahvo_disable_irq(int id);
2726+void tahvo_ack_irq(int id);
2727+int tahvo_get_backlight_level(void);
2728+int tahvo_get_max_backlight_level(void);
2729+void tahvo_set_backlight_level(int level);
2730+
2731+extern spinlock_t tahvo_lock;
2732+
2733+#endif /* __DRIVERS_CBUS_TAHVO_H */
2734--- /dev/null
2735+++ b/drivers/cbus/tahvo-usb.c
2736@@ -0,0 +1,773 @@
2737+/**
2738+ * drivers/cbus/tahvo-usb.c
2739+ *
2740+ * Tahvo USB transeiver
2741+ *
2742+ * Copyright (C) 2005-2006 Nokia Corporation
2743+ *
2744+ * Parts copied from drivers/i2c/chips/isp1301_omap.c
2745+ * Copyright (C) 2004 Texas Instruments
2746+ * Copyright (C) 2004 David Brownell
2747+ *
2748+ * Written by Juha Yrjölä <juha.yrjola@nokia.com>,
2749+ * Tony Lindgren <tony@atomide.com>, and
2750+ * Timo Teräs <timo.teras@nokia.com>
2751+ *
2752+ * This file is subject to the terms and conditions of the GNU General
2753+ * Public License. See the file "COPYING" in the main directory of this
2754+ * archive for more details.
2755+ *
2756+ * This program is distributed in the hope that it will be useful,
2757+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2758+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2759+ * GNU General Public License for more details.
2760+ *
2761+ * You should have received a copy of the GNU General Public License
2762+ * along with this program; if not, write to the Free Software
2763+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2764+ */
2765+
2766+#include <linux/kernel.h>
2767+#include <linux/module.h>
2768+#include <linux/init.h>
2769+#include <linux/slab.h>
2770+#include <linux/io.h>
2771+#include <linux/interrupt.h>
2772+#include <linux/platform_device.h>
2773+#include <linux/usb/ch9.h>
2774+#include <linux/usb/gadget.h>
2775+#include <linux/usb.h>
2776+#include <linux/usb/otg.h>
2777+#include <linux/i2c.h>
2778+#include <linux/workqueue.h>
2779+#include <linux/kobject.h>
2780+#include <linux/clk.h>
2781+#include <linux/mutex.h>
2782+
2783+#include <asm/irq.h>
2784+#include <plat/usb.h>
2785+
2786+#include "cbus.h"
2787+#include "tahvo.h"
2788+
2789+#define DRIVER_NAME "tahvo-usb"
2790+
2791+#define USBR_SLAVE_CONTROL (1 << 8)
2792+#define USBR_VPPVIO_SW (1 << 7)
2793+#define USBR_SPEED (1 << 6)
2794+#define USBR_REGOUT (1 << 5)
2795+#define USBR_MASTER_SW2 (1 << 4)
2796+#define USBR_MASTER_SW1 (1 << 3)
2797+#define USBR_SLAVE_SW (1 << 2)
2798+#define USBR_NSUSPEND (1 << 1)
2799+#define USBR_SEMODE (1 << 0)
2800+
2801+/* bits in OTG_CTRL */
2802+
2803+/* Bits that are controlled by OMAP OTG and are read-only */
2804+#define OTG_CTRL_OMAP_MASK (OTG_PULLDOWN|OTG_PULLUP|OTG_DRV_VBUS|\
2805+ OTG_PD_VBUS|OTG_PU_VBUS|OTG_PU_ID)
2806+/* Bits that are controlled by transceiver */
2807+#define OTG_CTRL_XCVR_MASK (OTG_ASESSVLD|OTG_BSESSEND|\
2808+ OTG_BSESSVLD|OTG_VBUSVLD|OTG_ID)
2809+/* Bits that are controlled by system */
2810+#define OTG_CTRL_SYS_MASK (OTG_A_BUSREQ|OTG_A_SETB_HNPEN|OTG_B_BUSREQ|\
2811+ OTG_B_HNPEN|OTG_BUSDROP)
2812+
2813+#if defined(CONFIG_USB_OHCI_HCD) && !defined(CONFIG_USB_OTG)
2814+#error tahvo-otg.c does not work with OCHI yet!
2815+#endif
2816+
2817+#define TAHVO_MODE_HOST 0
2818+#define TAHVO_MODE_PERIPHERAL 1
2819+
2820+#ifdef CONFIG_USB_OTG
2821+#define TAHVO_MODE(tu) (tu)->tahvo_mode
2822+#elif defined(CONFIG_USB_GADGET_OMAP)
2823+#define TAHVO_MODE(tu) TAHVO_MODE_PERIPHERAL
2824+#else
2825+#define TAHVO_MODE(tu) TAHVO_MODE_HOST
2826+#endif
2827+
2828+struct tahvo_usb {
2829+ struct platform_device *pt_dev;
2830+ struct otg_transceiver otg;
2831+ int vbus_state;
2832+ struct work_struct irq_work;
2833+ struct mutex serialize;
2834+#ifdef CONFIG_USB_OTG
2835+ int tahvo_mode;
2836+#endif
2837+};
2838+static struct platform_device tahvo_usb_device;
2839+
2840+/*
2841+ * ---------------------------------------------------------------------------
2842+ * OTG related functions
2843+ *
2844+ * These shoud be separated into omap-otg.c driver module, as they are used
2845+ * by various transceivers. These functions are needed in the UDC-only case
2846+ * as well. These functions are copied from GPL isp1301_omap.c
2847+ * ---------------------------------------------------------------------------
2848+ */
2849+static struct platform_device *tahvo_otg_dev;
2850+
2851+static irqreturn_t omap_otg_irq(int irq, void *arg)
2852+{
2853+ struct platform_device *otg_dev = arg;
2854+ struct tahvo_usb *tu = platform_get_drvdata(otg_dev);
2855+ u16 otg_irq;
2856+
2857+ otg_irq = omap_readw(OTG_IRQ_SRC);
2858+ if (otg_irq & OPRT_CHG) {
2859+ omap_writew(OPRT_CHG, OTG_IRQ_SRC);
2860+ } else if (otg_irq & B_SRP_TMROUT) {
2861+ omap_writew(B_SRP_TMROUT, OTG_IRQ_SRC);
2862+ } else if (otg_irq & B_HNP_FAIL) {
2863+ omap_writew(B_HNP_FAIL, OTG_IRQ_SRC);
2864+ } else if (otg_irq & A_SRP_DETECT) {
2865+ omap_writew(A_SRP_DETECT, OTG_IRQ_SRC);
2866+ } else if (otg_irq & A_REQ_TMROUT) {
2867+ omap_writew(A_REQ_TMROUT, OTG_IRQ_SRC);
2868+ } else if (otg_irq & A_VBUS_ERR) {
2869+ omap_writew(A_VBUS_ERR, OTG_IRQ_SRC);
2870+ } else if (otg_irq & DRIVER_SWITCH) {
2871+#ifdef CONFIG_USB_OTG
2872+ if ((!(omap_readl(OTG_CTRL) & OTG_DRIVER_SEL)) &&
2873+ tu->otg.host && tu->otg.state == OTG_STATE_A_HOST) {
2874+ /* role is host */
2875+ usb_bus_start_enum(tu->otg.host,
2876+ tu->otg.host->otg_port);
2877+ }
2878+#endif
2879+ omap_writew(DRIVER_SWITCH, OTG_IRQ_SRC);
2880+ } else
2881+ return IRQ_NONE;
2882+
2883+ return IRQ_HANDLED;
2884+
2885+}
2886+
2887+static int tahvo_otg_init(void)
2888+{
2889+ u32 l;
2890+
2891+#ifdef CONFIG_USB_OTG
2892+ if (!tahvo_otg_dev) {
2893+ printk("tahvo-usb: no tahvo_otg_dev\n");
2894+ return -ENODEV;
2895+ }
2896+#endif
2897+
2898+ l = omap_readl(OTG_SYSCON_1);
2899+ l &= ~OTG_IDLE_EN;
2900+ omap_writel(l, OTG_SYSCON_1);
2901+ udelay(100);
2902+
2903+ /* some of these values are board-specific... */
2904+ l = omap_readl(OTG_SYSCON_2);
2905+ l |= OTG_EN
2906+ /* for B-device: */
2907+ | SRP_GPDATA /* 9msec Bdev D+ pulse */
2908+ | SRP_GPDVBUS /* discharge after VBUS pulse */
2909+ // | (3 << 24) /* 2msec VBUS pulse */
2910+ /* for A-device: */
2911+ | (0 << 20) /* 200ms nominal A_WAIT_VRISE timer */
2912+ | SRP_DPW /* detect 167+ns SRP pulses */
2913+ | SRP_DATA | SRP_VBUS; /* accept both kinds of SRP pulse */
2914+ omap_writel(l, OTG_SYSCON_2);
2915+
2916+ omap_writew(DRIVER_SWITCH | OPRT_CHG
2917+ | B_SRP_TMROUT | B_HNP_FAIL
2918+ | A_VBUS_ERR | A_SRP_DETECT | A_REQ_TMROUT,
2919+ OTG_IRQ_EN);
2920+ l = omap_readl(OTG_SYSCON_2);
2921+ l |= OTG_EN;
2922+ omap_writel(l, OTG_SYSCON_2);
2923+
2924+ return 0;
2925+}
2926+
2927+static int __init omap_otg_probe(struct platform_device *pdev)
2928+{
2929+ int ret;
2930+
2931+ tahvo_otg_dev = pdev;
2932+ ret = tahvo_otg_init();
2933+ if (ret != 0) {
2934+ printk(KERN_ERR "tahvo-usb: tahvo_otg_init failed\n");
2935+ return ret;
2936+ }
2937+
2938+ return request_irq(tahvo_otg_dev->resource[1].start,
2939+ omap_otg_irq, IRQF_DISABLED, DRIVER_NAME,
2940+ &tahvo_usb_device);
2941+}
2942+
2943+static int __exit omap_otg_remove(struct platform_device *pdev)
2944+{
2945+ free_irq(tahvo_otg_dev->resource[1].start, &tahvo_usb_device);
2946+ tahvo_otg_dev = NULL;
2947+
2948+ return 0;
2949+}
2950+
2951+struct platform_driver omap_otg_driver = {
2952+ .driver = {
2953+ .name = "omap_otg",
2954+ },
2955+ .remove = __exit_p(omap_otg_remove),
2956+};
2957+
2958+/*
2959+ * ---------------------------------------------------------------------------
2960+ * Tahvo related functions
2961+ * These are Nokia proprietary code, except for the OTG register settings,
2962+ * which are copied from isp1301.c
2963+ * ---------------------------------------------------------------------------
2964+ */
2965+static ssize_t vbus_state_show(struct device *device,
2966+ struct device_attribute *attr, char *buf)
2967+{
2968+ struct tahvo_usb *tu = dev_get_drvdata(device);
2969+ return sprintf(buf, "%d\n", tu->vbus_state);
2970+}
2971+static DEVICE_ATTR(vbus_state, 0444, vbus_state_show, NULL);
2972+
2973+int vbus_active = 0;
2974+
2975+#if 0
2976+
2977+static int host_suspend(struct tahvo_usb *tu)
2978+{
2979+ struct device *dev;
2980+
2981+ if (!tu->otg.host)
2982+ return -ENODEV;
2983+
2984+ /* Currently ASSUMES only the OTG port matters;
2985+ * other ports could be active...
2986+ */
2987+ dev = tu->otg.host->controller;
2988+ return dev->driver->suspend(dev, PMSG_SUSPEND);
2989+}
2990+
2991+static int host_resume(struct tahvo_usb *tu)
2992+{
2993+ struct device *dev;
2994+
2995+ if (!tu->otg.host)
2996+ return -ENODEV;
2997+
2998+ dev = tu->otg.host->controller;
2999+ return dev->driver->resume(dev);
3000+}
3001+
3002+#else
3003+
3004+static int host_suspend(struct tahvo_usb *tu)
3005+{
3006+ return 0;
3007+}
3008+
3009+static int host_resume(struct tahvo_usb *tu)
3010+{
3011+ return 0;
3012+}
3013+
3014+#endif
3015+
3016+static void check_vbus_state(struct tahvo_usb *tu)
3017+{
3018+ int reg, prev_state;
3019+
3020+ reg = tahvo_read_reg(TAHVO_REG_IDSR);
3021+ if (reg & 0x01) {
3022+ u32 l;
3023+
3024+ vbus_active = 1;
3025+ switch (tu->otg.state) {
3026+ case OTG_STATE_B_IDLE:
3027+ /* Enable the gadget driver */
3028+ if (tu->otg.gadget)
3029+ usb_gadget_vbus_connect(tu->otg.gadget);
3030+ /* Set B-session valid and not B-sessio ended to indicate
3031+ * Vbus to be ok. */
3032+ l = omap_readl(OTG_CTRL);
3033+ l &= ~OTG_BSESSEND;
3034+ l |= OTG_BSESSVLD;
3035+ omap_writel(l, OTG_CTRL);
3036+
3037+ tu->otg.state = OTG_STATE_B_PERIPHERAL;
3038+ break;
3039+ case OTG_STATE_A_IDLE:
3040+ /* Session is now valid assuming the USB hub is driving Vbus */
3041+ tu->otg.state = OTG_STATE_A_HOST;
3042+ host_resume(tu);
3043+ break;
3044+ default:
3045+ break;
3046+ }
3047+ printk("USB cable connected\n");
3048+ } else {
3049+ switch (tu->otg.state) {
3050+ case OTG_STATE_B_PERIPHERAL:
3051+ if (tu->otg.gadget)
3052+ usb_gadget_vbus_disconnect(tu->otg.gadget);
3053+ tu->otg.state = OTG_STATE_B_IDLE;
3054+ break;
3055+ case OTG_STATE_A_HOST:
3056+ tu->otg.state = OTG_STATE_A_IDLE;
3057+ break;
3058+ default:
3059+ break;
3060+ }
3061+ printk("USB cable disconnected\n");
3062+ vbus_active = 0;
3063+ }
3064+
3065+ prev_state = tu->vbus_state;
3066+ tu->vbus_state = reg & 0x01;
3067+ if (prev_state != tu->vbus_state)
3068+ sysfs_notify(&tu->pt_dev->dev.kobj, NULL, "vbus_state");
3069+}
3070+
3071+static void tahvo_usb_become_host(struct tahvo_usb *tu)
3072+{
3073+ u32 l;
3074+
3075+ /* Clear system and transceiver controlled bits
3076+ * also mark the A-session is always valid */
3077+ tahvo_otg_init();
3078+
3079+ l = omap_readl(OTG_CTRL);
3080+ l &= ~(OTG_CTRL_XCVR_MASK | OTG_CTRL_SYS_MASK);
3081+ l |= OTG_ASESSVLD;
3082+ omap_writel(l, OTG_CTRL);
3083+
3084+ /* Power up the transceiver in USB host mode */
3085+ tahvo_write_reg(TAHVO_REG_USBR, USBR_REGOUT | USBR_NSUSPEND |
3086+ USBR_MASTER_SW2 | USBR_MASTER_SW1);
3087+ tu->otg.state = OTG_STATE_A_IDLE;
3088+
3089+ check_vbus_state(tu);
3090+}
3091+
3092+static void tahvo_usb_stop_host(struct tahvo_usb *tu)
3093+{
3094+ host_suspend(tu);
3095+ tu->otg.state = OTG_STATE_A_IDLE;
3096+}
3097+
3098+static void tahvo_usb_become_peripheral(struct tahvo_usb *tu)
3099+{
3100+ u32 l;
3101+
3102+ /* Clear system and transceiver controlled bits
3103+ * and enable ID to mark peripheral mode and
3104+ * BSESSEND to mark no Vbus */
3105+ tahvo_otg_init();
3106+ l = omap_readl(OTG_CTRL);
3107+ l &= ~(OTG_CTRL_XCVR_MASK | OTG_CTRL_SYS_MASK | OTG_BSESSVLD);
3108+ l |= OTG_ID | OTG_BSESSEND;
3109+ omap_writel(l, OTG_CTRL);
3110+
3111+ /* Power up transceiver and set it in USB perhiperal mode */
3112+ tahvo_write_reg(TAHVO_REG_USBR, USBR_SLAVE_CONTROL | USBR_REGOUT | USBR_NSUSPEND | USBR_SLAVE_SW);
3113+ tu->otg.state = OTG_STATE_B_IDLE;
3114+
3115+ check_vbus_state(tu);
3116+}
3117+
3118+static void tahvo_usb_stop_peripheral(struct tahvo_usb *tu)
3119+{
3120+ u32 l;
3121+
3122+ l = omap_readl(OTG_CTRL);
3123+ l &= ~OTG_BSESSVLD;
3124+ l |= OTG_BSESSEND;
3125+ omap_writel(l, OTG_CTRL);
3126+
3127+ if (tu->otg.gadget)
3128+ usb_gadget_vbus_disconnect(tu->otg.gadget);
3129+ tu->otg.state = OTG_STATE_B_IDLE;
3130+
3131+}
3132+
3133+static void tahvo_usb_power_off(struct tahvo_usb *tu)
3134+{
3135+ u32 l;
3136+ int id;
3137+
3138+ /* Disable gadget controller if any */
3139+ if (tu->otg.gadget)
3140+ usb_gadget_vbus_disconnect(tu->otg.gadget);
3141+
3142+ host_suspend(tu);
3143+
3144+ /* Disable OTG and interrupts */
3145+ if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL)
3146+ id = OTG_ID;
3147+ else
3148+ id = 0;
3149+ l = omap_readl(OTG_CTRL);
3150+ l &= ~(OTG_CTRL_XCVR_MASK | OTG_CTRL_SYS_MASK | OTG_BSESSVLD);
3151+ l |= id | OTG_BSESSEND;
3152+ omap_writel(l, OTG_CTRL);
3153+ omap_writew(0, OTG_IRQ_EN);
3154+
3155+ l = omap_readl(OTG_SYSCON_2);
3156+ l &= ~OTG_EN;
3157+ omap_writel(l, OTG_SYSCON_2);
3158+
3159+ l = omap_readl(OTG_SYSCON_1);
3160+ l |= OTG_IDLE_EN;
3161+ omap_writel(l, OTG_SYSCON_1);
3162+
3163+ /* Power off transceiver */
3164+ tahvo_write_reg(TAHVO_REG_USBR, 0);
3165+ tu->otg.state = OTG_STATE_UNDEFINED;
3166+}
3167+
3168+
3169+static int tahvo_usb_set_power(struct otg_transceiver *dev, unsigned mA)
3170+{
3171+ struct tahvo_usb *tu = container_of(dev, struct tahvo_usb, otg);
3172+
3173+ dev_dbg(&tu->pt_dev->dev, "set_power %d mA\n", mA);
3174+
3175+ if (dev->state == OTG_STATE_B_PERIPHERAL) {
3176+ /* REVISIT: Can Tahvo charge battery from VBUS? */
3177+ }
3178+ return 0;
3179+}
3180+
3181+static int tahvo_usb_set_suspend(struct otg_transceiver *dev, int suspend)
3182+{
3183+ struct tahvo_usb *tu = container_of(dev, struct tahvo_usb, otg);
3184+ u16 w;
3185+
3186+ dev_dbg(&tu->pt_dev->dev, "set_suspend\n");
3187+
3188+ w = tahvo_read_reg(TAHVO_REG_USBR);
3189+ if (suspend)
3190+ w &= ~USBR_NSUSPEND;
3191+ else
3192+ w |= USBR_NSUSPEND;
3193+ tahvo_write_reg(TAHVO_REG_USBR, w);
3194+
3195+ return 0;
3196+}
3197+
3198+static int tahvo_usb_start_srp(struct otg_transceiver *dev)
3199+{
3200+ struct tahvo_usb *tu = container_of(dev, struct tahvo_usb, otg);
3201+ u32 otg_ctrl;
3202+
3203+ dev_dbg(&tu->pt_dev->dev, "start_srp\n");
3204+
3205+ if (!dev || tu->otg.state != OTG_STATE_B_IDLE)
3206+ return -ENODEV;
3207+
3208+ otg_ctrl = omap_readl(OTG_CTRL);
3209+ if (!(otg_ctrl & OTG_BSESSEND))
3210+ return -EINVAL;
3211+
3212+ otg_ctrl |= OTG_B_BUSREQ;
3213+ otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_SYS_MASK;
3214+ omap_writel(otg_ctrl, OTG_CTRL);
3215+ tu->otg.state = OTG_STATE_B_SRP_INIT;
3216+
3217+ return 0;
3218+}
3219+
3220+static int tahvo_usb_start_hnp(struct otg_transceiver *otg)
3221+{
3222+ struct tahvo_usb *tu = container_of(otg, struct tahvo_usb, otg);
3223+
3224+ dev_dbg(&tu->pt_dev->dev, "start_hnp\n");
3225+#ifdef CONFIG_USB_OTG
3226+ /* REVISIT: Add this for OTG */
3227+#endif
3228+ return -EINVAL;
3229+}
3230+
3231+static int tahvo_usb_set_host(struct otg_transceiver *otg, struct usb_bus *host)
3232+{
3233+ struct tahvo_usb *tu = container_of(otg, struct tahvo_usb, otg);
3234+ u32 l;
3235+
3236+ dev_dbg(&tu->pt_dev->dev, "set_host %p\n", host);
3237+
3238+ if (otg == NULL)
3239+ return -ENODEV;
3240+
3241+#if defined(CONFIG_USB_OTG) || !defined(CONFIG_USB_GADGET_OMAP)
3242+
3243+ mutex_lock(&tu->serialize);
3244+
3245+ if (host == NULL) {
3246+ if (TAHVO_MODE(tu) == TAHVO_MODE_HOST)
3247+ tahvo_usb_power_off(tu);
3248+ tu->otg.host = NULL;
3249+ mutex_unlock(&tu->serialize);
3250+ return 0;
3251+ }
3252+
3253+ l = omap_readl(OTG_SYSCON_1);
3254+ l &= ~(OTG_IDLE_EN | HST_IDLE_EN | DEV_IDLE_EN);
3255+ omap_writel(l, OTG_SYSCON_1);
3256+
3257+ if (TAHVO_MODE(tu) == TAHVO_MODE_HOST) {
3258+ tu->otg.host = NULL;
3259+ tahvo_usb_become_host(tu);
3260+ } else
3261+ host_suspend(tu);
3262+
3263+ tu->otg.host = host;
3264+
3265+ mutex_unlock(&tu->serialize);
3266+#else
3267+ /* No host mode configured, so do not allow host controlled to be set */
3268+ return -EINVAL;
3269+#endif
3270+
3271+ return 0;
3272+}
3273+
3274+static int tahvo_usb_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget)
3275+{
3276+ struct tahvo_usb *tu = container_of(otg, struct tahvo_usb, otg);
3277+
3278+ dev_dbg(&tu->pt_dev->dev, "set_peripheral %p\n", gadget);
3279+
3280+ if (!otg)
3281+ return -ENODEV;
3282+
3283+#if defined(CONFIG_USB_OTG) || defined(CONFIG_USB_GADGET_OMAP)
3284+
3285+ mutex_lock(&tu->serialize);
3286+
3287+ if (!gadget) {
3288+ if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL)
3289+ tahvo_usb_power_off(tu);
3290+ tu->otg.gadget = NULL;
3291+ mutex_unlock(&tu->serialize);
3292+ return 0;
3293+ }
3294+
3295+ tu->otg.gadget = gadget;
3296+ if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL)
3297+ tahvo_usb_become_peripheral(tu);
3298+
3299+ mutex_unlock(&tu->serialize);
3300+#else
3301+ /* No gadget mode configured, so do not allow host controlled to be set */
3302+ return -EINVAL;
3303+#endif
3304+
3305+ return 0;
3306+}
3307+
3308+static void tahvo_usb_irq_work(struct work_struct *work)
3309+{
3310+ struct tahvo_usb *tu = container_of(work, struct tahvo_usb, irq_work);
3311+
3312+ mutex_lock(&tu->serialize);
3313+ check_vbus_state(tu);
3314+ mutex_unlock(&tu->serialize);
3315+}
3316+
3317+static void tahvo_usb_vbus_interrupt(unsigned long arg)
3318+{
3319+ struct tahvo_usb *tu = (struct tahvo_usb *) arg;
3320+
3321+ tahvo_ack_irq(TAHVO_INT_VBUSON);
3322+ /* Seems we need this to acknowledge the interrupt */
3323+ tahvo_read_reg(TAHVO_REG_IDSR);
3324+ schedule_work(&tu->irq_work);
3325+}
3326+
3327+#ifdef CONFIG_USB_OTG
3328+static ssize_t otg_mode_show(struct device *device,
3329+ struct device_attribute *attr, char *buf)
3330+{
3331+ struct tahvo_usb *tu = dev_get_drvdata(device);
3332+ switch (tu->tahvo_mode) {
3333+ case TAHVO_MODE_HOST:
3334+ return sprintf(buf, "host\n");
3335+ case TAHVO_MODE_PERIPHERAL:
3336+ return sprintf(buf, "peripheral\n");
3337+ }
3338+ return sprintf(buf, "unknown\n");
3339+}
3340+
3341+static ssize_t otg_mode_store(struct device *device,
3342+ struct device_attribute *attr,
3343+ const char *buf, size_t count)
3344+{
3345+ struct tahvo_usb *tu = dev_get_drvdata(device);
3346+ int r;
3347+
3348+ r = strlen(buf);
3349+ mutex_lock(&tu->serialize);
3350+ if (strncmp(buf, "host", 4) == 0) {
3351+ if (tu->tahvo_mode == TAHVO_MODE_PERIPHERAL)
3352+ tahvo_usb_stop_peripheral(tu);
3353+ tu->tahvo_mode = TAHVO_MODE_HOST;
3354+ if (tu->otg.host) {
3355+ printk(KERN_INFO "Selected HOST mode: host controller present.\n");
3356+ tahvo_usb_become_host(tu);
3357+ } else {
3358+ printk(KERN_INFO "Selected HOST mode: no host controller, powering off.\n");
3359+ tahvo_usb_power_off(tu);
3360+ }
3361+ } else if (strncmp(buf, "peripheral", 10) == 0) {
3362+ if (tu->tahvo_mode == TAHVO_MODE_HOST)
3363+ tahvo_usb_stop_host(tu);
3364+ tu->tahvo_mode = TAHVO_MODE_PERIPHERAL;
3365+ if (tu->otg.gadget) {
3366+ printk(KERN_INFO "Selected PERIPHERAL mode: gadget driver present.\n");
3367+ tahvo_usb_become_peripheral(tu);
3368+ } else {
3369+ printk(KERN_INFO "Selected PERIPHERAL mode: no gadget driver, powering off.\n");
3370+ tahvo_usb_power_off(tu);
3371+ }
3372+ } else
3373+ r = -EINVAL;
3374+
3375+ mutex_unlock(&tu->serialize);
3376+ return r;
3377+}
3378+
3379+static DEVICE_ATTR(otg_mode, 0644, otg_mode_show, otg_mode_store);
3380+#endif
3381+
3382+static int __init tahvo_usb_probe(struct platform_device *pdev)
3383+{
3384+ struct tahvo_usb *tu;
3385+ struct device *dev = &pdev->dev;
3386+ int ret;
3387+
3388+ ret = tahvo_get_status();
3389+ if (!ret)
3390+ return -ENODEV;
3391+
3392+ dev_dbg(dev, "probe\n");
3393+
3394+ /* Create driver data */
3395+ tu = kzalloc(sizeof(*tu), GFP_KERNEL);
3396+ if (!tu)
3397+ return -ENOMEM;
3398+
3399+ tu->pt_dev = container_of(dev, struct platform_device, dev);
3400+#ifdef CONFIG_USB_OTG
3401+ /* Default mode */
3402+#ifdef CONFIG_CBUS_TAHVO_USB_HOST_BY_DEFAULT
3403+ tu->tahvo_mode = TAHVO_MODE_HOST;
3404+#else
3405+ tu->tahvo_mode = TAHVO_MODE_PERIPHERAL;
3406+#endif
3407+#endif
3408+
3409+ INIT_WORK(&tu->irq_work, tahvo_usb_irq_work);
3410+ mutex_init(&tu->serialize);
3411+
3412+ /* Set initial state, so that we generate kevents only on
3413+ * state changes */
3414+ tu->vbus_state = tahvo_read_reg(TAHVO_REG_IDSR) & 0x01;
3415+
3416+ /* We cannot enable interrupt until omap_udc is initialized */
3417+ ret = tahvo_request_irq(TAHVO_INT_VBUSON, tahvo_usb_vbus_interrupt,
3418+ (unsigned long) tu, "vbus_interrupt");
3419+ if (ret != 0) {
3420+ kfree(tu);
3421+ printk(KERN_ERR "Could not register Tahvo interrupt for VBUS\n");
3422+ return ret;
3423+ }
3424+
3425+ /* Attributes */
3426+ ret = device_create_file(dev, &dev_attr_vbus_state);
3427+#ifdef CONFIG_USB_OTG
3428+ ret |= device_create_file(dev, &dev_attr_otg_mode);
3429+#endif
3430+ if (ret)
3431+ printk(KERN_ERR "attribute creation failed: %d\n", ret);
3432+
3433+ /* Create OTG interface */
3434+ tahvo_usb_power_off(tu);
3435+ tu->otg.state = OTG_STATE_UNDEFINED;
3436+ tu->otg.label = DRIVER_NAME;
3437+ tu->otg.set_host = tahvo_usb_set_host;
3438+ tu->otg.set_peripheral = tahvo_usb_set_peripheral;
3439+ tu->otg.set_power = tahvo_usb_set_power;
3440+ tu->otg.set_suspend = tahvo_usb_set_suspend;
3441+ tu->otg.start_srp = tahvo_usb_start_srp;
3442+ tu->otg.start_hnp = tahvo_usb_start_hnp;
3443+
3444+ ret = otg_set_transceiver(&tu->otg);
3445+ if (ret < 0) {
3446+ printk(KERN_ERR "Cannot register USB transceiver\n");
3447+ kfree(tu);
3448+ tahvo_free_irq(TAHVO_INT_VBUSON);
3449+ return ret;
3450+ }
3451+
3452+ dev_set_drvdata(dev, tu);
3453+
3454+ /* Act upon current vbus state once at startup. A vbus state irq may or
3455+ * may not be generated in addition to this. */
3456+ schedule_work(&tu->irq_work);
3457+ return 0;
3458+}
3459+
3460+static int __exit tahvo_usb_remove(struct platform_device *pdev)
3461+{
3462+ dev_dbg(&pdev->dev, "remove\n");
3463+
3464+ tahvo_free_irq(TAHVO_INT_VBUSON);
3465+ flush_scheduled_work();
3466+ otg_set_transceiver(0);
3467+ device_remove_file(&pdev->dev, &dev_attr_vbus_state);
3468+#ifdef CONFIG_USB_OTG
3469+ device_remove_file(&pdev->dev, &dev_attr_otg_mode);
3470+#endif
3471+ return 0;
3472+}
3473+
3474+static struct platform_driver tahvo_usb_driver = {
3475+ .driver = {
3476+ .name = "tahvo-usb",
3477+ },
3478+ .remove = __exit_p(tahvo_usb_remove),
3479+};
3480+
3481+static int __init tahvo_usb_init(void)
3482+{
3483+ int ret = 0;
3484+
3485+ ret = platform_driver_probe(&tahvo_usb_driver, tahvo_usb_probe);
3486+ if (ret)
3487+ return ret;
3488+
3489+ ret = platform_driver_probe(&omap_otg_driver, omap_otg_probe);
3490+ if (ret) {
3491+ platform_driver_unregister(&tahvo_usb_driver);
3492+ return ret;
3493+ }
3494+
3495+ return 0;
3496+}
3497+
3498+subsys_initcall(tahvo_usb_init);
3499+
3500+static void __exit tahvo_usb_exit(void)
3501+{
3502+ platform_driver_unregister(&omap_otg_driver);
3503+ platform_driver_unregister(&tahvo_usb_driver);
3504+}
3505+module_exit(tahvo_usb_exit);
3506+
3507+MODULE_DESCRIPTION("Tahvo USB OTG Transceiver Driver");
3508+MODULE_LICENSE("GPL");
3509+MODULE_AUTHOR("Juha Yrjölä, Tony Lindgren, and Timo Teräs");
3510--- a/drivers/Makefile
3511+++ b/drivers/Makefile
3512@@ -74,7 +74,7 @@ obj-$(CONFIG_GAMEPORT) += input/gamepor
3513 obj-$(CONFIG_INPUT) += input/
3514 obj-$(CONFIG_I2O) += message/
3515 obj-$(CONFIG_RTC_LIB) += rtc/
3516-obj-y += i2c/ media/
3517+obj-y += i2c/ media/ cbus/
3518 obj-$(CONFIG_PPS) += pps/
3519 obj-$(CONFIG_W1) += w1/
3520 obj-$(CONFIG_POWER_SUPPLY) += power/
3521--- a/arch/arm/Kconfig
3522+++ b/arch/arm/Kconfig
3523@@ -1930,6 +1930,10 @@ source "net/Kconfig"
3524 
3525 source "drivers/Kconfig"
3526 
3527+if ARCH_OMAP
3528+source "drivers/cbus/Kconfig"
3529+endif
3530+
3531 source "fs/Kconfig"
3532 
3533 source "arch/arm/Kconfig.debug"
3534

Archive Download this file



interactive