1 Index: linux-2.6.30.9/drivers/spi/Kconfig
2 ===================================================================
3 --- linux-2.6.30.9.orig/drivers/spi/Kconfig 2009-11-24 21:09:23.000000000 +0100
4 +++ linux-2.6.30.9/drivers/spi/Kconfig 2009-11-24 21:09:53.000000000 +0100
10 + tristate "EP93xx SSP SPI master"
11 + depends on SPI_MASTER && ARCH_EP93XX && EXPERIMENTAL
13 + This enables the EP93xx SPI master controller.
16 tristate "Freescale iMX SPI controller"
17 depends on ARCH_IMX && EXPERIMENTAL
18 Index: linux-2.6.30.9/drivers/spi/Makefile
19 ===================================================================
20 --- linux-2.6.30.9.orig/drivers/spi/Makefile 2009-11-24 21:09:23.000000000 +0100
21 +++ linux-2.6.30.9/drivers/spi/Makefile 2009-11-24 21:09:53.000000000 +0100
23 obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
24 obj-$(CONFIG_SPI_AU1550) += au1550_spi.o
25 obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o
26 +obj-$(CONFIG_SPI_EP93XX) += spi_ep93xx.o
27 obj-$(CONFIG_SPI_GPIO) += spi_gpio.o
28 obj-$(CONFIG_SPI_GPIO_OLD) += spi_gpio_old.o
29 obj-$(CONFIG_SPI_IMX) += spi_imx.o
30 Index: linux-2.6.30.9/drivers/spi/spi_ep93xx.c
31 ===================================================================
32 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
33 +++ linux-2.6.30.9/drivers/spi/spi_ep93xx.c 2009-11-24 21:21:25.000000000 +0100
36 + * linux/drivers/spi/spi_ep93xx.c
38 + * Copyright (C) 2007 Manfred Gruber <m.gruber@tirol.com>
39 + * Small changes by Peter Ivanov <ivanovp@gmail.com> to support MMC over SPI, 2008
40 + * SIM.ONE changes by Nuccio Raciti Simplemachine <nuccio.raciti@gmail.com>
42 + * Based on pxa2xx_spi.c/spi_imx.c and bitbang.c driver
44 + * This program is free software; you can redistribute it and/or modify
45 + * it under the terms of the GNU General Public License version 2 as
46 + * published by the Free Software Foundation.
50 +#include <linux/blkdev.h>
51 +#include <linux/clk.h>
52 +#include <linux/delay.h>
53 +#include <linux/dma-mapping.h>
54 +#include <linux/err.h>
55 +#include <linux/errno.h>
56 +#include <linux/init.h>
57 +#include <linux/io.h>
58 +#include <linux/interrupt.h>
59 +#include <linux/platform_device.h>
60 +#include <linux/spinlock.h>
61 +#include <linux/workqueue.h>
63 +#include <linux/spi/spi.h>
65 +#include <mach/hardware.h>
66 +#include <mach/ep93xx-regs.h>
67 +#include <asm/gpio.h>
69 +/* #define SPI_EP93XX_DEBUG */
71 +#define DEFINE_SSP_REG(reg, off) \
72 + static inline u32 read_##reg(void *p) \
73 + { return __raw_readl(p + (off)); } \
74 + static inline void write_##reg(u32 v, void *p) \
75 + { __raw_writel(v, p + (off)); }
77 +DEFINE_SSP_REG(SSPCR0, 0x00)
78 +DEFINE_SSP_REG(SSPCR1, 0x04)
79 +DEFINE_SSP_REG(SSPDR, 0x08)
80 +DEFINE_SSP_REG(SSPSR, 0x0c)
81 +DEFINE_SSP_REG(SSPCPSR, 0x10)
82 +DEFINE_SSP_REG(SSPIIR, 0x14)
83 +DEFINE_SSP_REG(SSPICR, 0x14)
86 +#define SSPCR0_DSS_MASK 0x0000000f
87 +#define SSPCR0_FRF_MASK 0x00000030
88 +#define SSPCR0_FRF_SHIFT 4
89 +#define SSPCR0_FRF_MOTOROLA (0 << SSPCR0_FRF_SHIFT)
90 +#define SSPCR0_FRF_TI (1 << SSPCR0_FRF_SHIFT)
91 +#define SSPCR0_FRF_NI (2 << SSPCR0_FRF_SHIFT)
92 +#define SSPCR0_SPO 0x00000040
93 +#define SSPCR0_SPH 0x00000080
94 +#define SSPCR0_SCR_MASK 0x0000ff00
95 +#define SSPCR0_SCR_SHIFT 8
98 +#define SSPC1_RIE 0x00000001
99 +#define SSPC1_TIE 0x00000002
100 +#define SSPC1_RORIE 0x00000004
101 +#define SSPC1_LBM 0x00000008
102 +#define SSPC1_SSE 0x00000010
103 +#define SSPC1_MS 0x00000020
104 +#define SSPC1_SOD 0x00000040
107 +#define SSPSR_TFE 0x00000001 /* TX FIFO is empty */
108 +#define SSPSR_TNF 0x00000002 /* TX FIFO is not full */
109 +#define SSPSR_RNE 0x00000004 /* RX FIFO is not empty */
110 +#define SSPSR_RFF 0x00000008 /* RX FIFO is full */
111 +#define SSPSR_BSY 0x00000010 /* SSP is busy */
112 +#define SSPSR_MASK 0x0000001F /* SSP is busy */
114 +/* Bits in SSPCPSR */
115 +#define SSPCPSR_SCR_MASK 0x000000ff
117 +/* Bits in SSPIIR */
118 +#define SSPIIR_RIS 0x00000001 /* RX FIFO IRQ status */
119 +#define SSPIIR_TIS 0x00000002 /* TX FIFO is not full */
120 +#define SSPIIR_RORIS 0x00000004 /* RX FIFO is full */
122 +#define SPI_SSPCLK 7.4e6
123 +#define SPI_SSPCLK_REV_E2 14.8e6 /* only for chip Rev E2 */
124 +#define SPI_MAX_SPEED 3.7e6
125 +#define SPI_MAX_SPEED_REV_E2 7.4e6 /* only for chip Rev E2 */
126 +#define SPI_CPSDVR_DIV_MIN 2
127 +#define SPI_CPSDVR_DIV_MAX 254
128 +#define SPI_SCR_DIV_MIN 0
129 +#define SPI_SCR_DIV_MAX 255
130 +#define SPI_DATARATE_OK 0
131 +#define SPI_DATARATE_NOK -1
133 +struct driver_data {
134 + /* Driver model hookup */
135 + struct platform_device *pdev;
137 + /* SPI framework hookup */
138 + struct spi_master *master;
140 + /* SSP register addresses */
146 + struct list_head queue;
151 + struct workqueue_struct *workqueue;
152 + struct work_struct work;
158 +static unsigned ep93xx_txrx_8(struct spi_device *spi, struct spi_transfer *t)
160 + struct driver_data *drv_data;
161 + const u8 *tx = t->tx_buf;
162 + u8 *rx = t->rx_buf;
163 + unsigned count = t->len;
167 + drv_data = spi_master_get_devdata(spi->master);
169 +#ifdef SPI_EP93XX_DEBUG
170 + dev_info(&spi->dev,
171 + "ep93xx_txrx_8: t->len %u \n", t->len);
174 + while (likely(count > 0)) {
178 +#ifdef SPI_EP93XX_DEBUG
179 + dev_info(&spi->dev,
180 + "ep93xx_txrx_8: write 0x%x \n", byte);
184 + write_SSPDR(byte, drv_data->ioaddr);
185 + busy = read_SSPSR(drv_data->ioaddr);
186 + while (busy & SSPSR_BSY) {
188 + busy = read_SSPSR(drv_data->ioaddr);
189 +#ifdef SPI_EP93XX_DEBUG
190 + dev_info(&spi->dev,
191 + "ep93xx_txrx_8: delay. SSPSR: 0x%X\n", busy);
194 + byte = read_SSPDR(drv_data->ioaddr);
198 +#ifdef SPI_EP93XX_DEBUG
199 + dev_info(&spi->dev,
200 + "ep93xx_txrx_8: read 0x%x \n", byte);
205 + return t->len - count;
209 +static unsigned ep93xx_txrx_16(struct spi_device *spi, struct spi_transfer *t)
212 + struct driver_data *drv_data;
213 + const u16 *tx = t->tx_buf;
214 + u16 *rx = t->rx_buf;
215 + unsigned count = t->len;
219 + drv_data = spi_master_get_devdata(spi->master);
221 +#ifdef SPI_EP93XX_DEBUG
222 + dev_info(&spi->dev,
223 + "ep93xx_txrx_16: t->len %u \n", t->len);
225 + while (likely(count > 0)) {
229 +#ifdef SPI_EP93XX_DEBUG
230 + dev_info(&spi->dev,
231 + "ep93xx_txrx_16: write 0x%x \n", word);
235 + write_SSPDR(word, drv_data->ioaddr);
236 + busy = read_SSPSR(drv_data->ioaddr);
237 + while (busy & SSPSR_BSY) {
239 + busy = read_SSPSR(drv_data->ioaddr);
240 +#ifdef SPI_EP93XX_DEBUG
241 + dev_info(&spi->dev,
242 + "ep93xx_txrx_8: delay.\n");
246 + word = read_SSPDR(drv_data->ioaddr);
250 +#ifdef SPI_EP93XX_DEBUG
251 + dev_info(&spi->dev,
252 + "ep93xx_txrx_16: read 0x%x \n", word);
257 + return t->len - count;
260 +static u32 spi_data_rate(u32 speed_hz, u32 *div_cpsdvr, u32 *div_scr,
261 + struct driver_data *drv_data, struct spi_device *spi)
263 + unsigned int spi_sspclk = SPI_SSPCLK;
264 + unsigned int bus_speed_max = SPI_MAX_SPEED;
265 + unsigned int bus_hz_tmp = 0;
266 + u32 div_cpsdvr_tmp;
268 + u32 rv = SPI_DATARATE_NOK;
271 + /* Checking CHIP_ID */
272 + chip_rev = (__raw_readl (EP93XX_SYSCON_CHIP_ID) >> 28) & 0xF;
275 + /* Chip version: Rev E2 */
276 + /* This device has double speed SSP clock */
277 + spi_sspclk = SPI_SSPCLK_REV_E2;
278 + bus_speed_max = SPI_MAX_SPEED_REV_E2;
279 +#ifdef SPI_EP93XX_DEBUG
280 + dev_info(&spi->dev,
281 + "Chip Rev E2 detected! This device has double speed SSP clock.\n");
285 + *div_cpsdvr = SPI_CPSDVR_DIV_MAX;
286 + *div_scr = SPI_SCR_DIV_MAX;
288 + for (div_cpsdvr_tmp = SPI_CPSDVR_DIV_MIN;
289 + div_cpsdvr_tmp <= SPI_CPSDVR_DIV_MAX && rv; div_cpsdvr_tmp++) {
290 + for (div_scr_tmp = SPI_SCR_DIV_MIN;
291 + div_scr_tmp <= SPI_SCR_DIV_MAX && rv; div_scr_tmp++) {
292 + bus_hz_tmp = spi_sspclk / (div_cpsdvr_tmp * (1 + div_scr_tmp));
293 + if (bus_hz_tmp <= speed_hz && bus_hz_tmp <= bus_speed_max) {
294 + *div_cpsdvr = div_cpsdvr_tmp;
295 + *div_scr = div_scr_tmp;
296 + rv = SPI_DATARATE_OK;
300 +#ifdef SPI_EP93XX_DEBUG
301 + dev_info(&spi->dev,
302 + "Needed SPI bus frequency: %i Hz\n", speed_hz);
303 + dev_info(&spi->dev,
304 + "Actual SPI bus frequency: %i Hz\n", bus_hz_tmp);
309 +/* Supported modes (returns -EINVAL if not supported mode requested) */
310 +#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH)
312 +static int ep93xx_spi_setup(struct spi_device *spi)
314 + struct driver_data *drv_data;
318 + unsigned int bits = spi->bits_per_word;
319 + unsigned long speed_hz = spi->max_speed_hz;
321 + drv_data = spi_master_get_devdata(spi->master);
324 + write_SSPCR1(SSPC1_SSE, drv_data->ioaddr);
325 + /* Enable SSP and loopback mode (only for testing!) */
326 + /* write_SSPCR1(SSPC1_SSE | SSPC1_LBM, drv_data->ioaddr); */
330 + if (bits < 4 || bits > 16) {
332 + "setup invalid bits_per_word %u (4 to 16)\n", bits);
335 + val = read_SSPCR0(drv_data->ioaddr);
336 + val = val & ~SSPCR0_DSS_MASK ;
337 + val = val | (bits-1);
338 + write_SSPCR0(val, drv_data->ioaddr);
339 +#ifdef SPI_EP93XX_DEBUG
340 + dev_info (&spi->dev, "Bits per word: %i\n", bits);
344 + if (spi->mode & ~MODEBITS) {
345 + dev_err(&spi->dev, "unsupported mode bits: %x\n",
346 + spi->mode & ~MODEBITS);
349 + val = read_SSPCR0(drv_data->ioaddr);
350 + val = val & ~SSPCR0_SPO;
351 + val = val & ~SSPCR0_SPH;
352 + if (spi->mode & SPI_CPOL)
354 + val = val | SSPCR0_SPO;
356 +#ifdef SPI_EP93XX_DEBUG
357 + dev_info (&spi->dev, "Clock polarity (CPOL): %s\n", (spi->mode & SPI_CPHA) ? "1" : "0");
359 + if (spi->mode & SPI_CPHA)
361 + val = val | SSPCR0_SPH;
363 +#ifdef SPI_EP93XX_DEBUG
364 + dev_info (&spi->dev, "Clock phase (CPHA): %s\n", (spi->mode & SPI_CPHA) ? "1" : "0");
366 + write_SSPCR0(val, drv_data->ioaddr);
369 + if (SPI_DATARATE_OK == (spi_data_rate(speed_hz, &div_cpsdvr,
370 + &div_scr, drv_data, spi))) {
372 + val = read_SSPCPSR(drv_data->ioaddr);
373 + val = val & ~SSPCPSR_SCR_MASK;
374 + val = val | div_cpsdvr;
375 +#ifdef SPI_EP93XX_DEBUG
376 + dev_info (&spi->dev, "SSPCPSR: 0x%X\n", val);
378 + write_SSPCPSR(val, drv_data->ioaddr);
380 + val = read_SSPCR0(drv_data->ioaddr);
381 + val = val & ~SSPCR0_SCR_MASK;
382 + val = val | (div_scr << SSPCR0_SCR_SHIFT);
383 +#ifdef SPI_EP93XX_DEBUG
384 + dev_info (&spi->dev, "SSPCR0: 0x%X (div_scr: 0x%X)\n", val, div_scr);
386 + write_SSPCR0(val, drv_data->ioaddr);
391 + val = read_SSPCR1(drv_data->ioaddr);
392 + val = val & ~SSPC1_SSE;
393 + write_SSPCR1(val, drv_data->ioaddr);
394 + val = read_SSPCR1(drv_data->ioaddr);
395 + val = val | SSPC1_SSE;
396 + write_SSPCR1(val, drv_data->ioaddr);
397 +#ifdef SPI_EP93XX_DEBUG
398 + dev_info (&spi->dev, "Loopback mode: %s\n", (val & SSPC1_LBM) ? "On" : "Off");
404 +static int ep93xx_spi_transfer(struct spi_device *spi, struct spi_message *m)
406 + struct driver_data *drv_data;
407 + unsigned long flags;
410 + m->actual_length = 0;
411 + m->status = -EINPROGRESS;
413 + drv_data = spi_master_get_devdata(spi->master);
415 + spin_lock_irqsave(&drv_data->lock, flags);
416 + if (!spi->max_speed_hz)
417 + status = -ENETDOWN;
419 + list_add_tail(&m->queue, &drv_data->queue);
420 + queue_work(drv_data->workqueue, &drv_data->work);
422 + spin_unlock_irqrestore(&drv_data->lock, flags);
426 +static void ep93xx_work(struct work_struct *work)
428 + struct driver_data *drv_data =
429 + container_of(work, struct driver_data, work);
430 + unsigned long flags;
432 + spin_lock_irqsave(&drv_data->lock, flags);
433 + drv_data->busy = 1;
435 + while (!list_empty(&drv_data->queue)) {
436 + struct spi_message *m;
437 + struct spi_device *spi;
438 + struct spi_transfer *t = NULL;
441 + m = container_of(drv_data->queue.next, struct spi_message,
443 + list_del_init(&m->queue);
444 + spin_unlock_irqrestore(&drv_data->lock, flags);
449 + list_for_each_entry(t, &m->transfers, transfer_list) {
451 + if (!t->tx_buf && !t->rx_buf && t->len) {
457 + if (!m->is_dma_mapped) {
461 + if (t->bits_per_word <= 8)
462 + status = ep93xx_txrx_8(spi, t);
464 + status = ep93xx_txrx_16(spi, t);
467 + if (status != t->len) {
469 + status = -EMSGSIZE;
472 + m->actual_length += status;
475 + /* protocol tweaks before next transfer */
476 + if (t->delay_usecs)
477 + udelay(t->delay_usecs);
479 + if (t->transfer_list.next == &m->transfers)
483 + m->status = status;
484 + m->complete(m->context);
486 + spin_lock_irqsave(&drv_data->lock, flags);
488 + drv_data->busy = 0;
489 + spin_unlock_irqrestore(&drv_data->lock, flags);
492 +static irqreturn_t ssp_int(int irq, void *dev_id)
494 + struct driver_data *drv_data = dev_id;
496 + status = read_SSPIIR(drv_data->ioaddr);
498 + if (status & SSPIIR_RORIS) {
499 + dev_err(&drv_data->pdev->dev, "SPI rx overrun.\n");
501 + /* We clear the overrun here ! */
502 + write_SSPICR(0, drv_data->ioaddr);
506 + if (status & SSPIIR_RIS)
507 + dev_info(&drv_data->pdev->dev, "SPI RX interrupt\n");
510 + if (status & SSPIIR_TIS)
511 + dev_info(&drv_data->pdev->dev, "SPI TX interrupt\n");
513 + write_SSPICR(0, drv_data->ioaddr);
514 + return IRQ_HANDLED;
517 +static int __init ep93xx_spi_probe(struct platform_device *pdev)
519 + struct device *dev = &pdev->dev;
520 + struct spi_master *master;
521 + struct driver_data *drv_data = 0;
522 + struct resource *memory_resource;
526 + /* Allocate master with space for drv_data and null dma buffer */
527 + master = spi_alloc_master(dev, sizeof(struct driver_data));
529 + dev_err(&pdev->dev, "cannot alloc spi_master\n");
532 + drv_data = spi_master_get_devdata(master);
533 + drv_data->master = master;
534 + drv_data->pdev = pdev;
536 + master->num_chipselect = EP93XX_GPIO_LINE_H(7) + 1;
537 + master->bus_num = pdev->id;
538 + master->setup = ep93xx_spi_setup;
539 + master->transfer = ep93xx_spi_transfer;
541 + spin_lock_init(&drv_data->lock);
542 + INIT_LIST_HEAD(&drv_data->queue);
544 + /* Setup register addresses */
545 + memory_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
546 + if (!memory_resource) {
547 + dev_err(&pdev->dev, "memory resources not defined\n");
549 + goto out_error_master_alloc;
551 + drv_data->ioaddr = ioremap(memory_resource->start,
552 + memory_resource->end - memory_resource->start);
553 + if (drv_data->ioaddr == NULL) {
554 + dev_err(&pdev->dev, "ioremap failed\n");
556 + goto out_error_master_alloc;
560 + /* Attach to IRQ */
561 + drv_data->irq = platform_get_irq(pdev, 0);
562 + if (drv_data->irq < 0)
563 + return drv_data->irq;
565 + if (drv_data->irq <= 0) {
566 + dev_err(&pdev->dev, "IRQ resource not defined\n");
568 + goto out_error_master_alloc;
571 + status = request_irq(drv_data->irq, ssp_int, 0, "ep93xx-spi", drv_data);
573 + dev_err(&pdev->dev, "cannot get SPI IRQ 0\n");
574 + goto out_error_master_alloc;
577 + /* SSP default configuration, enable */
578 + write_SSPCR1(SSPC1_SSE, drv_data->ioaddr);
580 + /* run as master */
581 + val = read_SSPCR1(drv_data->ioaddr);
582 + val = val & ~SSPC1_MS;
583 + write_SSPCR1(val, drv_data->ioaddr);
585 + /* frame format to Motorola SPI Format */
586 + val = read_SSPCR0(drv_data->ioaddr);
587 + val = val & ~SSPCR0_FRF_MASK ;
588 + val = val | SSPCR0_FRF_MOTOROLA;
589 + write_SSPCR0(val, drv_data->ioaddr);
591 + /* enable interrupts */
592 + val = read_SSPCR1(drv_data->ioaddr);
593 + /* for now only overrun is handled */
594 + /* val = val | SSPC1_RIE | SSPC1_TIE | SSPC1_RORIE; */
595 + val = val | SSPC1_RORIE;
596 + write_SSPCR1(val, drv_data->ioaddr);
598 + /* SSP default configuration, re enable */
599 + val = read_SSPCR1(drv_data->ioaddr);
600 + val = val & ~SSPC1_SSE;
601 + write_SSPCR1(val, drv_data->ioaddr);
602 + val = read_SSPCR1(drv_data->ioaddr);
603 + val = val | SSPC1_SSE;
604 + write_SSPCR1(val, drv_data->ioaddr);
606 + /* Register with the SPI framework */
607 + platform_set_drvdata(pdev, drv_data);
608 + status = spi_register_master(master);
610 + dev_err(&pdev->dev, "cannot register SPI master\n");
611 + goto out_error_master_alloc;
613 + dev_info(&pdev->dev, "SPI Controller initalized\n");
615 + INIT_WORK(&drv_data->work, ep93xx_work);
616 + spin_lock_init(&drv_data->lock);
617 + INIT_LIST_HEAD(&drv_data->queue);
619 + /* this task is the only thing to touch the SPI bits */
620 + drv_data->busy = 0;
621 + drv_data->workqueue = create_singlethread_workqueue(
622 + dev_name(drv_data->master->dev.parent));
623 +/* drv_data->master->cdev.dev->bus_id); */
624 + if (drv_data->workqueue == NULL) {
626 + goto out_error_free_irq;
632 + free_irq(drv_data->irq, master);
633 +out_error_master_alloc:
634 + if (drv_data->ioaddr != NULL)
635 + iounmap(drv_data->ioaddr);
636 + spi_master_put(master);
640 +static int __exit ep93xx_spi_remove(struct platform_device *pdev)
642 + struct driver_data *drv_data = platform_get_drvdata(pdev);
645 + WARN_ON(!list_empty(&drv_data->queue));
647 + destroy_workqueue(drv_data->workqueue);
649 + /* switch off SSP*/
650 + val = read_SSPCR1(drv_data->ioaddr);
651 + val = val & ~SSPC1_SSE;
652 + write_SSPCR1(val, drv_data->ioaddr);
655 + if (drv_data->irq > 0)
656 + free_irq(drv_data->irq, drv_data);
658 + /* Disconnect from the SPI framework */
659 + spi_unregister_master(drv_data->master);
660 + spi_master_put(drv_data->master);
662 + if (drv_data->ioaddr != NULL)
663 + iounmap(drv_data->ioaddr);
665 + /* Prevent double remove */
666 + platform_set_drvdata(pdev, NULL);
671 +static int ep93xx_spi_suspend(struct platform_device *pdev, pm_message_t msg)
676 +static int ep93xx_spi_resume(struct platform_device *pdev)
682 +#define ep93xx_spi_suspend NULL
683 +#define ep93xx_spi_resume NULL
686 +struct platform_driver ep93xx_spi_device = {
687 + .remove = __exit_p(ep93xx_spi_remove),
689 + .suspend = ep93xx_spi_suspend,
690 + .resume = ep93xx_spi_resume,
693 + .name = "ep93xx-spi",
694 + .bus = &spi_bus_type,
695 + .owner = THIS_MODULE,
699 +int __init ep93xx_spi_init(void)
701 + return platform_driver_probe(&ep93xx_spi_device, ep93xx_spi_probe);
704 +void __exit ep93xx_spi_exit(void)
706 + platform_driver_unregister(&ep93xx_spi_device);
709 +module_init(ep93xx_spi_init);
710 +module_exit(ep93xx_spi_exit);
712 +MODULE_DESCRIPTION("EP93XX SPI Driver");
713 +MODULE_AUTHOR("Manfred Gruber, <m.gruber@tirol.com>");
714 +MODULE_LICENSE("GPL");