summaryrefslogtreecommitdiffstats
path: root/meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.31-1-2-timberdale.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.31-1-2-timberdale.patch')
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.31-1-2-timberdale.patch12910
1 files changed, 12910 insertions, 0 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.31-1-2-timberdale.patch b/meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.31-1-2-timberdale.patch
new file mode 100644
index 0000000000..9db5b4ac72
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.31-1-2-timberdale.patch
@@ -0,0 +1,12910 @@
1diff -uNr linux-2.6.31/drivers/gpio/Kconfig linux-2.6.31.new/drivers/gpio/Kconfig
2--- linux-2.6.31/drivers/gpio/Kconfig 2009-10-23 11:18:30.000000000 -0700
3+++ linux-2.6.31.new/drivers/gpio/Kconfig 2009-10-23 11:17:19.000000000 -0700
4@@ -173,6 +173,12 @@
5
6 If unsure, say N.
7
8+config GPIO_TIMBERDALE
9+ bool "Support for timberdale GPIO IP"
10+ depends on MFD_TIMBERDALE && GPIOLIB && HAS_IOMEM
11+ ---help---
12+ Add support for the GPIO IP in the timberdale FPGA.
13+
14 comment "SPI GPIO expanders:"
15
16 config GPIO_MAX7301
17@@ -188,4 +194,11 @@
18 SPI driver for Microchip MCP23S08 I/O expander. This provides
19 a GPIO interface supporting inputs and outputs.
20
21+config GPIO_MC33880
22+ tristate "Freescale MC33880 high-side/low-side switch"
23+ depends on SPI_MASTER
24+ help
25+ SPI driver for Freescale MC33880 high-side/low-side switch.
26+ This provides GPIO interface supporting inputs and outputs.
27+
28 endif
29diff -uNr linux-2.6.31/drivers/gpio/Makefile linux-2.6.31.new/drivers/gpio/Makefile
30--- linux-2.6.31/drivers/gpio/Makefile 2009-10-23 11:18:30.000000000 -0700
31+++ linux-2.6.31.new/drivers/gpio/Makefile 2009-10-23 11:17:19.000000000 -0700
32@@ -14,3 +14,6 @@
33 obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o
34 obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o
35 obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o
36+obj-$(CONFIG_GPIO_TIMBERDALE) += timbgpio.o
37+obj-$(CONFIG_GPIO_MC33880) += mc33880.o
38+
39diff -uNr linux-2.6.31/drivers/gpio/mc33880.c linux-2.6.31.new/drivers/gpio/mc33880.c
40--- linux-2.6.31/drivers/gpio/mc33880.c 1969-12-31 16:00:00.000000000 -0800
41+++ linux-2.6.31.new/drivers/gpio/mc33880.c 2009-10-23 11:17:19.000000000 -0700
42@@ -0,0 +1,196 @@
43+/*
44+ * mc33880.c MC33880 high-side/low-side switch GPIO driver
45+ * Copyright (c) 2009 Intel Corporation
46+ *
47+ * This program is free software; you can redistribute it and/or modify
48+ * it under the terms of the GNU General Public License version 2 as
49+ * published by the Free Software Foundation.
50+ *
51+ * This program is distributed in the hope that it will be useful,
52+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
53+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
54+ * GNU General Public License for more details.
55+ *
56+ * You should have received a copy of the GNU General Public License
57+ * along with this program; if not, write to the Free Software
58+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
59+ */
60+
61+/* Supports:
62+ * Freescale MC33880 high-side/low-side switch
63+ */
64+
65+#include <linux/init.h>
66+#include <linux/mutex.h>
67+#include <linux/spi/spi.h>
68+#include <linux/spi/mc33880.h>
69+#include <linux/gpio.h>
70+
71+#define DRIVER_NAME "mc33880"
72+
73+/*
74+ * Pin configurations, see MAX7301 datasheet page 6
75+ */
76+#define PIN_CONFIG_MASK 0x03
77+#define PIN_CONFIG_IN_PULLUP 0x03
78+#define PIN_CONFIG_IN_WO_PULLUP 0x02
79+#define PIN_CONFIG_OUT 0x01
80+
81+#define PIN_NUMBER 8
82+
83+
84+/*
85+ * Some registers must be read back to modify.
86+ * To save time we cache them here in memory
87+ */
88+struct mc33880 {
89+ struct mutex lock; /* protect from simultanous accesses */
90+ u8 port_config;
91+ struct gpio_chip chip;
92+ struct spi_device *spi;
93+};
94+
95+static int mc33880_write_config(struct mc33880 *mc)
96+{
97+ return spi_write(mc->spi, &mc->port_config, sizeof(mc->port_config));
98+}
99+
100+
101+static int __mc33880_set(struct mc33880 *mc, unsigned offset, int value)
102+{
103+ if (value)
104+ mc->port_config |= 1 << offset;
105+ else
106+ mc->port_config &= ~(1 << offset);
107+
108+ return mc33880_write_config(mc);
109+}
110+
111+
112+static void mc33880_set(struct gpio_chip *chip, unsigned offset, int value)
113+{
114+ struct mc33880 *mc = container_of(chip, struct mc33880, chip);
115+
116+ mutex_lock(&mc->lock);
117+
118+ __mc33880_set(mc, offset, value);
119+
120+ mutex_unlock(&mc->lock);
121+}
122+
123+static int __devinit mc33880_probe(struct spi_device *spi)
124+{
125+ struct mc33880 *mc;
126+ struct mc33880_platform_data *pdata;
127+ int ret;
128+
129+ pdata = spi->dev.platform_data;
130+ if (!pdata || !pdata->base) {
131+ dev_dbg(&spi->dev, "incorrect or missing platform data\n");
132+ return -EINVAL;
133+ }
134+
135+ /*
136+ * bits_per_word cannot be configured in platform data
137+ */
138+ spi->bits_per_word = 8;
139+
140+ ret = spi_setup(spi);
141+ if (ret < 0)
142+ return ret;
143+
144+ mc = kzalloc(sizeof(struct mc33880), GFP_KERNEL);
145+ if (!mc)
146+ return -ENOMEM;
147+
148+ mutex_init(&mc->lock);
149+
150+ dev_set_drvdata(&spi->dev, mc);
151+
152+ mc->spi = spi;
153+
154+ mc->chip.label = DRIVER_NAME,
155+ mc->chip.set = mc33880_set;
156+ mc->chip.base = pdata->base;
157+ mc->chip.ngpio = PIN_NUMBER;
158+ mc->chip.can_sleep = 1;
159+ mc->chip.dev = &spi->dev;
160+ mc->chip.owner = THIS_MODULE;
161+
162+ mc->port_config = 0x00;
163+ /* write twice, because during initialisation the first setting
164+ * is just for testing SPI communication, and the second is the
165+ * "real" configuration
166+ */
167+ ret = mc33880_write_config(mc);
168+ mc->port_config = 0x00;
169+ if (!ret)
170+ ret = mc33880_write_config(mc);
171+
172+ if (ret) {
173+ printk(KERN_ERR "Failed writing to " DRIVER_NAME ": %d\n", ret);
174+ goto exit_destroy;
175+ }
176+
177+ ret = gpiochip_add(&mc->chip);
178+ if (ret)
179+ goto exit_destroy;
180+
181+ return ret;
182+
183+exit_destroy:
184+ dev_set_drvdata(&spi->dev, NULL);
185+ mutex_destroy(&mc->lock);
186+ kfree(mc);
187+ return ret;
188+}
189+
190+static int mc33880_remove(struct spi_device *spi)
191+{
192+ struct mc33880 *mc;
193+ int ret;
194+
195+ mc = dev_get_drvdata(&spi->dev);
196+ if (mc == NULL)
197+ return -ENODEV;
198+
199+ dev_set_drvdata(&spi->dev, NULL);
200+
201+ ret = gpiochip_remove(&mc->chip);
202+ if (!ret) {
203+ mutex_destroy(&mc->lock);
204+ kfree(mc);
205+ } else
206+ dev_err(&spi->dev, "Failed to remove the GPIO controller: %d\n",
207+ ret);
208+
209+ return ret;
210+}
211+
212+static struct spi_driver mc33880_driver = {
213+ .driver = {
214+ .name = DRIVER_NAME,
215+ .owner = THIS_MODULE,
216+ },
217+ .probe = mc33880_probe,
218+ .remove = __devexit_p(mc33880_remove),
219+};
220+
221+static int __init mc33880_init(void)
222+{
223+ return spi_register_driver(&mc33880_driver);
224+}
225+/* register after spi postcore initcall and before
226+ * subsys initcalls that may rely on these GPIOs
227+ */
228+subsys_initcall(mc33880_init);
229+
230+static void __exit mc33880_exit(void)
231+{
232+ spi_unregister_driver(&mc33880_driver);
233+}
234+module_exit(mc33880_exit);
235+
236+MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
237+MODULE_LICENSE("GPL v2");
238+
239diff -uNr linux-2.6.31/drivers/gpio/timbgpio.c linux-2.6.31.new/drivers/gpio/timbgpio.c
240--- linux-2.6.31/drivers/gpio/timbgpio.c 1969-12-31 16:00:00.000000000 -0800
241+++ linux-2.6.31.new/drivers/gpio/timbgpio.c 2009-10-23 11:17:19.000000000 -0700
242@@ -0,0 +1,342 @@
243+/*
244+ * timbgpio.c timberdale FPGA GPIO driver
245+ * Copyright (c) 2009 Intel Corporation
246+ *
247+ * This program is free software; you can redistribute it and/or modify
248+ * it under the terms of the GNU General Public License version 2 as
249+ * published by the Free Software Foundation.
250+ *
251+ * This program is distributed in the hope that it will be useful,
252+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
253+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
254+ * GNU General Public License for more details.
255+ *
256+ * You should have received a copy of the GNU General Public License
257+ * along with this program; if not, write to the Free Software
258+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
259+ */
260+
261+/* Supports:
262+ * Timberdale FPGA GPIO
263+ */
264+
265+#include <linux/module.h>
266+#include <linux/gpio.h>
267+#include <linux/platform_device.h>
268+#include <linux/io.h>
269+#include <linux/timb_gpio.h>
270+#include <linux/interrupt.h>
271+
272+#define DRIVER_NAME "timb-gpio"
273+
274+#define TGPIOVAL 0x00
275+#define TGPIODIR 0x04
276+#define TGPIO_IER 0x08
277+#define TGPIO_ISR 0x0c
278+#define TGPIO_IPR 0x10
279+#define TGPIO_ICR 0x14
280+#define TGPIO_FLR 0x18
281+#define TGPIO_LVR 0x1c
282+
283+struct timbgpio {
284+ void __iomem *membase;
285+ spinlock_t lock; /* mutual exclusion */
286+ struct gpio_chip gpio;
287+ int irq_base;
288+};
289+
290+static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index,
291+ unsigned offset, bool enabled)
292+{
293+ struct timbgpio *tgpio = container_of(gpio, struct timbgpio, gpio);
294+ u32 reg;
295+
296+ spin_lock(&tgpio->lock);
297+ reg = ioread32(tgpio->membase + offset);
298+
299+ if (enabled)
300+ reg |= (1 << index);
301+ else
302+ reg &= ~(1 << index);
303+
304+ iowrite32(reg, tgpio->membase + offset);
305+ spin_unlock(&tgpio->lock);
306+
307+ return 0;
308+}
309+
310+static int timbgpio_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
311+{
312+ return timbgpio_update_bit(gpio, nr, TGPIODIR, true);
313+}
314+
315+static int timbgpio_gpio_get(struct gpio_chip *gpio, unsigned nr)
316+{
317+ struct timbgpio *tgpio = container_of(gpio, struct timbgpio, gpio);
318+ u32 value;
319+
320+ value = ioread32(tgpio->membase + TGPIOVAL);
321+ return (value & (1 << nr)) ? 1 : 0;
322+}
323+
324+static int timbgpio_gpio_direction_output(struct gpio_chip *gpio,
325+ unsigned nr, int val)
326+{
327+ return timbgpio_update_bit(gpio, nr, TGPIODIR, false);
328+}
329+
330+static void timbgpio_gpio_set(struct gpio_chip *gpio,
331+ unsigned nr, int val)
332+{
333+ timbgpio_update_bit(gpio, nr, TGPIOVAL, val != 0);
334+}
335+
336+static int timbgpio_to_irq(struct gpio_chip *gpio, unsigned offset)
337+{
338+ struct timbgpio *tgpio = container_of(gpio, struct timbgpio, gpio);
339+
340+ if (tgpio->irq_base <= 0)
341+ return -EINVAL;
342+
343+ return tgpio->irq_base + offset;
344+}
345+
346+/*
347+ * GPIO IRQ
348+ */
349+static void timbgpio_irq_disable(unsigned irq)
350+{
351+ struct timbgpio *tgpio = get_irq_chip_data(irq);
352+ int offset = irq - tgpio->irq_base;
353+
354+ timbgpio_update_bit(&tgpio->gpio, offset, TGPIO_IER, 0);
355+}
356+
357+static void timbgpio_irq_enable(unsigned irq)
358+{
359+ struct timbgpio *tgpio = get_irq_chip_data(irq);
360+ int offset = irq - tgpio->irq_base;
361+
362+ timbgpio_update_bit(&tgpio->gpio, offset, TGPIO_IER, 1);
363+}
364+
365+static int timbgpio_irq_type(unsigned irq, unsigned trigger)
366+{
367+ struct timbgpio *tgpio = get_irq_chip_data(irq);
368+ int offset = irq - tgpio->irq_base;
369+ unsigned long flags;
370+ u32 lvr, flr;
371+
372+ if (offset < 0 || offset > tgpio->gpio.ngpio)
373+ return -EINVAL;
374+
375+ spin_lock_irqsave(&tgpio->lock, flags);
376+
377+ lvr = ioread32(tgpio->membase + TGPIO_LVR);
378+ flr = ioread32(tgpio->membase + TGPIO_FLR);
379+
380+ if (trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
381+ flr &= ~(1 << offset);
382+ if (trigger & IRQ_TYPE_LEVEL_HIGH)
383+ lvr |= 1 << offset;
384+ else
385+ lvr &= ~(1 << offset);
386+ }
387+
388+ if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
389+ return -EINVAL;
390+ else {
391+ flr |= 1 << offset;
392+ /* opposite compared to the datasheet, but it mirrors the
393+ * reality
394+ */
395+ if (trigger & IRQ_TYPE_EDGE_FALLING)
396+ lvr |= 1 << offset;
397+ else
398+ lvr &= ~(1 << offset);
399+ }
400+
401+ iowrite32(lvr, tgpio->membase + TGPIO_LVR);
402+ iowrite32(flr, tgpio->membase + TGPIO_FLR);
403+ iowrite32(1 << offset, tgpio->membase + TGPIO_ICR);
404+ spin_unlock_irqrestore(&tgpio->lock, flags);
405+
406+ return 0;
407+}
408+
409+static void timbgpio_irq(unsigned int irq, struct irq_desc *desc)
410+{
411+ struct timbgpio *tgpio = get_irq_data(irq);
412+ unsigned long ipr;
413+ int offset;
414+
415+ desc->chip->ack(irq);
416+ ipr = ioread32(tgpio->membase + TGPIO_IPR);
417+ iowrite32(ipr, tgpio->membase + TGPIO_ICR);
418+
419+ for_each_bit(offset, &ipr, tgpio->gpio.ngpio)
420+ generic_handle_irq(timbgpio_to_irq(&tgpio->gpio, offset));
421+}
422+
423+static struct irq_chip timbgpio_irqchip = {
424+ .name = "GPIO",
425+ .enable = timbgpio_irq_enable,
426+ .disable = timbgpio_irq_disable,
427+ .set_type = timbgpio_irq_type,
428+};
429+
430+static int __devinit timbgpio_probe(struct platform_device *pdev)
431+{
432+ int err, i;
433+ struct gpio_chip *gc;
434+ struct timbgpio *tgpio;
435+ struct resource *iomem;
436+ struct timbgpio_platform_data *pdata = pdev->dev.platform_data;
437+ int irq = platform_get_irq(pdev, 0);
438+
439+ if (!pdata || pdata->nr_pins > 32) {
440+ err = -EINVAL;
441+ goto err_mem;
442+ }
443+
444+ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
445+ if (!iomem) {
446+ err = -EINVAL;
447+ goto err_mem;
448+ }
449+
450+ tgpio = kzalloc(sizeof(*tgpio), GFP_KERNEL);
451+ if (!tgpio) {
452+ err = -EINVAL;
453+ goto err_mem;
454+ }
455+ tgpio->irq_base = pdata->irq_base;
456+
457+ spin_lock_init(&tgpio->lock);
458+
459+ if (!request_mem_region(iomem->start, resource_size(iomem),
460+ DRIVER_NAME)) {
461+ err = -EBUSY;
462+ goto err_request;
463+ }
464+
465+ tgpio->membase = ioremap(iomem->start, resource_size(iomem));
466+ if (!tgpio->membase) {
467+ err = -ENOMEM;
468+ goto err_ioremap;
469+ }
470+
471+ gc = &tgpio->gpio;
472+
473+ gc->label = dev_name(&pdev->dev);
474+ gc->owner = THIS_MODULE;
475+ gc->dev = &pdev->dev;
476+ gc->direction_input = timbgpio_gpio_direction_input;
477+ gc->get = timbgpio_gpio_get;
478+ gc->direction_output = timbgpio_gpio_direction_output;
479+ gc->set = timbgpio_gpio_set;
480+ gc->to_irq = (irq >= 0 && tgpio->irq_base > 0) ? timbgpio_to_irq : NULL;
481+ gc->dbg_show = NULL;
482+ gc->base = pdata->gpio_base;
483+ gc->ngpio = pdata->nr_pins;
484+ gc->can_sleep = 0;
485+
486+ err = gpiochip_add(gc);
487+ if (err)
488+ goto err_chipadd;
489+
490+ platform_set_drvdata(pdev, tgpio);
491+
492+ /* make sure to disable interrupts */
493+ iowrite32(0x0, tgpio->membase + TGPIO_IER);
494+
495+ if (irq < 0 || tgpio->irq_base <= 0)
496+ return 0;
497+
498+ for (i = 0; i < pdata->nr_pins; i++) {
499+ set_irq_chip_and_handler_name(tgpio->irq_base + i,
500+ &timbgpio_irqchip, handle_simple_irq, "mux");
501+ set_irq_chip_data(tgpio->irq_base + i, tgpio);
502+#ifdef CONFIG_ARM
503+ set_irq_flags(tgpio->irq_base + i, IRQF_VALID | IRQF_PROBE);
504+#endif
505+ }
506+
507+ set_irq_data(irq, tgpio);
508+ set_irq_chained_handler(irq, timbgpio_irq);
509+
510+ return 0;
511+
512+err_chipadd:
513+ iounmap(tgpio->membase);
514+err_ioremap:
515+ release_mem_region(iomem->start, resource_size(iomem));
516+err_request:
517+ kfree(tgpio);
518+err_mem:
519+ printk(KERN_ERR DRIVER_NAME": Failed to register GPIOs: %d\n", err);
520+
521+ return err;
522+}
523+
524+static int __devexit timbgpio_remove(struct platform_device *pdev)
525+{
526+ int err;
527+ struct timbgpio_platform_data *pdata = pdev->dev.platform_data;
528+ struct timbgpio *tgpio = platform_get_drvdata(pdev);
529+ struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
530+ int irq = platform_get_irq(pdev, 0);
531+
532+ if (irq >= 0 && tgpio->irq_base > 0) {
533+ int i;
534+ for (i = 0; i < pdata->nr_pins; i++) {
535+ set_irq_chip(tgpio->irq_base + i, NULL);
536+ set_irq_chip_data(tgpio->irq_base + i, NULL);
537+ }
538+
539+ set_irq_handler(irq, NULL);
540+ set_irq_data(irq, NULL);
541+ }
542+
543+ err = gpiochip_remove(&tgpio->gpio);
544+ if (err)
545+ printk(KERN_ERR DRIVER_NAME": failed to remove gpio_chip\n");
546+
547+ iounmap(tgpio->membase);
548+ release_mem_region(iomem->start, resource_size(iomem));
549+ kfree(tgpio);
550+
551+ platform_set_drvdata(pdev, NULL);
552+
553+ return 0;
554+}
555+
556+static struct platform_driver timbgpio_platform_driver = {
557+ .driver = {
558+ .name = DRIVER_NAME,
559+ .owner = THIS_MODULE,
560+ },
561+ .probe = timbgpio_probe,
562+ .remove = timbgpio_remove,
563+};
564+
565+/*--------------------------------------------------------------------------*/
566+
567+static int __init timbgpio_init(void)
568+{
569+ return platform_driver_register(&timbgpio_platform_driver);
570+}
571+
572+static void __exit timbgpio_exit(void)
573+{
574+ platform_driver_unregister(&timbgpio_platform_driver);
575+}
576+
577+module_init(timbgpio_init);
578+module_exit(timbgpio_exit);
579+
580+MODULE_DESCRIPTION("Timberdale GPIO driver");
581+MODULE_LICENSE("GPL v2");
582+MODULE_AUTHOR("Mocean Laboratories");
583+MODULE_ALIAS("platform:"DRIVER_NAME);
584+
585diff -uNr linux-2.6.31/drivers/i2c/busses/i2c-xiic.c linux-2.6.31.new/drivers/i2c/busses/i2c-xiic.c
586--- linux-2.6.31/drivers/i2c/busses/i2c-xiic.c 1969-12-31 16:00:00.000000000 -0800
587+++ linux-2.6.31.new/drivers/i2c/busses/i2c-xiic.c 2009-10-23 11:17:29.000000000 -0700
588@@ -0,0 +1,1132 @@
589+/*
590+ * i2c-xiic.c
591+ * Copyright (c) 2009 Intel Corporation
592+ *
593+ * This program is free software; you can redistribute it and/or modify
594+ * it under the terms of the GNU General Public License version 2 as
595+ * published by the Free Software Foundation.
596+ *
597+ * This program is distributed in the hope that it will be useful,
598+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
599+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
600+ * GNU General Public License for more details.
601+ *
602+ * You should have received a copy of the GNU General Public License
603+ * along with this program; if not, write to the Free Software
604+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
605+ */
606+
607+/* Supports:
608+ * Xilinx IIC
609+ */
610+#include <linux/kernel.h>
611+#include <linux/module.h>
612+#include <linux/init.h>
613+#include <linux/errno.h>
614+#include <linux/platform_device.h>
615+#include <linux/i2c.h>
616+#include <linux/interrupt.h>
617+#include <linux/wait.h>
618+#include <linux/i2c-xiic.h>
619+#include <linux/io.h>
620+
621+#define DRIVER_NAME "xiic-i2c"
622+
623+struct xiic_i2c {
624+ void __iomem *base;
625+ wait_queue_head_t wait;
626+ struct i2c_adapter adap;
627+ struct i2c_msg *tx_msg;
628+ spinlock_t lock; /* mutual exclusion */
629+ unsigned int tx_pos;
630+ unsigned int nmsgs;
631+ int state; /* see STATE_ */
632+
633+ struct i2c_msg *rx_msg; /* current RX message */
634+ int rx_pos;
635+};
636+
637+static inline void xiic_setreg8(struct xiic_i2c *i2c, int reg, u8 value);
638+
639+static inline u8 xiic_getreg8(struct xiic_i2c *i2c, int reg);
640+
641+static inline void xiic_setreg16(struct xiic_i2c *i2c, int reg, u16 value);
642+
643+static inline void xiic_setreg32(struct xiic_i2c *i2c, int reg, int value);
644+
645+static inline int xiic_getreg32(struct xiic_i2c *i2c, int reg);
646+
647+static void xiic_start_xfer(struct xiic_i2c *i2c);
648+static void __xiic_start_xfer(struct xiic_i2c *i2c);
649+
650+/************************** Constant Definitions ****************************/
651+
652+#define STATE_DONE 0x00
653+#define STATE_ERROR 0x01
654+#define STATE_START 0x02
655+
656+#define XIIC_MSB_OFFSET 0
657+#define XIIC_REG_OFFSET (0x100+XIIC_MSB_OFFSET)
658+
659+/*
660+ * Register offsets in bytes from RegisterBase. Three is added to the
661+ * base offset to access LSB (IBM style) of the word
662+ */
663+#define XIIC_CR_REG_OFFSET (0x00+XIIC_REG_OFFSET) /* Control Register */
664+#define XIIC_SR_REG_OFFSET (0x04+XIIC_REG_OFFSET) /* Status Register */
665+#define XIIC_DTR_REG_OFFSET (0x08+XIIC_REG_OFFSET) /* Data Tx Register */
666+#define XIIC_DRR_REG_OFFSET (0x0C+XIIC_REG_OFFSET) /* Data Rx Register */
667+#define XIIC_ADR_REG_OFFSET (0x10+XIIC_REG_OFFSET) /* Address Register */
668+#define XIIC_TFO_REG_OFFSET (0x14+XIIC_REG_OFFSET) /* Tx FIFO Occupancy */
669+#define XIIC_RFO_REG_OFFSET (0x18+XIIC_REG_OFFSET) /* Rx FIFO Occupancy */
670+#define XIIC_TBA_REG_OFFSET (0x1C+XIIC_REG_OFFSET) /* 10 Bit Address reg */
671+#define XIIC_RFD_REG_OFFSET (0x20+XIIC_REG_OFFSET) /* Rx FIFO Depth reg */
672+#define XIIC_GPO_REG_OFFSET (0x24+XIIC_REG_OFFSET) /* Output Register */
673+
674+/* Control Register masks */
675+#define XIIC_CR_ENABLE_DEVICE_MASK 0x01 /* Device enable = 1 */
676+#define XIIC_CR_TX_FIFO_RESET_MASK 0x02 /* Transmit FIFO reset=1 */
677+#define XIIC_CR_MSMS_MASK 0x04 /* Master starts Txing=1 */
678+#define XIIC_CR_DIR_IS_TX_MASK 0x08 /* Dir of tx. Txing=1 */
679+#define XIIC_CR_NO_ACK_MASK 0x10 /* Tx Ack. NO ack = 1 */
680+#define XIIC_CR_REPEATED_START_MASK 0x20 /* Repeated start = 1 */
681+#define XIIC_CR_GENERAL_CALL_MASK 0x40 /* Gen Call enabled = 1 */
682+
683+/* Status Register masks */
684+#define XIIC_SR_GEN_CALL_MASK 0x01 /* 1=a mstr issued a GC */
685+#define XIIC_SR_ADDR_AS_SLAVE_MASK 0x02 /* 1=when addr as slave */
686+#define XIIC_SR_BUS_BUSY_MASK 0x04 /* 1 = bus is busy */
687+#define XIIC_SR_MSTR_RDING_SLAVE_MASK 0x08 /* 1=Dir: mstr <-- slave */
688+#define XIIC_SR_TX_FIFO_FULL_MASK 0x10 /* 1 = Tx FIFO full */
689+#define XIIC_SR_RX_FIFO_FULL_MASK 0x20 /* 1 = Rx FIFO full */
690+#define XIIC_SR_RX_FIFO_EMPTY_MASK 0x40 /* 1 = Rx FIFO empty */
691+#define XIIC_SR_TX_FIFO_EMPTY_MASK 0x80 /* 1 = Tx FIFO empty */
692+
693+/* Interrupt Status Register masks Interrupt occurs when... */
694+#define XIIC_INTR_ARB_LOST_MASK 0x01 /* 1 = arbitration lost */
695+#define XIIC_INTR_TX_ERROR_MASK 0x02 /* 1=Tx error/msg complete */
696+#define XIIC_INTR_TX_EMPTY_MASK 0x04 /* 1 = Tx FIFO/reg empty */
697+#define XIIC_INTR_RX_FULL_MASK 0x08 /* 1=Rx FIFO/reg=OCY level */
698+#define XIIC_INTR_BNB_MASK 0x10 /* 1 = Bus not busy */
699+#define XIIC_INTR_AAS_MASK 0x20 /* 1 = when addr as slave */
700+#define XIIC_INTR_NAAS_MASK 0x40 /* 1 = not addr as slave */
701+#define XIIC_INTR_TX_HALF_MASK 0x80 /* 1 = TX FIFO half empty */
702+
703+/* The following constants specify the depth of the FIFOs */
704+#define IIC_RX_FIFO_DEPTH 16 /* Rx fifo capacity */
705+#define IIC_TX_FIFO_DEPTH 16 /* Tx fifo capacity */
706+
707+/* The following constants specify groups of interrupts that are typically
708+ * enabled or disables at the same time
709+ */
710+#define XIIC_TX_INTERRUPTS \
711+(XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)
712+
713+#define XIIC_TX_RX_INTERRUPTS (XIIC_INTR_RX_FULL_MASK | XIIC_TX_INTERRUPTS)
714+
715+/* The following constants are used with the following macros to specify the
716+ * operation, a read or write operation.
717+ */
718+#define XIIC_READ_OPERATION 1
719+#define XIIC_WRITE_OPERATION 0
720+
721+/*
722+ * Tx Fifo upper bit masks.
723+ */
724+#define XIIC_TX_DYN_START_MASK 0x0100 /* 1 = Set dynamic start */
725+#define XIIC_TX_DYN_STOP_MASK 0x0200 /* 1 = Set dynamic stop */
726+
727+/*
728+ * The following constants define the register offsets for the Interrupt
729+ * registers. There are some holes in the memory map for reserved addresses
730+ * to allow other registers to be added and still match the memory map of the
731+ * interrupt controller registers
732+ */
733+#define XIIC_DGIER_OFFSET 0x1C /* Device Global Interrupt Enable Register */
734+#define XIIC_IISR_OFFSET 0x20 /* Interrupt Status Register */
735+#define XIIC_IIER_OFFSET 0x28 /* Interrupt Enable Register */
736+#define XIIC_RESETR_OFFSET 0x40 /* Reset Register */
737+
738+#define XIIC_RESET_MASK 0xAUL
739+
740+/*
741+ * The following constant is used for the device global interrupt enable
742+ * register, to enable all interrupts for the device, this is the only bit
743+ * in the register
744+ */
745+#define XIIC_GINTR_ENABLE_MASK 0x80000000UL
746+
747+/***************** Macros (Inline Functions) Definitions *********************/
748+
749+
750+/******************************************************************************
751+*
752+* This macro disables all interrupts for the device by writing to the Global
753+* interrupt enable register. This register provides the ability to disable
754+* interrupts without any modifications to the interrupt enable register such
755+* that it is minimal effort to restore the interrupts to the previous enabled
756+* state. The corresponding function, XIIC_GINTR_ENABLE, is provided to
757+* restore the interrupts to the previous enabled state. This function is
758+* designed to be used in critical sections of device drivers such that it is
759+* not necessary to disable other device interrupts.
760+*
761+* @param Instance local i2c instance
762+*
763+* @return None.
764+*
765+* @note C-Style signature:
766+* void XIIC_GINTR_DISABLE(i2c);
767+*
768+******************************************************************************/
769+#define XIIC_GINTR_DISABLE(Instance) \
770+ xiic_setreg32(Instance, XIIC_DGIER_OFFSET, 0)
771+
772+/******************************************************************************
773+*
774+* This macro writes to the global interrupt enable register to enable
775+* interrupts from the device. This register provides the ability to enable
776+* interrupts without any modifications to the interrupt enable register such
777+* that it is minimal effort to restore the interrupts to the previous enabled
778+* state. This function does not enable individual interrupts as the interrupt
779+* enable register must be set appropriately. This function is designed to be
780+* used in critical sections of device drivers such that it is not necessary to
781+* disable other device interrupts.
782+*
783+* @param Instance local I2C instance
784+*
785+* @return None.
786+*
787+* @note C-Style signature:
788+* void XIIC_GINTR_ENABLE(i2c);
789+*
790+******************************************************************************/
791+#define XIIC_GINTR_ENABLE(Instance) \
792+ xiic_setreg32(Instance, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK)
793+
794+/******************************************************************************
795+*
796+*
797+* This function sets the Interrupt status register to the specified value.
798+* This register indicates the status of interrupt sources for the device.
799+* The status is independent of whether interrupts are enabled such that
800+* the status register may also be polled when interrupts are not enabled.
801+*
802+* Each bit of the register correlates to a specific interrupt source within the
803+* IIC device. All bits of this register are latched. Setting a bit which is 0
804+* within this register causes an interrupt to be generated. The device global
805+* interrupt enable register and the device interrupt enable register must be set
806+* appropriately to allow an interrupt to be passed out of the device. The
807+* interrupt is cleared by writing to this register with the bits to be
808+* cleared set to a one and all others to zero. This register implements a
809+* toggle on write functionality meaning any bits which are set in the value
810+* written cause the bits in the register to change to the opposite state.
811+*
812+* This function writes only the specified value to the register such that
813+* some status bits may be set and others cleared. It is the caller's
814+* responsibility to get the value of the register prior to setting the value
815+* to prevent an destructive behavior.
816+*
817+* @param Instance local I2C instance
818+* @param Status contains the value to be written to the Interrupt
819+* status register.
820+*
821+* @return None.
822+*
823+* @note C-Style signature:
824+* void XIIC_WRITE_IISR(i2c, u32 Status);
825+*
826+******************************************************************************/
827+#define XIIC_WRITE_IISR(Instance, Status) \
828+ xiic_setreg32(Instance, XIIC_IISR_OFFSET, (Status))
829+
830+/******************************************************************************
831+*
832+*
833+* This function gets the contents of the Interrupt Status Register.
834+* This register indicates the status of interrupt sources for the device.
835+* The status is independent of whether interrupts are enabled such
836+* that the status register may also be polled when interrupts are not enabled.
837+*
838+* Each bit of the register correlates to a specific interrupt source within the
839+* device. All bits of this register are latched. Writing a 1 to a bit within
840+* this register causes an interrupt to be generated if enabled in the interrupt
841+* enable register and the global interrupt enable is set. Since the status is
842+* latched, each status bit must be acknowledged in order for the bit in the
843+* status register to be updated. Each bit can be acknowledged by writing a
844+* 0 to the bit in the status register.
845+
846+* @param Instance local I2C instance
847+*
848+* @return A status which contains the value read from the Interrupt
849+* Status Register.
850+*
851+* @note C-Style signature:
852+* u32 XIIC_READ_IISR(i2c);
853+*
854+******************************************************************************/
855+#define XIIC_READ_IISR(Instance) \
856+ xiic_getreg32(Instance, XIIC_IISR_OFFSET)
857+
858+/******************************************************************************
859+*
860+* This function sets the contents of the Interrupt Enable Register . This
861+* register controls which interrupt sources of the IIC device are allowed to
862+* generate an interrupt. The global interrupt enable register and the device
863+* interrupt enable register must also be set appropriately for an interrupt
864+* to be passed out of the device.
865+*
866+* Each bit of the register correlates to a specific interrupt source within the
867+* device. Setting a bit in this register enables the interrupt source to gen
868+* an interrupt. Clearing a bit in this register disables interrupt generation
869+* for that interrupt source.
870+*
871+* This function writes only the specified value to the register such that
872+* some interrupt sources may be enabled and others disabled. It is the
873+* caller's responsibility to get the value of the interrupt enable register
874+* prior to setting the value to prevent a destructive behavior.
875+*
876+* @param Instance local I2C instance
877+* @param Enable contains the value to be written to the Interrupt Enable
878+* Register.
879+*
880+* @return None
881+*
882+* @note C-Style signature:
883+* void XIIC_WRITE_IIER(i2c, u32 Enable);
884+*
885+******************************************************************************/
886+#define XIIC_WRITE_IIER(Instance, Enable) \
887+ xiic_setreg32(Instance, XIIC_IIER_OFFSET, (Enable))
888+
889+/******************************************************************************
890+*
891+*
892+* This function gets the Interrupt enable register contents. This register
893+* controls which interrupt sources of the device are allowed to generate an
894+* interrupt. The global interrupt enable register and the device interrupt
895+* enable register must also be set appropriately for an interrupt to be
896+* passed out of the IIC device.
897+*
898+* Each bit of the register correlates to a specific interrupt source within the
899+* IIC device. Setting a bit in this register enables the interrupt source to
900+* generate an interrupt. Clearing a bit in this register disables interrupt
901+* generation for that interrupt source.
902+*
903+* @param Instance local I2C instance
904+*
905+* @return The contents read from the Interrupt Enable Register.
906+*
907+* @note C-Style signature:
908+* u32 XIIC_READ_IIER(i2c)
909+*
910+******************************************************************************/
911+#define XIIC_READ_IIER(Instance) \
912+ xiic_getreg32(Instance, XIIC_IIER_OFFSET)
913+
914+/************************** Function Prototypes ******************************/
915+
916+/******************************************************************************
917+*
918+* This macro disables the specified interrupts in the Interrupt enable
919+* register. It is non-destructive in that the register is read and only the
920+* interrupts specified is changed.
921+*
922+* @param BaseAddress is the base address of the IIC device.
923+* @param InterruptMask contains the interrupts to be disabled
924+*
925+* @return None.
926+*
927+* @note Signature:
928+* void XIic_mDisableIntr(u32 BaseAddress, u32 InterruptMask);
929+*
930+******************************************************************************/
931+#define XIic_mDisableIntr(Instance, InterruptMask) \
932+ XIIC_WRITE_IIER((Instance), XIIC_READ_IIER(Instance) & ~(InterruptMask))
933+
934+/******************************************************************************
935+*
936+* This macro enables the specified interrupts in the Interrupt enable
937+* register. It is non-destructive in that the register is read and only the
938+* interrupts specified is changed.
939+*
940+* @param BaseAddress is the base address of the IIC device.
941+* @param InterruptMask contains the interrupts to be disabled
942+*
943+* @return None.
944+*
945+* @note Signature:
946+* void XIic_mEnableIntr(u32 BaseAddress, u32 InterruptMask);
947+*
948+******************************************************************************/
949+#define XIic_mEnableIntr(Instance, InterruptMask) \
950+ XIIC_WRITE_IIER((Instance), XIIC_READ_IIER(Instance) | (InterruptMask))
951+
952+/******************************************************************************
953+*
954+* This macro clears the specified interrupt in the Interrupt status
955+* register. It is non-destructive in that the register is read and only the
956+* interrupt specified is cleared. Clearing an interrupt acknowledges it.
957+*
958+* @param BaseAddress is the base address of the IIC device.
959+* @param InterruptMask contains the interrupts to be disabled
960+*
961+* @return None.
962+*
963+* @note Signature:
964+* void XIic_mClearIntr(u32 BaseAddress, u32 InterruptMask);
965+*
966+******************************************************************************/
967+#define XIic_mClearIntr(Instance, InterruptMask) \
968+ XIIC_WRITE_IISR((Instance), XIIC_READ_IISR(Instance) & (InterruptMask))
969+
970+/******************************************************************************
971+*
972+* This macro clears and enables the specified interrupt in the Interrupt
973+* status and enable registers. It is non-destructive in that the registers are
974+* read and only the interrupt specified is modified.
975+* Clearing an interrupt acknowledges it.
976+*
977+* @param BaseAddress is the base address of the IIC device.
978+* @param InterruptMask contains the interrupts to be cleared and enabled
979+*
980+* @return None.
981+*
982+* @note Signature:
983+* void XIic_mClearEnableIntr(u32 BaseAddress, u32 InterruptMask);
984+*
985+******************************************************************************/
986+#define XIic_mClearEnableIntr(Instance, InterruptMask) { \
987+ XIIC_WRITE_IISR(Instance, \
988+ (XIIC_READ_IISR(Instance) & (InterruptMask))); \
989+ XIIC_WRITE_IIER(Instance, \
990+ (XIIC_READ_IIER(Instance) | (InterruptMask))); \
991+}
992+
993+
994+#define xiic_tx_space(i2c) ((i2c)->tx_msg->len - (i2c)->tx_pos)
995+#define xiic_rx_space(i2c) ((i2c)->rx_msg->len - (i2c)->rx_pos)
996+
997+static void xiic_clear_rx_fifo(struct xiic_i2c *i2c)
998+{
999+ u8 sr;
1000+ for (sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET);
1001+ !(sr & XIIC_SR_RX_FIFO_EMPTY_MASK);
1002+ sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET))
1003+ xiic_getreg8(i2c, XIIC_DRR_REG_OFFSET);
1004+}
1005+
1006+/******************************************************************************
1007+ *
1008+ * Initialize the IIC core for Dynamic Functionality.
1009+ *
1010+ * @param i2c local I2C instance
1011+ *
1012+ * @return None.
1013+ *
1014+ * @note None.
1015+ *
1016+ ******************************************************************************/
1017+static void xiic_reinit(struct xiic_i2c *i2c)
1018+{
1019+ xiic_setreg32(i2c, XIIC_RESETR_OFFSET, XIIC_RESET_MASK);
1020+
1021+ /* Set receive Fifo depth to maximum (zero based). */
1022+ xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, IIC_RX_FIFO_DEPTH - 1);
1023+
1024+ /* Reset Tx Fifo. */
1025+ xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_TX_FIFO_RESET_MASK);
1026+
1027+ /* Enable IIC Device, remove Tx Fifo reset & disable general call. */
1028+ xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_ENABLE_DEVICE_MASK);
1029+
1030+ /* make sure RX fifo is empty */
1031+ xiic_clear_rx_fifo(i2c);
1032+
1033+ /* Enable interrupts */
1034+ xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
1035+
1036+ XIic_mClearEnableIntr(i2c, XIIC_INTR_AAS_MASK |
1037+ XIIC_INTR_ARB_LOST_MASK);
1038+}
1039+
1040+/******************************************************************************
1041+ *
1042+ * De-Initialize the IIC core.
1043+ *
1044+ * @param i2c local I2C instance
1045+ *
1046+ * @return None.
1047+ *
1048+ * @note None.
1049+ *
1050+ ******************************************************************************/
1051+static void xiic_deinit(struct xiic_i2c *i2c)
1052+{
1053+ u8 cr;
1054+
1055+ xiic_setreg32(i2c, XIIC_RESETR_OFFSET, XIIC_RESET_MASK);
1056+
1057+ /* Disable IIC Device. */
1058+ cr = xiic_getreg8(i2c, XIIC_CR_REG_OFFSET);
1059+ xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, cr & ~XIIC_CR_ENABLE_DEVICE_MASK);
1060+}
1061+
1062+
1063+
1064+/*****************************************************************************
1065+ *
1066+ *
1067+ * This function is called when the receive register is full. The number
1068+ * of bytes received to cause the interrupt is adjustable using the Receive FIFO
1069+ * Depth register. The number of bytes in the register is read in the Receive
1070+ * FIFO occupancy register. Both these registers are zero based values (0-15)
1071+ * such that a value of zero indicates 1 byte.
1072+ *
1073+ * For a Master Receiver to properly signal the end of a message, the data must
1074+ * be read in up to the message length - 1, where control register bits will be
1075+ * set for bus controls to occur on reading of the last byte.
1076+ *
1077+ * @param InstancePtr is a pointer to the XIic instance to be worked on.
1078+ *
1079+ * @return None.
1080+ *
1081+ * @note None.
1082+ *
1083+ ******************************************************************************/
1084+static void xiic_read_rx(struct xiic_i2c *i2c)
1085+{
1086+ u8 bytes_in_fifo;
1087+ int i;
1088+
1089+ bytes_in_fifo = xiic_getreg8(i2c, XIIC_RFO_REG_OFFSET) + 1;
1090+
1091+ dev_dbg(i2c->adap.dev.parent, "%s entry, bytes in fifo: %d, msg: %d"
1092+ ", SR: 0x%x, CR: 0x%x\n",
1093+ __func__, bytes_in_fifo, xiic_rx_space(i2c),
1094+ xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),
1095+ xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
1096+
1097+ if (bytes_in_fifo > xiic_rx_space(i2c))
1098+ bytes_in_fifo = xiic_rx_space(i2c);
1099+
1100+ for (i = 0; i < bytes_in_fifo; i++)
1101+ i2c->rx_msg->buf[i2c->rx_pos++] =
1102+ xiic_getreg8(i2c, XIIC_DRR_REG_OFFSET);
1103+
1104+ xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET,
1105+ (xiic_rx_space(i2c) > IIC_RX_FIFO_DEPTH) ?
1106+ IIC_RX_FIFO_DEPTH - 1 : xiic_rx_space(i2c) - 1);
1107+}
1108+
1109+/******************************************************************************
1110+ *
1111+ * This function fills the FIFO using the occupancy register to determine the
1112+ * available space to be filled. When the repeated start option is on, the last
1113+ * byte is withheld to allow the control register to be properly set on the last
1114+ * byte.
1115+ *
1116+ * @param InstancePtr is a pointer to the XIic instance to be worked on.
1117+ *
1118+ * @param Role indicates the role of this IIC device, a slave or a master, on
1119+ * the IIC bus (XIIC_SLAVE_ROLE or XIIC_MASTER_ROLE)
1120+ *
1121+ * @return
1122+ *
1123+ * None.
1124+ *
1125+ * @note
1126+ *
1127+ * None.
1128+ *
1129+ ******************************************************************************/
1130+static int xiic_tx_fifo_space(struct xiic_i2c *i2c)
1131+{
1132+ return IIC_TX_FIFO_DEPTH - xiic_getreg8(i2c, XIIC_TFO_REG_OFFSET) - 1;
1133+}
1134+
1135+static void xiic_fill_tx_fifo(struct xiic_i2c *i2c)
1136+{
1137+ u8 fifo_space = xiic_tx_fifo_space(i2c);
1138+ int len = xiic_tx_space(i2c);
1139+
1140+ len = (len > fifo_space) ? fifo_space : len;
1141+
1142+ dev_dbg(i2c->adap.dev.parent, "%s entry, len: %d, fifo space: %d\n",
1143+ __func__, len, fifo_space);
1144+
1145+ while (len--) {
1146+ u16 data = i2c->tx_msg->buf[i2c->tx_pos++];
1147+ if ((xiic_tx_space(i2c) == 0) && (i2c->nmsgs == 1)) {
1148+ /* last message in transfer -> STOP */
1149+ data |= XIIC_TX_DYN_STOP_MASK;
1150+ dev_dbg(i2c->adap.dev.parent, "%s TX STOP\n", __func__);
1151+
1152+ xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data);
1153+ } else
1154+ xiic_setreg8(i2c, XIIC_DTR_REG_OFFSET, data);
1155+ }
1156+}
1157+
1158+static void xiic_wakeup(struct xiic_i2c *i2c, int code)
1159+{
1160+ i2c->tx_msg = NULL;
1161+ i2c->rx_msg = NULL;
1162+ i2c->nmsgs = 0;
1163+ i2c->state = code;
1164+ wake_up(&i2c->wait);
1165+}
1166+
1167+static void xiic_process(struct xiic_i2c *i2c)
1168+{
1169+ u32 pend, isr, ier;
1170+ u32 Clear = 0;
1171+
1172+ /* Get the interrupt Status from the IPIF. There is no clearing of
1173+ * interrupts in the IPIF. Interrupts must be cleared at the source.
1174+ * To find which interrupts are pending; AND interrupts pending with
1175+ * interrupts masked.
1176+ */
1177+ isr = XIIC_READ_IISR(i2c);
1178+ ier = XIIC_READ_IIER(i2c);
1179+ pend = isr & ier;
1180+
1181+ dev_dbg(i2c->adap.dev.parent, "%s entry, IER: 0x%x, ISR: 0x%x, "
1182+ "pend: 0x%x, SR: 0x%x, msg: %p, nmsgs: %d\n",
1183+ __func__, ier, isr, pend, xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),
1184+ i2c->tx_msg, i2c->nmsgs);
1185+
1186+ /* Do not processes a devices interrupts if the device has no
1187+ * interrupts pending
1188+ */
1189+ if (!pend)
1190+ return;
1191+
1192+ /* Service requesting interrupt */
1193+ if ((pend & XIIC_INTR_ARB_LOST_MASK) ||
1194+ ((pend & XIIC_INTR_TX_ERROR_MASK) &&
1195+ !(pend & XIIC_INTR_RX_FULL_MASK))) {
1196+ /* bus arbritration lost, or...
1197+ * Transmit error _OR_ RX completed
1198+ * if this happens when RX_FULL is not set
1199+ * this is probably a TX error
1200+ */
1201+
1202+ dev_dbg(i2c->adap.dev.parent,
1203+ "%s error\n", __func__);
1204+
1205+ /* dynamic mode seem to suffer from problems if we just flushes
1206+ * fifos and the next message is a TX with len 0 (only addr)
1207+ * reset the IP instead of just flush fifos
1208+ */
1209+ xiic_reinit(i2c);
1210+
1211+ if (i2c->tx_msg)
1212+ xiic_wakeup(i2c, STATE_ERROR);
1213+
1214+ } else if (pend & XIIC_INTR_RX_FULL_MASK) {
1215+ /* Receive register/FIFO is full */
1216+
1217+ Clear = XIIC_INTR_RX_FULL_MASK;
1218+ if (!i2c->rx_msg) {
1219+ dev_dbg(i2c->adap.dev.parent,
1220+ "%s unexpexted RX IRQ\n", __func__);
1221+ xiic_clear_rx_fifo(i2c);
1222+ goto out;
1223+ }
1224+
1225+ xiic_read_rx(i2c);
1226+ if (xiic_rx_space(i2c) == 0) {
1227+ /* this is the last part of the message */
1228+ i2c->rx_msg = NULL;
1229+
1230+ /* also clear TX error if there (RX complete) */
1231+ Clear |= (isr & XIIC_INTR_TX_ERROR_MASK);
1232+
1233+ dev_dbg(i2c->adap.dev.parent,
1234+ "%s end of message, nmsgs: %d\n",
1235+ __func__, i2c->nmsgs);
1236+
1237+ /* send next message if this wasn't the last,
1238+ * otherwise the transfer will be finialise when
1239+ * receiving the bus not busy interrupt
1240+ */
1241+ if (i2c->nmsgs > 1) {
1242+ i2c->nmsgs--;
1243+ i2c->tx_msg++;
1244+ dev_dbg(i2c->adap.dev.parent,
1245+ "%s will start next...\n", __func__);
1246+
1247+ __xiic_start_xfer(i2c);
1248+ }
1249+ }
1250+ } else if (pend & XIIC_INTR_BNB_MASK) {
1251+ /* IIC bus has transitioned to not busy */
1252+ Clear = XIIC_INTR_BNB_MASK;
1253+
1254+ /* The bus is not busy, disable BusNotBusy interrupt */
1255+ XIic_mDisableIntr(i2c, XIIC_INTR_BNB_MASK);
1256+
1257+ if (!i2c->tx_msg)
1258+ goto out;
1259+
1260+ if ((i2c->nmsgs == 1) && !i2c->rx_msg &&
1261+ xiic_tx_space(i2c) == 0)
1262+ xiic_wakeup(i2c, STATE_DONE);
1263+ else
1264+ xiic_wakeup(i2c, STATE_ERROR);
1265+
1266+ } else if (pend & (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)) {
1267+ /* Transmit register/FIFO is empty or ½ empty */
1268+
1269+ Clear = pend &
1270+ (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK);
1271+
1272+ if (!i2c->tx_msg) {
1273+ dev_dbg(i2c->adap.dev.parent,
1274+ "%s unexpexted TX IRQ\n", __func__);
1275+ goto out;
1276+ }
1277+
1278+ xiic_fill_tx_fifo(i2c);
1279+
1280+ /* current message sent and there is space in the fifo */
1281+ if (!xiic_tx_space(i2c) && xiic_tx_fifo_space(i2c) >= 2) {
1282+ dev_dbg(i2c->adap.dev.parent,
1283+ "%s end of message sent, nmsgs: %d\n",
1284+ __func__, i2c->nmsgs);
1285+ if (i2c->nmsgs > 1) {
1286+ i2c->nmsgs--;
1287+ i2c->tx_msg++;
1288+ __xiic_start_xfer(i2c);
1289+ } else {
1290+ XIic_mDisableIntr(i2c, XIIC_INTR_TX_HALF_MASK);
1291+
1292+ dev_err(i2c->adap.dev.parent,
1293+ "%s Got TX IRQ but no more to do...\n",
1294+ __func__);
1295+ }
1296+ } else if (!xiic_tx_space(i2c) && (i2c->nmsgs == 1))
1297+ /* current frame is sent and is last,
1298+ * make sure to disable tx half
1299+ */
1300+ XIic_mDisableIntr(i2c, XIIC_INTR_TX_HALF_MASK);
1301+ } else {
1302+ /* got IRQ which is not acked */
1303+ dev_err(i2c->adap.dev.parent, "%s Got unexpected IRQ\n",
1304+ __func__);
1305+ Clear = pend;
1306+ }
1307+out:
1308+ dev_dbg(i2c->adap.dev.parent, "%s Clear: 0x%x\n", __func__, Clear);
1309+
1310+ XIIC_WRITE_IISR(i2c, Clear);
1311+}
1312+
1313+/******************************************************************************
1314+ *
1315+ * This function checks to see if the IIC bus is busy. If so, it will enable
1316+ * the bus not busy interrupt such that the driver is notified when the bus
1317+ * is no longer busy.
1318+ *
1319+ * @param InstancePtr points to the Iic instance to be worked on.
1320+ *
1321+ * @return FALSE if the IIC bus is not busy else TRUE.
1322+ *
1323+ * @note The BusNotBusy interrupt is enabled which will update the
1324+ * EventStatus when the bus is no longer busy.
1325+ *
1326+ ******************************************************************************/
1327+static int xiic_bus_busy(struct xiic_i2c *i2c)
1328+{
1329+ u8 sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET);
1330+
1331+ return (sr & XIIC_SR_BUS_BUSY_MASK) ? -EBUSY : 0;
1332+}
1333+
1334+static int xiic_busy(struct xiic_i2c *i2c)
1335+{
1336+ int tries = 3;
1337+ int err;
1338+ if (i2c->tx_msg)
1339+ return -EBUSY;
1340+
1341+ /* for instance if previous transfer was terminated due to TX error
1342+ * it might be that the bus is on it's way to become available
1343+ * give it at most 3 ms to wake
1344+ */
1345+ err = xiic_bus_busy(i2c);
1346+ while (err && tries--) {
1347+ mdelay(1);
1348+ err = xiic_bus_busy(i2c);
1349+ }
1350+
1351+ return err;
1352+}
1353+
1354+static void xiic_dump_regs(struct xiic_i2c *i2c, const char *caller)
1355+{
1356+ dev_dbg(i2c->adap.dev.parent, "%s msg: %p, nmsgs: %d, "
1357+ "ISR: 0x%x, CR: 0x%x, SR: 0x%x\n",
1358+ caller, i2c->tx_msg, i2c->nmsgs, XIIC_READ_IISR(i2c),
1359+ xiic_getreg8(i2c, XIIC_CR_REG_OFFSET),
1360+ xiic_getreg8(i2c, XIIC_SR_REG_OFFSET));
1361+}
1362+
1363+static void xiic_start_recv(struct xiic_i2c *i2c)
1364+{
1365+ u8 rx_watermark;
1366+ struct i2c_msg *msg = i2c->rx_msg = i2c->tx_msg;
1367+
1368+ xiic_dump_regs(i2c, __func__);
1369+
1370+ /* Clear and enable Rx full interrupt. */
1371+ XIic_mClearEnableIntr(i2c, XIIC_INTR_RX_FULL_MASK |
1372+ XIIC_INTR_TX_ERROR_MASK);
1373+
1374+ /* we want to get all but last byte, because the TX_ERROR IRQ is used
1375+ * to inidicate error ACK on the address, and negative ack on the last
1376+ * received byte, so to not mix them receive all but last.
1377+ * In the case where there is only one byte to receive
1378+ * we can check if ERROR and RX full is set at the same time
1379+ */
1380+ rx_watermark = msg->len;
1381+ if (rx_watermark > IIC_RX_FIFO_DEPTH)
1382+ rx_watermark = IIC_RX_FIFO_DEPTH;
1383+ xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, rx_watermark - 1);
1384+
1385+ if (!(msg->flags & I2C_M_NOSTART))
1386+ /* write the address */
1387+ xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET,
1388+ (msg->addr << 1) | XIIC_READ_OPERATION |
1389+ XIIC_TX_DYN_START_MASK);
1390+
1391+ XIic_mClearEnableIntr(i2c,
1392+ XIIC_INTR_BNB_MASK);
1393+
1394+ xiic_dump_regs(i2c, "after address");
1395+
1396+ xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET,
1397+ msg->len | ((i2c->nmsgs == 1) ? XIIC_TX_DYN_STOP_MASK : 0));
1398+ if (i2c->nmsgs == 1) {
1399+ /* very last, enable bus busy as well */
1400+ XIic_mClearEnableIntr(i2c, XIIC_INTR_BNB_MASK);
1401+ }
1402+
1403+ xiic_dump_regs(i2c, "xiic_start_recv exit");
1404+
1405+ /* the message is tx:ed */
1406+ i2c->tx_pos = msg->len;
1407+}
1408+
1409+static void xiic_start_send(struct xiic_i2c *i2c)
1410+{
1411+ struct i2c_msg *msg = i2c->tx_msg;
1412+
1413+ XIic_mClearIntr(i2c, XIIC_INTR_TX_ERROR_MASK);
1414+
1415+ dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, len: %d, "
1416+ "ISR: 0x%x, CR: 0x%x\n",
1417+ __func__, msg, msg->len, XIIC_READ_IISR(i2c),
1418+ xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
1419+
1420+ if (!(msg->flags & I2C_M_NOSTART)) {
1421+ /* write the address */
1422+ u16 data = ((msg->addr << 1) & 0xfe) | XIIC_WRITE_OPERATION |
1423+ XIIC_TX_DYN_START_MASK;
1424+ if ((i2c->nmsgs == 1) && msg->len == 0)
1425+ /* no data and last message -> add STOP */
1426+ data |= XIIC_TX_DYN_STOP_MASK;
1427+
1428+ xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data);
1429+ }
1430+
1431+ xiic_fill_tx_fifo(i2c);
1432+
1433+ /* Clear any pending Tx empty, Tx Error and then enable them. */
1434+ XIic_mClearEnableIntr(i2c,
1435+ XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_ERROR_MASK |
1436+ XIIC_INTR_BNB_MASK);
1437+}
1438+
1439+static inline void xiic_setreg8(struct xiic_i2c *i2c, int reg, u8 value)
1440+{
1441+ iowrite8(value, i2c->base + reg);
1442+}
1443+
1444+static inline u8 xiic_getreg8(struct xiic_i2c *i2c, int reg)
1445+{
1446+ return ioread8(i2c->base + reg);
1447+}
1448+
1449+static inline void xiic_setreg16(struct xiic_i2c *i2c, int reg, u16 value)
1450+{
1451+ iowrite16(value, i2c->base + reg);
1452+}
1453+
1454+static inline void xiic_setreg32(struct xiic_i2c *i2c, int reg, int value)
1455+{
1456+ iowrite32(value, i2c->base + reg);
1457+}
1458+
1459+static inline int xiic_getreg32(struct xiic_i2c *i2c, int reg)
1460+{
1461+ return ioread32(i2c->base + reg);
1462+}
1463+
1464+static irqreturn_t xiic_isr(int irq, void *dev_id)
1465+{
1466+ struct xiic_i2c *i2c = dev_id;
1467+ spin_lock(&i2c->lock);
1468+ XIIC_GINTR_DISABLE(i2c);
1469+
1470+ dev_dbg(i2c->adap.dev.parent, "%s entry\n", __func__);
1471+
1472+ xiic_process(i2c);
1473+
1474+ XIIC_GINTR_ENABLE(i2c);
1475+
1476+ spin_unlock(&i2c->lock);
1477+
1478+ return IRQ_HANDLED;
1479+}
1480+
1481+static void __xiic_start_xfer(struct xiic_i2c *i2c)
1482+{
1483+ int first = 1;
1484+ int fifo_space = xiic_tx_fifo_space(i2c);
1485+ dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, fifos space: %d\n",
1486+ __func__, i2c->tx_msg, fifo_space);
1487+
1488+ if (!i2c->tx_msg)
1489+ return;
1490+
1491+ i2c->rx_pos = 0;
1492+ i2c->tx_pos = 0;
1493+ i2c->state = STATE_START;
1494+ while ((fifo_space >= 2) && (first || (i2c->nmsgs > 1))) {
1495+ if (!first) {
1496+ i2c->nmsgs--;
1497+ i2c->tx_msg++;
1498+ i2c->tx_pos = 0;
1499+ } else
1500+ first = 0;
1501+
1502+ if (i2c->tx_msg->flags & I2C_M_RD) {
1503+ /* we dont date putting several reads in the FIFO */
1504+ xiic_start_recv(i2c);
1505+ return;
1506+ } else {
1507+ xiic_start_send(i2c);
1508+ if (xiic_tx_space(i2c) != 0) {
1509+ /* the message could not be completely sent */
1510+ break;
1511+ }
1512+ }
1513+
1514+ fifo_space = xiic_tx_fifo_space(i2c);
1515+ }
1516+
1517+ /* there are more messages or the current one could not be completely
1518+ * put into the FIFO, also enable the half empty interrupt
1519+ */
1520+ if (i2c->nmsgs > 1 || xiic_tx_space(i2c))
1521+ XIic_mClearEnableIntr(i2c, XIIC_INTR_TX_HALF_MASK);
1522+
1523+}
1524+
1525+static void xiic_start_xfer(struct xiic_i2c *i2c)
1526+{
1527+ unsigned long flags;
1528+
1529+ spin_lock_irqsave(&i2c->lock, flags);
1530+ xiic_reinit(i2c);
1531+ XIIC_GINTR_DISABLE(i2c);
1532+ spin_unlock_irqrestore(&i2c->lock, flags);
1533+
1534+ __xiic_start_xfer(i2c);
1535+
1536+ XIIC_GINTR_ENABLE(i2c);
1537+}
1538+
1539+static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
1540+{
1541+ struct xiic_i2c *i2c = i2c_get_adapdata(adap);
1542+ int err;
1543+
1544+ dev_dbg(adap->dev.parent, "%s entry SR: 0x%x\n", __func__,
1545+ xiic_getreg8(i2c, XIIC_SR_REG_OFFSET));
1546+
1547+ err = xiic_busy(i2c);
1548+ if (err) {
1549+ xiic_dump_regs(i2c, "bus busy");
1550+ return err;
1551+ }
1552+
1553+ i2c->tx_msg = msgs;
1554+ i2c->nmsgs = num;
1555+
1556+ xiic_start_xfer(i2c);
1557+
1558+ if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) ||
1559+ (i2c->state == STATE_DONE), HZ))
1560+ return (i2c->state == STATE_DONE) ? num : -EIO;
1561+ else {
1562+ xiic_dump_regs(i2c, __func__);
1563+ i2c->tx_msg = NULL;
1564+ i2c->rx_msg = NULL;
1565+ i2c->nmsgs = 0;
1566+ return -ETIMEDOUT;
1567+ }
1568+}
1569+
1570+static u32 xiic_func(struct i2c_adapter *adap)
1571+{
1572+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
1573+}
1574+
1575+static const struct i2c_algorithm xiic_algorithm = {
1576+ .master_xfer = xiic_xfer,
1577+ .functionality = xiic_func,
1578+};
1579+
1580+static struct i2c_adapter xiic_adapter = {
1581+ .owner = THIS_MODULE,
1582+ .name = DRIVER_NAME,
1583+ .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
1584+ .algo = &xiic_algorithm,
1585+};
1586+
1587+
1588+static int __devinit xiic_i2c_probe(struct platform_device *pdev)
1589+{
1590+ struct xiic_i2c *i2c;
1591+ struct xiic_i2c_platform_data *pdata;
1592+ struct resource *res;
1593+ int ret, irq;
1594+ u8 i;
1595+
1596+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1597+ if (!res)
1598+ return -ENODEV;
1599+
1600+ irq = platform_get_irq(pdev, 0);
1601+ if (irq < 0)
1602+ return -ENODEV;
1603+
1604+ pdata = (struct xiic_i2c_platform_data *) pdev->dev.platform_data;
1605+ if (!pdata)
1606+ return -ENODEV;
1607+
1608+ i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
1609+ if (!i2c)
1610+ return -ENOMEM;
1611+
1612+ if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
1613+ dev_err(&pdev->dev, "Memory region busy\n");
1614+ ret = -EBUSY;
1615+ goto request_mem_failed;
1616+ }
1617+
1618+ i2c->base = ioremap(res->start, resource_size(res));
1619+ if (!i2c->base) {
1620+ dev_err(&pdev->dev, "Unable to map registers\n");
1621+ ret = -EIO;
1622+ goto map_failed;
1623+ }
1624+
1625+ /* hook up driver to tree */
1626+ platform_set_drvdata(pdev, i2c);
1627+ i2c->adap = xiic_adapter;
1628+ i2c_set_adapdata(&i2c->adap, i2c);
1629+ i2c->adap.dev.parent = &pdev->dev;
1630+
1631+ xiic_reinit(i2c);
1632+
1633+ spin_lock_init(&i2c->lock);
1634+ init_waitqueue_head(&i2c->wait);
1635+ ret = request_irq(irq, xiic_isr, 0, pdev->name, i2c);
1636+ if (ret) {
1637+ dev_err(&pdev->dev, "Cannot claim IRQ\n");
1638+ goto request_irq_failed;
1639+ }
1640+
1641+ /* add i2c adapter to i2c tree */
1642+ ret = i2c_add_adapter(&i2c->adap);
1643+ if (ret) {
1644+ dev_err(&pdev->dev, "Failed to add adapter\n");
1645+ goto add_adapter_failed;
1646+ }
1647+
1648+ /* add in known devices to the bus */
1649+ for (i = 0; i < pdata->num_devices; i++)
1650+ i2c_new_device(&i2c->adap, pdata->devices + i);
1651+
1652+ return 0;
1653+
1654+add_adapter_failed:
1655+ free_irq(irq, i2c);
1656+request_irq_failed:
1657+ xiic_deinit(i2c);
1658+ iounmap(i2c->base);
1659+map_failed:
1660+ release_mem_region(res->start, resource_size(res));
1661+request_mem_failed:
1662+ kfree(i2c);
1663+
1664+ return ret;
1665+}
1666+
1667+static int __devexit xiic_i2c_remove(struct platform_device* pdev)
1668+{
1669+ struct xiic_i2c *i2c = platform_get_drvdata(pdev);
1670+ struct resource *res;
1671+
1672+ /* remove adapter & data */
1673+ i2c_del_adapter(&i2c->adap);
1674+
1675+ xiic_deinit(i2c);
1676+
1677+ platform_set_drvdata(pdev, NULL);
1678+
1679+ free_irq(platform_get_irq(pdev, 0), i2c);
1680+
1681+ iounmap(i2c->base);
1682+
1683+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1684+ if (res)
1685+ release_mem_region(res->start, resource_size(res));
1686+
1687+ kfree(i2c);
1688+
1689+ return 0;
1690+}
1691+
1692+
1693+/* work with hotplug and coldplug */
1694+MODULE_ALIAS("platform:"DRIVER_NAME);
1695+
1696+static struct platform_driver xiic_i2c_driver = {
1697+ .probe = xiic_i2c_probe,
1698+ .remove = __devexit_p(xiic_i2c_remove),
1699+ .driver = {
1700+ .owner = THIS_MODULE,
1701+ .name = DRIVER_NAME,
1702+ },
1703+};
1704+
1705+static int __init xiic_i2c_init(void)
1706+{
1707+ return platform_driver_register(&xiic_i2c_driver);
1708+}
1709+
1710+static void __exit xiic_i2c_exit(void)
1711+{
1712+ platform_driver_unregister(&xiic_i2c_driver);
1713+}
1714+
1715+module_init(xiic_i2c_init);
1716+module_exit(xiic_i2c_exit);
1717+
1718+MODULE_AUTHOR("info@mocean-labs.com");
1719+MODULE_DESCRIPTION("Xilinx I2C bus driver");
1720+MODULE_LICENSE("GPL v2");
1721diff -uNr linux-2.6.31/drivers/i2c/busses/Kconfig linux-2.6.31.new/drivers/i2c/busses/Kconfig
1722--- linux-2.6.31/drivers/i2c/busses/Kconfig 2009-10-23 11:18:30.000000000 -0700
1723+++ linux-2.6.31.new/drivers/i2c/busses/Kconfig 2009-10-23 11:17:29.000000000 -0700
1724@@ -433,6 +433,16 @@
1725 This driver can also be built as a module. If so, the module
1726 will be called i2c-ocores.
1727
1728+config I2C_XILINX
1729+ tristate "Xilinx I2C Controller"
1730+ depends on EXPERIMENTAL && HAS_IOMEM
1731+ help
1732+ If you say yes to this option, support will be included for the
1733+ Xilinx I2C controller.
1734+
1735+ This driver can also be built as a module. If so, the module
1736+ will be called xilinx_i2c.
1737+
1738 config I2C_OMAP
1739 tristate "OMAP I2C adapter"
1740 depends on ARCH_OMAP
1741diff -uNr linux-2.6.31/drivers/i2c/busses/Makefile linux-2.6.31.new/drivers/i2c/busses/Makefile
1742--- linux-2.6.31/drivers/i2c/busses/Makefile 2009-10-23 11:18:30.000000000 -0700
1743+++ linux-2.6.31.new/drivers/i2c/busses/Makefile 2009-10-23 11:17:29.000000000 -0700
1744@@ -40,6 +40,7 @@
1745 obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
1746 obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o
1747 obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o
1748+obj-$(CONFIG_I2C_XILINX) += i2c-xiic.o
1749 obj-$(CONFIG_I2C_OMAP) += i2c-omap.o
1750 obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o
1751 obj-$(CONFIG_I2C_PNX) += i2c-pnx.o
1752diff -uNr linux-2.6.31/drivers/input/touchscreen/tsc2007.c linux-2.6.31.new/drivers/input/touchscreen/tsc2007.c
1753--- linux-2.6.31/drivers/input/touchscreen/tsc2007.c 2009-10-23 11:18:30.000000000 -0700
1754+++ linux-2.6.31.new/drivers/input/touchscreen/tsc2007.c 2009-10-23 11:17:19.000000000 -0700
1755@@ -21,15 +21,14 @@
1756 */
1757
1758 #include <linux/module.h>
1759-#include <linux/hrtimer.h>
1760 #include <linux/slab.h>
1761 #include <linux/input.h>
1762 #include <linux/interrupt.h>
1763 #include <linux/i2c.h>
1764 #include <linux/i2c/tsc2007.h>
1765
1766-#define TS_POLL_DELAY (10 * 1000) /* ns delay before the first sample */
1767-#define TS_POLL_PERIOD (5 * 1000) /* ns delay between samples */
1768+#define TS_POLL_DELAY 1 /* ms delay between samples */
1769+#define TS_POLL_PERIOD 1 /* ms delay between samples */
1770
1771 #define TSC2007_MEASURE_TEMP0 (0x0 << 4)
1772 #define TSC2007_MEASURE_AUX (0x2 << 4)
1773@@ -70,17 +69,15 @@
1774 struct tsc2007 {
1775 struct input_dev *input;
1776 char phys[32];
1777- struct hrtimer timer;
1778- struct ts_event tc;
1779+ struct delayed_work work;
1780
1781 struct i2c_client *client;
1782
1783- spinlock_t lock;
1784-
1785 u16 model;
1786 u16 x_plate_ohms;
1787
1788- unsigned pendown;
1789+ bool pendown;
1790+ bool ignore_first_irq;
1791 int irq;
1792
1793 int (*get_pendown_state)(void);
1794@@ -109,52 +106,96 @@
1795 return val;
1796 }
1797
1798-static void tsc2007_send_event(void *tsc)
1799+static void tsc2007_read_values(struct tsc2007 *tsc, struct ts_event *tc)
1800+{
1801+ /* y- still on; turn on only y+ (and ADC) */
1802+ tc->y = tsc2007_xfer(tsc, READ_Y);
1803+
1804+ /* turn y- off, x+ on, then leave in lowpower */
1805+ tc->x = tsc2007_xfer(tsc, READ_X);
1806+
1807+ /* turn y+ off, x- on; we'll use formula #1 */
1808+ tc->z1 = tsc2007_xfer(tsc, READ_Z1);
1809+ tc->z2 = tsc2007_xfer(tsc, READ_Z2);
1810+
1811+ /* Prepare for next touch reading - power down ADC, enable PENIRQ */
1812+ tsc2007_xfer(tsc, PWRDOWN);
1813+}
1814+
1815+static u32 tsc2007_calculate_pressure(struct tsc2007 *tsc, struct ts_event *tc)
1816 {
1817- struct tsc2007 *ts = tsc;
1818- u32 rt;
1819- u16 x, y, z1, z2;
1820-
1821- x = ts->tc.x;
1822- y = ts->tc.y;
1823- z1 = ts->tc.z1;
1824- z2 = ts->tc.z2;
1825+ u32 rt = 0;
1826
1827 /* range filtering */
1828- if (x == MAX_12BIT)
1829- x = 0;
1830+ if (tc->x == MAX_12BIT)
1831+ tc->x = 0;
1832
1833- if (likely(x && z1)) {
1834+ if (likely(tc->x && tc->z1)) {
1835 /* compute touch pressure resistance using equation #1 */
1836- rt = z2;
1837- rt -= z1;
1838- rt *= x;
1839- rt *= ts->x_plate_ohms;
1840- rt /= z1;
1841+ rt = tc->z2 - tc->z1;
1842+ rt *= tc->x;
1843+ rt *= tsc->x_plate_ohms;
1844+ rt /= tc->z1;
1845 rt = (rt + 2047) >> 12;
1846- } else
1847- rt = 0;
1848+ }
1849+
1850+ return rt;
1851+}
1852+
1853+static void tsc2007_send_up_event(struct tsc2007 *tsc)
1854+{
1855+ struct input_dev *input = tsc->input;
1856+
1857+ dev_dbg(&tsc->client->dev, "UP\n");
1858
1859- /* Sample found inconsistent by debouncing or pressure is beyond
1860- * the maximum. Don't report it to user space, repeat at least
1861- * once more the measurement
1862+ input_report_key(input, BTN_TOUCH, 0);
1863+ input_report_abs(input, ABS_PRESSURE, 0);
1864+ input_sync(input);
1865+}
1866+
1867+static void tsc2007_work(struct work_struct *work)
1868+{
1869+ struct tsc2007 *ts =
1870+ container_of(to_delayed_work(work), struct tsc2007, work);
1871+ struct ts_event tc;
1872+ u32 rt;
1873+
1874+ /*
1875+ * NOTE: We can't rely on the pressure to determine the pen down
1876+ * state, even though this controller has a pressure sensor.
1877+ * The pressure value can fluctuate for quite a while after
1878+ * lifting the pen and in some cases may not even settle at the
1879+ * expected value.
1880+ *
1881+ * The only safe way to check for the pen up condition is in the
1882+ * work function by reading the pen signal state (it's a GPIO
1883+ * and IRQ). Unfortunately such callback is not always available,
1884+ * in that case we have rely on the pressure anyway.
1885 */
1886+ if (ts->get_pendown_state) {
1887+ if (unlikely(!ts->get_pendown_state())) {
1888+ tsc2007_send_up_event(ts);
1889+ ts->pendown = false;
1890+ goto out;
1891+ }
1892+
1893+ dev_dbg(&ts->client->dev, "pen is still down\n");
1894+ }
1895+
1896+ tsc2007_read_values(ts, &tc);
1897+
1898+ rt = tsc2007_calculate_pressure(ts, &tc);
1899 if (rt > MAX_12BIT) {
1900+ /*
1901+ * Sample found inconsistent by debouncing or pressure is
1902+ * beyond the maximum. Don't report it to user space,
1903+ * repeat at least once more the measurement.
1904+ */
1905 dev_dbg(&ts->client->dev, "ignored pressure %d\n", rt);
1906+ goto out;
1907
1908- hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
1909- HRTIMER_MODE_REL);
1910- return;
1911 }
1912
1913- /* NOTE: We can't rely on the pressure to determine the pen down
1914- * state, even this controller has a pressure sensor. The pressure
1915- * value can fluctuate for quite a while after lifting the pen and
1916- * in some cases may not even settle at the expected value.
1917- *
1918- * The only safe way to check for the pen up condition is in the
1919- * timer by reading the pen signal state (it's a GPIO _and_ IRQ).
1920- */
1921 if (rt) {
1922 struct input_dev *input = ts->input;
1923
1924@@ -162,102 +203,82 @@
1925 dev_dbg(&ts->client->dev, "DOWN\n");
1926
1927 input_report_key(input, BTN_TOUCH, 1);
1928- ts->pendown = 1;
1929+ ts->pendown = true;
1930 }
1931
1932- input_report_abs(input, ABS_X, x);
1933- input_report_abs(input, ABS_Y, y);
1934+ input_report_abs(input, ABS_X, tc.x);
1935+ input_report_abs(input, ABS_Y, tc.y);
1936 input_report_abs(input, ABS_PRESSURE, rt);
1937
1938 input_sync(input);
1939
1940 dev_dbg(&ts->client->dev, "point(%4d,%4d), pressure (%4u)\n",
1941- x, y, rt);
1942- }
1943-
1944- hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
1945- HRTIMER_MODE_REL);
1946-}
1947-
1948-static int tsc2007_read_values(struct tsc2007 *tsc)
1949-{
1950- /* y- still on; turn on only y+ (and ADC) */
1951- tsc->tc.y = tsc2007_xfer(tsc, READ_Y);
1952-
1953- /* turn y- off, x+ on, then leave in lowpower */
1954- tsc->tc.x = tsc2007_xfer(tsc, READ_X);
1955-
1956- /* turn y+ off, x- on; we'll use formula #1 */
1957- tsc->tc.z1 = tsc2007_xfer(tsc, READ_Z1);
1958- tsc->tc.z2 = tsc2007_xfer(tsc, READ_Z2);
1959-
1960- /* power down */
1961- tsc2007_xfer(tsc, PWRDOWN);
1962-
1963- return 0;
1964-}
1965-
1966-static enum hrtimer_restart tsc2007_timer(struct hrtimer *handle)
1967-{
1968- struct tsc2007 *ts = container_of(handle, struct tsc2007, timer);
1969- unsigned long flags;
1970-
1971- spin_lock_irqsave(&ts->lock, flags);
1972-
1973- if (unlikely(!ts->get_pendown_state() && ts->pendown)) {
1974- struct input_dev *input = ts->input;
1975-
1976- dev_dbg(&ts->client->dev, "UP\n");
1977+ tc.x, tc.y, rt);
1978
1979- input_report_key(input, BTN_TOUCH, 0);
1980- input_report_abs(input, ABS_PRESSURE, 0);
1981- input_sync(input);
1982+ } else if (!ts->get_pendown_state && ts->pendown) {
1983+ /*
1984+ * We don't have callback to check pendown state, so we
1985+ * have to assume that since pressure reported is 0 the
1986+ * pen was lifted up.
1987+ */
1988+ tsc2007_send_up_event(ts);
1989+ ts->pendown = false;
1990+ }
1991
1992- ts->pendown = 0;
1993+ out:
1994+ if (ts->pendown)
1995+ schedule_delayed_work(&ts->work,
1996+ msecs_to_jiffies(TS_POLL_PERIOD));
1997+ else {
1998+ if (!ts->get_pendown_state)
1999+ ts->ignore_first_irq = 1;
2000 enable_irq(ts->irq);
2001- } else {
2002- /* pen is still down, continue with the measurement */
2003- dev_dbg(&ts->client->dev, "pen is still down\n");
2004-
2005- tsc2007_read_values(ts);
2006- tsc2007_send_event(ts);
2007 }
2008-
2009- spin_unlock_irqrestore(&ts->lock, flags);
2010-
2011- return HRTIMER_NORESTART;
2012 }
2013
2014 static irqreturn_t tsc2007_irq(int irq, void *handle)
2015 {
2016 struct tsc2007 *ts = handle;
2017- unsigned long flags;
2018
2019- spin_lock_irqsave(&ts->lock, flags);
2020+ if (ts->ignore_first_irq) {
2021+ ts->ignore_first_irq = 0;
2022+ return IRQ_HANDLED;
2023+ }
2024
2025- if (likely(ts->get_pendown_state())) {
2026+ if (!ts->get_pendown_state || likely(ts->get_pendown_state())) {
2027 disable_irq_nosync(ts->irq);
2028- hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY),
2029- HRTIMER_MODE_REL);
2030+ schedule_delayed_work(&ts->work,
2031+ msecs_to_jiffies(TS_POLL_DELAY));
2032 }
2033
2034 if (ts->clear_penirq)
2035 ts->clear_penirq();
2036
2037- spin_unlock_irqrestore(&ts->lock, flags);
2038-
2039 return IRQ_HANDLED;
2040 }
2041
2042-static int tsc2007_probe(struct i2c_client *client,
2043- const struct i2c_device_id *id)
2044+static void tsc2007_free_irq(struct tsc2007 *ts)
2045+{
2046+ free_irq(ts->irq, ts);
2047+ if (cancel_delayed_work_sync(&ts->work)) {
2048+ /*
2049+ * Work was pending, therefore we need to enable
2050+ * IRQ here to balance the disable_irq() done in the
2051+ * interrupt handler.
2052+ */
2053+ enable_irq(ts->irq);
2054+ }
2055+}
2056+
2057+static int __devinit tsc2007_probe(struct i2c_client *client,
2058+ const struct i2c_device_id *id)
2059 {
2060 struct tsc2007 *ts;
2061 struct tsc2007_platform_data *pdata = pdata = client->dev.platform_data;
2062 struct input_dev *input_dev;
2063 int err;
2064
2065- if (!pdata || !pdata->get_pendown_state) {
2066+ if (!pdata) {
2067 dev_err(&client->dev, "platform data is required!\n");
2068 return -EINVAL;
2069 }
2070@@ -274,22 +295,15 @@
2071 }
2072
2073 ts->client = client;
2074- i2c_set_clientdata(client, ts);
2075-
2076+ ts->irq = client->irq;
2077 ts->input = input_dev;
2078-
2079- hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
2080- ts->timer.function = tsc2007_timer;
2081-
2082- spin_lock_init(&ts->lock);
2083+ INIT_DELAYED_WORK(&ts->work, tsc2007_work);
2084
2085 ts->model = pdata->model;
2086 ts->x_plate_ohms = pdata->x_plate_ohms;
2087 ts->get_pendown_state = pdata->get_pendown_state;
2088 ts->clear_penirq = pdata->clear_penirq;
2089
2090- pdata->init_platform_hw();
2091-
2092 snprintf(ts->phys, sizeof(ts->phys),
2093 "%s/input0", dev_name(&client->dev));
2094
2095@@ -304,9 +318,8 @@
2096 input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
2097 input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0);
2098
2099- tsc2007_read_values(ts);
2100-
2101- ts->irq = client->irq;
2102+ if (pdata->init_platform_hw)
2103+ pdata->init_platform_hw();
2104
2105 err = request_irq(ts->irq, tsc2007_irq, 0,
2106 client->dev.driver->name, ts);
2107@@ -319,29 +332,37 @@
2108 if (err)
2109 goto err_free_irq;
2110
2111- dev_info(&client->dev, "registered with irq (%d)\n", ts->irq);
2112+ i2c_set_clientdata(client, ts);
2113+
2114+ /* Prepare for touch readings - power down ADC and enable PENIRQ */
2115+ err = tsc2007_xfer(ts, PWRDOWN);
2116+ if (err < 0)
2117+ goto err_unreg_dev;
2118
2119 return 0;
2120
2121+ err_unreg_dev:
2122+ input_unregister_device(ts->input);
2123 err_free_irq:
2124- free_irq(ts->irq, ts);
2125- hrtimer_cancel(&ts->timer);
2126+ tsc2007_free_irq(ts);
2127+ if (pdata->exit_platform_hw)
2128+ pdata->exit_platform_hw();
2129 err_free_mem:
2130 input_free_device(input_dev);
2131 kfree(ts);
2132 return err;
2133 }
2134
2135-static int tsc2007_remove(struct i2c_client *client)
2136+static int __devexit tsc2007_remove(struct i2c_client *client)
2137 {
2138 struct tsc2007 *ts = i2c_get_clientdata(client);
2139- struct tsc2007_platform_data *pdata;
2140+ struct tsc2007_platform_data *pdata = client->dev.platform_data;
2141
2142- pdata = client->dev.platform_data;
2143- pdata->exit_platform_hw();
2144+ tsc2007_free_irq(ts);
2145+
2146+ if (pdata->exit_platform_hw)
2147+ pdata->exit_platform_hw();
2148
2149- free_irq(ts->irq, ts);
2150- hrtimer_cancel(&ts->timer);
2151 input_unregister_device(ts->input);
2152 kfree(ts);
2153
2154@@ -362,7 +383,7 @@
2155 },
2156 .id_table = tsc2007_idtable,
2157 .probe = tsc2007_probe,
2158- .remove = tsc2007_remove,
2159+ .remove = __devexit_p(tsc2007_remove),
2160 };
2161
2162 static int __init tsc2007_init(void)
2163diff -uNr linux-2.6.31/drivers/media/radio/Kconfig linux-2.6.31.new/drivers/media/radio/Kconfig
2164--- linux-2.6.31/drivers/media/radio/Kconfig 2009-10-23 11:18:30.000000000 -0700
2165+++ linux-2.6.31.new/drivers/media/radio/Kconfig 2009-10-23 11:17:28.000000000 -0700
2166@@ -406,4 +406,38 @@
2167 Say Y here if TEA5764 have a 32768 Hz crystal in circuit, say N
2168 here if TEA5764 reference frequency is connected in FREQIN.
2169
2170+config RADIO_SAA7706H
2171+ tristate "SAA7706H Car Radio DSP"
2172+ depends on I2C && VIDEO_V4L2
2173+ ---help---
2174+ Say Y here if you want to use the SAA7706H Car radio Digital
2175+ Signal Processor, found for instance on the Russellville development
2176+ board. On the russellville the device is connected to internal
2177+ timberdale I2C bus.
2178+
2179+ To compile this driver as a module, choose M here: the
2180+ module will be called SAA7706H.
2181+
2182+config RADIO_TEF6862
2183+ tristate "TEF6862 Car Radio Enhanced Selectivity Tuner"
2184+ depends on I2C && VIDEO_V4L2
2185+ ---help---
2186+ Say Y here if you want to use the TEF6862 Car Radio Enhanced
2187+ Selectivity Tuner, found for instance on the Russellville development
2188+ board. On the russellville the device is connected to internal
2189+ timberdale I2C bus.
2190+
2191+ To compile this driver as a module, choose M here: the
2192+ module will be called TEF6862.
2193+
2194+config RADIO_TIMBERDALE
2195+ tristate "Enable the Timberdale radio driver"
2196+ depends on MFD_TIMBERDALE && VIDEO_V4L2 && HAS_IOMEM
2197+ select RADIO_TEF6862
2198+ select RADIO_SAA7706H
2199+ ---help---
2200+ This is a kind of umbrella driver for the Radio Tuner and DSP
2201+ found behind the Timberdale FPGA on the Russellville board.
2202+ Enable this driver will automatically select the DSP and tuner.
2203+
2204 endif # RADIO_ADAPTERS
2205diff -uNr linux-2.6.31/drivers/media/radio/Makefile linux-2.6.31.new/drivers/media/radio/Makefile
2206--- linux-2.6.31/drivers/media/radio/Makefile 2009-10-23 11:18:30.000000000 -0700
2207+++ linux-2.6.31.new/drivers/media/radio/Makefile 2009-10-23 11:17:28.000000000 -0700
2208@@ -20,5 +20,8 @@
2209 obj-$(CONFIG_USB_SI470X) += radio-si470x.o
2210 obj-$(CONFIG_USB_MR800) += radio-mr800.o
2211 obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o
2212+obj-$(CONFIG_RADIO_SAA7706H) += saa7706h.o
2213+obj-$(CONFIG_RADIO_TEF6862) += tef6862.o
2214+obj-$(CONFIG_RADIO_TIMBERDALE) += radio-timb.o
2215
2216 EXTRA_CFLAGS += -Isound
2217diff -uNr linux-2.6.31/drivers/media/radio/radio-timb.c linux-2.6.31.new/drivers/media/radio/radio-timb.c
2218--- linux-2.6.31/drivers/media/radio/radio-timb.c 1969-12-31 16:00:00.000000000 -0800
2219+++ linux-2.6.31.new/drivers/media/radio/radio-timb.c 2009-10-23 11:17:28.000000000 -0700
2220@@ -0,0 +1,545 @@
2221+/*
2222+ * radio-timb.c Timberdale FPGA Radio driver
2223+ * Copyright (c) 2009 Intel Corporation
2224+ *
2225+ * This program is free software; you can redistribute it and/or modify
2226+ * it under the terms of the GNU General Public License version 2 as
2227+ * published by the Free Software Foundation.
2228+ *
2229+ * This program is distributed in the hope that it will be useful,
2230+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2231+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2232+ * GNU General Public License for more details.
2233+ *
2234+ * You should have received a copy of the GNU General Public License
2235+ * along with this program; if not, write to the Free Software
2236+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2237+ */
2238+
2239+#include <linux/list.h>
2240+#include <linux/version.h>
2241+#include <linux/module.h>
2242+#include <linux/io.h>
2243+#include <media/v4l2-common.h>
2244+#include <media/v4l2-ioctl.h>
2245+#include <media/v4l2-device.h>
2246+#include <linux/platform_device.h>
2247+#include <linux/interrupt.h>
2248+#include <linux/i2c.h>
2249+#include <media/timb_radio.h>
2250+
2251+#define DRIVER_NAME "timb-radio"
2252+
2253+#define RDS_BLOCK_SIZE 4
2254+#define RDS_BUFFER_SIZE (RDS_BLOCK_SIZE * 100)
2255+
2256+struct timbradio {
2257+ struct mutex lock; /* for mutual exclusion */
2258+ void __iomem *membase;
2259+ struct timb_radio_platform_data pdata;
2260+ struct v4l2_subdev *sd_tuner;
2261+ struct module *tuner_owner;
2262+ struct v4l2_subdev *sd_dsp;
2263+ struct module *dsp_owner;
2264+ struct video_device *video_dev;
2265+ /* RDS related */
2266+ int open_count;
2267+ int rds_irq;
2268+ wait_queue_head_t read_queue;
2269+ unsigned char buffer[RDS_BUFFER_SIZE];
2270+ unsigned int rd_index;
2271+ unsigned int wr_index;
2272+};
2273+
2274+
2275+static int timbradio_vidioc_querycap(struct file *file, void *priv,
2276+ struct v4l2_capability *v)
2277+{
2278+ strlcpy(v->driver, DRIVER_NAME, sizeof(v->driver));
2279+ strlcpy(v->card, "Timberdale Radio", sizeof(v->card));
2280+ snprintf(v->bus_info, sizeof(v->bus_info), "platform:"DRIVER_NAME);
2281+ v->version = KERNEL_VERSION(0, 0, 1);
2282+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
2283+ return 0;
2284+}
2285+
2286+static int timbradio_vidioc_g_tuner(struct file *file, void *priv,
2287+ struct v4l2_tuner *v)
2288+{
2289+ struct timbradio *tr = video_drvdata(file);
2290+ int ret;
2291+
2292+ mutex_lock(&tr->lock);
2293+ ret = v4l2_subdev_call(tr->sd_tuner, tuner, g_tuner, v);
2294+ mutex_unlock(&tr->lock);
2295+
2296+ return ret;
2297+}
2298+
2299+static int timbradio_vidioc_s_tuner(struct file *file, void *priv,
2300+ struct v4l2_tuner *v)
2301+{
2302+ struct timbradio *tr = video_drvdata(file);
2303+ int ret;
2304+
2305+ mutex_lock(&tr->lock);
2306+ ret = v4l2_subdev_call(tr->sd_tuner, tuner, s_tuner, v);
2307+ mutex_unlock(&tr->lock);
2308+
2309+ return ret;
2310+}
2311+
2312+static int timbradio_vidioc_g_input(struct file *filp, void *priv,
2313+ unsigned int *i)
2314+{
2315+ *i = 0;
2316+ return 0;
2317+}
2318+
2319+static int timbradio_vidioc_s_input(struct file *filp, void *priv,
2320+ unsigned int i)
2321+{
2322+ return i ? -EINVAL : 0;
2323+}
2324+
2325+static int timbradio_vidioc_g_audio(struct file *file, void *priv,
2326+ struct v4l2_audio *a)
2327+{
2328+ a->index = 0;
2329+ strlcpy(a->name, "Radio", sizeof(a->name));
2330+ a->capability = V4L2_AUDCAP_STEREO;
2331+ return 0;
2332+}
2333+
2334+
2335+static int timbradio_vidioc_s_audio(struct file *file, void *priv,
2336+ struct v4l2_audio *a)
2337+{
2338+ return a->index ? -EINVAL : 0;
2339+}
2340+
2341+static int timbradio_vidioc_s_frequency(struct file *file, void *priv,
2342+ struct v4l2_frequency *f)
2343+{
2344+ struct timbradio *tr = video_drvdata(file);
2345+ int ret;
2346+
2347+ mutex_lock(&tr->lock);
2348+ ret = v4l2_subdev_call(tr->sd_tuner, tuner, s_frequency, f);
2349+ mutex_unlock(&tr->lock);
2350+
2351+ return ret;
2352+}
2353+
2354+static int timbradio_vidioc_g_frequency(struct file *file, void *priv,
2355+ struct v4l2_frequency *f)
2356+{
2357+ struct timbradio *tr = video_drvdata(file);
2358+ int ret;
2359+
2360+ mutex_lock(&tr->lock);
2361+ ret = v4l2_subdev_call(tr->sd_tuner, tuner, g_frequency, f);
2362+ mutex_unlock(&tr->lock);
2363+
2364+ return ret;
2365+}
2366+
2367+static int timbradio_vidioc_queryctrl(struct file *file, void *priv,
2368+ struct v4l2_queryctrl *qc)
2369+{
2370+ struct timbradio *tr = video_drvdata(file);
2371+ int ret;
2372+
2373+ mutex_lock(&tr->lock);
2374+ ret = v4l2_subdev_call(tr->sd_dsp, core, queryctrl, qc);
2375+ mutex_unlock(&tr->lock);
2376+
2377+ return ret;
2378+}
2379+
2380+static int timbradio_vidioc_g_ctrl(struct file *file, void *priv,
2381+ struct v4l2_control *ctrl)
2382+{
2383+ struct timbradio *tr = video_drvdata(file);
2384+ int ret;
2385+
2386+ mutex_lock(&tr->lock);
2387+ ret = v4l2_subdev_call(tr->sd_dsp, core, g_ctrl, ctrl);
2388+ mutex_unlock(&tr->lock);
2389+
2390+ return ret;
2391+}
2392+
2393+static int timbradio_vidioc_s_ctrl(struct file *file, void *priv,
2394+ struct v4l2_control *ctrl)
2395+{
2396+ struct timbradio *tr = video_drvdata(file);
2397+ int ret;
2398+
2399+ mutex_lock(&tr->lock);
2400+ ret = v4l2_subdev_call(tr->sd_dsp, core, s_ctrl, ctrl);
2401+ mutex_unlock(&tr->lock);
2402+
2403+ return ret;
2404+}
2405+
2406+static const struct v4l2_ioctl_ops timbradio_ioctl_ops = {
2407+ .vidioc_querycap = timbradio_vidioc_querycap,
2408+ .vidioc_g_tuner = timbradio_vidioc_g_tuner,
2409+ .vidioc_s_tuner = timbradio_vidioc_s_tuner,
2410+ .vidioc_g_frequency = timbradio_vidioc_g_frequency,
2411+ .vidioc_s_frequency = timbradio_vidioc_s_frequency,
2412+ .vidioc_g_input = timbradio_vidioc_g_input,
2413+ .vidioc_s_input = timbradio_vidioc_s_input,
2414+ .vidioc_g_audio = timbradio_vidioc_g_audio,
2415+ .vidioc_s_audio = timbradio_vidioc_s_audio,
2416+ .vidioc_queryctrl = timbradio_vidioc_queryctrl,
2417+ .vidioc_g_ctrl = timbradio_vidioc_g_ctrl,
2418+ .vidioc_s_ctrl = timbradio_vidioc_s_ctrl
2419+};
2420+
2421+static irqreturn_t timbradio_irq(int irq, void *devid)
2422+{
2423+ struct timbradio *tr = devid;
2424+ u32 data = ioread32(tr->membase);
2425+
2426+ tr->buffer[tr->wr_index++] = data >> 24;
2427+ tr->buffer[tr->wr_index++] = data >> 16;
2428+ tr->buffer[tr->wr_index++] = data >> 8;
2429+ tr->buffer[tr->wr_index++] = data;
2430+ tr->wr_index %= RDS_BUFFER_SIZE;
2431+
2432+ wake_up(&tr->read_queue);
2433+
2434+ /* new RDS data received, read it */
2435+ return IRQ_HANDLED;
2436+}
2437+
2438+/**************************************************************************
2439+ * File Operations Interface
2440+ **************************************************************************/
2441+
2442+static ssize_t timbradio_rds_fops_read(struct file *file, char __user *buf,
2443+ size_t count, loff_t *ppos)
2444+{
2445+ struct timbradio *tr = video_drvdata(file);
2446+ int outblocks = 0;
2447+
2448+ /* block if no new data available */
2449+ while (tr->wr_index == tr->rd_index) {
2450+ if (file->f_flags & O_NONBLOCK)
2451+ return -EWOULDBLOCK;
2452+
2453+ if (wait_event_interruptible(tr->read_queue,
2454+ tr->wr_index != tr->rd_index))
2455+ return -EINTR;
2456+ }
2457+
2458+ count /= RDS_BLOCK_SIZE;
2459+ /* copy RDS block out of internal buffer and to user buffer */
2460+ mutex_lock(&tr->lock);
2461+ while (outblocks < count) {
2462+ if (tr->rd_index == tr->wr_index)
2463+ break;
2464+
2465+ if (copy_to_user(buf, tr->buffer + tr->rd_index,
2466+ RDS_BLOCK_SIZE))
2467+ break;
2468+ tr->rd_index += RDS_BLOCK_SIZE;
2469+ tr->rd_index %= RDS_BUFFER_SIZE;
2470+ outblocks++;
2471+ }
2472+ mutex_unlock(&tr->lock);
2473+
2474+ return outblocks *RDS_BLOCK_SIZE;
2475+}
2476+
2477+static unsigned int timbradio_rds_fops_poll(struct file *file,
2478+ struct poll_table_struct *pts)
2479+{
2480+ struct timbradio *tr = video_drvdata(file);
2481+
2482+ poll_wait(file, &tr->read_queue, pts);
2483+
2484+ if (tr->rd_index != tr->wr_index)
2485+ return POLLIN | POLLRDNORM;
2486+
2487+ return 0;
2488+}
2489+
2490+struct find_addr_arg {
2491+ char const *name;
2492+ struct i2c_client *client;
2493+};
2494+
2495+static int find_name(struct device *dev, void *argp)
2496+{
2497+ struct find_addr_arg *arg = (struct find_addr_arg *)argp;
2498+ struct i2c_client *client = i2c_verify_client(dev);
2499+
2500+ if (client && !strcmp(arg->name, client->name) && client->driver)
2501+ arg->client = client;
2502+
2503+ return 0;
2504+}
2505+
2506+static struct i2c_client *find_client(struct i2c_adapter *adapt,
2507+ const char *name)
2508+{
2509+ struct find_addr_arg find_arg;
2510+ /* now find the client */
2511+#ifdef MODULE
2512+ request_module(name);
2513+#endif
2514+ /* code for finding the I2C child */
2515+ find_arg.name = name;
2516+ find_arg.client = NULL;
2517+ device_for_each_child(&adapt->dev, &find_arg, find_name);
2518+ return find_arg.client;
2519+}
2520+
2521+static int timbradio_rds_fops_open(struct file *file)
2522+{
2523+ struct timbradio *tr = video_drvdata(file);
2524+ int err = 0;
2525+
2526+ mutex_lock(&tr->lock);
2527+ if (tr->open_count == 0) {
2528+ /* device currently not open, check if the DSP and tuner is not
2529+ * yet found, in that case find them
2530+ */
2531+ if (!tr->sd_tuner) {
2532+ struct i2c_adapter *adapt;
2533+ struct i2c_client *tuner;
2534+ struct i2c_client *dsp;
2535+
2536+ /* find the I2C bus */
2537+ adapt = i2c_get_adapter(tr->pdata.i2c_adapter);
2538+ if (!adapt) {
2539+ printk(KERN_ERR DRIVER_NAME": No I2C bus\n");
2540+ err = -ENODEV;
2541+ goto out;
2542+ }
2543+
2544+ /* now find the tuner and dsp */
2545+ tuner = find_client(adapt, tr->pdata.tuner);
2546+ dsp = find_client(adapt, tr->pdata.dsp);
2547+
2548+ i2c_put_adapter(adapt);
2549+
2550+ if (!tuner || !dsp) {
2551+ printk(KERN_ERR DRIVER_NAME
2552+ ": Failed to get tuner or DSP\n");
2553+ err = -ENODEV;
2554+ goto out;
2555+ }
2556+
2557+ tr->sd_tuner = i2c_get_clientdata(tuner);
2558+ tr->sd_dsp = i2c_get_clientdata(dsp);
2559+
2560+ tr->tuner_owner = tr->sd_tuner->owner;
2561+ tr->dsp_owner = tr->sd_dsp->owner;
2562+ /* Lock the modules */
2563+ if (!try_module_get(tr->tuner_owner)) {
2564+ err = -ENODEV;
2565+ goto err_get_tuner;
2566+ }
2567+
2568+ if (!try_module_get(tr->dsp_owner)) {
2569+ err = -ENODEV;
2570+ goto err_get_dsp;
2571+ }
2572+ }
2573+
2574+ /* enable the IRQ for receiving RDS data */
2575+ err = request_irq(tr->rds_irq, timbradio_irq, 0, DRIVER_NAME,
2576+ tr);
2577+ }
2578+ goto out;
2579+
2580+err_get_dsp:
2581+ module_put(tr->tuner_owner);
2582+err_get_tuner:
2583+ tr->sd_tuner = NULL;
2584+ tr->sd_dsp = NULL;
2585+out:
2586+ if (!err)
2587+ tr->open_count++;
2588+ mutex_unlock(&tr->lock);
2589+ return err;
2590+}
2591+
2592+static int timbradio_rds_fops_release(struct file *file)
2593+{
2594+ struct timbradio *tr = video_drvdata(file);
2595+
2596+ mutex_lock(&tr->lock);
2597+ tr->open_count--;
2598+ if (!tr->open_count) {
2599+ free_irq(tr->rds_irq, tr);
2600+
2601+ tr->wr_index = 0;
2602+ tr->rd_index = 0;
2603+
2604+ /* cancel read processes */
2605+ wake_up_interruptible(&tr->read_queue);
2606+ }
2607+ mutex_unlock(&tr->lock);
2608+
2609+ return 0;
2610+}
2611+
2612+
2613+static const struct v4l2_file_operations timbradio_fops = {
2614+ .owner = THIS_MODULE,
2615+ .ioctl = video_ioctl2,
2616+ .read = timbradio_rds_fops_read,
2617+ .poll = timbradio_rds_fops_poll,
2618+ .open = timbradio_rds_fops_open,
2619+ .release = timbradio_rds_fops_release,
2620+};
2621+
2622+static const struct video_device timbradio_template = {
2623+ .name = "Timberdale Radio",
2624+ .fops = &timbradio_fops,
2625+ .ioctl_ops = &timbradio_ioctl_ops,
2626+ .release = video_device_release_empty,
2627+ .minor = -1
2628+};
2629+
2630+
2631+
2632+static int timbradio_probe(struct platform_device *pdev)
2633+{
2634+ struct timb_radio_platform_data *pdata = pdev->dev.platform_data;
2635+ struct timbradio *tr;
2636+ struct resource *iomem;
2637+ int irq;
2638+ int err;
2639+
2640+ if (!pdata) {
2641+ printk(KERN_ERR DRIVER_NAME": Platform data missing\n");
2642+ err = -EINVAL;
2643+ goto err;
2644+ }
2645+
2646+ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2647+ if (!iomem) {
2648+ err = -ENODEV;
2649+ goto err;
2650+ }
2651+
2652+ irq = platform_get_irq(pdev, 0);
2653+ if (irq < 0) {
2654+ err = -ENODEV;
2655+ goto err;
2656+ }
2657+
2658+ if (!request_mem_region(iomem->start, resource_size(iomem),
2659+ DRIVER_NAME)) {
2660+ err = -EBUSY;
2661+ goto err;
2662+ }
2663+
2664+ tr = kzalloc(sizeof(*tr), GFP_KERNEL);
2665+ if (!tr) {
2666+ err = -ENOMEM;
2667+ goto err_alloc;
2668+ }
2669+ mutex_init(&tr->lock);
2670+
2671+ tr->membase = ioremap(iomem->start, resource_size(iomem));
2672+ if (!tr->membase) {
2673+ err = -ENOMEM;
2674+ goto err_ioremap;
2675+ }
2676+
2677+ memcpy(&tr->pdata, pdata, sizeof(tr->pdata));
2678+
2679+ tr->video_dev = video_device_alloc();
2680+ if (!tr->video_dev) {
2681+ err = -ENOMEM;
2682+ goto err_video_req;
2683+ }
2684+ *tr->video_dev = timbradio_template;
2685+ tr->rds_irq = irq;
2686+ init_waitqueue_head(&tr->read_queue);
2687+
2688+ err = video_register_device(tr->video_dev, VFL_TYPE_RADIO, -1);
2689+ if (err) {
2690+ printk(KERN_ALERT DRIVER_NAME": Error reg video\n");
2691+ goto err_video_req;
2692+ }
2693+
2694+ video_set_drvdata(tr->video_dev, tr);
2695+
2696+ platform_set_drvdata(pdev, tr);
2697+ return 0;
2698+
2699+err_video_req:
2700+ if (tr->video_dev->minor != -1)
2701+ video_unregister_device(tr->video_dev);
2702+ else
2703+ video_device_release(tr->video_dev);
2704+ iounmap(tr->membase);
2705+err_ioremap:
2706+ kfree(tr);
2707+err_alloc:
2708+ release_mem_region(iomem->start, resource_size(iomem));
2709+err:
2710+ printk(KERN_ERR DRIVER_NAME ": Failed to register: %d\n", err);
2711+
2712+ return err;
2713+}
2714+
2715+static int timbradio_remove(struct platform_device *pdev)
2716+{
2717+ struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2718+ struct timbradio *tr = platform_get_drvdata(pdev);
2719+
2720+ if (tr->video_dev->minor != -1)
2721+ video_unregister_device(tr->video_dev);
2722+ else
2723+ video_device_release(tr->video_dev);
2724+
2725+ if (tr->sd_tuner) {
2726+ module_put(tr->tuner_owner);
2727+ module_put(tr->dsp_owner);
2728+ }
2729+
2730+ iounmap(tr->membase);
2731+ release_mem_region(iomem->start, resource_size(iomem));
2732+ kfree(tr);
2733+
2734+ return 0;
2735+}
2736+
2737+static struct platform_driver timbradio_platform_driver = {
2738+ .driver = {
2739+ .name = DRIVER_NAME,
2740+ .owner = THIS_MODULE,
2741+ },
2742+ .probe = timbradio_probe,
2743+ .remove = timbradio_remove,
2744+};
2745+
2746+/*--------------------------------------------------------------------------*/
2747+
2748+static int __init timbradio_init(void)
2749+{
2750+ return platform_driver_register(&timbradio_platform_driver);
2751+}
2752+
2753+static void __exit timbradio_exit(void)
2754+{
2755+ platform_driver_unregister(&timbradio_platform_driver);
2756+}
2757+
2758+module_init(timbradio_init);
2759+module_exit(timbradio_exit);
2760+
2761+MODULE_DESCRIPTION("Timberdale Radio driver");
2762+MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
2763+MODULE_LICENSE("GPL v2");
2764+MODULE_ALIAS("platform:"DRIVER_NAME);
2765+
2766diff -uNr linux-2.6.31/drivers/media/radio/saa7706h.c linux-2.6.31.new/drivers/media/radio/saa7706h.c
2767--- linux-2.6.31/drivers/media/radio/saa7706h.c 1969-12-31 16:00:00.000000000 -0800
2768+++ linux-2.6.31.new/drivers/media/radio/saa7706h.c 2009-10-23 11:17:28.000000000 -0700
2769@@ -0,0 +1,496 @@
2770+/*
2771+ * saa7706.c Philips SAA7706H Car Radio DSP driver
2772+ * Copyright (c) 2009 Intel Corporation
2773+ *
2774+ * This program is free software; you can redistribute it and/or modify
2775+ * it under the terms of the GNU General Public License version 2 as
2776+ * published by the Free Software Foundation.
2777+ *
2778+ * This program is distributed in the hope that it will be useful,
2779+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2780+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2781+ * GNU General Public License for more details.
2782+ *
2783+ * You should have received a copy of the GNU General Public License
2784+ * along with this program; if not, write to the Free Software
2785+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2786+ */
2787+
2788+#include <linux/module.h>
2789+#include <linux/init.h>
2790+#include <linux/errno.h>
2791+#include <linux/kernel.h>
2792+#include <linux/interrupt.h>
2793+#include <linux/i2c.h>
2794+#include <linux/i2c-id.h>
2795+#include <media/v4l2-ioctl.h>
2796+#include <media/v4l2-device.h>
2797+#include <media/v4l2-chip-ident.h>
2798+
2799+#define DRIVER_NAME "saa7706h"
2800+
2801+/* the I2C memory map looks like this
2802+
2803+ $1C00 - $FFFF Not Used
2804+ $2200 - $3FFF Reserved YRAM (DSP2) space
2805+ $2000 - $21FF YRAM (DSP2)
2806+ $1FF0 - $1FFF Hardware Registers
2807+ $1280 - $1FEF Reserved XRAM (DSP2) space
2808+ $1000 - $127F XRAM (DSP2)
2809+ $0FFF DSP CONTROL
2810+ $0A00 - $0FFE Reserved
2811+ $0980 - $09FF Reserved YRAM (DSP1) space
2812+ $0800 - $097F YRAM (DSP1)
2813+ $0200 - $07FF Not Used
2814+ $0180 - $01FF Reserved XRAM (DSP1) space
2815+ $0000 - $017F XRAM (DSP1)
2816+*/
2817+
2818+#define SAA7706H_REG_CTRL 0x0fff
2819+#define SAA7706H_CTRL_BYP_PLL 0x0001
2820+#define SAA7706H_CTRL_PLL_DIV_MASK 0x003e
2821+#define SAA7706H_CTRL_PLL3_62975MHZ 0x003e
2822+#define SAA7706H_CTRL_DSP_TURBO 0x0040
2823+#define SAA7706H_CTRL_PC_RESET_DSP1 0x0080
2824+#define SAA7706H_CTRL_PC_RESET_DSP2 0x0100
2825+#define SAA7706H_CTRL_DSP1_ROM_EN_MASK 0x0600
2826+#define SAA7706H_CTRL_DSP1_FUNC_PROM 0x0000
2827+#define SAA7706H_CTRL_DSP2_ROM_EN_MASK 0x1800
2828+#define SAA7706H_CTRL_DSP2_FUNC_PROM 0x0000
2829+#define SAA7706H_CTRL_DIG_SIL_INTERPOL 0x8000
2830+
2831+#define SAA7706H_REG_EVALUATION 0x1ff0
2832+#define SAA7706H_EVAL_DISABLE_CHARGE_PUMP 0x000001
2833+#define SAA7706H_EVAL_DCS_CLOCK 0x000002
2834+#define SAA7706H_EVAL_GNDRC1_ENABLE 0x000004
2835+#define SAA7706H_EVAL_GNDRC2_ENABLE 0x000008
2836+
2837+#define SAA7706H_REG_CL_GEN1 0x1ff3
2838+#define SAA7706H_CL_GEN1_MIN_LOOPGAIN_MASK 0x00000f
2839+#define SAA7706H_CL_GEN1_LOOPGAIN_MASK 0x0000f0
2840+#define SAA7706H_CL_GEN1_COARSE_RATION 0xffff00
2841+
2842+#define SAA7706H_REG_CL_GEN2 0x1ff4
2843+#define SAA7706H_CL_GEN2_WSEDGE_FALLING 0x000001
2844+#define SAA7706H_CL_GEN2_STOP_VCO 0x000002
2845+#define SAA7706H_CL_GEN2_FRERUN 0x000004
2846+#define SAA7706H_CL_GEN2_ADAPTIVE 0x000008
2847+#define SAA7706H_CL_GEN2_FINE_RATIO_MASK 0x0ffff0
2848+
2849+#define SAA7706H_REG_CL_GEN4 0x1ff6
2850+#define SAA7706H_CL_GEN4_BYPASS_PLL1 0x001000
2851+#define SAA7706H_CL_GEN4_PLL1_DIV_MASK 0x03e000
2852+#define SAA7706H_CL_GEN4_DSP1_TURBO 0x040000
2853+
2854+#define SAA7706H_REG_SEL 0x1ff7
2855+#define SAA7706H_SEL_DSP2_SRCA_MASK 0x000007
2856+#define SAA7706H_SEL_DSP2_FMTA_MASK 0x000031
2857+#define SAA7706H_SEL_DSP2_SRCB_MASK 0x0001c0
2858+#define SAA7706H_SEL_DSP2_FMTB_MASK 0x000e00
2859+#define SAA7706H_SEL_DSP1_SRC_MASK 0x003000
2860+#define SAA7706H_SEL_DSP1_FMT_MASK 0x01c003
2861+#define SAA7706H_SEL_SPDIF2 0x020000
2862+#define SAA7706H_SEL_HOST_IO_FMT_MASK 0x1c0000
2863+#define SAA7706H_SEL_EN_HOST_IO 0x200000
2864+
2865+#define SAA7706H_REG_IAC 0x1ff8
2866+#define SAA7706H_REG_CLK_SET 0x1ff9
2867+#define SAA7706H_REG_CLK_COEFF 0x1ffa
2868+#define SAA7706H_REG_INPUT_SENS 0x1ffb
2869+#define SAA7706H_INPUT_SENS_RDS_VOL_MASK 0x0003f
2870+#define SAA7706H_INPUT_SENS_FM_VOL_MASK 0x00fc0
2871+#define SAA7706H_INPUT_SENS_FM_MPX 0x01000
2872+#define SAA7706H_INPUT_SENS_OFF_FILTER_A_EN 0x02000
2873+#define SAA7706H_INPUT_SENS_OFF_FILTER_B_EN 0x04000
2874+#define SAA7706H_REG_PHONE_NAV_AUDIO 0x1ffc
2875+#define SAA7706H_REG_IO_CONF_DSP2 0x1ffd
2876+#define SAA7706H_REG_STATUS_DSP2 0x1ffe
2877+#define SAA7706H_REG_PC_DSP2 0x1fff
2878+
2879+#define SAA7706H_DSP1_MOD0 0x0800
2880+#define SAA7706H_DSP1_ROM_VER 0x097f
2881+#define SAA7706H_DSP2_MPTR0 0x1000
2882+
2883+#define SAA7706H_DSP1_MODPNTR 0x0000
2884+
2885+#define SAA7706H_DSP2_XMEM_CONTLLCW 0x113e
2886+#define SAA7706H_DSP2_XMEM_BUSAMP 0x114a
2887+#define SAA7706H_DSP2_XMEM_FDACPNTR 0x11f9
2888+#define SAA7706H_DSP2_XMEM_IIS1PNTR 0x11fb
2889+
2890+#define SAA7706H_DSP2_YMEM_PVGA 0x212a
2891+#define SAA7706H_DSP2_YMEM_PVAT1 0x212b
2892+#define SAA7706H_DSP2_YMEM_PVAT 0x212c
2893+#define SAA7706H_DSP2_YMEM_ROM_VER 0x21ff
2894+
2895+#define SUPPORTED_DSP1_ROM_VER 0x667
2896+
2897+struct saa7706h_state {
2898+ struct v4l2_subdev sd;
2899+ unsigned muted;
2900+};
2901+
2902+static inline struct saa7706h_state *to_state(struct v4l2_subdev *sd)
2903+{
2904+ return container_of(sd, struct saa7706h_state, sd);
2905+}
2906+
2907+static int saa7706h_i2c_send(struct i2c_client *client, const u8 *data, int len)
2908+{
2909+ int err = i2c_master_send(client, data, len);
2910+ if (err == len)
2911+ return 0;
2912+ else if (err > 0)
2913+ return -EIO;
2914+ return err;
2915+}
2916+
2917+static int saa7706h_i2c_transfer(struct i2c_client *client,
2918+ struct i2c_msg *msgs, int num)
2919+{
2920+ int err = i2c_transfer(client->adapter, msgs, num);
2921+ if (err == num)
2922+ return 0;
2923+ else if (err > 0)
2924+ return -EIO;
2925+ else
2926+ return err;
2927+}
2928+
2929+static int saa7706h_set_reg24(struct i2c_client *client, u16 reg, u32 val)
2930+{
2931+ u8 buf[5];
2932+ int pos = 0;
2933+
2934+ buf[pos++] = reg >> 8;
2935+ buf[pos++] = reg;
2936+ buf[pos++] = val >> 16;
2937+ buf[pos++] = val >> 8;
2938+ buf[pos++] = val;
2939+
2940+ return saa7706h_i2c_send(client, buf, pos);
2941+}
2942+
2943+static int saa7706h_set_reg16(struct i2c_client *client, u16 reg, u16 val)
2944+{
2945+ u8 buf[4];
2946+ int pos = 0;
2947+
2948+ buf[pos++] = reg >> 8;
2949+ buf[pos++] = reg;
2950+ buf[pos++] = val >> 8;
2951+ buf[pos++] = val;
2952+
2953+ return saa7706h_i2c_send(client, buf, pos);
2954+}
2955+
2956+static int saa7706h_get_reg16(struct i2c_client *client, u16 reg)
2957+{
2958+ u8 buf[2];
2959+ int err;
2960+ u8 regaddr[] = {reg >> 8, reg};
2961+ struct i2c_msg msg[] = { {client->addr, 0, sizeof(regaddr), regaddr},
2962+ {client->addr, I2C_M_RD, sizeof(buf), buf} };
2963+
2964+ err = saa7706h_i2c_transfer(client, msg, ARRAY_SIZE(msg));
2965+ if (err)
2966+ return err;
2967+
2968+ return buf[0] << 8 | buf[1];
2969+}
2970+
2971+static int saa7706h_unmute(struct v4l2_subdev *sd)
2972+{
2973+ struct i2c_client *client = v4l2_get_subdevdata(sd);
2974+ struct saa7706h_state *state = to_state(sd);
2975+ int err;
2976+
2977+ err = saa7706h_set_reg16(client, SAA7706H_REG_CTRL,
2978+ SAA7706H_CTRL_PLL3_62975MHZ | SAA7706H_CTRL_PC_RESET_DSP1 |
2979+ SAA7706H_CTRL_PC_RESET_DSP2);
2980+ if (err)
2981+ goto out;
2982+
2983+ /* newer versions of the chip requires a small sleep after reset */
2984+ msleep(1);
2985+
2986+ err = saa7706h_set_reg16(client, SAA7706H_REG_CTRL,
2987+ SAA7706H_CTRL_PLL3_62975MHZ);
2988+ if (err)
2989+ goto out;
2990+
2991+ err = saa7706h_set_reg24(client, SAA7706H_REG_EVALUATION, 0);
2992+ if (err)
2993+ goto out;
2994+
2995+ err = saa7706h_set_reg24(client, SAA7706H_REG_CL_GEN1, 0x040022);
2996+ if (err)
2997+ goto out;
2998+
2999+ err = saa7706h_set_reg24(client, SAA7706H_REG_CL_GEN2,
3000+ SAA7706H_CL_GEN2_WSEDGE_FALLING);
3001+ if (err)
3002+ goto out;
3003+
3004+ err = saa7706h_set_reg24(client, SAA7706H_REG_CL_GEN4, 0x024080);
3005+ if (err)
3006+ goto out;
3007+
3008+ err = saa7706h_set_reg24(client, SAA7706H_REG_SEL, 0x200080);
3009+ if (err)
3010+ goto out;
3011+
3012+ err = saa7706h_set_reg24(client, SAA7706H_REG_IAC, 0xf4caed);
3013+ if (err)
3014+ goto out;
3015+
3016+ err = saa7706h_set_reg24(client, SAA7706H_REG_CLK_SET, 0x124334);
3017+ if (err)
3018+ goto out;
3019+
3020+ err = saa7706h_set_reg24(client, SAA7706H_REG_CLK_COEFF, 0x004a1a);
3021+ if (err)
3022+ goto out;
3023+
3024+ err = saa7706h_set_reg24(client, SAA7706H_REG_INPUT_SENS, 0x0071c7);
3025+ if (err)
3026+ goto out;
3027+
3028+ err = saa7706h_set_reg24(client, SAA7706H_REG_PHONE_NAV_AUDIO,
3029+ 0x0e22ff);
3030+ if (err)
3031+ goto out;
3032+
3033+ err = saa7706h_set_reg24(client, SAA7706H_REG_IO_CONF_DSP2, 0x001ff8);
3034+ if (err)
3035+ goto out;
3036+
3037+ err = saa7706h_set_reg24(client, SAA7706H_REG_STATUS_DSP2, 0x080003);
3038+ if (err)
3039+ goto out;
3040+
3041+ err = saa7706h_set_reg24(client, SAA7706H_REG_PC_DSP2, 0x000004);
3042+ if (err)
3043+ goto out;
3044+
3045+ err = saa7706h_set_reg16(client, SAA7706H_DSP1_MOD0, 0x0c6c);
3046+ if (err)
3047+ goto out;
3048+
3049+ err = saa7706h_set_reg24(client, SAA7706H_DSP2_MPTR0, 0x000b4b);
3050+ if (err)
3051+ goto out;
3052+
3053+ err = saa7706h_set_reg24(client, SAA7706H_DSP1_MODPNTR, 0x000600);
3054+ if (err)
3055+ goto out;
3056+
3057+ err = saa7706h_set_reg24(client, SAA7706H_DSP1_MODPNTR, 0x0000c0);
3058+ if (err)
3059+ goto out;
3060+
3061+ err = saa7706h_set_reg24(client, SAA7706H_DSP2_XMEM_CONTLLCW, 0x000819);
3062+ if (err)
3063+ goto out;
3064+
3065+ err = saa7706h_set_reg24(client, SAA7706H_DSP2_XMEM_CONTLLCW, 0x00085a);
3066+ if (err)
3067+ goto out;
3068+
3069+ err = saa7706h_set_reg24(client, SAA7706H_DSP2_XMEM_BUSAMP, 0x7fffff);
3070+ if (err)
3071+ goto out;
3072+
3073+ err = saa7706h_set_reg24(client, SAA7706H_DSP2_XMEM_FDACPNTR, 0x2000cb);
3074+ if (err)
3075+ goto out;
3076+
3077+ err = saa7706h_set_reg24(client, SAA7706H_DSP2_XMEM_IIS1PNTR, 0x2000cb);
3078+ if (err)
3079+ goto out;
3080+
3081+ err = saa7706h_set_reg16(client, SAA7706H_DSP2_YMEM_PVGA, 0x0f80);
3082+ if (err)
3083+ goto out;
3084+
3085+ err = saa7706h_set_reg16(client, SAA7706H_DSP2_YMEM_PVAT1, 0x0800);
3086+ if (err)
3087+ goto out;
3088+
3089+ err = saa7706h_set_reg16(client, SAA7706H_DSP2_YMEM_PVAT, 0x0800);
3090+ if (err)
3091+ goto out;
3092+
3093+ err = saa7706h_set_reg24(client, SAA7706H_DSP2_XMEM_CONTLLCW, 0x000905);
3094+ if (err)
3095+ goto out;
3096+
3097+ state->muted = 0;
3098+out:
3099+ return err;
3100+}
3101+
3102+static int saa7706h_mute(struct v4l2_subdev *sd)
3103+{
3104+ struct i2c_client *client = v4l2_get_subdevdata(sd);
3105+ struct saa7706h_state *state = to_state(sd);
3106+ int err;
3107+
3108+ err = saa7706h_set_reg16(client, SAA7706H_REG_CTRL,
3109+ SAA7706H_CTRL_PLL3_62975MHZ | SAA7706H_CTRL_PC_RESET_DSP1 |
3110+ SAA7706H_CTRL_PC_RESET_DSP2);
3111+ if (err)
3112+ goto out;
3113+
3114+ state->muted = 1;
3115+out:
3116+ return err;
3117+}
3118+
3119+static int saa7706h_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
3120+{
3121+ switch (qc->id) {
3122+ case V4L2_CID_AUDIO_MUTE:
3123+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
3124+ }
3125+ return -EINVAL;
3126+}
3127+
3128+static int saa7706h_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
3129+{
3130+ struct saa7706h_state *state = to_state(sd);
3131+
3132+ switch (ctrl->id) {
3133+ case V4L2_CID_AUDIO_MUTE:
3134+ ctrl->value = state->muted;
3135+ return 0;
3136+ }
3137+ return -EINVAL;
3138+}
3139+
3140+static int saa7706h_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
3141+{
3142+ switch (ctrl->id) {
3143+ case V4L2_CID_AUDIO_MUTE:
3144+ if (ctrl->value)
3145+ return saa7706h_mute(sd);
3146+ else
3147+ return saa7706h_unmute(sd);
3148+ }
3149+ return -EINVAL;
3150+}
3151+
3152+static int saa7706h_g_chip_ident(struct v4l2_subdev *sd,
3153+ struct v4l2_dbg_chip_ident *chip)
3154+{
3155+ struct i2c_client *client = v4l2_get_subdevdata(sd);
3156+
3157+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7706H, 0);
3158+}
3159+
3160+static const struct v4l2_subdev_core_ops saa7706h_core_ops = {
3161+ .g_chip_ident = saa7706h_g_chip_ident,
3162+ .queryctrl = saa7706h_queryctrl,
3163+ .g_ctrl = saa7706h_g_ctrl,
3164+ .s_ctrl = saa7706h_s_ctrl,
3165+};
3166+
3167+static const struct v4l2_subdev_ops saa7706h_ops = {
3168+ .core = &saa7706h_core_ops,
3169+};
3170+
3171+/*
3172+ * Generic i2c probe
3173+ * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
3174+ */
3175+
3176+static int __devinit saa7706h_probe(struct i2c_client *client,
3177+ const struct i2c_device_id *id)
3178+{
3179+ struct saa7706h_state *state;
3180+ struct v4l2_subdev *sd;
3181+ int err;
3182+
3183+ /* Check if the adapter supports the needed features */
3184+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
3185+ return -EIO;
3186+
3187+ v4l_info(client, "chip found @ 0x%02x (%s)\n",
3188+ client->addr << 1, client->adapter->name);
3189+
3190+ state = kmalloc(sizeof(struct saa7706h_state), GFP_KERNEL);
3191+ if (state == NULL)
3192+ return -ENOMEM;
3193+ sd = &state->sd;
3194+ v4l2_i2c_subdev_init(sd, client, &saa7706h_ops);
3195+
3196+ /* check the rom versions */
3197+ err = saa7706h_get_reg16(client, SAA7706H_DSP1_ROM_VER);
3198+ if (err < 0)
3199+ goto err;
3200+ if (err != SUPPORTED_DSP1_ROM_VER)
3201+ printk(KERN_WARNING DRIVER_NAME
3202+ ": Unknown DSP1 ROM code version: 0x%x\n", err);
3203+
3204+ state->muted = 1;
3205+
3206+ /* startup in a muted state */
3207+ err = saa7706h_mute(sd);
3208+ if (err)
3209+ goto err;
3210+
3211+ return 0;
3212+
3213+err:
3214+ v4l2_device_unregister_subdev(sd);
3215+ kfree(to_state(sd));
3216+
3217+ printk(KERN_ERR DRIVER_NAME ": Failed to probe: %d\n", err);
3218+
3219+ return err;
3220+}
3221+
3222+static int __devexit saa7706h_remove(struct i2c_client *client)
3223+{
3224+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
3225+
3226+ saa7706h_mute(sd);
3227+ v4l2_device_unregister_subdev(sd);
3228+ kfree(to_state(sd));
3229+ return 0;
3230+}
3231+
3232+static const struct i2c_device_id saa7706h_id[] = {
3233+ {DRIVER_NAME, 0},
3234+ {},
3235+};
3236+
3237+MODULE_DEVICE_TABLE(i2c, saa7706h_id);
3238+
3239+static struct i2c_driver saa7706h_driver = {
3240+ .driver = {
3241+ .owner = THIS_MODULE,
3242+ .name = DRIVER_NAME,
3243+ },
3244+ .probe = saa7706h_probe,
3245+ .remove = saa7706h_remove,
3246+ .id_table = saa7706h_id,
3247+};
3248+
3249+static __init int saa7706h_init(void)
3250+{
3251+ return i2c_add_driver(&saa7706h_driver);
3252+}
3253+
3254+static __exit void saa7706h_exit(void)
3255+{
3256+ i2c_del_driver(&saa7706h_driver);
3257+}
3258+
3259+module_init(saa7706h_init);
3260+module_exit(saa7706h_exit);
3261+
3262+MODULE_DESCRIPTION("SAA7706H Car Radio DSP driver");
3263+MODULE_AUTHOR("Mocean Laboratories");
3264+MODULE_LICENSE("GPL v2");
3265+
3266diff -uNr linux-2.6.31/drivers/media/radio/tef6862.c linux-2.6.31.new/drivers/media/radio/tef6862.c
3267--- linux-2.6.31/drivers/media/radio/tef6862.c 1969-12-31 16:00:00.000000000 -0800
3268+++ linux-2.6.31.new/drivers/media/radio/tef6862.c 2009-10-23 11:17:28.000000000 -0700
3269@@ -0,0 +1,232 @@
3270+/*
3271+ * tef6862.c Philips TEF6862 Car Radio Enhanced Selectivity Tuner
3272+ * Copyright (c) 2009 Intel Corporation
3273+ *
3274+ * This program is free software; you can redistribute it and/or modify
3275+ * it under the terms of the GNU General Public License version 2 as
3276+ * published by the Free Software Foundation.
3277+ *
3278+ * This program is distributed in the hope that it will be useful,
3279+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3280+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3281+ * GNU General Public License for more details.
3282+ *
3283+ * You should have received a copy of the GNU General Public License
3284+ * along with this program; if not, write to the Free Software
3285+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
3286+ */
3287+
3288+#include <linux/module.h>
3289+#include <linux/init.h>
3290+#include <linux/errno.h>
3291+#include <linux/kernel.h>
3292+#include <linux/interrupt.h>
3293+#include <linux/i2c.h>
3294+#include <linux/i2c-id.h>
3295+#include <media/v4l2-ioctl.h>
3296+#include <media/v4l2-device.h>
3297+#include <media/v4l2-chip-ident.h>
3298+
3299+#define DRIVER_NAME "tef6862"
3300+
3301+#define FREQ_MUL 16000
3302+
3303+#define TEF6862_LO_FREQ (875 * FREQ_MUL / 10)
3304+#define TEF6862_HI_FREQ (108 * FREQ_MUL)
3305+
3306+/* Write mode sub addresses */
3307+#define WM_SUB_BANDWIDTH 0x0
3308+#define WM_SUB_PLLM 0x1
3309+#define WM_SUB_PLLL 0x2
3310+#define WM_SUB_DAA 0x3
3311+#define WM_SUB_AGC 0x4
3312+#define WM_SUB_BAND 0x5
3313+#define WM_SUB_CONTROL 0x6
3314+#define WM_SUB_LEVEL 0x7
3315+#define WM_SUB_IFCF 0x8
3316+#define WM_SUB_IFCAP 0x9
3317+#define WM_SUB_ACD 0xA
3318+#define WM_SUB_TEST 0xF
3319+
3320+/* Different modes of the MSA register */
3321+#define MODE_BUFFER 0x0
3322+#define MODE_PRESET 0x1
3323+#define MODE_SEARCH 0x2
3324+#define MODE_AF_UPDATE 0x3
3325+#define MODE_JUMP 0x4
3326+#define MODE_CHECK 0x5
3327+#define MODE_LOAD 0x6
3328+#define MODE_END 0x7
3329+#define MODE_SHIFT 5
3330+
3331+struct tef6862_state {
3332+ struct v4l2_subdev sd;
3333+ unsigned long freq;
3334+};
3335+
3336+static inline struct tef6862_state *to_state(struct v4l2_subdev *sd)
3337+{
3338+ return container_of(sd, struct tef6862_state, sd);
3339+}
3340+
3341+static u16 tef6862_sigstr(struct i2c_client *client)
3342+{
3343+ u8 buf[4];
3344+ int err = i2c_master_recv(client, buf, sizeof(buf));
3345+ if (err == sizeof(buf))
3346+ return buf[3] << 8;
3347+ return 0;
3348+}
3349+
3350+static int tef6862_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v)
3351+{
3352+ if (v->index > 0)
3353+ return -EINVAL;
3354+
3355+ /* only support FM for now */
3356+ strlcpy(v->name, "FM", sizeof(v->name));
3357+ v->type = V4L2_TUNER_RADIO;
3358+ v->rangelow = TEF6862_LO_FREQ;
3359+ v->rangehigh = TEF6862_HI_FREQ;
3360+ v->rxsubchans = V4L2_TUNER_SUB_MONO;
3361+ v->capability = V4L2_TUNER_CAP_LOW;
3362+ v->audmode = V4L2_TUNER_MODE_STEREO;
3363+ v->signal = tef6862_sigstr(v4l2_get_subdevdata(sd));
3364+
3365+ return 0;
3366+}
3367+
3368+static int tef6862_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v)
3369+{
3370+ return v->index ? -EINVAL : 0;
3371+}
3372+
3373+static int tef6862_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
3374+{
3375+ struct tef6862_state *state = to_state(sd);
3376+ struct i2c_client *client = v4l2_get_subdevdata(sd);
3377+ u16 pll;
3378+ u8 i2cmsg[3];
3379+ int err;
3380+
3381+ if (f->tuner != 0)
3382+ return -EINVAL;
3383+
3384+ pll = 1964 + ((f->frequency - TEF6862_LO_FREQ) * 20) / FREQ_MUL;
3385+ i2cmsg[0] = (MODE_PRESET << MODE_SHIFT) | WM_SUB_PLLM;
3386+ i2cmsg[1] = (pll >> 8) & 0xff;
3387+ i2cmsg[2] = pll & 0xff;
3388+
3389+ err = i2c_master_send(client, i2cmsg, sizeof(i2cmsg));
3390+ if (!err)
3391+ state->freq = f->frequency;
3392+ return err;
3393+}
3394+
3395+static int tef6862_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
3396+{
3397+ struct tef6862_state *state = to_state(sd);
3398+
3399+ if (f->tuner != 0)
3400+ return -EINVAL;
3401+ f->type = V4L2_TUNER_RADIO;
3402+ f->frequency = state->freq;
3403+ return 0;
3404+}
3405+
3406+static int tef6862_g_chip_ident(struct v4l2_subdev *sd,
3407+ struct v4l2_dbg_chip_ident *chip)
3408+{
3409+ struct i2c_client *client = v4l2_get_subdevdata(sd);
3410+
3411+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEF6862, 0);
3412+}
3413+
3414+static const struct v4l2_subdev_tuner_ops tef6862_tuner_ops = {
3415+ .g_tuner = tef6862_g_tuner,
3416+ .s_tuner = tef6862_s_tuner,
3417+ .s_frequency = tef6862_s_frequency,
3418+ .g_frequency = tef6862_g_frequency,
3419+};
3420+
3421+static const struct v4l2_subdev_core_ops tef6862_core_ops = {
3422+ .g_chip_ident = tef6862_g_chip_ident,
3423+};
3424+
3425+static const struct v4l2_subdev_ops tef6862_ops = {
3426+ .core = &tef6862_core_ops,
3427+ .tuner = &tef6862_tuner_ops,
3428+};
3429+
3430+/*
3431+ * Generic i2c probe
3432+ * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
3433+ */
3434+
3435+static int __devinit tef6862_probe(struct i2c_client *client,
3436+ const struct i2c_device_id *id)
3437+{
3438+ struct tef6862_state *state;
3439+ struct v4l2_subdev *sd;
3440+
3441+ /* Check if the adapter supports the needed features */
3442+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
3443+ return -EIO;
3444+
3445+ v4l_info(client, "chip found @ 0x%02x (%s)\n",
3446+ client->addr << 1, client->adapter->name);
3447+
3448+ state = kmalloc(sizeof(struct tef6862_state), GFP_KERNEL);
3449+ if (state == NULL)
3450+ return -ENOMEM;
3451+ state->freq = TEF6862_LO_FREQ;
3452+
3453+ sd = &state->sd;
3454+ v4l2_i2c_subdev_init(sd, client, &tef6862_ops);
3455+
3456+ return 0;
3457+}
3458+
3459+static int __devexit tef6862_remove(struct i2c_client *client)
3460+{
3461+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
3462+
3463+ v4l2_device_unregister_subdev(sd);
3464+ kfree(to_state(sd));
3465+ return 0;
3466+}
3467+
3468+static const struct i2c_device_id tef6862_id[] = {
3469+ {DRIVER_NAME, 0},
3470+ {},
3471+};
3472+
3473+MODULE_DEVICE_TABLE(i2c, tef6862_id);
3474+
3475+static struct i2c_driver tef6862_driver = {
3476+ .driver = {
3477+ .owner = THIS_MODULE,
3478+ .name = DRIVER_NAME,
3479+ },
3480+ .probe = tef6862_probe,
3481+ .remove = tef6862_remove,
3482+ .id_table = tef6862_id,
3483+};
3484+
3485+static __init int tef6862_init(void)
3486+{
3487+ return i2c_add_driver(&tef6862_driver);
3488+}
3489+
3490+static __exit void tef6862_exit(void)
3491+{
3492+ i2c_del_driver(&tef6862_driver);
3493+}
3494+
3495+module_init(tef6862_init);
3496+module_exit(tef6862_exit);
3497+
3498+MODULE_DESCRIPTION("TEF6862 Car Radio Enhanced Selectivity Tuner");
3499+MODULE_AUTHOR("Mocean Laboratories");
3500+MODULE_LICENSE("GPL v2");
3501+
3502diff -uNr linux-2.6.31/drivers/media/video/adv7180.c linux-2.6.31.new/drivers/media/video/adv7180.c
3503--- linux-2.6.31/drivers/media/video/adv7180.c 1969-12-31 16:00:00.000000000 -0800
3504+++ linux-2.6.31.new/drivers/media/video/adv7180.c 2009-10-23 11:17:28.000000000 -0700
3505@@ -0,0 +1,475 @@
3506+/*
3507+ * adv7180.c Analog Devices ADV7180 video decoder driver
3508+ * Copyright (c) 2009 Intel Corporation
3509+ *
3510+ * This program is free software; you can redistribute it and/or modify
3511+ * it under the terms of the GNU General Public License version 2 as
3512+ * published by the Free Software Foundation.
3513+ *
3514+ * This program is distributed in the hope that it will be useful,
3515+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3516+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3517+ * GNU General Public License for more details.
3518+ *
3519+ * You should have received a copy of the GNU General Public License
3520+ * along with this program; if not, write to the Free Software
3521+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
3522+ */
3523+
3524+#include <linux/module.h>
3525+#include <linux/init.h>
3526+#include <linux/errno.h>
3527+#include <linux/kernel.h>
3528+#include <linux/interrupt.h>
3529+#include <linux/i2c.h>
3530+#include <linux/i2c-id.h>
3531+#include <media/v4l2-ioctl.h>
3532+#include <linux/videodev2.h>
3533+#include <media/v4l2-device.h>
3534+#include <media/v4l2-chip-ident.h>
3535+#include <linux/mutex.h>
3536+
3537+#define DRIVER_NAME "adv7180"
3538+
3539+#define ADV7180_INPUT_CONTROL_REG 0x00
3540+#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM 0x00
3541+#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM_PED 0x10
3542+#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_J_SECAM 0x20
3543+#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_M_SECAM 0x30
3544+#define ADV7180_INPUT_CONTROL_NTSC_J 0x40
3545+#define ADV7180_INPUT_CONTROL_NTSC_M 0x50
3546+#define ADV7180_INPUT_CONTROL_PAL60 0x60
3547+#define ADV7180_INPUT_CONTROL_NTSC_443 0x70
3548+#define ADV7180_INPUT_CONTROL_PAL_BG 0x80
3549+#define ADV7180_INPUT_CONTROL_PAL_N 0x90
3550+#define ADV7180_INPUT_CONTROL_PAL_M 0xa0
3551+#define ADV7180_INPUT_CONTROL_PAL_M_PED 0xb0
3552+#define ADV7180_INPUT_CONTROL_PAL_COMB_N 0xc0
3553+#define ADV7180_INPUT_CONTROL_PAL_COMB_N_PED 0xd0
3554+#define ADV7180_INPUT_CONTROL_PAL_SECAM 0xe0
3555+#define ADV7180_INPUT_CONTROL_PAL_SECAM_PED 0xf0
3556+
3557+#define ADV7180_EXTENDED_OUTPUT_CONTROL_REG 0x04
3558+#define ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS 0xC5
3559+
3560+#define ADV7180_AUTODETECT_ENABLE_REG 0x07
3561+#define ADV7180_AUTODETECT_DEFAULT 0x7f
3562+
3563+#define ADV7180_ADI_CTRL_REG 0x0e
3564+#define ADV7180_ADI_CTRL_IRQ_SPACE 0x20
3565+
3566+#define ADV7180_STATUS1_REG 0x10
3567+#define ADV7180_STATUS1_IN_LOCK 0x01
3568+#define ADV7180_STATUS1_AUTOD_MASK 0x70
3569+#define ADV7180_STATUS1_AUTOD_NTSM_M_J 0x00
3570+#define ADV7180_STATUS1_AUTOD_NTSC_4_43 0x10
3571+#define ADV7180_STATUS1_AUTOD_PAL_M 0x20
3572+#define ADV7180_STATUS1_AUTOD_PAL_60 0x30
3573+#define ADV7180_STATUS1_AUTOD_PAL_B_G 0x40
3574+#define ADV7180_STATUS1_AUTOD_SECAM 0x50
3575+#define ADV7180_STATUS1_AUTOD_PAL_COMB 0x60
3576+#define ADV7180_STATUS1_AUTOD_SECAM_525 0x70
3577+
3578+#define ADV7180_IDENT_REG 0x11
3579+#define ADV7180_ID_7180 0x18
3580+
3581+#define ADV7180_ICONF1_ADI 0x40
3582+#define ADV7180_ICONF1_ACTIVE_LOW 0x01
3583+#define ADV7180_ICONF1_PSYNC_ONLY 0x10
3584+#define ADV7180_ICONF1_ACTIVE_TO_CLR 0xC0
3585+
3586+#define ADV7180_IRQ1_LOCK 0x01
3587+#define ADV7180_IRQ1_UNLOCK 0x02
3588+#define ADV7180_ISR1_ADI 0x42
3589+#define ADV7180_ICR1_ADI 0x43
3590+#define ADV7180_IMR1_ADI 0x44
3591+#define ADV7180_IMR2_ADI 0x48
3592+#define ADV7180_IRQ3_AD_CHANGE 0x08
3593+#define ADV7180_ISR3_ADI 0x4A
3594+#define ADV7180_ICR3_ADI 0x4B
3595+#define ADV7180_IMR3_ADI 0x4C
3596+#define ADV7180_IMR4_ADI 0x50
3597+
3598+#define ADV7180_NTSC_V_BIT_END_REG 0xE6
3599+#define ADV7180_NTSC_V_BIT_END_MANUAL_NVEND 0x4F
3600+
3601+struct adv7180_state {
3602+ struct v4l2_subdev sd;
3603+ struct work_struct work;
3604+ struct mutex mutex; /* mutual excl. when accessing chip */
3605+ int irq;
3606+ v4l2_std_id curr_norm;
3607+ bool autodetect;
3608+};
3609+
3610+static v4l2_std_id adv7180_std_to_v4l2(u8 status1)
3611+{
3612+ switch (status1 & ADV7180_STATUS1_AUTOD_MASK) {
3613+ case ADV7180_STATUS1_AUTOD_NTSM_M_J:
3614+ return V4L2_STD_NTSC;
3615+ case ADV7180_STATUS1_AUTOD_NTSC_4_43:
3616+ return V4L2_STD_NTSC_443;
3617+ case ADV7180_STATUS1_AUTOD_PAL_M:
3618+ return V4L2_STD_PAL_M;
3619+ case ADV7180_STATUS1_AUTOD_PAL_60:
3620+ return V4L2_STD_PAL_60;
3621+ case ADV7180_STATUS1_AUTOD_PAL_B_G:
3622+ return V4L2_STD_PAL;
3623+ case ADV7180_STATUS1_AUTOD_SECAM:
3624+ return V4L2_STD_SECAM;
3625+ case ADV7180_STATUS1_AUTOD_PAL_COMB:
3626+ return V4L2_STD_PAL_Nc | V4L2_STD_PAL_N;
3627+ case ADV7180_STATUS1_AUTOD_SECAM_525:
3628+ return V4L2_STD_SECAM;
3629+ default:
3630+ return V4L2_STD_UNKNOWN;
3631+ }
3632+}
3633+
3634+static int v4l2_std_to_adv7180(v4l2_std_id std)
3635+{
3636+ if (std == V4L2_STD_PAL_60)
3637+ return ADV7180_INPUT_CONTROL_PAL60;
3638+ if (std == V4L2_STD_NTSC_443)
3639+ return ADV7180_INPUT_CONTROL_NTSC_443;
3640+ if (std == V4L2_STD_PAL_N)
3641+ return ADV7180_INPUT_CONTROL_PAL_N;
3642+ if (std == V4L2_STD_PAL_M)
3643+ return ADV7180_INPUT_CONTROL_PAL_M;
3644+ if (std == V4L2_STD_PAL_Nc)
3645+ return ADV7180_INPUT_CONTROL_PAL_COMB_N;
3646+
3647+ /* pal is a combination of several variants */
3648+ if (std & V4L2_STD_PAL)
3649+ return ADV7180_INPUT_CONTROL_PAL_BG;
3650+ if (std & V4L2_STD_NTSC)
3651+ return ADV7180_INPUT_CONTROL_NTSC_M;
3652+ if (std & V4L2_STD_SECAM)
3653+ return ADV7180_INPUT_CONTROL_PAL_SECAM;
3654+
3655+ return -EINVAL;
3656+}
3657+
3658+static u32 adv7180_status_to_v4l2(u8 status1)
3659+{
3660+ if (!(status1 & ADV7180_STATUS1_IN_LOCK))
3661+ return V4L2_IN_ST_NO_SIGNAL;
3662+
3663+ return 0;
3664+}
3665+
3666+static int __adv7180_status(struct i2c_client *client, u32 *status,
3667+ v4l2_std_id *std)
3668+{
3669+ int status1 = i2c_smbus_read_byte_data(client, ADV7180_STATUS1_REG);
3670+
3671+ if (status1 < 0)
3672+ return status1;
3673+
3674+ if (status)
3675+ *status = adv7180_status_to_v4l2(status1);
3676+ if (std)
3677+ *std = adv7180_std_to_v4l2(status1);
3678+
3679+ return 0;
3680+}
3681+
3682+static inline struct adv7180_state *to_state(struct v4l2_subdev *sd)
3683+{
3684+ return container_of(sd, struct adv7180_state, sd);
3685+}
3686+
3687+static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
3688+{
3689+ struct adv7180_state *state = to_state(sd);
3690+ int err = mutex_lock_interruptible(&state->mutex);
3691+ if (err)
3692+ return err;
3693+
3694+ /* when we are interrupt driven we know the state */
3695+ if (!state->autodetect || state->irq > 0)
3696+ *std = state->curr_norm;
3697+ else
3698+ err = __adv7180_status(v4l2_get_subdevdata(sd), NULL, std);
3699+
3700+ mutex_unlock(&state->mutex);
3701+ return err;
3702+}
3703+
3704+static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
3705+{
3706+ struct adv7180_state *state = to_state(sd);
3707+ struct i2c_client *client = v4l2_get_subdevdata(sd);
3708+ int ret = mutex_lock_interruptible(&state->mutex);
3709+ if (ret)
3710+ return ret;
3711+
3712+ /* all standards -> autodetect */
3713+ if (std == V4L2_STD_ALL) {
3714+ ret = i2c_smbus_write_byte_data(client,
3715+ ADV7180_INPUT_CONTROL_REG,
3716+ ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM);
3717+ if (ret < 0)
3718+ goto out;
3719+
3720+ __adv7180_status(client, NULL, &state->curr_norm);
3721+ state->autodetect = true;
3722+ } else {
3723+ ret = v4l2_std_to_adv7180(std);
3724+ if (ret < 0)
3725+ goto out;
3726+
3727+ ret = i2c_smbus_write_byte_data(client,
3728+ ADV7180_INPUT_CONTROL_REG, ret);
3729+ if (ret < 0)
3730+ goto out;
3731+
3732+ state->curr_norm = std;
3733+ state->autodetect = false;
3734+ }
3735+ ret = 0;
3736+out:
3737+ mutex_unlock(&state->mutex);
3738+ return ret;
3739+}
3740+
3741+static int adv7180_g_input_status(struct v4l2_subdev *sd, u32 *status)
3742+{
3743+ struct adv7180_state *state = to_state(sd);
3744+ int ret = mutex_lock_interruptible(&state->mutex);
3745+ if (ret)
3746+ return ret;
3747+
3748+ ret = __adv7180_status(v4l2_get_subdevdata(sd), status, NULL);
3749+ mutex_unlock(&state->mutex);
3750+ return ret;
3751+}
3752+
3753+static int adv7180_g_chip_ident(struct v4l2_subdev *sd,
3754+ struct v4l2_dbg_chip_ident *chip)
3755+{
3756+ struct i2c_client *client = v4l2_get_subdevdata(sd);
3757+
3758+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7180, 0);
3759+}
3760+
3761+static const struct v4l2_subdev_video_ops adv7180_video_ops = {
3762+ .querystd = adv7180_querystd,
3763+ .g_input_status = adv7180_g_input_status,
3764+};
3765+
3766+static const struct v4l2_subdev_core_ops adv7180_core_ops = {
3767+ .g_chip_ident = adv7180_g_chip_ident,
3768+ .s_std = adv7180_s_std,
3769+};
3770+
3771+static const struct v4l2_subdev_ops adv7180_ops = {
3772+ .core = &adv7180_core_ops,
3773+ .video = &adv7180_video_ops,
3774+};
3775+
3776+static void adv7180_work(struct work_struct *work)
3777+{
3778+ struct adv7180_state *state = container_of(work, struct adv7180_state,
3779+ work);
3780+ struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
3781+ u8 isr3;
3782+
3783+ mutex_lock(&state->mutex);
3784+ i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
3785+ ADV7180_ADI_CTRL_IRQ_SPACE);
3786+ isr3 = i2c_smbus_read_byte_data(client, ADV7180_ISR3_ADI);
3787+ /* clear */
3788+ i2c_smbus_write_byte_data(client, ADV7180_ICR3_ADI, isr3);
3789+ i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG, 0);
3790+
3791+ if (isr3 & ADV7180_IRQ3_AD_CHANGE && state->autodetect)
3792+ __adv7180_status(client, NULL, &state->curr_norm);
3793+ mutex_unlock(&state->mutex);
3794+
3795+ enable_irq(state->irq);
3796+}
3797+
3798+static irqreturn_t adv7180_irq(int irq, void *devid)
3799+{
3800+ struct adv7180_state *state = devid;
3801+
3802+ schedule_work(&state->work);
3803+
3804+ disable_irq_nosync(state->irq);
3805+
3806+ return IRQ_HANDLED;
3807+}
3808+
3809+/*
3810+ * Generic i2c probe
3811+ * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
3812+ */
3813+
3814+static int __devinit adv7180_probe(struct i2c_client *client,
3815+ const struct i2c_device_id *id)
3816+{
3817+ struct adv7180_state *state;
3818+ struct v4l2_subdev *sd;
3819+ int ret;
3820+
3821+ /* Check if the adapter supports the needed features */
3822+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
3823+ return -EIO;
3824+
3825+ v4l_info(client, "chip found @ 0x%02x (%s)\n",
3826+ client->addr << 1, client->adapter->name);
3827+
3828+ state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL);
3829+ if (state == NULL) {
3830+ ret = -ENOMEM;
3831+ goto err;
3832+ }
3833+
3834+ state->irq = client->irq;
3835+ INIT_WORK(&state->work, adv7180_work);
3836+ mutex_init(&state->mutex);
3837+ state->autodetect = true;
3838+ sd = &state->sd;
3839+ v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
3840+
3841+ /* Initialize adv7180 */
3842+ /* Enable autodetection */
3843+ ret = i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG,
3844+ ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM);
3845+ if (ret < 0)
3846+ goto err_unreg_subdev;
3847+
3848+ ret = i2c_smbus_write_byte_data(client, ADV7180_AUTODETECT_ENABLE_REG,
3849+ ADV7180_AUTODETECT_DEFAULT);
3850+ if (ret < 0)
3851+ goto err_unreg_subdev;
3852+
3853+ /* ITU-R BT.656-4 compatible */
3854+ ret = i2c_smbus_write_byte_data(client,
3855+ ADV7180_EXTENDED_OUTPUT_CONTROL_REG,
3856+ ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS);
3857+ if (ret < 0)
3858+ goto err_unreg_subdev;
3859+
3860+
3861+ /* Manually set V bit end position in NTSC mode */
3862+ ret = i2c_smbus_write_byte_data(client,
3863+ ADV7180_NTSC_V_BIT_END_REG,
3864+ ADV7180_NTSC_V_BIT_END_MANUAL_NVEND);
3865+ if (ret < 0)
3866+ goto err_unreg_subdev;
3867+
3868+ /* read current norm */
3869+ __adv7180_status(client, NULL, &state->curr_norm);
3870+
3871+ /* register for interrupts */
3872+ if (state->irq > 0) {
3873+ ret = request_irq(state->irq, adv7180_irq, 0, DRIVER_NAME,
3874+ state);
3875+ if (ret)
3876+ goto err_unreg_subdev;
3877+
3878+ ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
3879+ ADV7180_ADI_CTRL_IRQ_SPACE);
3880+ if (ret < 0)
3881+ goto err_unreg_subdev;
3882+
3883+ /* config the Interrupt pin to be active low */
3884+ ret = i2c_smbus_write_byte_data(client, ADV7180_ICONF1_ADI,
3885+ ADV7180_ICONF1_ACTIVE_LOW | ADV7180_ICONF1_PSYNC_ONLY);
3886+ if (ret < 0)
3887+ goto err_unreg_subdev;
3888+
3889+ ret = i2c_smbus_write_byte_data(client, ADV7180_IMR1_ADI, 0);
3890+ if (ret < 0)
3891+ goto err_unreg_subdev;
3892+
3893+ ret = i2c_smbus_write_byte_data(client, ADV7180_IMR2_ADI, 0);
3894+ if (ret < 0)
3895+ goto err_unreg_subdev;
3896+
3897+ /* enable AD change interrupts interrupts */
3898+ ret = i2c_smbus_write_byte_data(client, ADV7180_IMR3_ADI,
3899+ ADV7180_IRQ3_AD_CHANGE);
3900+ if (ret < 0)
3901+ goto err_unreg_subdev;
3902+
3903+ ret = i2c_smbus_write_byte_data(client, ADV7180_IMR4_ADI, 0);
3904+ if (ret < 0)
3905+ goto err_unreg_subdev;
3906+
3907+ ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
3908+ 0);
3909+ if (ret < 0)
3910+ goto err_unreg_subdev;
3911+ }
3912+
3913+ return 0;
3914+
3915+err_unreg_subdev:
3916+ mutex_destroy(&state->mutex);
3917+ v4l2_device_unregister_subdev(sd);
3918+ kfree(state);
3919+err:
3920+ printk(KERN_ERR DRIVER_NAME ": Failed to probe: %d\n", ret);
3921+ return ret;
3922+}
3923+
3924+static int __devexit adv7180_remove(struct i2c_client *client)
3925+{
3926+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
3927+ struct adv7180_state *state = to_state(sd);
3928+
3929+ if (state->irq > 0) {
3930+ free_irq(client->irq, state);
3931+ if (cancel_work_sync(&state->work)) {
3932+ /*
3933+ * Work was pending, therefore we need to enable
3934+ * IRQ here to balance the disable_irq() done in the
3935+ * interrupt handler.
3936+ */
3937+ enable_irq(state->irq);
3938+ }
3939+ }
3940+
3941+ mutex_destroy(&state->mutex);
3942+ v4l2_device_unregister_subdev(sd);
3943+ kfree(to_state(sd));
3944+ return 0;
3945+}
3946+
3947+static const struct i2c_device_id adv7180_id[] = {
3948+ {DRIVER_NAME, 0},
3949+ {},
3950+};
3951+
3952+MODULE_DEVICE_TABLE(i2c, adv7180_id);
3953+
3954+static struct i2c_driver adv7180_driver = {
3955+ .driver = {
3956+ .owner = THIS_MODULE,
3957+ .name = DRIVER_NAME,
3958+ },
3959+ .probe = adv7180_probe,
3960+ .remove = adv7180_remove,
3961+ .id_table = adv7180_id,
3962+};
3963+
3964+static __init int adv7180_init(void)
3965+{
3966+ return i2c_add_driver(&adv7180_driver);
3967+}
3968+
3969+static __exit void adv7180_exit(void)
3970+{
3971+ i2c_del_driver(&adv7180_driver);
3972+}
3973+
3974+module_init(adv7180_init);
3975+module_exit(adv7180_exit);
3976+
3977+MODULE_DESCRIPTION("Analog Devices ADV7180 video decoder driver");
3978+MODULE_AUTHOR("Mocean Laboratories");
3979+MODULE_LICENSE("GPL v2");
3980+
3981diff -uNr linux-2.6.31/drivers/media/video/Kconfig linux-2.6.31.new/drivers/media/video/Kconfig
3982--- linux-2.6.31/drivers/media/video/Kconfig 2009-10-23 11:18:30.000000000 -0700
3983+++ linux-2.6.31.new/drivers/media/video/Kconfig 2009-10-23 11:17:28.000000000 -0700
3984@@ -265,6 +265,15 @@
3985
3986 comment "Video decoders"
3987
3988+config VIDEO_ADV7180
3989+ tristate "Analog Devices ADV7180 decoder"
3990+ depends on VIDEO_V4L2 && I2C
3991+ ---help---
3992+ Support for the Analog Devices ADV7180 video decoder.
3993+
3994+ To compile this driver as a module, choose M here: the
3995+ module will be called adv7180.
3996+
3997 config VIDEO_BT819
3998 tristate "BT819A VideoStream decoder"
3999 depends on VIDEO_V4L2 && I2C
4000@@ -816,6 +825,13 @@
4001 ---help---
4002 This is a v4l2 driver for the TI OMAP2 camera capture interface
4003
4004+config VIDEO_TIMBERDALE
4005+ tristate "Support for timberdale Video In/LogiWIN"
4006+ depends on VIDEO_V4L2 && MFD_TIMBERDALE_DMA
4007+ select VIDEO_ADV7180
4008+ ---help---
4009+ Add support for the Video In peripherial of the timberdale FPGA.
4010+
4011 #
4012 # USB Multimedia device configuration
4013 #
4014diff -uNr linux-2.6.31/drivers/media/video/Makefile linux-2.6.31.new/drivers/media/video/Makefile
4015--- linux-2.6.31/drivers/media/video/Makefile 2009-10-23 11:18:30.000000000 -0700
4016+++ linux-2.6.31.new/drivers/media/video/Makefile 2009-10-23 11:17:27.000000000 -0700
4017@@ -45,6 +45,7 @@
4018 obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o
4019 obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
4020 obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
4021+obj-$(CONFIG_VIDEO_ADV7180) += adv7180.o
4022 obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o
4023 obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
4024 obj-$(CONFIG_VIDEO_BT819) += bt819.o
4025@@ -156,6 +157,8 @@
4026
4027 obj-$(CONFIG_VIDEO_AU0828) += au0828/
4028
4029+obj-$(CONFIG_VIDEO_TIMBERDALE) += timblogiw.o
4030+
4031 obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/
4032
4033 obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
4034diff -uNr linux-2.6.31/drivers/media/video/timblogiw.c linux-2.6.31.new/drivers/media/video/timblogiw.c
4035--- linux-2.6.31/drivers/media/video/timblogiw.c 1969-12-31 16:00:00.000000000 -0800
4036+++ linux-2.6.31.new/drivers/media/video/timblogiw.c 2009-10-23 11:17:28.000000000 -0700
4037@@ -0,0 +1,1058 @@
4038+/*
4039+ * timblogiw.c timberdale FPGA LogiWin Video In driver
4040+ * Copyright (c) 2009 Intel Corporation
4041+ *
4042+ * This program is free software; you can redistribute it and/or modify
4043+ * it under the terms of the GNU General Public License version 2 as
4044+ * published by the Free Software Foundation.
4045+ *
4046+ * This program is distributed in the hope that it will be useful,
4047+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4048+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4049+ * GNU General Public License for more details.
4050+ *
4051+ * You should have received a copy of the GNU General Public License
4052+ * along with this program; if not, write to the Free Software
4053+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
4054+ */
4055+
4056+/* Supports:
4057+ * Timberdale FPGA LogiWin Video In
4058+ */
4059+
4060+#include <linux/list.h>
4061+#include <linux/version.h>
4062+#include <linux/module.h>
4063+#include <linux/dma-mapping.h>
4064+#include <media/v4l2-common.h>
4065+#include <media/v4l2-ioctl.h>
4066+#include <media/v4l2-device.h>
4067+#include <linux/platform_device.h>
4068+#include <linux/interrupt.h>
4069+#include "timblogiw.h"
4070+#include <linux/mfd/timbdma.h>
4071+#include <linux/i2c.h>
4072+
4073+#define DRIVER_NAME "timb-video"
4074+
4075+#define TIMBLOGIW_CTRL 0x40
4076+
4077+#define TIMBLOGIW_H_SCALE 0x20
4078+#define TIMBLOGIW_V_SCALE 0x28
4079+
4080+#define TIMBLOGIW_X_CROP 0x58
4081+#define TIMBLOGIW_Y_CROP 0x60
4082+
4083+#define TIMBLOGIW_W_CROP 0x00
4084+#define TIMBLOGIW_H_CROP 0x08
4085+
4086+#define TIMBLOGIW_VERSION_CODE 0x02
4087+
4088+#define TIMBLOGIW_BUF 0x04
4089+#define TIMBLOGIW_TBI 0x2c
4090+#define TIMBLOGIW_BPL 0x30
4091+
4092+#define dbg(...)
4093+
4094+#define BYTES_PER_LINE (720 * 2)
4095+
4096+#define DMA_BUFFER_SIZE (BYTES_PER_LINE * 576)
4097+
4098+#define TIMBLOGIW_VIDEO_FORMAT V4L2_PIX_FMT_UYVY
4099+
4100+static void timblogiw_release_buffers(struct timblogiw *lw);
4101+
4102+const struct timblogiw_tvnorm timblogiw_tvnorms[] = {
4103+ {
4104+ .std = V4L2_STD_PAL,
4105+ .width = 720,
4106+ .height = 576
4107+ },
4108+ {
4109+ .std = V4L2_STD_NTSC,
4110+ .width = 720,
4111+ .height = 480
4112+ }
4113+};
4114+
4115+static int timblogiw_bytes_per_line(const struct timblogiw_tvnorm *norm)
4116+{
4117+ return norm->width * 2;
4118+}
4119+
4120+
4121+static int timblogiw_frame_size(const struct timblogiw_tvnorm *norm)
4122+{
4123+ return norm->height * timblogiw_bytes_per_line(norm);
4124+}
4125+
4126+static const struct timblogiw_tvnorm *timblogiw_get_norm(const v4l2_std_id std)
4127+{
4128+ int i;
4129+ for (i = 0; i < ARRAY_SIZE(timblogiw_tvnorms); i++)
4130+ if (timblogiw_tvnorms[i].std & std)
4131+ return timblogiw_tvnorms + i;
4132+
4133+ /* default to first element */
4134+ return timblogiw_tvnorms;
4135+}
4136+
4137+static void timblogiw_handleframe(unsigned long arg)
4138+{
4139+ struct timblogiw_frame *f;
4140+ struct timblogiw *lw = (struct timblogiw *)arg;
4141+
4142+ spin_lock_bh(&lw->queue_lock);
4143+ if (lw->dma.filled && !list_empty(&lw->inqueue)) {
4144+ /* put the entry in the outqueue */
4145+ f = list_entry(lw->inqueue.next, struct timblogiw_frame, frame);
4146+
4147+ /* sync memory and unmap */
4148+ dma_sync_single_for_cpu(lw->dev, lw->dma.filled->handle,
4149+ timblogiw_frame_size(lw->cur_norm), DMA_FROM_DEVICE);
4150+
4151+ /* copy data from the DMA buffer */
4152+ memcpy(f->bufmem, lw->dma.filled->buf, f->buf.length);
4153+ /* buffer consumed */
4154+ lw->dma.filled = NULL;
4155+
4156+ do_gettimeofday(&f->buf.timestamp);
4157+ f->buf.sequence = ++lw->frame_count;
4158+ f->buf.field = V4L2_FIELD_NONE;
4159+ f->state = F_DONE;
4160+ f->buf.bytesused = f->buf.length;
4161+ list_move_tail(&f->frame, &lw->outqueue);
4162+ /* wake up any waiter */
4163+ wake_up(&lw->wait_frame);
4164+ } else {
4165+ /* No user buffer available, consume buffer anyway
4166+ * who wants an old video frame?
4167+ */
4168+ lw->dma.filled = NULL;
4169+ }
4170+ spin_unlock_bh(&lw->queue_lock);
4171+}
4172+
4173+static int __timblogiw_start_dma(struct timblogiw *lw)
4174+{
4175+ int size = timblogiw_frame_size(lw->cur_norm);
4176+ int ret;
4177+ struct timbdma_transfer *transfer = lw->dma.transfer + lw->dma.curr;
4178+ int bytes_per_line = timblogiw_bytes_per_line(lw->cur_norm);
4179+
4180+ ret = timbdma_prep_desc(transfer->desc, transfer->handle, size);
4181+ if (ret)
4182+ goto err;
4183+
4184+ ret = timbdma_start(DMA_IRQ_VIDEO_RX, transfer->desc, bytes_per_line);
4185+ if (ret)
4186+ goto err;
4187+ return ret;
4188+err:
4189+ return ret;
4190+}
4191+
4192+static int timblogiw_isr(u32 flag, void *pdev)
4193+{
4194+ struct timblogiw *lw = (struct timblogiw *)pdev;
4195+
4196+ if (lw->stream == STREAM_OFF) {
4197+ timbdma_stop(DMA_IRQ_VIDEO_RX);
4198+ /* stream is stopped, signal that the current transfer is
4199+ * finished */
4200+ complete(&lw->irq_done);
4201+ } else {
4202+ struct timeval timestamp;
4203+
4204+ do_gettimeofday(&timestamp);
4205+
4206+ if (!lw->dma.filled && (flag & DMA_IRQ_VIDEO_RX)) {
4207+ /* Got a frame, store it, and flip to next DMA buffer */
4208+ lw->dma.filled = lw->dma.transfer + lw->dma.curr;
4209+ lw->dma.curr = !lw->dma.curr;
4210+ } else if (lw->dma.filled && (flag & DMA_IRQ_VIDEO_RX))
4211+ printk("No free frame\n");
4212+
4213+ __timblogiw_start_dma(lw);
4214+
4215+ if (flag & DMA_IRQ_VIDEO_DROP)
4216+ dbg("%s: frame dropped\n", __func__);
4217+ if (flag & DMA_IRQ_VIDEO_RX) {
4218+ dbg("%s: frame RX\n", __func__);
4219+ tasklet_schedule(&lw->tasklet);
4220+ }
4221+ }
4222+
4223+ return 0;
4224+}
4225+
4226+static void timblogiw_empty_framequeues(struct timblogiw *lw)
4227+{
4228+ u32 i;
4229+
4230+ dbg("%s\n", __func__);
4231+
4232+ INIT_LIST_HEAD(&lw->inqueue);
4233+ INIT_LIST_HEAD(&lw->outqueue);
4234+
4235+ for (i = 0; i < lw->num_frames; i++) {
4236+ lw->frame[i].state = F_UNUSED;
4237+ lw->frame[i].buf.bytesused = 0;
4238+ }
4239+}
4240+
4241+u32 timblogiw_request_buffers(struct timblogiw *lw, u32 count)
4242+{
4243+ /* needs to be page aligned cause the */
4244+ /* buffers can be mapped individually! */
4245+ const size_t imagesize = PAGE_ALIGN(timblogiw_frame_size(lw->cur_norm));
4246+ void *buff = NULL;
4247+ int ret;
4248+ u32 i;
4249+
4250+ dbg("%s - request of %i buffers of size %zi\n",
4251+ __func__, count, imagesize);
4252+
4253+ lw->dma.transfer[0].buf = kzalloc(DMA_BUFFER_SIZE, GFP_KERNEL);
4254+ if (!lw->dma.transfer[0].buf)
4255+ goto err;
4256+
4257+ lw->dma.transfer[1].buf = kzalloc(DMA_BUFFER_SIZE, GFP_KERNEL);
4258+ if (!lw->dma.transfer[1].buf)
4259+ goto err;
4260+
4261+ lw->dma.transfer[0].desc =
4262+ timbdma_alloc_desc(DMA_BUFFER_SIZE, BYTES_PER_LINE * 2);
4263+ if (!lw->dma.transfer[0].desc)
4264+ goto err;
4265+
4266+ lw->dma.transfer[1].desc =
4267+ timbdma_alloc_desc(DMA_BUFFER_SIZE, BYTES_PER_LINE * 2);
4268+ if (!lw->dma.transfer[1].desc)
4269+ goto err;
4270+
4271+ /* map up the DMA buffers */
4272+ lw->dma.transfer[0].handle = dma_map_single(lw->dev,
4273+ lw->dma.transfer[0].buf, DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
4274+ ret = dma_mapping_error(lw->dev, lw->dma.transfer[0].handle);
4275+ if (ret) {
4276+ lw->dma.transfer[0].handle = 0;
4277+ goto err;
4278+ }
4279+
4280+ lw->dma.transfer[1].handle = dma_map_single(lw->dev,
4281+ lw->dma.transfer[1].buf, DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
4282+ ret = dma_mapping_error(lw->dev, lw->dma.transfer[1].handle);
4283+ if (ret) {
4284+ lw->dma.transfer[1].handle = 0;
4285+ goto err;
4286+ }
4287+
4288+ if (count > TIMBLOGIW_NUM_FRAMES)
4289+ count = TIMBLOGIW_NUM_FRAMES;
4290+
4291+ lw->num_frames = count;
4292+ while (lw->num_frames > 0) {
4293+ buff = vmalloc_32(lw->num_frames * imagesize);
4294+ if (buff) {
4295+ memset(buff, 0, lw->num_frames * imagesize);
4296+ break;
4297+ }
4298+ lw->num_frames--;
4299+ }
4300+
4301+ for (i = 0; i < lw->num_frames; i++) {
4302+ lw->frame[i].bufmem = buff + i * imagesize;
4303+ lw->frame[i].buf.index = i;
4304+ lw->frame[i].buf.m.offset = i * imagesize;
4305+ lw->frame[i].buf.length = timblogiw_frame_size(lw->cur_norm);
4306+ lw->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
4307+ lw->frame[i].buf.sequence = 0;
4308+ lw->frame[i].buf.field = V4L2_FIELD_NONE;
4309+ lw->frame[i].buf.memory = V4L2_MEMORY_MMAP;
4310+ lw->frame[i].buf.flags = 0;
4311+ }
4312+
4313+ lw->dma.curr = 0;
4314+ lw->dma.filled = NULL;
4315+ return lw->num_frames;
4316+err:
4317+ timblogiw_release_buffers(lw);
4318+
4319+ return 0;
4320+}
4321+
4322+static void timblogiw_release_buffers(struct timblogiw *lw)
4323+{
4324+ dbg("%s\n", __func__);
4325+
4326+ if (lw->frame[0].bufmem != NULL) {
4327+ vfree(lw->frame[0].bufmem);
4328+ lw->frame[0].bufmem = NULL;
4329+ }
4330+
4331+ if (lw->dma.transfer[0].handle)
4332+ dma_unmap_single(lw->dev, lw->dma.transfer[0].handle,
4333+ DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
4334+
4335+ if (lw->dma.transfer[1].handle)
4336+ dma_unmap_single(lw->dev, lw->dma.transfer[1].handle,
4337+ DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
4338+
4339+ if (lw->dma.transfer[0].buf != NULL)
4340+ kfree(lw->dma.transfer[0].buf);
4341+ lw->dma.transfer[0].buf = NULL;
4342+
4343+ if (lw->dma.transfer[1].buf != NULL)
4344+ kfree(lw->dma.transfer[1].buf);
4345+ lw->dma.transfer[1].buf = NULL;
4346+
4347+ if (lw->dma.transfer[0].desc != NULL)
4348+ timbdma_free_desc(lw->dma.transfer[0].desc);
4349+ lw->dma.transfer[0].desc = NULL;
4350+
4351+ if (lw->dma.transfer[1].desc != NULL)
4352+ timbdma_free_desc(lw->dma.transfer[1].desc);
4353+ lw->dma.transfer[1].desc = NULL;
4354+
4355+
4356+ lw->num_frames = TIMBLOGIW_NUM_FRAMES;
4357+}
4358+
4359+/* IOCTL functions */
4360+
4361+static int timblogiw_g_fmt(struct file *file, void *priv,
4362+ struct v4l2_format *format)
4363+{
4364+ struct video_device *vdev = video_devdata(file);
4365+ struct timblogiw *lw = video_get_drvdata(vdev);
4366+
4367+ dbg("%s\n", __func__);
4368+
4369+ if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
4370+ return -EINVAL;
4371+
4372+ format->fmt.pix.width = lw->cur_norm->width;
4373+ format->fmt.pix.height = lw->cur_norm->height;
4374+ format->fmt.pix.pixelformat = TIMBLOGIW_VIDEO_FORMAT;
4375+ format->fmt.pix.bytesperline = timblogiw_bytes_per_line(lw->cur_norm);
4376+ format->fmt.pix.sizeimage = timblogiw_frame_size(lw->cur_norm);
4377+ format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
4378+ format->fmt.pix.field = V4L2_FIELD_NONE;
4379+ return 0;
4380+}
4381+
4382+static int timblogiw_try_fmt(struct file *file, void *priv,
4383+ struct v4l2_format *format)
4384+{
4385+ struct video_device *vdev = video_devdata(file);
4386+ struct timblogiw *lw = video_get_drvdata(vdev);
4387+ struct v4l2_pix_format *pix = &format->fmt.pix;
4388+
4389+ dbg("%s - width=%d, height=%d, pixelformat=%d, field=%d\n"
4390+ "bytes per line %d, size image: %d, colorspace: %d\n",
4391+ __func__,
4392+ pix->width, pix->height, pix->pixelformat, pix->field,
4393+ pix->bytesperline, pix->sizeimage, pix->colorspace);
4394+
4395+ if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
4396+ return -EINVAL;
4397+
4398+ if (pix->field != V4L2_FIELD_NONE)
4399+ return -EINVAL;
4400+
4401+ if (pix->pixelformat != TIMBLOGIW_VIDEO_FORMAT)
4402+ return -EINVAL;
4403+
4404+ if ((lw->cur_norm->height != pix->height) ||
4405+ (lw->cur_norm->width != pix->width)) {
4406+ pix->width = lw->cur_norm->width;
4407+ pix->height = lw->cur_norm->height;
4408+ }
4409+
4410+ return 0;
4411+}
4412+
4413+static int timblogiw_querycap(struct file *file, void *priv,
4414+ struct v4l2_capability *cap)
4415+{
4416+ dbg("%s\n", __func__);
4417+ memset(cap, 0, sizeof(*cap));
4418+ strncpy(cap->card, "Timberdale Video", sizeof(cap->card)-1);
4419+ strncpy(cap->driver, "Timblogiw", sizeof(cap->card)-1);
4420+ cap->version = TIMBLOGIW_VERSION_CODE;
4421+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
4422+ V4L2_CAP_STREAMING;
4423+
4424+ return 0;
4425+}
4426+
4427+static int timblogiw_enum_fmt(struct file *file, void *priv,
4428+ struct v4l2_fmtdesc *fmt)
4429+{
4430+ dbg("%s, index: %d\n", __func__, fmt->index);
4431+
4432+ if (fmt->index != 0)
4433+ return -EINVAL;
4434+ memset(fmt, 0, sizeof(*fmt));
4435+ fmt->index = 0;
4436+ fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
4437+ strncpy(fmt->description, "4:2:2, packed, YUYV",
4438+ sizeof(fmt->description)-1);
4439+ fmt->pixelformat = TIMBLOGIW_VIDEO_FORMAT;
4440+ memset(fmt->reserved, 0, sizeof(fmt->reserved));
4441+
4442+ return 0;
4443+}
4444+
4445+static int timblogiw_reqbufs(struct file *file, void *priv,
4446+ struct v4l2_requestbuffers *rb)
4447+{
4448+ struct video_device *vdev = video_devdata(file);
4449+ struct timblogiw *lw = video_get_drvdata(vdev);
4450+
4451+ dbg("%s\n", __func__);
4452+
4453+ if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
4454+ rb->memory != V4L2_MEMORY_MMAP)
4455+ return -EINVAL;
4456+
4457+ timblogiw_empty_framequeues(lw);
4458+
4459+ timblogiw_release_buffers(lw);
4460+ if (rb->count)
4461+ rb->count = timblogiw_request_buffers(lw, rb->count);
4462+
4463+ dbg("%s - VIDIOC_REQBUFS: io method is mmap. num bufs %i\n",
4464+ __func__, rb->count);
4465+
4466+ return 0;
4467+}
4468+
4469+static int timblogiw_querybuf(struct file *file, void *priv,
4470+ struct v4l2_buffer *b)
4471+{
4472+ struct video_device *vdev = video_devdata(file);
4473+ struct timblogiw *lw = video_get_drvdata(vdev);
4474+
4475+ dbg("%s\n", __func__);
4476+
4477+ if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
4478+ b->index >= lw->num_frames)
4479+ return -EINVAL;
4480+
4481+ memcpy(b, &lw->frame[b->index].buf, sizeof(*b));
4482+
4483+ if (lw->frame[b->index].vma_use_count)
4484+ b->flags |= V4L2_BUF_FLAG_MAPPED;
4485+
4486+ if (lw->frame[b->index].state == F_DONE)
4487+ b->flags |= V4L2_BUF_FLAG_DONE;
4488+ else if (lw->frame[b->index].state != F_UNUSED)
4489+ b->flags |= V4L2_BUF_FLAG_QUEUED;
4490+
4491+ return 0;
4492+}
4493+
4494+static int timblogiw_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
4495+{
4496+ struct video_device *vdev = video_devdata(file);
4497+ struct timblogiw *lw = video_get_drvdata(vdev);
4498+ unsigned long lock_flags;
4499+
4500+ if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
4501+ b->index >= lw->num_frames)
4502+ return -EINVAL;
4503+
4504+ if (lw->frame[b->index].state != F_UNUSED)
4505+ return -EAGAIN;
4506+
4507+ if (!lw->frame[b->index].bufmem)
4508+ return -EINVAL;
4509+
4510+ if (b->memory != V4L2_MEMORY_MMAP)
4511+ return -EINVAL;
4512+
4513+ lw->frame[b->index].state = F_QUEUED;
4514+
4515+ spin_lock_irqsave(&lw->queue_lock, lock_flags);
4516+ list_add_tail(&lw->frame[b->index].frame, &lw->inqueue);
4517+ spin_unlock_irqrestore(&lw->queue_lock, lock_flags);
4518+
4519+ return 0;
4520+}
4521+
4522+static int timblogiw_dqbuf(struct file *file, void *priv,
4523+ struct v4l2_buffer *b)
4524+{
4525+ struct video_device *vdev = video_devdata(file);
4526+ struct timblogiw *lw = video_get_drvdata(vdev);
4527+ struct timblogiw_frame *f;
4528+ unsigned long lock_flags;
4529+ int ret = 0;
4530+
4531+ if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
4532+ dbg("%s - VIDIOC_DQBUF, illegal buf type!\n",
4533+ __func__);
4534+ return -EINVAL;
4535+ }
4536+
4537+ if (list_empty(&lw->outqueue)) {
4538+ if (file->f_flags & O_NONBLOCK)
4539+ return -EAGAIN;
4540+
4541+ ret = wait_event_interruptible(lw->wait_frame,
4542+ !list_empty(&lw->outqueue));
4543+ if (ret)
4544+ return ret;
4545+ }
4546+
4547+ spin_lock_irqsave(&lw->queue_lock, lock_flags);
4548+ f = list_entry(lw->outqueue.next,
4549+ struct timblogiw_frame, frame);
4550+ list_del(lw->outqueue.next);
4551+ spin_unlock_irqrestore(&lw->queue_lock, lock_flags);
4552+
4553+ f->state = F_UNUSED;
4554+ memcpy(b, &f->buf, sizeof(*b));
4555+
4556+ if (f->vma_use_count)
4557+ b->flags |= V4L2_BUF_FLAG_MAPPED;
4558+
4559+ return 0;
4560+}
4561+
4562+static int timblogiw_g_std(struct file *file, void *priv, v4l2_std_id *std)
4563+{
4564+ struct video_device *vdev = video_devdata(file);
4565+ struct timblogiw *lw = video_get_drvdata(vdev);
4566+
4567+ dbg("%s\n", __func__);
4568+
4569+ *std = lw->cur_norm->std;
4570+ return 0;
4571+}
4572+
4573+static int timblogiw_s_std(struct file *file, void *priv, v4l2_std_id *std)
4574+{
4575+ struct video_device *vdev = video_devdata(file);
4576+ struct timblogiw *lw = video_get_drvdata(vdev);
4577+ int err;
4578+
4579+ dbg("%s\n", __func__);
4580+
4581+ err = v4l2_subdev_call(lw->sd_enc, core, s_std, *std);
4582+ if (!err)
4583+ lw->cur_norm = timblogiw_get_norm(*std);
4584+
4585+ return err;
4586+}
4587+
4588+static int timblogiw_enuminput(struct file *file, void *priv,
4589+ struct v4l2_input *inp)
4590+{
4591+ dbg("%s\n", __func__);
4592+
4593+ if (inp->index != 0)
4594+ return -EINVAL;
4595+
4596+ memset(inp, 0, sizeof(*inp));
4597+ inp->index = 0;
4598+
4599+ strncpy(inp->name, "Timb input 1", sizeof(inp->name) - 1);
4600+ inp->type = V4L2_INPUT_TYPE_CAMERA;
4601+ inp->std = V4L2_STD_ALL;
4602+
4603+ return 0;
4604+}
4605+
4606+static int timblogiw_g_input(struct file *file, void *priv,
4607+ unsigned int *input)
4608+{
4609+ dbg("%s\n", __func__);
4610+
4611+ *input = 0;
4612+
4613+ return 0;
4614+}
4615+
4616+static int timblogiw_s_input(struct file *file, void *priv, unsigned int input)
4617+{
4618+ dbg("%s\n", __func__);
4619+
4620+ if (input != 0)
4621+ return -EINVAL;
4622+ return 0;
4623+}
4624+
4625+static int timblogiw_streamon(struct file *file, void *priv, unsigned int type)
4626+{
4627+ struct video_device *vdev = video_devdata(file);
4628+ struct timblogiw *lw = video_get_drvdata(vdev);
4629+ struct timblogiw_frame *f;
4630+
4631+ dbg("%s\n", __func__);
4632+
4633+ if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
4634+ dbg("%s - No capture device\n", __func__);
4635+ return -EINVAL;
4636+ }
4637+
4638+ if (list_empty(&lw->inqueue)) {
4639+ dbg("%s - inqueue is empty\n", __func__);
4640+ return -EINVAL;
4641+ }
4642+
4643+ if (lw->stream == STREAM_ON)
4644+ return 0;
4645+
4646+ lw->stream = STREAM_ON;
4647+
4648+ f = list_entry(lw->inqueue.next,
4649+ struct timblogiw_frame, frame);
4650+
4651+ dbg("%s - f size: %d, bpr: %d, dma addr: %x\n", __func__,
4652+ timblogiw_frame_size(lw->cur_norm),
4653+ timblogiw_bytes_per_line(lw->cur_norm),
4654+ (unsigned int)lw->dma.transfer[lw->dma.curr].handle);
4655+
4656+ __timblogiw_start_dma(lw);
4657+
4658+ return 0;
4659+}
4660+
4661+static void timblogiw_stopstream(struct timblogiw *lw)
4662+{
4663+ if (lw->stream == STREAM_ON) {
4664+ /* The FPGA might be busy copying the current frame, we have
4665+ * to wait for the frame to finish
4666+ */
4667+ unsigned long lock_flags;
4668+
4669+ init_completion(&lw->irq_done);
4670+
4671+ spin_lock_irqsave(&lw->queue_lock, lock_flags);
4672+ lw->stream = STREAM_OFF;
4673+ spin_unlock_irqrestore(&lw->queue_lock, lock_flags);
4674+
4675+ wait_for_completion_timeout(&lw->irq_done,
4676+ msecs_to_jiffies(100));
4677+ }
4678+}
4679+
4680+static int timblogiw_streamoff(struct file *file, void *priv,
4681+ unsigned int type)
4682+{
4683+ struct video_device *vdev = video_devdata(file);
4684+ struct timblogiw *lw = video_get_drvdata(vdev);
4685+
4686+ dbg("%s\n", __func__);
4687+
4688+ if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
4689+ return -EINVAL;
4690+
4691+ timblogiw_stopstream(lw);
4692+
4693+ timblogiw_empty_framequeues(lw);
4694+
4695+ return 0;
4696+}
4697+
4698+static int timblogiw_querystd(struct file *file, void *priv, v4l2_std_id *std)
4699+{
4700+ struct video_device *vdev = video_devdata(file);
4701+ struct timblogiw *lw = video_get_drvdata(vdev);
4702+
4703+ dbg("%s\n", __func__);
4704+
4705+ return v4l2_subdev_call(lw->sd_enc, video, querystd, std);
4706+}
4707+
4708+static int timblogiw_enum_framesizes(struct file *file, void *priv,
4709+ struct v4l2_frmsizeenum *fsize)
4710+{
4711+ struct video_device *vdev = video_devdata(file);
4712+ struct timblogiw *lw = video_get_drvdata(vdev);
4713+
4714+ dbg("%s - index: %d, format: %d\n", __func__,
4715+ fsize->index, fsize->pixel_format);
4716+
4717+ if ((fsize->index != 0) ||
4718+ (fsize->pixel_format != TIMBLOGIW_VIDEO_FORMAT))
4719+ return -EINVAL;
4720+
4721+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
4722+ fsize->discrete.width = lw->cur_norm->width;
4723+ fsize->discrete.height = lw->cur_norm->height;
4724+
4725+ return 0;
4726+}
4727+
4728+struct find_addr_arg {
4729+ char const *name;
4730+ struct i2c_client *client;
4731+};
4732+
4733+static int find_name(struct device *dev, void *argp)
4734+{
4735+ struct find_addr_arg *arg = (struct find_addr_arg *)argp;
4736+ struct i2c_client *client = i2c_verify_client(dev);
4737+
4738+ if (client && !strcmp(arg->name, client->name) && client->driver)
4739+ arg->client = client;
4740+
4741+ return 0;
4742+}
4743+
4744+static struct i2c_client *find_client(struct i2c_adapter *adapt,
4745+ const char *name)
4746+{
4747+ struct find_addr_arg find_arg;
4748+ /* now find the client */
4749+#ifdef MODULE
4750+ request_module(name);
4751+#endif
4752+ /* code for finding the I2C child */
4753+ find_arg.name = name;
4754+ find_arg.client = NULL;
4755+ device_for_each_child(&adapt->dev, &find_arg, find_name);
4756+ return find_arg.client;
4757+}
4758+
4759+/*******************************
4760+ * Device Operations functions *
4761+ *******************************/
4762+
4763+static int timblogiw_open(struct file *file)
4764+{
4765+ struct video_device *vdev = video_devdata(file);
4766+ struct timblogiw *lw = video_get_drvdata(vdev);
4767+ v4l2_std_id std = V4L2_STD_UNKNOWN;
4768+ int err = 0;
4769+
4770+ dbg("%s -\n", __func__);
4771+
4772+ mutex_init(&lw->fileop_lock);
4773+ spin_lock_init(&lw->queue_lock);
4774+ init_waitqueue_head(&lw->wait_frame);
4775+
4776+ mutex_lock(&lw->lock);
4777+
4778+ if (!lw->sd_enc) {
4779+ struct i2c_adapter *adapt;
4780+ struct i2c_client *encoder;
4781+
4782+ /* find the video decoder */
4783+ adapt = i2c_get_adapter(lw->pdata.i2c_adapter);
4784+ if (!adapt) {
4785+ printk(KERN_ERR DRIVER_NAME": No I2C bus\n");
4786+ err = -ENODEV;
4787+ goto out;
4788+ }
4789+
4790+ /* now find the encoder */
4791+ encoder = find_client(adapt, lw->pdata.encoder);
4792+
4793+ i2c_put_adapter(adapt);
4794+
4795+ if (!encoder) {
4796+ printk(KERN_ERR DRIVER_NAME": Failed to get encoder\n");
4797+ err = -ENODEV;
4798+ goto out;
4799+ }
4800+
4801+ lw->sd_enc = i2c_get_clientdata(encoder);
4802+ lw->enc_owner = lw->sd_enc->owner;
4803+ /* Lock the module */
4804+ if (!try_module_get(lw->enc_owner)) {
4805+ lw->sd_enc = NULL;
4806+ err = -ENODEV;
4807+ goto out;
4808+ }
4809+ }
4810+
4811+ timblogiw_querystd(file, NULL, &std);
4812+ lw->cur_norm = timblogiw_get_norm(std);
4813+
4814+ file->private_data = lw;
4815+ lw->stream = STREAM_OFF;
4816+ lw->num_frames = TIMBLOGIW_NUM_FRAMES;
4817+
4818+ timblogiw_empty_framequeues(lw);
4819+ timbdma_set_interruptcb(DMA_IRQ_VIDEO_RX | DMA_IRQ_VIDEO_DROP,
4820+ timblogiw_isr, (void *)lw);
4821+
4822+out:
4823+ mutex_unlock(&lw->lock);
4824+
4825+ return err;
4826+}
4827+
4828+static int timblogiw_close(struct file *file)
4829+{
4830+ struct timblogiw *lw = file->private_data;
4831+
4832+ dbg("%s - entry\n", __func__);
4833+
4834+ mutex_lock(&lw->lock);
4835+
4836+ timblogiw_stopstream(lw);
4837+
4838+ timbdma_set_interruptcb(DMA_IRQ_VIDEO_RX | DMA_IRQ_VIDEO_DROP, NULL,
4839+ NULL);
4840+ timblogiw_release_buffers(lw);
4841+
4842+ mutex_unlock(&lw->lock);
4843+ return 0;
4844+}
4845+
4846+static ssize_t timblogiw_read(struct file *file, char __user *data,
4847+ size_t count, loff_t *ppos)
4848+{
4849+ dbg("%s - read request\n", __func__);
4850+ return -EINVAL;
4851+}
4852+
4853+static void timblogiw_vm_open(struct vm_area_struct *vma)
4854+{
4855+ struct timblogiw_frame *f = vma->vm_private_data;
4856+ f->vma_use_count++;
4857+}
4858+
4859+static void timblogiw_vm_close(struct vm_area_struct *vma)
4860+{
4861+ struct timblogiw_frame *f = vma->vm_private_data;
4862+ f->vma_use_count--;
4863+}
4864+
4865+static struct vm_operations_struct timblogiw_vm_ops = {
4866+ .open = timblogiw_vm_open,
4867+ .close = timblogiw_vm_close,
4868+};
4869+
4870+static int timblogiw_mmap(struct file *filp, struct vm_area_struct *vma)
4871+{
4872+ unsigned long size = vma->vm_end - vma->vm_start, start = vma->vm_start;
4873+ void *pos;
4874+ u32 i;
4875+ int ret = -EINVAL;
4876+
4877+ struct timblogiw *lw = filp->private_data;
4878+ dbg("%s\n", __func__);
4879+
4880+ if (mutex_lock_interruptible(&lw->fileop_lock))
4881+ return -ERESTARTSYS;
4882+
4883+ if (!(vma->vm_flags & VM_WRITE) ||
4884+ size != PAGE_ALIGN(lw->frame[0].buf.length))
4885+ goto error_unlock;
4886+
4887+ for (i = 0; i < lw->num_frames; i++)
4888+ if ((lw->frame[i].buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
4889+ break;
4890+
4891+ if (i == lw->num_frames) {
4892+ dbg("%s - user supplied mapping address is out of range\n",
4893+ __func__);
4894+ goto error_unlock;
4895+ }
4896+
4897+ vma->vm_flags |= VM_IO;
4898+ vma->vm_flags |= VM_RESERVED; /* Do not swap out this VMA */
4899+
4900+ pos = lw->frame[i].bufmem;
4901+ while (size > 0) { /* size is page-aligned */
4902+ if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
4903+ dbg("%s - vm_insert_page failed\n", __func__);
4904+ ret = -EAGAIN;
4905+ goto error_unlock;
4906+ }
4907+ start += PAGE_SIZE;
4908+ pos += PAGE_SIZE;
4909+ size -= PAGE_SIZE;
4910+ }
4911+
4912+ vma->vm_ops = &timblogiw_vm_ops;
4913+ vma->vm_private_data = &lw->frame[i];
4914+ timblogiw_vm_open(vma);
4915+ ret = 0;
4916+
4917+error_unlock:
4918+ mutex_unlock(&lw->fileop_lock);
4919+ return ret;
4920+}
4921+
4922+
4923+void timblogiw_vdev_release(struct video_device *vdev)
4924+{
4925+ kfree(vdev);
4926+}
4927+
4928+static const struct v4l2_ioctl_ops timblogiw_ioctl_ops = {
4929+ .vidioc_querycap = timblogiw_querycap,
4930+ .vidioc_enum_fmt_vid_cap = timblogiw_enum_fmt,
4931+ .vidioc_g_fmt_vid_cap = timblogiw_g_fmt,
4932+ .vidioc_try_fmt_vid_cap = timblogiw_try_fmt,
4933+ .vidioc_s_fmt_vid_cap = timblogiw_try_fmt,
4934+ .vidioc_reqbufs = timblogiw_reqbufs,
4935+ .vidioc_querybuf = timblogiw_querybuf,
4936+ .vidioc_qbuf = timblogiw_qbuf,
4937+ .vidioc_dqbuf = timblogiw_dqbuf,
4938+ .vidioc_g_std = timblogiw_g_std,
4939+ .vidioc_s_std = timblogiw_s_std,
4940+ .vidioc_enum_input = timblogiw_enuminput,
4941+ .vidioc_g_input = timblogiw_g_input,
4942+ .vidioc_s_input = timblogiw_s_input,
4943+ .vidioc_streamon = timblogiw_streamon,
4944+ .vidioc_streamoff = timblogiw_streamoff,
4945+ .vidioc_querystd = timblogiw_querystd,
4946+ .vidioc_enum_framesizes = timblogiw_enum_framesizes,
4947+};
4948+
4949+static const struct v4l2_file_operations timblogiw_fops = {
4950+ .owner = THIS_MODULE,
4951+ .open = timblogiw_open,
4952+ .release = timblogiw_close,
4953+ .ioctl = video_ioctl2, /* V4L2 ioctl handler */
4954+ .mmap = timblogiw_mmap,
4955+ .read = timblogiw_read,
4956+};
4957+
4958+static const struct video_device timblogiw_template = {
4959+ .name = TIMBLOGIWIN_NAME,
4960+ .fops = &timblogiw_fops,
4961+ .ioctl_ops = &timblogiw_ioctl_ops,
4962+ .release = &timblogiw_vdev_release,
4963+ .minor = -1,
4964+ .tvnorms = V4L2_STD_PAL | V4L2_STD_NTSC
4965+};
4966+
4967+static int timblogiw_probe(struct platform_device *dev)
4968+{
4969+ int err;
4970+ struct timblogiw *lw = NULL;
4971+ struct resource *iomem;
4972+ struct timb_video_platform_data *pdata = dev->dev.platform_data;
4973+
4974+ if (!pdata) {
4975+ printk(KERN_ERR DRIVER_NAME": Platform data missing\n");
4976+ err = -EINVAL;
4977+ goto err_mem;
4978+ }
4979+
4980+ iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
4981+ if (!iomem) {
4982+ err = -EINVAL;
4983+ goto err_mem;
4984+ }
4985+
4986+ lw = kzalloc(sizeof(*lw), GFP_KERNEL);
4987+ if (!lw) {
4988+ err = -ENOMEM;
4989+ goto err_mem;
4990+ }
4991+
4992+ if (dev->dev.parent)
4993+ lw->dev = dev->dev.parent;
4994+ else
4995+ lw->dev = &dev->dev;
4996+
4997+ memcpy(&lw->pdata, pdata, sizeof(lw->pdata));
4998+
4999+ mutex_init(&lw->lock);
5000+
5001+ lw->video_dev = video_device_alloc();
5002+ if (!lw->video_dev) {
5003+ err = -ENOMEM;
5004+ goto err_mem;
5005+ }
5006+ *lw->video_dev = timblogiw_template;
5007+
5008+ err = video_register_device(lw->video_dev, VFL_TYPE_GRABBER, 0);
5009+ if (err) {
5010+ printk(KERN_ALERT DRIVER_NAME": Error reg video\n");
5011+ goto err_request;
5012+ }
5013+
5014+ tasklet_init(&lw->tasklet, timblogiw_handleframe, (unsigned long)lw);
5015+
5016+ if (!request_mem_region(iomem->start, resource_size(iomem),
5017+ DRIVER_NAME)) {
5018+ err = -EBUSY;
5019+ goto err_request;
5020+ }
5021+
5022+ lw->membase = ioremap(iomem->start, resource_size(iomem));
5023+ if (!lw->membase) {
5024+ err = -ENOMEM;
5025+ goto err_ioremap;
5026+ }
5027+
5028+ platform_set_drvdata(dev, lw);
5029+ video_set_drvdata(lw->video_dev, lw);
5030+
5031+ return 0;
5032+
5033+err_ioremap:
5034+ release_mem_region(iomem->start, resource_size(iomem));
5035+err_request:
5036+ if (-1 != lw->video_dev->minor)
5037+ video_unregister_device(lw->video_dev);
5038+ else
5039+ video_device_release(lw->video_dev);
5040+err_mem:
5041+ kfree(lw);
5042+ printk(KERN_ERR DRIVER_NAME ": Failed to register: %d\n", err);
5043+
5044+ return err;
5045+}
5046+
5047+static int timblogiw_remove(struct platform_device *dev)
5048+{
5049+ struct timblogiw *lw = platform_get_drvdata(dev);
5050+ struct resource *iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
5051+
5052+ if (-1 != lw->video_dev->minor)
5053+ video_unregister_device(lw->video_dev);
5054+ else
5055+ video_device_release(lw->video_dev);
5056+
5057+ if (lw->sd_enc)
5058+ module_put(lw->enc_owner);
5059+ tasklet_kill(&lw->tasklet);
5060+ iounmap(lw->membase);
5061+ release_mem_region(iomem->start, resource_size(iomem));
5062+ kfree(lw);
5063+
5064+ return 0;
5065+}
5066+
5067+static struct platform_driver timblogiw_platform_driver = {
5068+ .driver = {
5069+ .name = DRIVER_NAME,
5070+ .owner = THIS_MODULE,
5071+ },
5072+ .probe = timblogiw_probe,
5073+ .remove = timblogiw_remove,
5074+};
5075+
5076+/*--------------------------------------------------------------------------*/
5077+
5078+static int __init timblogiw_init(void)
5079+{
5080+ return platform_driver_register(&timblogiw_platform_driver);
5081+}
5082+
5083+static void __exit timblogiw_exit(void)
5084+{
5085+ platform_driver_unregister(&timblogiw_platform_driver);
5086+}
5087+
5088+module_init(timblogiw_init);
5089+module_exit(timblogiw_exit);
5090+
5091+MODULE_DESCRIPTION("Timberdale Video In driver");
5092+MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
5093+MODULE_LICENSE("GPL v2");
5094+MODULE_ALIAS("platform:"DRIVER_NAME);
5095+
5096diff -uNr linux-2.6.31/drivers/media/video/timblogiw.h linux-2.6.31.new/drivers/media/video/timblogiw.h
5097--- linux-2.6.31/drivers/media/video/timblogiw.h 1969-12-31 16:00:00.000000000 -0800
5098+++ linux-2.6.31.new/drivers/media/video/timblogiw.h 2009-10-23 11:17:28.000000000 -0700
5099@@ -0,0 +1,96 @@
5100+/*
5101+ * timblogiw.h timberdale FPGA LogiWin Video In driver defines
5102+ * Copyright (c) 2009 Intel Corporation
5103+ *
5104+ * This program is free software; you can redistribute it and/or modify
5105+ * it under the terms of the GNU General Public License version 2 as
5106+ * published by the Free Software Foundation.
5107+ *
5108+ * This program is distributed in the hope that it will be useful,
5109+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5110+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5111+ * GNU General Public License for more details.
5112+ *
5113+ * You should have received a copy of the GNU General Public License
5114+ * along with this program; if not, write to the Free Software
5115+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
5116+ */
5117+
5118+/* Supports:
5119+ * Timberdale FPGA LogiWin Video In
5120+ */
5121+
5122+#ifndef _TIMBLOGIW_H
5123+#define _TIMBLOGIW_H
5124+
5125+#include <linux/interrupt.h>
5126+#include <media/timb_video.h>
5127+#include <linux/completion.h>
5128+
5129+#define TIMBLOGIWIN_NAME "Timberdale Video-In"
5130+
5131+#define TIMBLOGIW_NUM_FRAMES 10
5132+
5133+
5134+enum timblogiw_stream_state {
5135+ STREAM_OFF,
5136+ STREAM_ON,
5137+};
5138+
5139+enum timblogiw_frame_state {
5140+ F_UNUSED = 0,
5141+ F_QUEUED,
5142+ F_DONE,
5143+};
5144+
5145+struct timblogiw_frame {
5146+ void *bufmem;
5147+ struct v4l2_buffer buf;
5148+ enum timblogiw_frame_state state;
5149+ struct list_head frame;
5150+ unsigned long vma_use_count;
5151+};
5152+
5153+struct timblogiw_tvnorm {
5154+ v4l2_std_id std;
5155+ u16 width;
5156+ u16 height;
5157+};
5158+
5159+
5160+
5161+struct timbdma_transfer {
5162+ dma_addr_t handle;
5163+ void *buf;
5164+ void *desc;
5165+};
5166+
5167+struct timblogiw_dma_control {
5168+ struct timbdma_transfer transfer[2];
5169+ struct timbdma_transfer *filled;
5170+ int curr;
5171+};
5172+
5173+struct timblogiw {
5174+ struct timblogiw_frame frame[TIMBLOGIW_NUM_FRAMES];
5175+ int num_frames;
5176+ unsigned int frame_count;
5177+ struct list_head inqueue, outqueue;
5178+ spinlock_t queue_lock; /* mutual exclusion */
5179+ enum timblogiw_stream_state stream;
5180+ struct video_device *video_dev;
5181+ struct mutex lock, fileop_lock;
5182+ wait_queue_head_t wait_frame;
5183+ struct completion irq_done;
5184+ struct timblogiw_tvnorm const *cur_norm;
5185+ struct device *dev;
5186+ struct timblogiw_dma_control dma;
5187+ void __iomem *membase;
5188+ struct tasklet_struct tasklet;
5189+ struct timb_video_platform_data pdata;
5190+ struct v4l2_subdev *sd_enc; /* encoder */
5191+ struct module *enc_owner;
5192+};
5193+
5194+#endif /* _TIMBLOGIW_H */
5195+
5196diff -uNr linux-2.6.31/drivers/mfd/Kconfig linux-2.6.31.new/drivers/mfd/Kconfig
5197--- linux-2.6.31/drivers/mfd/Kconfig 2009-10-23 11:18:30.000000000 -0700
5198+++ linux-2.6.31.new/drivers/mfd/Kconfig 2009-10-23 11:17:29.000000000 -0700
5199@@ -263,6 +263,25 @@
5200 This enables the PCAP ASIC present on EZX Phones. This is
5201 needed for MMC, TouchScreen, Sound, USB, etc..
5202
5203+config MFD_TIMBERDALE
5204+ tristate "Support for the Timberdale FPGA"
5205+ select MFD_CORE
5206+ depends on PCI
5207+ ---help---
5208+ This is the core driver for the timberdale FPGA. This device is a
5209+ multifunctioanl device which may provide numerous interfaces.
5210+
5211+ The timberdale FPGA can be found on the Intel Atom development board
5212+ for automotive in-vehicle infontainment board called Russellville.
5213+
5214+config MFD_TIMBERDALE_DMA
5215+ tristate "Support for timberdale DMA"
5216+ depends on MFD_TIMBERDALE
5217+ depends on HAS_IOMEM
5218+ ---help---
5219+ Add support the DMA block inside the timberdale FPGA. This to be able
5220+ to do DMA transfers directly to some of the blocks inside the FPGA
5221+
5222 endmenu
5223
5224 menu "Multimedia Capabilities Port drivers"
5225diff -uNr linux-2.6.31/drivers/mfd/Makefile linux-2.6.31.new/drivers/mfd/Makefile
5226--- linux-2.6.31/drivers/mfd/Makefile 2009-10-23 11:18:30.000000000 -0700
5227+++ linux-2.6.31.new/drivers/mfd/Makefile 2009-10-23 11:17:29.000000000 -0700
5228@@ -44,3 +44,7 @@
5229 obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o
5230 obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o
5231 obj-$(CONFIG_AB3100_CORE) += ab3100-core.o
5232+
5233+obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o
5234+obj-$(CONFIG_MFD_TIMBERDALE_DMA) += timbdma.o
5235+
5236diff -uNr linux-2.6.31/drivers/mfd/timbdma.c linux-2.6.31.new/drivers/mfd/timbdma.c
5237--- linux-2.6.31/drivers/mfd/timbdma.c 1969-12-31 16:00:00.000000000 -0800
5238+++ linux-2.6.31.new/drivers/mfd/timbdma.c 2009-10-23 11:17:29.000000000 -0700
5239@@ -0,0 +1,542 @@
5240+/*
5241+ * timbdma.c timberdale FPGA DMA driver
5242+ * Copyright (c) 2009 Intel Corporation
5243+ *
5244+ * This program is free software; you can redistribute it and/or modify
5245+ * it under the terms of the GNU General Public License version 2 as
5246+ * published by the Free Software Foundation.
5247+ *
5248+ * This program is distributed in the hope that it will be useful,
5249+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5250+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5251+ * GNU General Public License for more details.
5252+ *
5253+ * You should have received a copy of the GNU General Public License
5254+ * along with this program; if not, write to the Free Software
5255+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
5256+ */
5257+
5258+/* Supports:
5259+ * Timberdale FPGA DMA engine
5260+ */
5261+
5262+#include <linux/version.h>
5263+#include <linux/module.h>
5264+#include <linux/interrupt.h>
5265+#include <linux/platform_device.h>
5266+#include <linux/io-mapping.h>
5267+#include <linux/dma-mapping.h>
5268+#include <linux/mfd/timbdma.h>
5269+
5270+#define DRIVER_NAME "timb-dma"
5271+
5272+#define TIMBDMA_ACR 0x34
5273+#define TIMBDMA_32BIT_ADDR 0x01
5274+
5275+#define TIMBDMA_ISR 0x080000
5276+#define TIMBDMA_IPR 0x080004
5277+#define TIMBDMA_IER 0x080008
5278+
5279+/* DMA configuration registers */
5280+/* RX registers */
5281+#define TIMBDMA_OFFS_RX_DHAR 0x00
5282+#define TIMBDMA_OFFS_RX_DLAR 0x04
5283+#define TIMBDMA_OFFS_RX_LR 0x0C
5284+#define TIMBDMA_OFFS_RX_BLR 0x10
5285+#define TIMBDMA_OFFS_RX_ER 0x14
5286+#define TIMBDMA_RX_EN 0x01
5287+/* bytes per Row, video specific register */
5288+#define TIMBDMA_OFFS_RX_BPRR 0x30
5289+
5290+/* TX registers */
5291+#define TIMBDMA_OFFS_TX_DHAR 0x18
5292+#define TIMBDMA_OFFS_TX_DLAR 0x1C
5293+#define TIMBDMA_OFFS_TX_BLR 0x24
5294+#define TIMBDMA_OFFS_TX_LR 0x28
5295+
5296+#define DMA_DESC_SIZE 8
5297+
5298+struct dma_desc {
5299+ u32 len;
5300+ u32 chunk_size;
5301+ u8 buf[0];
5302+};
5303+
5304+struct timbdma_control {
5305+ timbdma_interruptcb callback;
5306+ void *callback_data;
5307+ dma_addr_t desc;
5308+ int desc_len;
5309+ /* the following are used to store a desc while the hw has not been
5310+ * probed yet
5311+ */
5312+ struct dma_desc *stored_desc;
5313+ int stored_bytes_per_row;
5314+};
5315+
5316+struct timbdma_dev {
5317+ void __iomem *membase;
5318+ struct device *dev;
5319+ struct timbdma_control control[DMA_IRQS];
5320+ spinlock_t lock; /* mutual exclusion */
5321+};
5322+
5323+static struct timbdma_dev *self_g;
5324+
5325+
5326+void *timbdma_alloc_desc(u32 size, u16 alignment)
5327+{
5328+ /* calculate the number of chunks needed */
5329+ int chunk_size = USHORT_MAX - (USHORT_MAX % alignment);
5330+ int chunks = size / chunk_size;
5331+ int len;
5332+ struct dma_desc *dma_desc;
5333+
5334+ if (size % chunk_size)
5335+ chunks++;
5336+
5337+ len = sizeof(struct dma_desc) + DMA_DESC_SIZE * chunks;
5338+
5339+ dma_desc = kzalloc(len, GFP_KERNEL);
5340+ if (dma_desc) {
5341+ dma_desc->len = DMA_DESC_SIZE * chunks;
5342+ dma_desc->chunk_size = chunk_size;
5343+ }
5344+ return dma_desc;
5345+}
5346+EXPORT_SYMBOL(timbdma_alloc_desc);
5347+
5348+void timbdma_free_desc(void *desc)
5349+{
5350+ kfree(desc);
5351+}
5352+EXPORT_SYMBOL(timbdma_free_desc);
5353+
5354+int timbdma_prep_desc(void *desc, dma_addr_t addr, u32 size)
5355+{
5356+ struct dma_desc *dma_desc = desc;
5357+ u8 *buf = dma_desc->buf;
5358+ dma_addr_t cur_addr = addr;
5359+ int chunks = size / dma_desc->chunk_size;
5360+ if (size % dma_desc->chunk_size)
5361+ chunks++;
5362+
5363+ if (dma_desc->len < chunks * DMA_DESC_SIZE)
5364+ return -EINVAL;
5365+
5366+ while (size > 0) {
5367+ int chunk_size = dma_desc->chunk_size;
5368+ if (chunk_size > size)
5369+ chunk_size = size;
5370+ buf[7] = (cur_addr >> 24) & 0xff;
5371+ buf[6] = (cur_addr >> 16) & 0xff;
5372+ buf[5] = (cur_addr >> 8) & 0xff;
5373+ buf[4] = (cur_addr >> 0) & 0xff;
5374+
5375+ buf[3] = (chunk_size >> 8) & 0xff;
5376+ buf[2] = (chunk_size >> 0) & 0xff;
5377+
5378+ buf[1] = 0x00;
5379+ buf[0] = 0x21; /* tran, valid */
5380+
5381+ buf += DMA_DESC_SIZE;
5382+ cur_addr += chunk_size;
5383+ size -= chunk_size;
5384+ }
5385+
5386+ /* make sure to mark the last one as end */
5387+ (buf-DMA_DESC_SIZE)[0] |= 0x2;
5388+
5389+ return 0;
5390+}
5391+EXPORT_SYMBOL(timbdma_prep_desc);
5392+
5393+static irqreturn_t timbdma_handleinterrupt(int irq, void *devid)
5394+{
5395+ struct timbdma_dev *dev = (struct timbdma_dev *)devid;
5396+ u32 ipr, ier;
5397+ int i;
5398+
5399+ ipr = ioread32(dev->membase + TIMBDMA_IPR);
5400+ /* the MSI-X controller is level triggered, help it a bit,
5401+ * by disabling interrupts and re-enable them in the end.
5402+ */
5403+ ier = ioread32(dev->membase + TIMBDMA_IER);
5404+ iowrite32(0, dev->membase + TIMBDMA_IER);
5405+
5406+ if (ipr) {
5407+ /* ack */
5408+ iowrite32(ipr, dev->membase + TIMBDMA_ISR);
5409+
5410+ /* call the callbacks */
5411+ for (i = 0; i < DMA_IRQS; i++) {
5412+ int mask = 1 << i;
5413+ if (ipr & mask) {
5414+ struct timbdma_control *ctrl = dev->control + i;
5415+ struct timbdma_control *unmap_ctrl = ctrl;
5416+
5417+ /* special case for video frame drop */
5418+ if (mask == DMA_IRQ_VIDEO_DROP)
5419+ unmap_ctrl = dev->control + i - 1;
5420+
5421+ /* unmap memory */
5422+ dma_unmap_single(dev->dev, unmap_ctrl->desc,
5423+ unmap_ctrl->desc_len, DMA_TO_DEVICE);
5424+ unmap_ctrl->desc = 0;
5425+
5426+ if (ctrl->callback)
5427+ ctrl->callback(mask,
5428+ ctrl->callback_data);
5429+ }
5430+ }
5431+
5432+ iowrite32(ier, dev->membase + TIMBDMA_IER);
5433+ return IRQ_HANDLED;
5434+ } else {
5435+ iowrite32(ier, dev->membase + TIMBDMA_IER);
5436+ return IRQ_NONE;
5437+ }
5438+}
5439+
5440+static int __timbdma_start(struct timbdma_dev *dev, int index,
5441+ struct dma_desc *dma_desc, int bytes_per_row)
5442+{
5443+ u32 offset;
5444+ unsigned long flags;
5445+ struct timbdma_control *ctrl;
5446+ int err;
5447+
5448+ ctrl = dev->control + index;
5449+
5450+ BUG_ON(ctrl->desc);
5451+
5452+ /* check if we already have a descriptor */
5453+ if (ctrl->desc)
5454+ return -EALREADY;
5455+
5456+ /* map up the descriptor */
5457+ ctrl->desc = dma_map_single(dev->dev, dma_desc->buf, dma_desc->len,
5458+ DMA_TO_DEVICE);
5459+ err = dma_mapping_error(dev->dev, ctrl->desc);
5460+ if (err) {
5461+ ctrl->desc = 0;
5462+ return err;
5463+ }
5464+ ctrl->desc_len = dma_desc->len;
5465+
5466+ /* now enable the DMA transfer */
5467+ offset = index / 2 * 0x40;
5468+
5469+ spin_lock_irqsave(&dev->lock, flags);
5470+ if (!(index % 2)) {
5471+ /* RX */
5472+ /* descriptor address */
5473+ iowrite32(0, dev->membase + offset + TIMBDMA_OFFS_RX_DHAR);
5474+ iowrite32(ctrl->desc, dev->membase + offset +
5475+ TIMBDMA_OFFS_RX_DLAR);
5476+ /* Bytes per line */
5477+ iowrite32(bytes_per_row, dev->membase + offset +
5478+ TIMBDMA_OFFS_RX_BPRR);
5479+ /* enable RX */
5480+ iowrite32(TIMBDMA_RX_EN, dev->membase + offset +
5481+ TIMBDMA_OFFS_RX_ER);
5482+ } else {
5483+ /* TX */
5484+ /* address high */
5485+ iowrite32(0, dev->membase + offset + TIMBDMA_OFFS_TX_DHAR);
5486+ iowrite32(ctrl->desc, dev->membase + offset +
5487+ TIMBDMA_OFFS_TX_DLAR);
5488+ }
5489+ spin_unlock_irqrestore(&dev->lock, flags);
5490+
5491+ return 0;
5492+}
5493+int timbdma_start(u32 flag, void *desc, int bytes_per_row)
5494+{
5495+ int i;
5496+ struct timbdma_dev *dev = self_g;
5497+ struct dma_desc *dma_desc = desc;
5498+ int ret = 0;
5499+
5500+ /* only allow 1 flag bit to be set */
5501+ for (i = 0; i < DMA_IRQS && !(flag & (1 << i)); i++)
5502+ ;
5503+ if (i == DMA_IRQS || (flag & ~(1 << i)))
5504+ return -EINVAL;
5505+
5506+ if (!dev->membase) {
5507+ /* the physical DMA device has not showed up yet */
5508+ unsigned long flags;
5509+ struct timbdma_control *ctrl = dev->control + i;
5510+ BUG_ON(ctrl->stored_desc);
5511+ if (ctrl->stored_desc)
5512+ ret = -EALREADY;
5513+ else {
5514+ spin_lock_irqsave(&dev->lock, flags);
5515+ ctrl->stored_desc = desc;
5516+ ctrl->stored_bytes_per_row = bytes_per_row;
5517+ spin_unlock_irqrestore(&dev->lock, flags);
5518+ }
5519+ } else
5520+ ret = __timbdma_start(dev, i, dma_desc, bytes_per_row);
5521+
5522+ if (ret)
5523+ printk(KERN_ERR DRIVER_NAME": Failed to start DMA: %d\n", ret);
5524+ return ret;
5525+}
5526+EXPORT_SYMBOL(timbdma_start);
5527+
5528+int timbdma_stop(u32 flags)
5529+{
5530+ int i;
5531+ unsigned long irqflags;
5532+ struct timbdma_dev *dev = self_g;
5533+ int ret = 0;
5534+
5535+ spin_lock_irqsave(&dev->lock, irqflags);
5536+
5537+ /* now disable the DMA transfers */
5538+ for (i = 0; i < DMA_IRQS; i++)
5539+ if (flags & (1 << i)) {
5540+ /*
5541+ RX enable registers are located at:
5542+ 0x14
5543+ 0x54
5544+ 0x94
5545+
5546+ TX DESC ADDR LOW registers are located at:
5547+ 0x1C
5548+ 0x5C
5549+ */
5550+ struct timbdma_control *ctrl = dev->control + i;
5551+ if (ctrl->desc) {
5552+ u32 offset = i / 2 * 0x40;
5553+
5554+ if (!(i % 2)) {
5555+ /* even -> RX enable */
5556+ offset += TIMBDMA_OFFS_RX_ER;
5557+ /** TODO: FIX received length */
5558+ } else {
5559+ /* odd -> TX desc addr low */
5560+ offset += TIMBDMA_OFFS_TX_DLAR;
5561+ /** TODO: FIX written lenth */
5562+ }
5563+
5564+ if (dev->membase)
5565+ iowrite32(0, dev->membase + offset);
5566+
5567+ dma_unmap_single(dev->dev, ctrl->desc,
5568+ ctrl->desc_len, DMA_TO_DEVICE);
5569+ ctrl->desc = 0;
5570+ } else if (ctrl->stored_desc)
5571+ ctrl->stored_desc = NULL;
5572+ }
5573+
5574+ if (dev->membase)
5575+ /* ack any pending IRQs */
5576+ iowrite32(flags, dev->membase + TIMBDMA_ISR);
5577+
5578+ spin_unlock_irqrestore(&dev->lock, irqflags);
5579+
5580+ return ret;
5581+}
5582+EXPORT_SYMBOL(timbdma_stop);
5583+
5584+void timbdma_set_interruptcb(u32 flags, timbdma_interruptcb icb, void *data)
5585+{
5586+ int i;
5587+ unsigned long irqflags;
5588+ struct timbdma_dev *dev = self_g;
5589+ u32 ier;
5590+
5591+ spin_lock_irqsave(&dev->lock, irqflags);
5592+
5593+ for (i = 0; i < DMA_IRQS; i++)
5594+ if (flags & (1 << i)) {
5595+ struct timbdma_control *ctrl = dev->control + i;
5596+ ctrl->callback = icb;
5597+ ctrl->callback_data = data;
5598+ }
5599+
5600+ /* the DMA device might not have showed up yet */
5601+ if (dev->membase) {
5602+ /* Ack any pending IRQ */
5603+ iowrite32(flags, dev->membase + TIMBDMA_ISR);
5604+
5605+ /* if a null callback is given -> clear interrupt,
5606+ * else -> enable
5607+ */
5608+ ier = ioread32(dev->membase + TIMBDMA_IER);
5609+ if (icb != NULL)
5610+ ier |= flags;
5611+ else
5612+ ier &= ~flags;
5613+ iowrite32(ier, dev->membase + TIMBDMA_IER);
5614+ }
5615+
5616+ spin_unlock_irqrestore(&dev->lock, irqflags);
5617+}
5618+EXPORT_SYMBOL(timbdma_set_interruptcb);
5619+
5620+static void timbdma_start_operations(struct timbdma_dev *self)
5621+{
5622+ int i;
5623+ u32 ier;
5624+ unsigned long flags;
5625+
5626+ spin_lock_irqsave(&self->lock, flags);
5627+ ier = ioread32(self->membase + TIMBDMA_IER);
5628+ for (i = 0; i < DMA_IRQS; i++)
5629+ if (self->control[i].callback)
5630+ ier |= 1 << i;
5631+ iowrite32(ier, self->membase + TIMBDMA_IER);
5632+ spin_unlock_irqrestore(&self->lock, flags);
5633+
5634+ /* look for any transfers that were started before the HW was
5635+ * available, and start them
5636+ */
5637+ for (i = 0; i < DMA_IRQS; i++) {
5638+ struct timbdma_control *ctrl = self->control + i;
5639+ if (ctrl->stored_desc) {
5640+ struct dma_desc *dma_desc = ctrl->stored_desc;
5641+ ctrl->stored_desc = NULL;
5642+ if (__timbdma_start(self, i, dma_desc,
5643+ ctrl->stored_bytes_per_row))
5644+ printk(KERN_ERR DRIVER_NAME
5645+ ": Failed to start DMA\n");
5646+ }
5647+ }
5648+}
5649+
5650+
5651+static int timbdma_probe(struct platform_device *dev)
5652+{
5653+ int err, irq;
5654+ struct resource *iomem;
5655+ struct timbdma_dev *self = self_g;
5656+
5657+ iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
5658+ if (!iomem) {
5659+ err = -EINVAL;
5660+ goto err_request;
5661+ }
5662+
5663+ if (dev->dev.parent)
5664+ self->dev = dev->dev.parent;
5665+ else
5666+ self->dev = &dev->dev;
5667+
5668+ if (!request_mem_region(iomem->start,
5669+ resource_size(iomem), DRIVER_NAME)) {
5670+ err = -EBUSY;
5671+ goto err_request;
5672+ }
5673+
5674+ self->membase = ioremap(iomem->start, resource_size(iomem));
5675+ if (!self->membase) {
5676+ printk(KERN_ERR DRIVER_NAME ": Failed to remap I/O memory\n");
5677+ err = -ENOMEM;
5678+ goto err_ioremap;
5679+ }
5680+
5681+ /* 32bit addressing */
5682+ iowrite32(TIMBDMA_32BIT_ADDR, self->membase + TIMBDMA_ACR);
5683+
5684+ /* disable and clear any interrupts */
5685+ iowrite32(0x0, self->membase + TIMBDMA_IER);
5686+ iowrite32(0x0, self->membase + TIMBDMA_ISR);
5687+
5688+ /* register interrupt */
5689+ irq = platform_get_irq(dev, 0);
5690+ if (irq < 0) {
5691+ err = irq;
5692+ goto err_get_irq;
5693+ }
5694+
5695+ /* request IRQ */
5696+ err = request_irq(irq, timbdma_handleinterrupt, IRQF_SHARED,
5697+ DRIVER_NAME, self);
5698+ if (err) {
5699+ printk(KERN_ERR DRIVER_NAME ": Failed to request IRQ\n");
5700+ goto err_get_irq;
5701+ }
5702+
5703+ platform_set_drvdata(dev, self);
5704+
5705+ /* assign the global pointer */
5706+ self_g = self;
5707+
5708+ timbdma_start_operations(self);
5709+
5710+ return 0;
5711+
5712+err_get_irq:
5713+ iounmap(self->membase);
5714+err_ioremap:
5715+ release_mem_region(iomem->start, resource_size(iomem));
5716+err_request:
5717+ printk(KERN_ERR DRIVER_NAME ": Failed to register Timberdale DMA: %d\n",
5718+ err);
5719+ self->membase = NULL;
5720+ self->dev = NULL;
5721+
5722+ return err;
5723+}
5724+
5725+static int timbdma_remove(struct platform_device *dev)
5726+{
5727+ struct timbdma_dev *self = platform_get_drvdata(dev);
5728+ struct resource *iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
5729+
5730+ free_irq(platform_get_irq(dev, 0), self);
5731+ iounmap(self->membase);
5732+ release_mem_region(iomem->start, resource_size(iomem));
5733+ self->membase = NULL;
5734+ self->dev = NULL;
5735+ return 0;
5736+}
5737+
5738+static struct platform_driver timbdma_platform_driver = {
5739+ .driver = {
5740+ .name = DRIVER_NAME,
5741+ .owner = THIS_MODULE,
5742+ },
5743+ .probe = timbdma_probe,
5744+ .remove = timbdma_remove,
5745+};
5746+
5747+/*--------------------------------------------------------------------------*/
5748+
5749+static int __init timbdma_init(void)
5750+{
5751+ struct timbdma_dev *self;
5752+ int err;
5753+
5754+ self = kzalloc(sizeof(*self), GFP_KERNEL);
5755+ if (!self)
5756+ return -ENOMEM;
5757+
5758+ spin_lock_init(&self->lock);
5759+
5760+ self_g = self;
5761+ err = platform_driver_register(&timbdma_platform_driver);
5762+ if (err)
5763+ kfree(self);
5764+
5765+ return err;
5766+}
5767+
5768+static void __exit timbdma_exit(void)
5769+{
5770+ platform_driver_unregister(&timbdma_platform_driver);
5771+ kfree(self_g);
5772+}
5773+
5774+module_init(timbdma_init);
5775+module_exit(timbdma_exit);
5776+
5777+MODULE_DESCRIPTION("Timberdale DMA driver");
5778+MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
5779+MODULE_LICENSE("GPL v2");
5780+MODULE_ALIAS("platform:"DRIVER_NAME);
5781+
5782diff -uNr linux-2.6.31/drivers/mfd/timberdale.c linux-2.6.31.new/drivers/mfd/timberdale.c
5783--- linux-2.6.31/drivers/mfd/timberdale.c 1969-12-31 16:00:00.000000000 -0800
5784+++ linux-2.6.31.new/drivers/mfd/timberdale.c 2009-10-23 11:17:29.000000000 -0700
5785@@ -0,0 +1,914 @@
5786+/*
5787+ * timberdale.c timberdale FPGA mfd shim driver
5788+ * Copyright (c) 2009 Intel Corporation
5789+ *
5790+ * This program is free software; you can redistribute it and/or modify
5791+ * it under the terms of the GNU General Public License version 2 as
5792+ * published by the Free Software Foundation.
5793+ *
5794+ * This program is distributed in the hope that it will be useful,
5795+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5796+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5797+ * GNU General Public License for more details.
5798+ *
5799+ * You should have received a copy of the GNU General Public License
5800+ * along with this program; if not, write to the Free Software
5801+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
5802+ */
5803+
5804+/* Supports:
5805+ * Timberdale FPGA
5806+ */
5807+
5808+#include <linux/kernel.h>
5809+#include <linux/module.h>
5810+#include <linux/pci.h>
5811+#include <linux/msi.h>
5812+#include <linux/init.h>
5813+#include <linux/interrupt.h>
5814+#include <linux/platform_device.h>
5815+#include <linux/mfd/core.h>
5816+#include <linux/irq.h>
5817+
5818+#include <linux/timb_gpio.h>
5819+
5820+#include <linux/i2c.h>
5821+#include <linux/i2c-ocores.h>
5822+#include <linux/i2c-xiic.h>
5823+#include <linux/i2c/tsc2007.h>
5824+#include <linux/can/platform/ascb.h>
5825+
5826+#include <linux/spi/spi.h>
5827+#include <linux/spi/xilinx_spi.h>
5828+#include <linux/spi/max7301.h>
5829+#include <linux/spi/mc33880.h>
5830+
5831+#include <media/timb_video.h>
5832+#include <media/timb_radio.h>
5833+#include <linux/most/timbmlb.h>
5834+
5835+#include <sound/timbi2s.h>
5836+
5837+#include "timberdale.h"
5838+
5839+#define DRIVER_NAME "timberdale"
5840+
5841+struct timberdale_device {
5842+ resource_size_t intc_mapbase;
5843+ resource_size_t ctl_mapbase;
5844+ unsigned char __iomem *ctl_membase;
5845+ /* locking from interrupts while modifiying registers */
5846+ spinlock_t lock;
5847+ struct {
5848+ u32 major;
5849+ u32 minor;
5850+ u32 config;
5851+ } fw;
5852+};
5853+
5854+/*--------------------------------------------------------------------------*/
5855+
5856+static struct tsc2007_platform_data timberdale_tsc2007_platform_data = {
5857+ .model = 2003,
5858+ .x_plate_ohms = 100
5859+};
5860+
5861+static struct ascb_platform_data timberdale_ascb_platform_data = {
5862+ .gpio_pin = GPIO_PIN_ASCB
5863+};
5864+
5865+static struct i2c_board_info timberdale_i2c_board_info[] = {
5866+ {
5867+ I2C_BOARD_INFO("tsc2007", 0x48),
5868+ .platform_data = &timberdale_tsc2007_platform_data,
5869+ .irq = IRQ_TIMBERDALE_TSC_INT
5870+ },
5871+ {
5872+ /* Requires jumper JP9 to be off */
5873+ I2C_BOARD_INFO("adv7180", 0x42 >> 1),
5874+ .irq = IRQ_TIMBERDALE_ADV7180
5875+ },
5876+ {
5877+ I2C_BOARD_INFO("tef6862", 0x60)
5878+ },
5879+ {
5880+ I2C_BOARD_INFO("saa7706h", 0x1C)
5881+ },
5882+ {
5883+ I2C_BOARD_INFO("ascb-can", 0x18),
5884+ .platform_data = &timberdale_ascb_platform_data,
5885+ }
5886+};
5887+
5888+static __devinitdata struct xiic_i2c_platform_data
5889+timberdale_xiic_platform_data = {
5890+ .devices = timberdale_i2c_board_info,
5891+ .num_devices = ARRAY_SIZE(timberdale_i2c_board_info)
5892+};
5893+
5894+static __devinitdata struct ocores_i2c_platform_data
5895+timberdale_ocores_platform_data = {
5896+ .regstep = 4,
5897+ .clock_khz = 62500,
5898+ .devices = timberdale_i2c_board_info,
5899+ .num_devices = ARRAY_SIZE(timberdale_i2c_board_info)
5900+};
5901+
5902+const static __devinitconst struct resource timberdale_xiic_resources[] = {
5903+ {
5904+ .start = XIICOFFSET,
5905+ .end = XIICEND,
5906+ .flags = IORESOURCE_MEM,
5907+ },
5908+ {
5909+ .start = IRQ_TIMBERDALE_I2C,
5910+ .end = IRQ_TIMBERDALE_I2C,
5911+ .flags = IORESOURCE_IRQ,
5912+ },
5913+};
5914+
5915+const static __devinitconst struct resource timberdale_ocores_resources[] = {
5916+ {
5917+ .start = OCORESOFFSET,
5918+ .end = OCORESEND,
5919+ .flags = IORESOURCE_MEM,
5920+ },
5921+ {
5922+ .start = IRQ_TIMBERDALE_I2C,
5923+ .end = IRQ_TIMBERDALE_I2C,
5924+ .flags = IORESOURCE_IRQ,
5925+ },
5926+};
5927+
5928+const struct max7301_platform_data timberdale_max7301_platform_data = {
5929+ .base = 200
5930+};
5931+
5932+const struct mc33880_platform_data timberdale_mc33880_platform_data = {
5933+ .base = 100
5934+};
5935+
5936+static struct spi_board_info timberdale_spi_16bit_board_info[] = {
5937+ {
5938+ .modalias = "max7301",
5939+ .max_speed_hz = 26000,
5940+ .chip_select = 2,
5941+ .mode = SPI_MODE_0,
5942+ .platform_data = &timberdale_max7301_platform_data
5943+ },
5944+};
5945+
5946+static struct spi_board_info timberdale_spi_8bit_board_info[] = {
5947+ {
5948+ .modalias = "mc33880",
5949+ .max_speed_hz = 4000,
5950+ .chip_select = 1,
5951+ .mode = SPI_MODE_1,
5952+ .platform_data = &timberdale_mc33880_platform_data
5953+ },
5954+};
5955+
5956+static __devinitdata struct xspi_platform_data timberdale_xspi_platform_data = {
5957+ /* Current(2009-03-06) revision of
5958+ * Timberdale we can handle 3 chip selects
5959+ */
5960+ .num_chipselect = 3,
5961+ /* bits per word and devices will be filled in runtime depending
5962+ * on the HW config
5963+ */
5964+};
5965+
5966+const static __devinitconst struct resource timberdale_spi_resources[] = {
5967+ {
5968+ .start = SPIOFFSET,
5969+ .end = SPIEND,
5970+ .flags = IORESOURCE_MEM,
5971+ },
5972+ {
5973+ .start = IRQ_TIMBERDALE_SPI,
5974+ .end = IRQ_TIMBERDALE_SPI,
5975+ .flags = IORESOURCE_IRQ,
5976+ },
5977+};
5978+
5979+const static __devinitconst struct resource timberdale_eth_resources[] = {
5980+ {
5981+ .start = ETHOFFSET,
5982+ .end = ETHEND,
5983+ .flags = IORESOURCE_MEM,
5984+ },
5985+ {
5986+ .start = IRQ_TIMBERDALE_ETHSW_IF,
5987+ .end = IRQ_TIMBERDALE_ETHSW_IF,
5988+ .flags = IORESOURCE_IRQ,
5989+ },
5990+};
5991+
5992+static __devinitdata struct timbgpio_platform_data
5993+ timberdale_gpio_platform_data = {
5994+ .gpio_base = 0,
5995+ .nr_pins = GPIO_NR_PINS,
5996+ .irq_base = 200,
5997+};
5998+
5999+const static __devinitconst struct resource timberdale_gpio_resources[] = {
6000+ {
6001+ .start = GPIOOFFSET,
6002+ .end = GPIOEND,
6003+ .flags = IORESOURCE_MEM,
6004+ },
6005+ {
6006+ .start = IRQ_TIMBERDALE_GPIO,
6007+ .end = IRQ_TIMBERDALE_GPIO,
6008+ .flags = IORESOURCE_IRQ,
6009+ },
6010+};
6011+
6012+static __devinitdata struct timbmlb_platform_data
6013+ timberdale_mlb_platform_data = {
6014+ .reset_pin = GPIO_PIN_INIC_RST
6015+};
6016+
6017+const static __devinitconst struct resource timberdale_most_resources[] = {
6018+ {
6019+ .start = MOSTOFFSET,
6020+ .end = MOSTEND,
6021+ .flags = IORESOURCE_MEM,
6022+ },
6023+ {
6024+ .start = IRQ_TIMBERDALE_MLB,
6025+ .end = IRQ_TIMBERDALE_MLB,
6026+ .flags = IORESOURCE_IRQ,
6027+ },
6028+};
6029+
6030+const static __devinitconst struct resource timberdale_mlogicore_resources[] = {
6031+ {
6032+ .start = MLCOREOFFSET,
6033+ .end = MLCOREEND,
6034+ .flags = IORESOURCE_MEM,
6035+ },
6036+ {
6037+ .start = IRQ_TIMBERDALE_MLCORE,
6038+ .end = IRQ_TIMBERDALE_MLCORE,
6039+ .flags = IORESOURCE_IRQ,
6040+ },
6041+ {
6042+ .start = IRQ_TIMBERDALE_MLCORE_BUF,
6043+ .end = IRQ_TIMBERDALE_MLCORE_BUF,
6044+ .flags = IORESOURCE_IRQ,
6045+ },
6046+};
6047+
6048+const static __devinitconst struct resource timberdale_uart_resources[] = {
6049+ {
6050+ .start = UARTOFFSET,
6051+ .end = UARTEND,
6052+ .flags = IORESOURCE_MEM,
6053+ },
6054+ {
6055+ .start = IRQ_TIMBERDALE_UART,
6056+ .end = IRQ_TIMBERDALE_UART,
6057+ .flags = IORESOURCE_IRQ,
6058+ },
6059+};
6060+
6061+const static __devinitconst struct resource timberdale_uartlite_resources[] = {
6062+ {
6063+ .start = UARTLITEOFFSET,
6064+ .end = UARTLITEEND,
6065+ .flags = IORESOURCE_MEM,
6066+ },
6067+ {
6068+ .start = IRQ_TIMBERDALE_UARTLITE,
6069+ .end = IRQ_TIMBERDALE_UARTLITE,
6070+ .flags = IORESOURCE_IRQ,
6071+ },
6072+};
6073+
6074+static __devinitdata struct timbi2s_bus_data timbi2s_bus_data[] = {
6075+ {
6076+ .rx = 0,
6077+ .sample_rate = 8000,
6078+ },
6079+ {
6080+ .rx = 1,
6081+ .sample_rate = 8000,
6082+ },
6083+ {
6084+ .rx = 1,
6085+ .sample_rate = 44100,
6086+ },
6087+};
6088+
6089+static __devinitdata struct timbi2s_platform_data timbi2s_platform_data = {
6090+ .busses = timbi2s_bus_data,
6091+ .num_busses = ARRAY_SIZE(timbi2s_bus_data),
6092+ .main_clk = 62500000,
6093+};
6094+
6095+const static __devinitconst struct resource timberdale_i2s_resources[] = {
6096+ {
6097+ .start = I2SOFFSET,
6098+ .end = I2SEND,
6099+ .flags = IORESOURCE_MEM,
6100+ },
6101+ {
6102+ .start = IRQ_TIMBERDALE_I2S,
6103+ .end = IRQ_TIMBERDALE_I2S,
6104+ .flags = IORESOURCE_IRQ,
6105+ },
6106+};
6107+
6108+static __devinitdata struct timb_video_platform_data
6109+ timberdale_video_platform_data = {
6110+ .i2c_adapter = 0,
6111+ .encoder = "adv7180"
6112+};
6113+
6114+const static __devinitconst struct resource timberdale_radio_resources[] = {
6115+ {
6116+ .start = RDSOFFSET,
6117+ .end = RDSEND,
6118+ .flags = IORESOURCE_MEM,
6119+ },
6120+ {
6121+ .start = IRQ_TIMBERDALE_RDS,
6122+ .end = IRQ_TIMBERDALE_RDS,
6123+ .flags = IORESOURCE_IRQ,
6124+ },
6125+};
6126+
6127+static __devinitdata struct timb_radio_platform_data
6128+ timberdale_radio_platform_data = {
6129+ .i2c_adapter = 0,
6130+ .tuner = "tef6862",
6131+ .dsp = "saa7706h"
6132+};
6133+
6134+const static __devinitconst struct resource timberdale_video_resources[] = {
6135+ {
6136+ .start = LOGIWOFFSET,
6137+ .end = LOGIWEND,
6138+ .flags = IORESOURCE_MEM,
6139+ },
6140+ /*
6141+ note that the "frame buffer" is located in DMA area
6142+ starting at 0x1200000
6143+ */
6144+};
6145+
6146+const static __devinitconst struct resource timberdale_dma_resources[] = {
6147+ {
6148+ .start = DMAOFFSET,
6149+ .end = DMAEND,
6150+ .flags = IORESOURCE_MEM,
6151+ },
6152+ {
6153+ .start = IRQ_TIMBERDALE_DMA,
6154+ .end = IRQ_TIMBERDALE_DMA,
6155+ .flags = IORESOURCE_IRQ,
6156+ },
6157+};
6158+
6159+static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg0[] = {
6160+ {
6161+ .name = "timb-uart",
6162+ .num_resources = ARRAY_SIZE(timberdale_uart_resources),
6163+ .resources = timberdale_uart_resources,
6164+ },
6165+ {
6166+ .name = "xiic-i2c",
6167+ .num_resources = ARRAY_SIZE(timberdale_xiic_resources),
6168+ .resources = timberdale_xiic_resources,
6169+ .platform_data = &timberdale_xiic_platform_data,
6170+ .data_size = sizeof(timberdale_xiic_platform_data),
6171+ },
6172+ {
6173+ .name = "timb-gpio",
6174+ .num_resources = ARRAY_SIZE(timberdale_gpio_resources),
6175+ .resources = timberdale_gpio_resources,
6176+ .platform_data = &timberdale_gpio_platform_data,
6177+ .data_size = sizeof(timberdale_gpio_platform_data),
6178+ },
6179+ {
6180+ .name = "timb-i2s",
6181+ .num_resources = ARRAY_SIZE(timberdale_i2s_resources),
6182+ .resources = timberdale_i2s_resources,
6183+ .platform_data = &timbi2s_platform_data,
6184+ .data_size = sizeof(timbi2s_platform_data),
6185+ },
6186+ {
6187+ .name = "timb-most",
6188+ .num_resources = ARRAY_SIZE(timberdale_most_resources),
6189+ .resources = timberdale_most_resources,
6190+ .platform_data = &timberdale_mlb_platform_data,
6191+ .data_size = sizeof(timberdale_mlb_platform_data),
6192+ },
6193+ {
6194+ .name = "timb-video",
6195+ .num_resources = ARRAY_SIZE(timberdale_video_resources),
6196+ .resources = timberdale_video_resources,
6197+ .platform_data = &timberdale_video_platform_data,
6198+ .data_size = sizeof(timberdale_video_platform_data),
6199+ },
6200+ {
6201+ .name = "timb-radio",
6202+ .num_resources = ARRAY_SIZE(timberdale_radio_resources),
6203+ .resources = timberdale_radio_resources,
6204+ .platform_data = &timberdale_radio_platform_data,
6205+ .data_size = sizeof(timberdale_radio_platform_data),
6206+ },
6207+ {
6208+ .name = "xilinx_spi",
6209+ .num_resources = ARRAY_SIZE(timberdale_spi_resources),
6210+ .resources = timberdale_spi_resources,
6211+ .platform_data = &timberdale_xspi_platform_data,
6212+ .data_size = sizeof(timberdale_xspi_platform_data),
6213+ },
6214+ {
6215+ .name = "ks8842",
6216+ .num_resources = ARRAY_SIZE(timberdale_eth_resources),
6217+ .resources = timberdale_eth_resources,
6218+ },
6219+ {
6220+ .name = "timb-dma",
6221+ .num_resources = ARRAY_SIZE(timberdale_dma_resources),
6222+ .resources = timberdale_dma_resources,
6223+ },
6224+};
6225+
6226+static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = {
6227+ {
6228+ .name = "timb-uart",
6229+ .num_resources = ARRAY_SIZE(timberdale_uart_resources),
6230+ .resources = timberdale_uart_resources,
6231+ },
6232+ {
6233+ .name = "uartlite",
6234+ .num_resources = ARRAY_SIZE(timberdale_uartlite_resources),
6235+ .resources = timberdale_uartlite_resources,
6236+ },
6237+ {
6238+ .name = "xiic-i2c",
6239+ .num_resources = ARRAY_SIZE(timberdale_xiic_resources),
6240+ .resources = timberdale_xiic_resources,
6241+ .platform_data = &timberdale_xiic_platform_data,
6242+ .data_size = sizeof(timberdale_xiic_platform_data),
6243+ },
6244+ {
6245+ .name = "timb-gpio",
6246+ .num_resources = ARRAY_SIZE(timberdale_gpio_resources),
6247+ .resources = timberdale_gpio_resources,
6248+ .platform_data = &timberdale_gpio_platform_data,
6249+ .data_size = sizeof(timberdale_gpio_platform_data),
6250+ },
6251+ {
6252+ .name = "timb-mlogicore",
6253+ .num_resources = ARRAY_SIZE(timberdale_mlogicore_resources),
6254+ .resources = timberdale_mlogicore_resources,
6255+ },
6256+ {
6257+ .name = "timb-video",
6258+ .num_resources = ARRAY_SIZE(timberdale_video_resources),
6259+ .resources = timberdale_video_resources,
6260+ .platform_data = &timberdale_video_platform_data,
6261+ .data_size = sizeof(timberdale_video_platform_data),
6262+ },
6263+ {
6264+ .name = "timb-radio",
6265+ .num_resources = ARRAY_SIZE(timberdale_radio_resources),
6266+ .resources = timberdale_radio_resources,
6267+ .platform_data = &timberdale_radio_platform_data,
6268+ .data_size = sizeof(timberdale_radio_platform_data),
6269+ },
6270+ {
6271+ .name = "xilinx_spi",
6272+ .num_resources = ARRAY_SIZE(timberdale_spi_resources),
6273+ .resources = timberdale_spi_resources,
6274+ .platform_data = &timberdale_xspi_platform_data,
6275+ .data_size = sizeof(timberdale_xspi_platform_data),
6276+ },
6277+ {
6278+ .name = "ks8842",
6279+ .num_resources = ARRAY_SIZE(timberdale_eth_resources),
6280+ .resources = timberdale_eth_resources,
6281+ },
6282+ {
6283+ .name = "timb-dma",
6284+ .num_resources = ARRAY_SIZE(timberdale_dma_resources),
6285+ .resources = timberdale_dma_resources,
6286+ },
6287+};
6288+
6289+static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = {
6290+ {
6291+ .name = "timb-uart",
6292+ .num_resources = ARRAY_SIZE(timberdale_uart_resources),
6293+ .resources = timberdale_uart_resources,
6294+ },
6295+ {
6296+ .name = "xiic-i2c",
6297+ .num_resources = ARRAY_SIZE(timberdale_xiic_resources),
6298+ .resources = timberdale_xiic_resources,
6299+ .platform_data = &timberdale_xiic_platform_data,
6300+ .data_size = sizeof(timberdale_xiic_platform_data),
6301+ },
6302+ {
6303+ .name = "timb-gpio",
6304+ .num_resources = ARRAY_SIZE(timberdale_gpio_resources),
6305+ .resources = timberdale_gpio_resources,
6306+ .platform_data = &timberdale_gpio_platform_data,
6307+ .data_size = sizeof(timberdale_gpio_platform_data),
6308+ },
6309+ {
6310+ .name = "timb-video",
6311+ .num_resources = ARRAY_SIZE(timberdale_video_resources),
6312+ .resources = timberdale_video_resources,
6313+ .platform_data = &timberdale_video_platform_data,
6314+ .data_size = sizeof(timberdale_video_platform_data),
6315+ },
6316+ {
6317+ .name = "timb-radio",
6318+ .num_resources = ARRAY_SIZE(timberdale_radio_resources),
6319+ .resources = timberdale_radio_resources,
6320+ .platform_data = &timberdale_radio_platform_data,
6321+ .data_size = sizeof(timberdale_radio_platform_data),
6322+ },
6323+ {
6324+ .name = "xilinx_spi",
6325+ .num_resources = ARRAY_SIZE(timberdale_spi_resources),
6326+ .resources = timberdale_spi_resources,
6327+ .platform_data = &timberdale_xspi_platform_data,
6328+ .data_size = sizeof(timberdale_xspi_platform_data),
6329+ },
6330+ {
6331+ .name = "timb-dma",
6332+ .num_resources = ARRAY_SIZE(timberdale_dma_resources),
6333+ .resources = timberdale_dma_resources,
6334+ },
6335+};
6336+
6337+static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg3[] = {
6338+ {
6339+ .name = "timb-uart",
6340+ .num_resources = ARRAY_SIZE(timberdale_uart_resources),
6341+ .resources = timberdale_uart_resources,
6342+ },
6343+ {
6344+ .name = "ocores-i2c",
6345+ .num_resources = ARRAY_SIZE(timberdale_ocores_resources),
6346+ .resources = timberdale_ocores_resources,
6347+ .platform_data = &timberdale_ocores_platform_data,
6348+ .data_size = sizeof(timberdale_ocores_platform_data),
6349+ },
6350+ {
6351+ .name = "timb-gpio",
6352+ .num_resources = ARRAY_SIZE(timberdale_gpio_resources),
6353+ .resources = timberdale_gpio_resources,
6354+ .platform_data = &timberdale_gpio_platform_data,
6355+ .data_size = sizeof(timberdale_gpio_platform_data),
6356+ },
6357+ {
6358+ .name = "timb-i2s",
6359+ .num_resources = ARRAY_SIZE(timberdale_i2s_resources),
6360+ .resources = timberdale_i2s_resources,
6361+ .platform_data = &timbi2s_platform_data,
6362+ .data_size = sizeof(timbi2s_platform_data),
6363+ },
6364+ {
6365+ .name = "timb-most",
6366+ .num_resources = ARRAY_SIZE(timberdale_most_resources),
6367+ .resources = timberdale_most_resources,
6368+ .platform_data = &timberdale_mlb_platform_data,
6369+ .data_size = sizeof(timberdale_mlb_platform_data),
6370+ },
6371+ {
6372+ .name = "timb-video",
6373+ .num_resources = ARRAY_SIZE(timberdale_video_resources),
6374+ .resources = timberdale_video_resources,
6375+ .platform_data = &timberdale_video_platform_data,
6376+ .data_size = sizeof(timberdale_video_platform_data),
6377+ },
6378+ {
6379+ .name = "timb-radio",
6380+ .num_resources = ARRAY_SIZE(timberdale_radio_resources),
6381+ .resources = timberdale_radio_resources,
6382+ .platform_data = &timberdale_radio_platform_data,
6383+ .data_size = sizeof(timberdale_radio_platform_data),
6384+ },
6385+ {
6386+ .name = "xilinx_spi",
6387+ .num_resources = ARRAY_SIZE(timberdale_spi_resources),
6388+ .resources = timberdale_spi_resources,
6389+ .platform_data = &timberdale_xspi_platform_data,
6390+ .data_size = sizeof(timberdale_xspi_platform_data),
6391+ },
6392+ {
6393+ .name = "ks8842",
6394+ .num_resources = ARRAY_SIZE(timberdale_eth_resources),
6395+ .resources = timberdale_eth_resources,
6396+ },
6397+ {
6398+ .name = "timb-dma",
6399+ .num_resources = ARRAY_SIZE(timberdale_dma_resources),
6400+ .resources = timberdale_dma_resources,
6401+ },
6402+};
6403+
6404+static const __devinitconst struct resource timberdale_sdhc_resources[] = {
6405+ /* located in bar 1 and bar 2 */
6406+ {
6407+ .start = SDHC0OFFSET,
6408+ .end = SDHC0END,
6409+ .flags = IORESOURCE_MEM,
6410+ },
6411+ {
6412+ .start = IRQ_TIMBERDALE_SDHC,
6413+ .end = IRQ_TIMBERDALE_SDHC,
6414+ .flags = IORESOURCE_IRQ,
6415+ },
6416+};
6417+
6418+static __devinitdata struct mfd_cell timberdale_cells_bar1[] = {
6419+ {
6420+ .name = "sdhci",
6421+ .num_resources = ARRAY_SIZE(timberdale_sdhc_resources),
6422+ .resources = timberdale_sdhc_resources,
6423+ },
6424+};
6425+
6426+static __devinitdata struct mfd_cell timberdale_cells_bar2[] = {
6427+ {
6428+ .name = "sdhci",
6429+ .num_resources = ARRAY_SIZE(timberdale_sdhc_resources),
6430+ .resources = timberdale_sdhc_resources,
6431+ },
6432+};
6433+
6434+static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr,
6435+ char *buf)
6436+{
6437+ struct pci_dev *pdev = to_pci_dev(dev);
6438+ struct timberdale_device *priv = pci_get_drvdata(pdev);
6439+
6440+ return sprintf(buf, "%d.%d.%d\n", priv->fw.major, priv->fw.minor,
6441+ priv->fw.config);
6442+}
6443+
6444+static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
6445+
6446+/*--------------------------------------------------------------------------*/
6447+
6448+static int __devinit timb_probe(struct pci_dev *dev,
6449+ const struct pci_device_id *id)
6450+{
6451+ struct timberdale_device *priv;
6452+ int err, i;
6453+ resource_size_t mapbase;
6454+ struct msix_entry *msix_entries = NULL;
6455+ u8 ip_setup;
6456+
6457+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
6458+ if (!priv)
6459+ return -ENOMEM;
6460+
6461+ spin_lock_init(&priv->lock);
6462+ pci_set_drvdata(dev, priv);
6463+
6464+ err = pci_enable_device(dev);
6465+ if (err)
6466+ goto err_enable;
6467+
6468+ mapbase = pci_resource_start(dev, 0);
6469+ if (!mapbase) {
6470+ printk(KERN_ERR DRIVER_NAME ": No resource\n");
6471+ goto err_start;
6472+ }
6473+
6474+ /* create a resource for the PCI master register */
6475+ priv->ctl_mapbase = mapbase + CHIPCTLOFFSET;
6476+ if (!request_mem_region(priv->ctl_mapbase, CHIPCTLSIZE, "timb-ctl")) {
6477+ printk(KERN_ERR DRIVER_NAME ": Failed to request ctl mem\n");
6478+ goto err_request;
6479+ }
6480+
6481+ priv->ctl_membase = ioremap(priv->ctl_mapbase, CHIPCTLSIZE);
6482+ if (!priv->ctl_membase) {
6483+ printk(KERN_ALERT DRIVER_NAME": Map error, ctl\n");
6484+ goto err_ioremap;
6485+ }
6486+
6487+ /* read the HW config */
6488+ priv->fw.major = ioread32(priv->ctl_membase + TIMB_REV_MAJOR);
6489+ priv->fw.minor = ioread32(priv->ctl_membase + TIMB_REV_MINOR);
6490+ priv->fw.config = ioread32(priv->ctl_membase + TIMB_HW_CONFIG);
6491+
6492+ if (priv->fw.major > TIMB_SUPPORTED_MAJOR) {
6493+ printk(KERN_ERR DRIVER_NAME": The driver supports an older "
6494+ "version of the FPGA, please update the driver to "
6495+ "support %d.%d\n", priv->fw.major, priv->fw.minor);
6496+ goto err_ioremap;
6497+ }
6498+ if (priv->fw.major < TIMB_SUPPORTED_MAJOR ||
6499+ priv->fw.minor < TIMB_REQUIRED_MINOR) {
6500+ printk(KERN_ERR DRIVER_NAME
6501+ ": The FPGA image is too old (%d.%d), "
6502+ "please upgrade the FPGA to at least: %d.%d\n",
6503+ priv->fw.major, priv->fw.minor,
6504+ TIMB_SUPPORTED_MAJOR, TIMB_REQUIRED_MINOR);
6505+ goto err_ioremap;
6506+ }
6507+
6508+ msix_entries = kzalloc(TIMBERDALE_NR_IRQS * sizeof(*msix_entries),
6509+ GFP_KERNEL);
6510+ if (!msix_entries)
6511+ goto err_ioremap;
6512+
6513+ for (i = 0; i < TIMBERDALE_NR_IRQS; i++)
6514+ msix_entries[i].entry = i;
6515+
6516+ err = pci_enable_msix(dev, msix_entries, TIMBERDALE_NR_IRQS);
6517+ if (err) {
6518+ printk(KERN_WARNING DRIVER_NAME
6519+ ": MSI-X init failed: %d, expected entries: %d\n",
6520+ err, TIMBERDALE_NR_IRQS);
6521+ goto err_msix;
6522+ }
6523+
6524+ err = device_create_file(&dev->dev, &dev_attr_fw_ver);
6525+ if (err)
6526+ goto err_create_file;
6527+
6528+ /* Reset all FPGA PLB peripherals */
6529+ iowrite32(0x1, priv->ctl_membase + TIMB_SW_RST);
6530+
6531+ /* update IRQ offsets in I2C board info */
6532+ for (i = 0; i < ARRAY_SIZE(timberdale_i2c_board_info); i++)
6533+ timberdale_i2c_board_info[i].irq =
6534+ msix_entries[timberdale_i2c_board_info[i].irq].vector;
6535+
6536+ /* Update the SPI configuration depending on the HW (8 or 16 bit) */
6537+ if (priv->fw.config & TIMB_HW_CONFIG_SPI_8BIT) {
6538+ timberdale_xspi_platform_data.bits_per_word = 8;
6539+ timberdale_xspi_platform_data.devices =
6540+ timberdale_spi_8bit_board_info;
6541+ timberdale_xspi_platform_data.num_devices =
6542+ ARRAY_SIZE(timberdale_spi_8bit_board_info);
6543+ } else {
6544+ timberdale_xspi_platform_data.bits_per_word = 16;
6545+ timberdale_xspi_platform_data.devices =
6546+ timberdale_spi_16bit_board_info;
6547+ timberdale_xspi_platform_data.num_devices =
6548+ ARRAY_SIZE(timberdale_spi_16bit_board_info);
6549+ }
6550+
6551+ ip_setup = priv->fw.config & TIMB_HW_VER_MASK;
6552+ if (ip_setup == TIMB_HW_VER0)
6553+ err = mfd_add_devices(&dev->dev, -1,
6554+ timberdale_cells_bar0_cfg0,
6555+ ARRAY_SIZE(timberdale_cells_bar0_cfg0),
6556+ &dev->resource[0], msix_entries[0].vector);
6557+ else if (ip_setup == TIMB_HW_VER1)
6558+ err = mfd_add_devices(&dev->dev, -1,
6559+ timberdale_cells_bar0_cfg1,
6560+ ARRAY_SIZE(timberdale_cells_bar0_cfg1),
6561+ &dev->resource[0], msix_entries[0].vector);
6562+ else if (ip_setup == TIMB_HW_VER2)
6563+ err = mfd_add_devices(&dev->dev, -1,
6564+ timberdale_cells_bar0_cfg2,
6565+ ARRAY_SIZE(timberdale_cells_bar0_cfg2),
6566+ &dev->resource[0], msix_entries[0].vector);
6567+ else if (ip_setup == TIMB_HW_VER3)
6568+ err = mfd_add_devices(&dev->dev, -1,
6569+ timberdale_cells_bar0_cfg3,
6570+ ARRAY_SIZE(timberdale_cells_bar0_cfg3),
6571+ &dev->resource[0], msix_entries[0].vector);
6572+ else {
6573+ /* unknown version */
6574+ printk(KERN_ERR"Uknown IP setup: %d.%d.%d\n",
6575+ priv->fw.major, priv->fw.minor, ip_setup);
6576+ err = -ENODEV;
6577+ goto err_mfd;
6578+ }
6579+
6580+ if (err) {
6581+ printk(KERN_WARNING DRIVER_NAME
6582+ ": mfd_add_devices failed: %d\n", err);
6583+ goto err_mfd;
6584+ }
6585+
6586+ err = mfd_add_devices(&dev->dev, 0,
6587+ timberdale_cells_bar1, ARRAY_SIZE(timberdale_cells_bar1),
6588+ &dev->resource[1], msix_entries[0].vector);
6589+ if (err) {
6590+ printk(KERN_WARNING DRIVER_NAME
6591+ "mfd_add_devices failed: %d\n", err);
6592+ goto err_mfd2;
6593+ }
6594+
6595+ /* only version 0 and 3 have the iNand routed to SDHCI */
6596+ if (((priv->fw.config & TIMB_HW_VER_MASK) == TIMB_HW_VER0) ||
6597+ ((priv->fw.config & TIMB_HW_VER_MASK) == TIMB_HW_VER3)) {
6598+ err = mfd_add_devices(&dev->dev, 1, timberdale_cells_bar2,
6599+ ARRAY_SIZE(timberdale_cells_bar2),
6600+ &dev->resource[2], msix_entries[0].vector);
6601+ if (err) {
6602+ printk(KERN_WARNING DRIVER_NAME
6603+ ": mfd_add_devices failed: %d\n", err);
6604+ goto err_mfd2;
6605+ }
6606+ }
6607+
6608+ kfree(msix_entries);
6609+
6610+ printk(KERN_INFO
6611+ "Found Timberdale Card. Rev: %d.%d, HW config: 0x%02x\n",
6612+ priv->fw.major, priv->fw.minor, priv->fw.config);
6613+
6614+ return 0;
6615+
6616+err_mfd2:
6617+ mfd_remove_devices(&dev->dev);
6618+err_mfd:
6619+ device_remove_file(&dev->dev, &dev_attr_fw_ver);
6620+err_create_file:
6621+ pci_disable_msix(dev);
6622+err_msix:
6623+ iounmap(priv->ctl_membase);
6624+err_ioremap:
6625+ release_mem_region(priv->ctl_mapbase, CHIPCTLSIZE);
6626+err_request:
6627+ pci_set_drvdata(dev, NULL);
6628+err_start:
6629+ pci_disable_device(dev);
6630+err_enable:
6631+ kfree(msix_entries);
6632+ kfree(priv);
6633+ pci_set_drvdata(dev, NULL);
6634+ return -ENODEV;
6635+}
6636+
6637+static void __devexit timb_remove(struct pci_dev *dev)
6638+{
6639+ struct timberdale_device *priv = pci_get_drvdata(dev);
6640+
6641+ mfd_remove_devices(&dev->dev);
6642+
6643+ device_remove_file(&dev->dev, &dev_attr_fw_ver);
6644+
6645+ iounmap(priv->ctl_membase);
6646+ release_mem_region(priv->ctl_mapbase, CHIPCTLSIZE);
6647+
6648+ pci_disable_msix(dev);
6649+ pci_disable_device(dev);
6650+ pci_set_drvdata(dev, NULL);
6651+ kfree(priv);
6652+}
6653+
6654+static struct pci_device_id timberdale_pci_tbl[] = {
6655+ { PCI_DEVICE(PCI_VENDOR_ID_TIMB, PCI_DEVICE_ID_TIMB) },
6656+ { 0 }
6657+};
6658+MODULE_DEVICE_TABLE(pci, timberdale_pci_tbl);
6659+
6660+static struct pci_driver timberdale_pci_driver = {
6661+ .name = DRIVER_NAME,
6662+ .id_table = timberdale_pci_tbl,
6663+ .probe = timb_probe,
6664+ .remove = __devexit_p(timb_remove),
6665+};
6666+
6667+static int __init timberdale_init(void)
6668+{
6669+ int err;
6670+
6671+ err = pci_register_driver(&timberdale_pci_driver);
6672+ if (err < 0) {
6673+ printk(KERN_ERR
6674+ "Failed to register PCI driver for %s device.\n",
6675+ timberdale_pci_driver.name);
6676+ return -ENODEV;
6677+ }
6678+
6679+ printk(KERN_INFO "Driver for %s has been successfully registered.\n",
6680+ timberdale_pci_driver.name);
6681+
6682+ return 0;
6683+}
6684+
6685+static void __exit timberdale_exit(void)
6686+{
6687+ pci_unregister_driver(&timberdale_pci_driver);
6688+
6689+ printk(KERN_INFO "Driver for %s has been successfully unregistered.\n",
6690+ timberdale_pci_driver.name);
6691+}
6692+
6693+module_init(timberdale_init);
6694+module_exit(timberdale_exit);
6695+
6696+MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
6697+MODULE_VERSION(DRV_VERSION);
6698+MODULE_LICENSE("GPL v2");
6699+
6700diff -uNr linux-2.6.31/drivers/mfd/timberdale.h linux-2.6.31.new/drivers/mfd/timberdale.h
6701--- linux-2.6.31/drivers/mfd/timberdale.h 1969-12-31 16:00:00.000000000 -0800
6702+++ linux-2.6.31.new/drivers/mfd/timberdale.h 2009-10-23 11:17:29.000000000 -0700
6703@@ -0,0 +1,152 @@
6704+/*
6705+ * timberdale.h timberdale FPGA mfd shim driver defines
6706+ * Copyright (c) 2009 Intel Corporation
6707+ *
6708+ * This program is free software; you can redistribute it and/or modify
6709+ * it under the terms of the GNU General Public License version 2 as
6710+ * published by the Free Software Foundation.
6711+ *
6712+ * This program is distributed in the hope that it will be useful,
6713+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6714+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6715+ * GNU General Public License for more details.
6716+ *
6717+ * You should have received a copy of the GNU General Public License
6718+ * along with this program; if not, write to the Free Software
6719+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
6720+ */
6721+
6722+/* Supports:
6723+ * Timberdale FPGA
6724+ */
6725+
6726+#ifndef MFD_TIMBERDALE_H
6727+#define MFD_TIMBERDALE_H
6728+
6729+#define DRV_VERSION "1.0"
6730+
6731+/* This driver only support versions >= 3.8 and < 4.0 */
6732+#define TIMB_SUPPORTED_MAJOR 3
6733+
6734+/* This driver only support minor >= 8 */
6735+#define TIMB_REQUIRED_MINOR 8
6736+
6737+/* Registers of the interrupt controller */
6738+#define ISR 0x00
6739+#define IPR 0x04
6740+#define IER 0x08
6741+#define IAR 0x0c
6742+#define SIE 0x10
6743+#define CIE 0x14
6744+#define MER 0x1c
6745+
6746+/* Registers of the control area */
6747+#define TIMB_REV_MAJOR 0x00
6748+#define TIMB_REV_MINOR 0x04
6749+#define TIMB_HW_CONFIG 0x08
6750+#define TIMB_SW_RST 0x40
6751+
6752+/* bits in the TIMB_HW_CONFIG register */
6753+#define TIMB_HW_CONFIG_SPI_8BIT 0x80
6754+
6755+#define TIMB_HW_VER_MASK 0x0f
6756+#define TIMB_HW_VER0 0x00
6757+#define TIMB_HW_VER1 0x01
6758+#define TIMB_HW_VER2 0x02
6759+#define TIMB_HW_VER3 0x03
6760+
6761+#define OCORESOFFSET 0x0
6762+#define OCORESEND 0x1f
6763+
6764+#define SPIOFFSET 0x80
6765+#define SPIEND 0xff
6766+
6767+#define UARTLITEOFFSET 0x100
6768+#define UARTLITEEND 0x10f
6769+
6770+#define RDSOFFSET 0x180
6771+#define RDSEND 0x183
6772+
6773+#define ETHOFFSET 0x300
6774+#define ETHEND 0x3ff
6775+
6776+#define GPIOOFFSET 0x400
6777+#define GPIOEND 0x7ff
6778+
6779+#define CHIPCTLOFFSET 0x800
6780+#define CHIPCTLEND 0x8ff
6781+#define CHIPCTLSIZE (CHIPCTLEND - CHIPCTLOFFSET)
6782+
6783+#define INTCOFFSET 0xc00
6784+#define INTCEND 0xfff
6785+#define INTCSIZE (INTCEND - INTCOFFSET)
6786+
6787+#define MOSTOFFSET 0x1000
6788+#define MOSTEND 0x13ff
6789+
6790+#define UARTOFFSET 0x1400
6791+#define UARTEND 0x17ff
6792+
6793+#define XIICOFFSET 0x1800
6794+#define XIICEND 0x19ff
6795+
6796+#define I2SOFFSET 0x1C00
6797+#define I2SEND 0x1fff
6798+
6799+#define LOGIWOFFSET 0x30000
6800+#define LOGIWEND 0x37fff
6801+
6802+#define MLCOREOFFSET 0x40000
6803+#define MLCOREEND 0x43fff
6804+
6805+#define DMAOFFSET 0x01000000
6806+#define DMAEND 0x013fffff
6807+
6808+/* SDHC0 is placed in PCI bar 1 */
6809+#define SDHC0OFFSET 0x00
6810+#define SDHC0END 0xff
6811+
6812+/* SDHC1 is placed in PCI bar 2 */
6813+#define SDHC1OFFSET 0x00
6814+#define SDHC1END 0xff
6815+
6816+#define PCI_VENDOR_ID_TIMB 0x10ee
6817+#define PCI_DEVICE_ID_TIMB 0xa123
6818+
6819+#define IRQ_TIMBERDALE_INIC 0
6820+#define IRQ_TIMBERDALE_MLB 1
6821+#define IRQ_TIMBERDALE_GPIO 2
6822+#define IRQ_TIMBERDALE_I2C 3
6823+#define IRQ_TIMBERDALE_UART 4
6824+#define IRQ_TIMBERDALE_DMA 5
6825+#define IRQ_TIMBERDALE_I2S 6
6826+#define IRQ_TIMBERDALE_TSC_INT 7
6827+#define IRQ_TIMBERDALE_SDHC 8
6828+#define IRQ_TIMBERDALE_ADV7180 9
6829+#define IRQ_TIMBERDALE_ETHSW_IF 10
6830+#define IRQ_TIMBERDALE_SPI 11
6831+#define IRQ_TIMBERDALE_UARTLITE 12
6832+#define IRQ_TIMBERDALE_MLCORE 13
6833+#define IRQ_TIMBERDALE_MLCORE_BUF 14
6834+#define IRQ_TIMBERDALE_RDS 15
6835+
6836+#define TIMBERDALE_NR_IRQS 16
6837+
6838+/* Some of the interrupts are level triggered, some are edge triggered */
6839+#define IRQ_TIMBERDALE_EDGE_MASK ((1 << IRQ_TIMBERDALE_ADV7180) | \
6840+ (1 << IRQ_TIMBERDALE_TSC_INT) | \
6841+ (1 << IRQ_TIMBERDALE_MLB) | (1 << IRQ_TIMBERDALE_INIC))
6842+
6843+#define IRQ_TIMBERDALE_LEVEL_MASK ((1 << IRQ_TIMBERDALE_SPI) | \
6844+ (1 << IRQ_TIMBERDALE_ETHSW_IF) | (1 << IRQ_TIMBERDALE_SDHC) | \
6845+ (1 << IRQ_TIMBERDALE_I2S) | (1 << IRQ_TIMBERDALE_UART) | \
6846+ (1 << IRQ_TIMBERDALE_I2C) | (1 << IRQ_TIMBERDALE_GPIO) | \
6847+ (1 << IRQ_TIMBERDALE_DMA))
6848+
6849+#define GPIO_PIN_ASCB 8
6850+#define GPIO_PIN_INIC_RST 14
6851+#define GPIO_PIN_BT_RST 15
6852+#define GPIO_NR_PINS 16
6853+
6854+#endif
6855+
6856diff -uNr linux-2.6.31/drivers/mmc/host/sdhci.c linux-2.6.31.new/drivers/mmc/host/sdhci.c
6857--- linux-2.6.31/drivers/mmc/host/sdhci.c 2009-10-23 11:18:30.000000000 -0700
6858+++ linux-2.6.31.new/drivers/mmc/host/sdhci.c 2009-10-23 11:17:25.000000000 -0700
6859@@ -652,7 +652,7 @@
6860 count = sdhci_calc_timeout(host, data);
6861 sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
6862
6863- if (host->flags & SDHCI_USE_DMA)
6864+ if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))
6865 host->flags |= SDHCI_REQ_USE_DMA;
6866
6867 /*
6868@@ -1597,7 +1597,7 @@
6869 {
6870 int ret;
6871
6872- if (host->flags & SDHCI_USE_DMA) {
6873+ if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
6874 if (host->ops->enable_dma)
6875 host->ops->enable_dma(host);
6876 }
6877@@ -1678,23 +1678,20 @@
6878 caps = sdhci_readl(host, SDHCI_CAPABILITIES);
6879
6880 if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
6881- host->flags |= SDHCI_USE_DMA;
6882- else if (!(caps & SDHCI_CAN_DO_DMA))
6883- DBG("Controller doesn't have DMA capability\n");
6884+ host->flags |= SDHCI_USE_SDMA;
6885+ else if (!(caps & SDHCI_CAN_DO_SDMA))
6886+ DBG("Controller doesn't have SDMA capability\n");
6887 else
6888- host->flags |= SDHCI_USE_DMA;
6889+ host->flags |= SDHCI_USE_SDMA;
6890
6891 if ((host->quirks & SDHCI_QUIRK_BROKEN_DMA) &&
6892- (host->flags & SDHCI_USE_DMA)) {
6893+ (host->flags & SDHCI_USE_SDMA)) {
6894 DBG("Disabling DMA as it is marked broken\n");
6895- host->flags &= ~SDHCI_USE_DMA;
6896+ host->flags &= ~SDHCI_USE_SDMA;
6897 }
6898
6899- if (host->flags & SDHCI_USE_DMA) {
6900- if ((host->version >= SDHCI_SPEC_200) &&
6901- (caps & SDHCI_CAN_DO_ADMA2))
6902- host->flags |= SDHCI_USE_ADMA;
6903- }
6904+ if ((host->version >= SDHCI_SPEC_200) && (caps & SDHCI_CAN_DO_ADMA2))
6905+ host->flags |= SDHCI_USE_ADMA;
6906
6907 if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) &&
6908 (host->flags & SDHCI_USE_ADMA)) {
6909@@ -1702,13 +1699,14 @@
6910 host->flags &= ~SDHCI_USE_ADMA;
6911 }
6912
6913- if (host->flags & SDHCI_USE_DMA) {
6914+ if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
6915 if (host->ops->enable_dma) {
6916 if (host->ops->enable_dma(host)) {
6917 printk(KERN_WARNING "%s: No suitable DMA "
6918 "available. Falling back to PIO.\n",
6919 mmc_hostname(mmc));
6920- host->flags &= ~(SDHCI_USE_DMA | SDHCI_USE_ADMA);
6921+ host->flags &=
6922+ ~(SDHCI_USE_SDMA | SDHCI_USE_ADMA);
6923 }
6924 }
6925 }
6926@@ -1736,7 +1734,7 @@
6927 * mask, but PIO does not need the hw shim so we set a new
6928 * mask here in that case.
6929 */
6930- if (!(host->flags & SDHCI_USE_DMA)) {
6931+ if (!(host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))) {
6932 host->dma_mask = DMA_BIT_MASK(64);
6933 mmc_dev(host->mmc)->dma_mask = &host->dma_mask;
6934 }
6935@@ -1810,7 +1808,7 @@
6936 */
6937 if (host->flags & SDHCI_USE_ADMA)
6938 mmc->max_hw_segs = 128;
6939- else if (host->flags & SDHCI_USE_DMA)
6940+ else if (host->flags & SDHCI_USE_SDMA)
6941 mmc->max_hw_segs = 1;
6942 else /* PIO */
6943 mmc->max_hw_segs = 128;
6944@@ -1893,10 +1891,10 @@
6945
6946 mmc_add_host(mmc);
6947
6948- printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s%s\n",
6949+ printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s\n",
6950 mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)),
6951- (host->flags & SDHCI_USE_ADMA)?"A":"",
6952- (host->flags & SDHCI_USE_DMA)?"DMA":"PIO");
6953+ (host->flags & SDHCI_USE_ADMA) ? "ADMA" :
6954+ (host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO");
6955
6956 sdhci_enable_card_detection(host);
6957
6958diff -uNr linux-2.6.31/drivers/mmc/host/sdhci.h linux-2.6.31.new/drivers/mmc/host/sdhci.h
6959--- linux-2.6.31/drivers/mmc/host/sdhci.h 2009-10-23 11:18:30.000000000 -0700
6960+++ linux-2.6.31.new/drivers/mmc/host/sdhci.h 2009-10-23 11:17:25.000000000 -0700
6961@@ -143,7 +143,7 @@
6962 #define SDHCI_CAN_DO_ADMA2 0x00080000
6963 #define SDHCI_CAN_DO_ADMA1 0x00100000
6964 #define SDHCI_CAN_DO_HISPD 0x00200000
6965-#define SDHCI_CAN_DO_DMA 0x00400000
6966+#define SDHCI_CAN_DO_SDMA 0x00400000
6967 #define SDHCI_CAN_VDD_330 0x01000000
6968 #define SDHCI_CAN_VDD_300 0x02000000
6969 #define SDHCI_CAN_VDD_180 0x04000000
6970@@ -250,7 +250,7 @@
6971 spinlock_t lock; /* Mutex */
6972
6973 int flags; /* Host attributes */
6974-#define SDHCI_USE_DMA (1<<0) /* Host is DMA capable */
6975+#define SDHCI_USE_SDMA (1<<0) /* Host is SDMA capable */
6976 #define SDHCI_USE_ADMA (1<<1) /* Host is ADMA capable */
6977 #define SDHCI_REQ_USE_DMA (1<<2) /* Use DMA for this req. */
6978 #define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */
6979diff -uNr linux-2.6.31/drivers/mmc/host/sdhci-pci.c linux-2.6.31.new/drivers/mmc/host/sdhci-pci.c
6980--- linux-2.6.31/drivers/mmc/host/sdhci-pci.c 2009-10-23 11:18:30.000000000 -0700
6981+++ linux-2.6.31.new/drivers/mmc/host/sdhci-pci.c 2009-10-23 11:17:25.000000000 -0700
6982@@ -395,7 +395,7 @@
6983
6984 if (((pdev->class & 0xFFFF00) == (PCI_CLASS_SYSTEM_SDHCI << 8)) &&
6985 ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) &&
6986- (host->flags & SDHCI_USE_DMA)) {
6987+ (host->flags & SDHCI_USE_SDMA)) {
6988 dev_warn(&pdev->dev, "Will use DMA mode even though HW "
6989 "doesn't fully claim to support it.\n");
6990 }
6991diff -uNr linux-2.6.31/drivers/net/Kconfig linux-2.6.31.new/drivers/net/Kconfig
6992--- linux-2.6.31/drivers/net/Kconfig 2009-10-23 11:18:30.000000000 -0700
6993+++ linux-2.6.31.new/drivers/net/Kconfig 2009-10-23 11:17:23.000000000 -0700
6994@@ -1730,6 +1730,16 @@
6995 This platform driver is for Micrel KSZ8842 / KS8842
6996 2-port ethernet switch chip (managed, VLAN, QoS).
6997
6998+config KS8842_TIMB_DMA
6999+ bool "Use Timberdale specific DMA engine"
7000+ depends on KS8842 && MFD_TIMBERDALE
7001+ select MFD_TIMBERDALE_DMA
7002+ help
7003+ This option enables usage of the timberdale specific DMA engine
7004+ for the KS8842 driver. Rather than using PIO which results in
7005+ single accesses over PCIe, the DMA block of the timberdale FPGA
7006+ will burst data to and from the KS8842.
7007+
7008 config KS8851
7009 tristate "Micrel KS8851 SPI"
7010 depends on SPI
7011diff -uNr linux-2.6.31/drivers/net/ks8842.c linux-2.6.31.new/drivers/net/ks8842.c
7012--- linux-2.6.31/drivers/net/ks8842.c 2009-10-23 11:18:30.000000000 -0700
7013+++ linux-2.6.31.new/drivers/net/ks8842.c 2009-10-23 11:17:22.000000000 -0700
7014@@ -26,11 +26,17 @@
7015 #include <linux/netdevice.h>
7016 #include <linux/etherdevice.h>
7017 #include <linux/ethtool.h>
7018+#include <linux/mfd/timbdma.h>
7019
7020 #define DRV_NAME "ks8842"
7021
7022 /* Timberdale specific Registers */
7023-#define REG_TIMB_RST 0x1c
7024+#define REG_TIMB_RST 0x1c
7025+#define REG_TIMB_FIFO 0x20
7026+#define REG_TIMB_ISR 0x24
7027+#define REG_TIMB_IER 0x28
7028+#define REG_TIMB_IAR 0x2C
7029+#define REQ_TIMB_DMA_RESUME 0x30
7030
7031 /* KS8842 registers */
7032
7033@@ -73,6 +79,11 @@
7034 #define IRQ_RX_ERROR 0x0080
7035 #define ENABLED_IRQS (IRQ_LINK_CHANGE | IRQ_TX | IRQ_RX | IRQ_RX_STOPPED | \
7036 IRQ_TX_STOPPED | IRQ_RX_OVERRUN | IRQ_RX_ERROR)
7037+#ifdef CONFIG_KS8842_TIMB_DMA
7038+ #define ENABLED_IRQS_IP (IRQ_LINK_CHANGE | IRQ_RX_STOPPED | \
7039+ IRQ_TX_STOPPED | IRQ_RX_OVERRUN | IRQ_RX_ERROR)
7040+ #define ENABLED_IRQS_DMA (ENABLED_IRQS_IP | IRQ_RX)
7041+#endif
7042 #define REG_ISR 0x02
7043 #define REG_RXSR 0x04
7044 #define RXSR_VALID 0x8000
7045@@ -111,14 +122,50 @@
7046 #define REG_P1CR4 0x02
7047 #define REG_P1SR 0x04
7048
7049+#ifdef CONFIG_KS8842_TIMB_DMA
7050+#define DMA_BUFFER_SIZE 2048
7051+
7052+#define DMA_DEV(a) ((a->dev->parent) ? a->dev->parent : a->dev)
7053+
7054+#define DMA_ONGOING(a) (a->dma_tx.ongoing | a->dma_rx.ongoing)
7055+
7056+struct ks8842_dma_ctl {
7057+ void *desc;
7058+ void *buf;
7059+ dma_addr_t addr;
7060+ unsigned ongoing;
7061+};
7062+
7063+struct ks8842_rx_dma_ctl {
7064+ void *desc;
7065+ struct sk_buff *skb;
7066+ dma_addr_t addr;
7067+};
7068+
7069+#endif
7070+
7071 struct ks8842_adapter {
7072 void __iomem *hw_addr;
7073 int irq;
7074 struct tasklet_struct tasklet;
7075 spinlock_t lock; /* spinlock to be interrupt safe */
7076- struct platform_device *pdev;
7077+ struct device *dev;
7078+ struct work_struct timeout_work;
7079+ struct net_device *netdev;
7080+#ifdef CONFIG_KS8842_TIMB_DMA
7081+ unsigned use_dma;
7082+ struct ks8842_dma_ctl dma_tx;
7083+ struct ks8842_rx_dma_ctl dma_rx;
7084+#endif
7085 };
7086
7087+#ifdef CONFIG_KS8842_TIMB_DMA
7088+static inline void ks8842_resume_dma(struct ks8842_adapter *adapter)
7089+{
7090+ iowrite32(1, adapter->hw_addr + REQ_TIMB_DMA_RESUME);
7091+}
7092+#endif
7093+
7094 static inline void ks8842_select_bank(struct ks8842_adapter *adapter, u16 bank)
7095 {
7096 iowrite16(bank, adapter->hw_addr + REG_SELECT_BANK);
7097@@ -195,7 +242,6 @@
7098 msleep(10);
7099 iowrite16(0, adapter->hw_addr + REG_GRR);
7100 */
7101- iowrite16(32, adapter->hw_addr + REG_SELECT_BANK);
7102 iowrite32(0x1, adapter->hw_addr + REG_TIMB_RST);
7103 msleep(20);
7104 }
7105@@ -203,8 +249,10 @@
7106 static void ks8842_update_link_status(struct net_device *netdev,
7107 struct ks8842_adapter *adapter)
7108 {
7109+ u16 p1mbsr = ks8842_read16(adapter, 45, REG_P1MBSR);
7110+
7111 /* check the status of the link */
7112- if (ks8842_read16(adapter, 45, REG_P1MBSR) & 0x4) {
7113+ if (p1mbsr & 0x4) {
7114 netif_carrier_on(netdev);
7115 netif_wake_queue(netdev);
7116 } else {
7117@@ -241,10 +289,8 @@
7118 /* Enable QMU Transmit flow control / transmit padding / Transmit CRC */
7119 ks8842_write16(adapter, 16, 0x000E, REG_TXCR);
7120
7121- /* enable the receiver, uni + multi + broadcast + flow ctrl
7122- + crc strip */
7123- ks8842_write16(adapter, 16, 0x8 | 0x20 | 0x40 | 0x80 | 0x400,
7124- REG_RXCR);
7125+ /* enable the receiver, uni + multi + broadcast + crc strip */
7126+ ks8842_write16(adapter, 16, 0x8 | 0x20 | 0x40 | 0x80, REG_RXCR);
7127
7128 /* TX frame pointer autoincrement */
7129 ks8842_write16(adapter, 17, 0x4000, REG_TXFDPR);
7130@@ -261,13 +307,11 @@
7131 /* enable no excessive collison drop */
7132 ks8842_enable_bits(adapter, 32, 1 << 3, REG_SGCR2);
7133
7134- /* Enable port 1 force flow control / back pressure / transmit / recv */
7135- ks8842_write16(adapter, 48, 0x1E07, REG_P1CR2);
7136+ /* Enable port 1 / back pressure / transmit / recv */
7137+ ks8842_write16(adapter, 48, 0xE07, REG_P1CR2);
7138
7139 /* restart port auto-negotiation */
7140 ks8842_enable_bits(adapter, 49, 1 << 13, REG_P1CR4);
7141- /* only advertise 10Mbps */
7142- ks8842_clear_bits(adapter, 49, 3 << 2, REG_P1CR4);
7143
7144 /* Enable the transmitter */
7145 ks8842_enable_tx(adapter);
7146@@ -279,7 +323,17 @@
7147 ks8842_write16(adapter, 18, 0xffff, REG_ISR);
7148
7149 /* enable interrupts */
7150- ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER);
7151+#ifdef CONFIG_KS8842_TIMB_DMA
7152+ if (adapter->use_dma) {
7153+ iowrite16(ENABLED_IRQS_IP, adapter->hw_addr + REG_TIMB_IER);
7154+ ks8842_write16(adapter, 18, ENABLED_IRQS_DMA, REG_IER);
7155+ } else {
7156+#endif
7157+ ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER);
7158+ iowrite16(ENABLED_IRQS, adapter->hw_addr + REG_TIMB_IER);
7159+#ifdef CONFIG_KS8842_TIMB_DMA
7160+ }
7161+#endif
7162
7163 /* enable the switch */
7164 ks8842_write16(adapter, 32, 0x1, REG_SW_ID_AND_ENABLE);
7165@@ -302,11 +356,73 @@
7166 ks8842_write16(adapter, 39, mac, REG_MACAR3);
7167 }
7168
7169+static void ks8842_write_mac_addr(struct ks8842_adapter *adapter, u8 *mac)
7170+{
7171+ unsigned long flags;
7172+ unsigned i;
7173+
7174+ spin_lock_irqsave(&adapter->lock, flags);
7175+ for (i = 0; i < ETH_ALEN; i++) {
7176+ ks8842_write8(adapter, 2, mac[ETH_ALEN - i - 1], REG_MARL + i);
7177+ ks8842_write8(adapter, 39, mac[ETH_ALEN - i - 1],
7178+ REG_MACAR1 + i);
7179+ }
7180+ spin_unlock_irqrestore(&adapter->lock, flags);
7181+}
7182+
7183 static inline u16 ks8842_tx_fifo_space(struct ks8842_adapter *adapter)
7184 {
7185 return ks8842_read16(adapter, 16, REG_TXMIR) & 0x1fff;
7186 }
7187
7188+#ifdef CONFIG_KS8842_TIMB_DMA
7189+static int ks8842_tx_frame_dma(struct sk_buff *skb, struct net_device *netdev)
7190+{
7191+ struct ks8842_adapter *adapter = netdev_priv(netdev);
7192+ struct ks8842_dma_ctl *ctl = &adapter->dma_tx;
7193+ int err;
7194+ int len = skb->len + sizeof(u32);
7195+ u8 *buf = ctl->buf;
7196+
7197+ if (ctl->ongoing) {
7198+ dev_dbg(adapter->dev, "%s: TX ongoing\n", __func__);
7199+ /* transfer ongoing */
7200+ return NETDEV_TX_BUSY;
7201+ }
7202+
7203+ /* copy data to the TX buffer */
7204+ /* the control word, enable IRQ, port 1 and the length */
7205+ *buf++ = 0x00;
7206+ *buf++ = 0x01; /* Port 1 */
7207+ *buf++ = skb->len & 0xff;
7208+ *buf++ = (skb->len >> 8) & 0xff;
7209+ skb_copy_from_linear_data(skb, buf, skb->len);
7210+
7211+ dma_sync_single_range_for_device(DMA_DEV(adapter), ctl->addr, 0, len,
7212+ DMA_TO_DEVICE);
7213+
7214+ /* make sure the length is a multiple of 4 */
7215+ if (len % 4)
7216+ len += 4 - len % 4;
7217+
7218+ err = timbdma_prep_desc(ctl->desc, ctl->addr, len);
7219+ if (err)
7220+ return NETDEV_TX_BUSY;
7221+
7222+ ctl->ongoing = 1;
7223+ err = timbdma_start(DMA_IRQ_ETH_TX, ctl->desc, 0);
7224+ if (err) {
7225+ ctl->ongoing = 0;
7226+ return NETDEV_TX_BUSY;
7227+ }
7228+ netdev->stats.tx_bytes += skb->len;
7229+
7230+ dev_kfree_skb(skb);
7231+
7232+ return NETDEV_TX_OK;
7233+}
7234+#endif
7235+
7236 static int ks8842_tx_frame(struct sk_buff *skb, struct net_device *netdev)
7237 {
7238 struct ks8842_adapter *adapter = netdev_priv(netdev);
7239@@ -314,7 +430,7 @@
7240 u32 *ptr = (u32 *)skb->data;
7241 u32 ctrl;
7242
7243- dev_dbg(&adapter->pdev->dev,
7244+ dev_dbg(adapter->dev,
7245 "%s: len %u head %p data %p tail %p end %p\n",
7246 __func__, skb->len, skb->head, skb->data,
7247 skb_tail_pointer(skb), skb_end_pointer(skb));
7248@@ -344,6 +460,104 @@
7249 return NETDEV_TX_OK;
7250 }
7251
7252+#ifdef CONFIG_KS8842_TIMB_DMA
7253+static int __ks8842_start_new_rx_dma(struct net_device *netdev,
7254+ struct ks8842_adapter *adapter)
7255+{
7256+ struct ks8842_rx_dma_ctl *ctl = &adapter->dma_rx;
7257+ int err;
7258+
7259+ ctl->skb = netdev_alloc_skb(netdev, DMA_BUFFER_SIZE);
7260+ if (ctl->skb) {
7261+ ctl->addr = dma_map_single(DMA_DEV(adapter), ctl->skb->data,
7262+ DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
7263+ err = dma_mapping_error(DMA_DEV(adapter), ctl->addr);
7264+ if (unlikely(err)) {
7265+ ctl->addr = 0;
7266+ goto out;
7267+ }
7268+ err = timbdma_prep_desc(ctl->desc, ctl->addr, DMA_BUFFER_SIZE);
7269+ if (unlikely(err))
7270+ goto out;
7271+ err = timbdma_start(DMA_IRQ_ETH_RX, ctl->desc, 0);
7272+ if (unlikely(err))
7273+ goto out;
7274+ } else {
7275+ err = -ENOMEM;
7276+ ctl->addr = 0;
7277+ goto out;
7278+ }
7279+
7280+ return err;
7281+out:
7282+ if (ctl->addr)
7283+ dma_unmap_single(DMA_DEV(adapter), ctl->addr, DMA_BUFFER_SIZE,
7284+ DMA_FROM_DEVICE);
7285+ ctl->addr = 0;
7286+ if (ctl->skb)
7287+ dev_kfree_skb(ctl->skb);
7288+
7289+ ctl->skb = NULL;
7290+
7291+ printk(KERN_ERR DRV_NAME": Failed to start RX DMA: %d\n", err);
7292+ return err;
7293+}
7294+
7295+static void ks8842_rx_frame_dma(struct net_device *netdev,
7296+ struct ks8842_adapter *adapter)
7297+{
7298+ struct ks8842_rx_dma_ctl *ctl = &adapter->dma_rx;
7299+ struct sk_buff *skb = ctl->skb;
7300+ dma_addr_t addr = ctl->addr;
7301+ u32 status;
7302+
7303+ /* kick next transfer going */
7304+ __ks8842_start_new_rx_dma(netdev, adapter);
7305+
7306+ /* now handle the data we got */
7307+ dma_unmap_single(DMA_DEV(adapter), addr, DMA_BUFFER_SIZE,
7308+ DMA_FROM_DEVICE);
7309+
7310+ status = *((u32 *)skb->data);
7311+
7312+ dev_dbg(adapter->dev, "%s - rx_data: status: %x\n",
7313+ __func__, status & 0xffff);
7314+
7315+ /* check the status */
7316+ if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) {
7317+ int len = (status >> 16) & 0x7ff;
7318+
7319+ dev_dbg(adapter->dev, "%s, got package, len: %d, skb: %p\n",
7320+ __func__, len, skb);
7321+
7322+ netdev->stats.rx_packets++;
7323+ netdev->stats.rx_bytes += len;
7324+ if (status & RXSR_MULTICAST)
7325+ netdev->stats.multicast++;
7326+
7327+ /* we are not nice to the stack, we want to be nice
7328+ * to our DMA engine instead, reserve 4 bytes
7329+ * which is the status word
7330+ */
7331+ skb_reserve(skb, 4);
7332+ skb_put(skb, len);
7333+
7334+ skb->protocol = eth_type_trans(skb, netdev);
7335+ netif_rx(skb);
7336+ } else {
7337+ dev_dbg(adapter->dev, "RX error, status: %x\n", status);
7338+ netdev->stats.rx_errors++;
7339+ if (status & RXSR_TOO_LONG)
7340+ netdev->stats.rx_length_errors++;
7341+ if (status & RXSR_CRC_ERROR)
7342+ netdev->stats.rx_crc_errors++;
7343+ if (status & RXSR_RUNT)
7344+ netdev->stats.rx_frame_errors++;
7345+ dev_kfree_skb(skb);
7346+ }
7347+}
7348+#endif
7349+
7350 static void ks8842_rx_frame(struct net_device *netdev,
7351 struct ks8842_adapter *adapter)
7352 {
7353@@ -352,14 +566,14 @@
7354
7355 status &= 0xffff;
7356
7357- dev_dbg(&adapter->pdev->dev, "%s - rx_data: status: %x\n",
7358+ dev_dbg(adapter->dev, "%s - rx_data: status: %x\n",
7359 __func__, status);
7360
7361 /* check the status */
7362 if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) {
7363 struct sk_buff *skb = netdev_alloc_skb(netdev, len + 2);
7364
7365- dev_dbg(&adapter->pdev->dev, "%s, got package, len: %d\n",
7366+ dev_dbg(adapter->dev, "%s, got package, len: %d\n",
7367 __func__, len);
7368 if (skb) {
7369 u32 *data;
7370@@ -386,7 +600,7 @@
7371 } else
7372 netdev->stats.rx_dropped++;
7373 } else {
7374- dev_dbg(&adapter->pdev->dev, "RX error, status: %x\n", status);
7375+ dev_dbg(adapter->dev, "RX error, status: %x\n", status);
7376 netdev->stats.rx_errors++;
7377 if (status & RXSR_TOO_LONG)
7378 netdev->stats.rx_length_errors++;
7379@@ -409,7 +623,7 @@
7380 void ks8842_handle_rx(struct net_device *netdev, struct ks8842_adapter *adapter)
7381 {
7382 u16 rx_data = ks8842_read16(adapter, 16, REG_RXMIR) & 0x1fff;
7383- dev_dbg(&adapter->pdev->dev, "%s Entry - rx_data: %d\n",
7384+ dev_dbg(adapter->dev, "%s Entry - rx_data: %d\n",
7385 __func__, rx_data);
7386 while (rx_data) {
7387 ks8842_rx_frame(netdev, adapter);
7388@@ -420,7 +634,7 @@
7389 void ks8842_handle_tx(struct net_device *netdev, struct ks8842_adapter *adapter)
7390 {
7391 u16 sr = ks8842_read16(adapter, 16, REG_TXSR);
7392- dev_dbg(&adapter->pdev->dev, "%s - entry, sr: %x\n", __func__, sr);
7393+ dev_dbg(adapter->dev, "%s - entry, sr: %x\n", __func__, sr);
7394 netdev->stats.tx_packets++;
7395 if (netif_queue_stopped(netdev))
7396 netif_wake_queue(netdev);
7397@@ -429,7 +643,7 @@
7398 void ks8842_handle_rx_overrun(struct net_device *netdev,
7399 struct ks8842_adapter *adapter)
7400 {
7401- dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__);
7402+ dev_dbg(adapter->dev, "%s: entry\n", __func__);
7403 netdev->stats.rx_errors++;
7404 netdev->stats.rx_fifo_errors++;
7405 }
7406@@ -448,20 +662,33 @@
7407 spin_unlock_irqrestore(&adapter->lock, flags);
7408
7409 isr = ks8842_read16(adapter, 18, REG_ISR);
7410- dev_dbg(&adapter->pdev->dev, "%s - ISR: 0x%x\n", __func__, isr);
7411+ dev_dbg(adapter->dev, "%s - ISR: 0x%x\n", __func__, isr);
7412+
7413+#ifdef CONFIG_KS8842_TIMB_DMA
7414+ if (adapter->use_dma)
7415+ isr &= ~IRQ_RX;
7416+#endif
7417
7418 /* Ack */
7419 ks8842_write16(adapter, 18, isr, REG_ISR);
7420
7421+ /* Ack in the timberdale IP as well */
7422+ iowrite32(0x1, adapter->hw_addr + REG_TIMB_IAR);
7423+
7424 if (!netif_running(netdev))
7425 return;
7426
7427 if (isr & IRQ_LINK_CHANGE)
7428 ks8842_update_link_status(netdev, adapter);
7429
7430+ /* should not get IRQ_RX when in DMA mode */
7431 if (isr & (IRQ_RX | IRQ_RX_ERROR))
7432- ks8842_handle_rx(netdev, adapter);
7433+#ifdef CONFIG_KS8842_TIMB_DMA
7434+ if (!adapter->use_dma)
7435+#endif
7436+ ks8842_handle_rx(netdev, adapter);
7437
7438+ /* should only happen when not doing DMA */
7439 if (isr & IRQ_TX)
7440 ks8842_handle_tx(netdev, adapter);
7441
7442@@ -480,8 +707,18 @@
7443
7444 /* re-enable interrupts, put back the bank selection register */
7445 spin_lock_irqsave(&adapter->lock, flags);
7446- ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER);
7447+#ifdef CONFIG_KS8842_TIMB_DMA
7448+ if (adapter->use_dma)
7449+ ks8842_write16(adapter, 18, ENABLED_IRQS_DMA, REG_IER);
7450+ else
7451+#endif
7452+ ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER);
7453+
7454 iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK);
7455+#ifdef CONFIG_KS8842_TIMB_DMA
7456+ /* resume DMA operations */
7457+ ks8842_resume_dma(adapter);
7458+#endif
7459 spin_unlock_irqrestore(&adapter->lock, flags);
7460 }
7461
7462@@ -493,11 +730,17 @@
7463 irqreturn_t ret = IRQ_NONE;
7464
7465 isr = ks8842_read16(adapter, 18, REG_ISR);
7466- dev_dbg(&adapter->pdev->dev, "%s - ISR: 0x%x\n", __func__, isr);
7467+ dev_dbg(adapter->dev, "%s - ISR: 0x%x\n", __func__, isr);
7468
7469 if (isr) {
7470- /* disable IRQ */
7471- ks8842_write16(adapter, 18, 0x00, REG_IER);
7472+#ifdef CONFIG_KS8842_TIMB_DMA
7473+ if (adapter->use_dma)
7474+ /* disable all but RX IRQ, since the FPGA relies on it*/
7475+ ks8842_write16(adapter, 18, IRQ_RX, REG_IER);
7476+ else
7477+#endif
7478+ /* disable IRQ */
7479+ ks8842_write16(adapter, 18, 0x00, REG_IER);
7480
7481 /* schedule tasklet */
7482 tasklet_schedule(&adapter->tasklet);
7483@@ -506,23 +749,129 @@
7484 }
7485
7486 iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK);
7487-
7488+#ifdef CONFIG_KS8842_TIMB_DMA
7489+ ks8842_resume_dma(adapter);
7490+#endif
7491 return ret;
7492 }
7493
7494+#ifdef CONFIG_KS8842_TIMB_DMA
7495+static int ks8842_dma_irq(u32 flag, void *data)
7496+{
7497+ struct net_device *netdev = data;
7498+ struct ks8842_adapter *adapter = netdev_priv(netdev);
7499+
7500+ if (flag & DMA_IRQ_ETH_RX) {
7501+ dev_dbg(adapter->dev, "RX DMA finished\n");
7502+ ks8842_rx_frame_dma(netdev, adapter);
7503+ }
7504+ if (flag & DMA_IRQ_ETH_TX) {
7505+ struct ks8842_dma_ctl *ctl = &adapter->dma_tx;
7506+ dev_dbg(adapter->dev, "TX DMA finished\n");
7507+
7508+ netdev->stats.tx_packets++;
7509+ ctl->ongoing = 0;
7510+
7511+ if (netif_queue_stopped(netdev))
7512+ netif_wake_queue(netdev);
7513+ }
7514+
7515+ return 0;
7516+}
7517+
7518+static void ks8842_dealloc_dma_bufs(struct ks8842_adapter *adapter)
7519+{
7520+ struct ks8842_dma_ctl *tx_ctl = &adapter->dma_tx;
7521+ struct ks8842_rx_dma_ctl *rx_ctl = &adapter->dma_rx;
7522+
7523+ if (tx_ctl->ongoing)
7524+ timbdma_stop(DMA_IRQ_ETH_TX);
7525+ tx_ctl->ongoing = 0;
7526+ if (rx_ctl->skb)
7527+ timbdma_stop(DMA_IRQ_ETH_RX);
7528+
7529+ timbdma_set_interruptcb(DMA_IRQ_ETH_RX | DMA_IRQ_ETH_TX, NULL, NULL);
7530+
7531+ if (rx_ctl->desc)
7532+ timbdma_free_desc(rx_ctl->desc);
7533+ rx_ctl->desc = NULL;
7534+ if (tx_ctl->desc)
7535+ timbdma_free_desc(tx_ctl->desc);
7536+ tx_ctl->desc = NULL;
7537+ if (rx_ctl->addr)
7538+ dma_unmap_single(DMA_DEV(adapter), rx_ctl->addr,
7539+ DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
7540+ rx_ctl->addr = 0;
7541+ if (tx_ctl->addr)
7542+ dma_unmap_single(DMA_DEV(adapter), tx_ctl->addr,
7543+ DMA_BUFFER_SIZE, DMA_TO_DEVICE);
7544+ tx_ctl->addr = 0;
7545+ dev_kfree_skb(rx_ctl->skb);
7546+ rx_ctl->skb = NULL;
7547+ kfree(tx_ctl->buf);
7548+ tx_ctl->buf = NULL;
7549+}
7550+#endif
7551
7552 /* Netdevice operations */
7553
7554 static int ks8842_open(struct net_device *netdev)
7555 {
7556 struct ks8842_adapter *adapter = netdev_priv(netdev);
7557+#ifdef CONFIG_KS8842_TIMB_DMA
7558+ struct ks8842_dma_ctl *tx_ctl = &adapter->dma_tx;
7559+ struct ks8842_rx_dma_ctl *rx_ctl = &adapter->dma_rx;
7560+ int use_dma = 0;
7561+#endif
7562 int err;
7563
7564- dev_dbg(&adapter->pdev->dev, "%s - entry\n", __func__);
7565+ dev_dbg(adapter->dev, "%s - entry\n", __func__);
7566+
7567+#ifdef CONFIG_KS8842_TIMB_DMA
7568+ if (adapter->use_dma) {
7569+ /* allocate SG descriptor */
7570+ tx_ctl->buf = kmalloc(DMA_BUFFER_SIZE, GFP_KERNEL);
7571+ if (!tx_ctl->buf)
7572+ goto no_dma;
7573+ tx_ctl->addr = dma_map_single(DMA_DEV(adapter), tx_ctl->buf,
7574+ DMA_BUFFER_SIZE, DMA_TO_DEVICE);
7575+ err = dma_mapping_error(DMA_DEV(adapter), tx_ctl->addr);
7576+ if (err) {
7577+ tx_ctl->addr = 0;
7578+ goto no_dma;
7579+ }
7580+ tx_ctl->desc = timbdma_alloc_desc(DMA_BUFFER_SIZE, 1);
7581+ if (!tx_ctl->desc)
7582+ goto no_dma;
7583+
7584+ rx_ctl->desc = timbdma_alloc_desc(DMA_BUFFER_SIZE, 1);
7585+ if (!rx_ctl->desc)
7586+ goto no_dma;
7587+
7588+ timbdma_set_interruptcb(DMA_IRQ_ETH_RX | DMA_IRQ_ETH_TX,
7589+ ks8842_dma_irq, (void *)netdev);
7590+
7591+ /* start RX dma */
7592+ err = __ks8842_start_new_rx_dma(netdev, adapter);
7593+ if (err)
7594+ goto no_dma;
7595+
7596+ use_dma = 1;
7597+ }
7598+no_dma:
7599+ if (!use_dma) {
7600+ printk(KERN_WARNING DRV_NAME
7601+ ": Failed to initiate DMA, falling back to PIO\n");
7602+ ks8842_dealloc_dma_bufs(adapter);
7603+ adapter->use_dma = 0;
7604+ }
7605+#endif
7606
7607 /* reset the HW */
7608 ks8842_reset_hw(adapter);
7609
7610+ ks8842_write_mac_addr(adapter, netdev->dev_addr);
7611+
7612 ks8842_update_link_status(netdev, adapter);
7613
7614 err = request_irq(adapter->irq, ks8842_irq, IRQF_SHARED, DRV_NAME,
7615@@ -536,11 +885,19 @@
7616 return 0;
7617 }
7618
7619+
7620 static int ks8842_close(struct net_device *netdev)
7621 {
7622 struct ks8842_adapter *adapter = netdev_priv(netdev);
7623
7624- dev_dbg(&adapter->pdev->dev, "%s - entry\n", __func__);
7625+ dev_dbg(adapter->dev, "%s - entry\n", __func__);
7626+
7627+ cancel_work_sync(&adapter->timeout_work);
7628+
7629+#ifdef CONFIG_KS8842_TIMB_DMA
7630+ if (adapter->use_dma)
7631+ ks8842_dealloc_dma_bufs(adapter);
7632+#endif
7633
7634 /* free the irq */
7635 free_irq(adapter->irq, adapter);
7636@@ -556,8 +913,20 @@
7637 int ret;
7638 struct ks8842_adapter *adapter = netdev_priv(netdev);
7639
7640- dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__);
7641+ dev_dbg(adapter->dev, "%s: entry\n", __func__);
7642
7643+#ifdef CONFIG_KS8842_TIMB_DMA
7644+ if (adapter->use_dma) {
7645+ unsigned long flags;
7646+ ret = ks8842_tx_frame_dma(skb, netdev);
7647+ /* for now only allow one transfer at the time */
7648+ spin_lock_irqsave(&adapter->lock, flags);
7649+ if (adapter->dma_tx.ongoing)
7650+ netif_stop_queue(netdev);
7651+ spin_unlock_irqrestore(&adapter->lock, flags);
7652+ return ret;
7653+ }
7654+#endif
7655 ret = ks8842_tx_frame(skb, netdev);
7656
7657 if (ks8842_tx_fifo_space(adapter) < netdev->mtu + 8)
7658@@ -569,44 +938,77 @@
7659 static int ks8842_set_mac(struct net_device *netdev, void *p)
7660 {
7661 struct ks8842_adapter *adapter = netdev_priv(netdev);
7662- unsigned long flags;
7663 struct sockaddr *addr = p;
7664 char *mac = (u8 *)addr->sa_data;
7665- int i;
7666
7667- dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__);
7668+ dev_dbg(adapter->dev, "%s: entry\n", __func__);
7669
7670 if (!is_valid_ether_addr(addr->sa_data))
7671 return -EADDRNOTAVAIL;
7672
7673 memcpy(netdev->dev_addr, mac, netdev->addr_len);
7674
7675- spin_lock_irqsave(&adapter->lock, flags);
7676- for (i = 0; i < ETH_ALEN; i++) {
7677- ks8842_write8(adapter, 2, mac[ETH_ALEN - i - 1], REG_MARL + i);
7678- ks8842_write8(adapter, 39, mac[ETH_ALEN - i - 1],
7679- REG_MACAR1 + i);
7680- }
7681- spin_unlock_irqrestore(&adapter->lock, flags);
7682+ ks8842_write_mac_addr(adapter, mac);
7683 return 0;
7684 }
7685
7686-static void ks8842_tx_timeout(struct net_device *netdev)
7687+static void ks8842_tx_timeout_work(struct work_struct *work)
7688 {
7689- struct ks8842_adapter *adapter = netdev_priv(netdev);
7690+ struct ks8842_adapter *adapter =
7691+ container_of(work, struct ks8842_adapter, timeout_work);
7692+ struct net_device *netdev = adapter->netdev;
7693 unsigned long flags;
7694
7695- dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__);
7696+ dev_dbg(adapter->dev, "%s: entry\n", __func__);
7697
7698 spin_lock_irqsave(&adapter->lock, flags);
7699+#ifdef CONFIG_KS8842_TIMB_DMA
7700+ if (adapter->use_dma) {
7701+ struct ks8842_dma_ctl *tx_ctl = &adapter->dma_tx;
7702+ struct ks8842_rx_dma_ctl *rx_ctl = &adapter->dma_rx;
7703+
7704+ if (tx_ctl->ongoing)
7705+ timbdma_stop(DMA_IRQ_ETH_TX);
7706+ tx_ctl->ongoing = 0;
7707+
7708+ timbdma_stop(DMA_IRQ_ETH_RX);
7709+
7710+ dma_unmap_single(DMA_DEV(adapter), rx_ctl->addr,
7711+ DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
7712+ rx_ctl->addr = 0;
7713+
7714+ dev_kfree_skb(rx_ctl->skb);
7715+ rx_ctl->skb = NULL;
7716+ }
7717+#endif
7718+
7719 /* disable interrupts */
7720 ks8842_write16(adapter, 18, 0, REG_IER);
7721 ks8842_write16(adapter, 18, 0xFFFF, REG_ISR);
7722+
7723+ netif_stop_queue(netdev);
7724+
7725 spin_unlock_irqrestore(&adapter->lock, flags);
7726
7727 ks8842_reset_hw(adapter);
7728
7729+ ks8842_write_mac_addr(adapter, netdev->dev_addr);
7730+
7731 ks8842_update_link_status(netdev, adapter);
7732+
7733+#ifdef CONFIG_KS8842_TIMB_DMA
7734+ if (adapter->use_dma)
7735+ __ks8842_start_new_rx_dma(netdev, adapter);
7736+#endif
7737+}
7738+
7739+static void ks8842_tx_timeout(struct net_device *netdev)
7740+{
7741+ struct ks8842_adapter *adapter = netdev_priv(netdev);
7742+
7743+ dev_dbg(adapter->dev, "%s: entry\n", __func__);
7744+
7745+ schedule_work(&adapter->timeout_work);
7746 }
7747
7748 static const struct net_device_ops ks8842_netdev_ops = {
7749@@ -641,6 +1043,8 @@
7750 SET_NETDEV_DEV(netdev, &pdev->dev);
7751
7752 adapter = netdev_priv(netdev);
7753+ adapter->netdev = netdev;
7754+ INIT_WORK(&adapter->timeout_work, ks8842_tx_timeout_work);
7755 adapter->hw_addr = ioremap(iomem->start, resource_size(iomem));
7756 if (!adapter->hw_addr)
7757 goto err_ioremap;
7758@@ -651,8 +1055,10 @@
7759 goto err_get_irq;
7760 }
7761
7762- adapter->pdev = pdev;
7763-
7764+ adapter->dev = &pdev->dev;
7765+#ifdef CONFIG_KS8842_TIMB_DMA
7766+ adapter->use_dma = 1;
7767+#endif
7768 tasklet_init(&adapter->tasklet, ks8842_tasklet, (unsigned long)netdev);
7769 spin_lock_init(&adapter->lock);
7770
7771@@ -660,6 +1066,8 @@
7772 netdev->ethtool_ops = &ks8842_ethtool_ops;
7773
7774 ks8842_read_mac_addr(adapter, netdev->dev_addr);
7775+ if (!is_valid_ether_addr(netdev->dev_addr))
7776+ random_ether_addr(netdev->dev_addr);
7777
7778 id = ks8842_read16(adapter, 32, REG_SW_ID_AND_ENABLE);
7779
7780diff -uNr linux-2.6.31/drivers/net/Makefile linux-2.6.31.new/drivers/net/Makefile
7781--- linux-2.6.31/drivers/net/Makefile 2009-10-23 11:18:30.000000000 -0700
7782+++ linux-2.6.31.new/drivers/net/Makefile 2009-10-23 11:17:22.000000000 -0700
7783@@ -16,6 +16,7 @@
7784 obj-$(CONFIG_CHELSIO_T3) += cxgb3/
7785 obj-$(CONFIG_EHEA) += ehea/
7786 obj-$(CONFIG_CAN) += can/
7787+obj-$(CONFIG_MOST) += most/
7788 obj-$(CONFIG_BONDING) += bonding/
7789 obj-$(CONFIG_ATL1) += atlx/
7790 obj-$(CONFIG_ATL2) += atlx/
7791diff -uNr linux-2.6.31/drivers/net/most/Kconfig linux-2.6.31.new/drivers/net/most/Kconfig
7792--- linux-2.6.31/drivers/net/most/Kconfig 1969-12-31 16:00:00.000000000 -0800
7793+++ linux-2.6.31.new/drivers/net/most/Kconfig 2009-10-23 11:17:22.000000000 -0700
7794@@ -0,0 +1,14 @@
7795+menu "MOST Device Drivers"
7796+ depends on MOST
7797+
7798+config MOST_TIMB_MLB
7799+ tristate "The timberdale MOST block"
7800+ depends on MOST
7801+ depends on MFD_TIMBERDALE_DMA
7802+ depends on GENERIC_GPIO
7803+ depends on HAS_IOMEM
7804+ default N
7805+ ---help---
7806+ Adds support for MOST on the timberdale FPGA.
7807+
7808+endmenu
7809diff -uNr linux-2.6.31/drivers/net/most/Makefile linux-2.6.31.new/drivers/net/most/Makefile
7810--- linux-2.6.31/drivers/net/most/Makefile 1969-12-31 16:00:00.000000000 -0800
7811+++ linux-2.6.31.new/drivers/net/most/Makefile 2009-10-23 11:17:22.000000000 -0700
7812@@ -0,0 +1,6 @@
7813+#
7814+# Makefile for the Linux Media Oriented Systems Transport drivers.
7815+#
7816+
7817+obj-$(CONFIG_MOST_TIMB_MLB) += timbmlb.o
7818+
7819diff -uNr linux-2.6.31/drivers/net/most/timbmlb.c linux-2.6.31.new/drivers/net/most/timbmlb.c
7820--- linux-2.6.31/drivers/net/most/timbmlb.c 1969-12-31 16:00:00.000000000 -0800
7821+++ linux-2.6.31.new/drivers/net/most/timbmlb.c 2009-10-23 11:17:22.000000000 -0700
7822@@ -0,0 +1,1087 @@
7823+/*
7824+ * timbmlb.c Driver for the timberdale MLB block
7825+ * Copyright (c) 2009 Intel Corporation
7826+ *
7827+ * This program is free software; you can redistribute it and/or modify
7828+ * it under the terms of the GNU General Public License version 2 as
7829+ * published by the Free Software Foundation.
7830+ *
7831+ * This program is distributed in the hope that it will be useful,
7832+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7833+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7834+ * GNU General Public License for more details.
7835+ *
7836+ * You should have received a copy of the GNU General Public License
7837+ * along with this program; if not, write to the Free Software
7838+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
7839+ */
7840+#include <linux/module.h>
7841+#include <linux/interrupt.h>
7842+#include <linux/platform_device.h>
7843+#include <linux/mfd/timbdma.h>
7844+#include <linux/spinlock.h>
7845+#include <net/most/most_core.h>
7846+#include <linux/gpio.h>
7847+#include <linux/most/timbmlb.h>
7848+
7849+#define DRIVER_NAME "timb-most"
7850+
7851+#define MLB_REG_CFG 0x00
7852+#define MLB_REG_CH_CTRL 0x04
7853+#define MLB_REG_ISR 0x08
7854+#define MLB_REG_IMR 0x0C
7855+#define MLB_REG_CH_CFG_1 0x10
7856+#define MLB_REG_CH_CFG_2 0x14
7857+#define MLB_REG_CH_CFG_3 0x18
7858+#define MLB_REG_CH_CFG_4 0x1C
7859+#define MLB_REG_CH_CFG_5 0x20
7860+#define MLB_REG_CH_CFG_6 0x24
7861+#define MLB_REG_CH_CFG_7 0x28
7862+#define MLB_REG_CTRL_RX 0x2C /* 8 bits */
7863+#define MLB_REG_CTRL_TX MLB_REG_CTRL_RX
7864+#define MLB_REG_ASYNC_RX 0x30 /* 32 bits */
7865+#define MLB_REG_ASYNC_TX MLB_REG_ASYNC_RX
7866+#define MLB_REG_SYNC_RX 0x34 /* 32 bits */
7867+#define MLB_REG_SYNC_TX MLB_REG_SYNC_RX
7868+#define MLB_REG_FIFO_RST 0x38
7869+
7870+#define MLB_WR_CFG_CTRL_RX_EMPTY 0x20000
7871+#define MLB_WR_CFG_ASYNC_RX_EMPTY 0x10000
7872+#define MLB_CFG_SYNC_TX_EN 0x00200
7873+#define MLB_CFG_SYNC_RX_EN 0x00100
7874+#define MLB_CFG_ASYNC_RX_EN 0x00080
7875+#define MLB_CFG_CTRL_RX_EN 0x00040
7876+
7877+#define MLB_CH_CTRL_ASYNC_TX_START 0x8000
7878+#define MLB_CH_CTRL_ASYNC_RX_BREAK 0x4000
7879+#define MLB_CH_CTRL_CTRL_TX_START 0x0800
7880+#define MLB_CH_CTRL_CTRL_RX_BREAK 0x0400
7881+
7882+#define MLB_WR_I_SYNC_RX_EMPTY 0x80000
7883+#define MLB_WR_I_SYNC_RX_ALMOST_FULL 0x40000
7884+#define MLB_WR_I_SYNC_TX_FULL 0x20000
7885+#define MLB_WR_I_SYNC_TX_ALMOST_EMPTY 0x10000
7886+#define MLB_I_ASYNC_TX_READY 0x08000
7887+#define MLB_I_ASYNC_TX_PROT_ERR 0x04000
7888+#define MLB_I_ASYNC_TX_RX_BREAK 0x02000
7889+#define MLB_I_ASYNC_TX_BUSY_BREAK 0x01000
7890+#define MLB_I_ASYNC_RX_READY 0x00800
7891+#define MLB_I_ASYNC_RX_PROT_ERR 0x00400
7892+#define MLB_I_ASYNC_RX_CMD_BREAK 0x00200
7893+#define MLB_I_SYNC_LOCK 0x00100
7894+#define MLB_I_CTRL_TX_READY 0x00080
7895+#define MLB_I_CTRL_TX_PROT_ERR 0x00040
7896+#define MLB_I_CTRL_TX_RX_BREAK 0x00020
7897+#define MLB_I_CTRL_TX_BUSY_BREAK 0x00010
7898+#define MLB_I_CTRL_RX_READY 0x00008
7899+#define MLB_I_CTRL_RX_PROT_ERR 0x00004
7900+#define MLB_I_CTRL_RX_CMD_BREAK 0x00002
7901+#define MLB_I_SYNC_RX_PROT_ERR 0x00001
7902+
7903+#define MLB_CH_CFG_NOT_ALLOCATED 0x0000
7904+#define MLB_CH_CFG_SYNC_TX 0x0001
7905+#define MLB_CH_CFG_SYNC_RX 0x0002
7906+#define MLB_CH_CFG_ASYNC_TX 0x0003
7907+#define MLB_CH_CFG_ASYNC_RX 0x0004
7908+#define MLB_CH_CFG_CTRL_TX 0x0005
7909+#define MLB_CH_CFG_CTRL_RX 0x0006
7910+
7911+#define MLB_FIFO_RST_CTRL_TX 0x010000
7912+#define MLB_FIFO_RST_CTRL_RX 0x020000
7913+#define MLB_FIFO_RST_ASYNC_TX 0x040000
7914+#define MLB_FIFO_RST_ASYNC_RX 0x080000
7915+#define MLB_FIFO_RST_SYNC_TX 0x100000
7916+#define MLB_FIFO_RST_SYNC_RX 0x200000
7917+#define MLB_FIFO_RST_MLB 0x400000
7918+#define MLB_FIFO_RST_ALL (MLB_FIFO_RST_CTRL_TX | \
7919+ MLB_FIFO_RST_CTRL_RX | \
7920+ MLB_FIFO_RST_ASYNC_TX | \
7921+ MLB_FIFO_RST_ASYNC_RX | \
7922+ MLB_FIFO_RST_SYNC_TX | \
7923+ MLB_FIFO_RST_SYNC_RX | \
7924+ MLB_FIFO_RST_MLB)
7925+
7926+#define ASYNC_SKB_SIZE 1024
7927+#define SYNC_SKB_SIZE 32
7928+
7929+#define SYNC_MAX_DMA_SIZE 4096
7930+
7931+#define RX_CHAN 0
7932+#define TX_CHAN 1
7933+#define CHANNELS 2
7934+
7935+#define DMA_DEV(s) ((s->mdev->parent->parent) ? \
7936+ s->mdev->parent->parent : s->mdev->parent)
7937+
7938+struct timbmost {
7939+ void __iomem *membase;
7940+ struct most_dev *mdev;
7941+ int irq;
7942+ int reset_pin;
7943+ spinlock_t lock; /* mutual exclusion */
7944+
7945+ /* one queue per channel (type) */
7946+ struct sk_buff_head ctl_q;
7947+ struct sk_buff_head async_q;
7948+ struct sk_buff_head sync_q;
7949+
7950+ /* The SKB currently written/read into by the DMA engine
7951+ * only used for the synchronous channel
7952+ */
7953+ struct sk_buff *sync_read_skb;
7954+ dma_addr_t sync_read_handle;
7955+ void *sync_read_desc;
7956+ struct sk_buff *sync_write_skb;
7957+ void *sync_write_desc;
7958+ int sync_write_next_map;
7959+
7960+ /* channel numbers */
7961+ u8 ctl_channels[CHANNELS];
7962+ u8 sync_channels[CHANNELS];
7963+ u8 async_channels[CHANNELS];
7964+};
7965+
7966+static void timbmost_ctl_write_wake(struct timbmost *self);
7967+static void timbmost_async_write_wake(struct timbmost *self);
7968+
7969+static void __timbmost_dump_regs(struct timbmost *self, const char *caption)
7970+{
7971+ dev_dbg(self->mdev->parent, "%s\nMLB_CFG:\t%x\tCH_CTRL:\t%x\n",
7972+ caption,
7973+ ioread32(self->membase + MLB_REG_CFG),
7974+ ioread32(self->membase + MLB_REG_CH_CTRL));
7975+
7976+ dev_dbg(self->mdev->parent, "ISTAT:\t%x\tIMASK:\t%x\n",
7977+ ioread32(self->membase + MLB_REG_ISR),
7978+ ioread32(self->membase + MLB_REG_IMR));
7979+
7980+ dev_dbg(self->mdev->parent, "CH_CFG1:\t%x\tCH_CFG2:\t%x\n",
7981+ ioread32(self->membase + MLB_REG_CH_CFG_1),
7982+ ioread32(self->membase + MLB_REG_CH_CFG_2));
7983+
7984+ dev_dbg(self->mdev->parent, "CH_CFG3:\t%x\tCH_CFG4:\t%x\n",
7985+ ioread32(self->membase + MLB_REG_CH_CFG_3),
7986+ ioread32(self->membase + MLB_REG_CH_CFG_4));
7987+
7988+ dev_dbg(self->mdev->parent, "CH_CFG5:\t%x\tCH_CFG6:\t%x\n",
7989+ ioread32(self->membase + MLB_REG_CH_CFG_5),
7990+ ioread32(self->membase + MLB_REG_CH_CFG_6));
7991+
7992+ dev_dbg(self->mdev->parent, "CH_CFG7:\t%x\n",
7993+ ioread32(self->membase + MLB_REG_CH_CFG_7));
7994+}
7995+
7996+static void __timbmost_hw_reset(struct timbmost *self)
7997+{
7998+ /* disable all interrupts */
7999+ iowrite32(0, self->membase + MLB_REG_IMR);
8000+ iowrite32(0, self->membase + MLB_REG_ISR);
8001+
8002+ /* disable RX and TX */
8003+ iowrite32(0, self->membase + MLB_REG_CFG);
8004+ iowrite32(0, self->membase + MLB_REG_CH_CTRL);
8005+
8006+ /* make sure the channels are not allocated */
8007+ iowrite32(MLB_CH_CFG_NOT_ALLOCATED, self->membase + MLB_REG_CH_CFG_1);
8008+ iowrite32(MLB_CH_CFG_NOT_ALLOCATED, self->membase + MLB_REG_CH_CFG_2);
8009+ iowrite32(MLB_CH_CFG_NOT_ALLOCATED, self->membase + MLB_REG_CH_CFG_3);
8010+ iowrite32(MLB_CH_CFG_NOT_ALLOCATED, self->membase + MLB_REG_CH_CFG_4);
8011+ iowrite32(MLB_CH_CFG_NOT_ALLOCATED, self->membase + MLB_REG_CH_CFG_5);
8012+ iowrite32(MLB_CH_CFG_NOT_ALLOCATED, self->membase + MLB_REG_CH_CFG_6);
8013+
8014+ /* reset */
8015+ iowrite32(MLB_FIFO_RST_ALL, self->membase + MLB_REG_FIFO_RST);
8016+
8017+ /* reset the INIC */
8018+ gpio_direction_output(self->reset_pin, 0);
8019+ msleep(10);
8020+ gpio_set_value(self->reset_pin, 1);
8021+}
8022+
8023+static void __timbmost_ctl_rx(struct timbmost *self)
8024+{
8025+ u32 cfg;
8026+ do {
8027+ struct sk_buff *skb =
8028+ most_skb_alloc(CTL_FRAME_SIZE, GFP_ATOMIC);
8029+ if (!skb)
8030+ return;
8031+
8032+ do {
8033+ u32 word = ioread32(self->membase + MLB_REG_CTRL_RX);
8034+ int i;
8035+
8036+ for (i = 0; i < 4; i++)
8037+ *skb_put(skb, 1) = (word >> (i * 8)) & 0xff;
8038+
8039+ cfg = ioread32(self->membase + MLB_REG_CFG);
8040+ } while ((skb->len < CTL_FRAME_SIZE) &&
8041+ !(cfg & MLB_WR_CFG_CTRL_RX_EMPTY));
8042+
8043+ /* deliver SKB upstreams */
8044+ skb->dev = (void *)self->mdev;
8045+ most_cb(skb)->channel_type = CHAN_CTL;
8046+ /* only one channel is supported... */
8047+ most_cb(skb)->channel = self->ctl_channels[RX_CHAN];
8048+
8049+ most_recv_frame(skb);
8050+ } while (!(cfg & MLB_WR_CFG_CTRL_RX_EMPTY));
8051+}
8052+
8053+static void __timbmost_async_rx(struct timbmost *self)
8054+{
8055+ /* TODO: The FIFO is 32bit not 8bit */
8056+ u32 cfg;
8057+
8058+ __timbmost_dump_regs(self, "Before read");
8059+
8060+ do {
8061+ struct sk_buff *skb =
8062+ most_skb_alloc(ASYNC_SKB_SIZE, GFP_ATOMIC);
8063+ if (!skb)
8064+ return;
8065+
8066+ do {
8067+ *skb_put(skb, 1) =
8068+ ioread32(self->membase + MLB_REG_ASYNC_RX);
8069+ cfg = ioread32(self->membase + MLB_REG_CFG);
8070+ } while ((skb->len < ASYNC_SKB_SIZE) &&
8071+ !(cfg & MLB_WR_CFG_ASYNC_RX_EMPTY));
8072+
8073+ /* deliver SKB upstreams */
8074+ skb->dev = (void *)self->mdev;
8075+ most_cb(skb)->channel_type = CHAN_ASYNC;
8076+ /* only one channel is supported... */
8077+ most_cb(skb)->channel = self->async_channels[RX_CHAN];
8078+
8079+ most_recv_frame(skb);
8080+ } while (!(cfg & MLB_WR_CFG_ASYNC_RX_EMPTY));
8081+}
8082+
8083+static void __timbmost_sync_read_wake(struct timbmost *self)
8084+{
8085+ struct sk_buff *skb = self->sync_read_skb;
8086+ dma_addr_t map;
8087+ int err;
8088+
8089+ if (skb)
8090+ return;
8091+
8092+ skb = most_skb_alloc(SYNC_SKB_SIZE, GFP_ATOMIC);
8093+ if (!skb)
8094+ return;
8095+
8096+ map = dma_map_single(DMA_DEV(self), skb->data, SYNC_SKB_SIZE,
8097+ DMA_FROM_DEVICE);
8098+ if (dma_mapping_error(DMA_DEV(self), map))
8099+ goto map_failed;
8100+
8101+ err = timbdma_prep_desc(self->sync_read_desc, map, SYNC_SKB_SIZE);
8102+ if (err)
8103+ goto prep_failed;
8104+
8105+ dev_dbg(self->mdev->parent, "%s: will start RX: to: %x, size: %d\n",
8106+ __func__, (u32)map, SYNC_SKB_SIZE);
8107+
8108+ err = timbdma_start(DMA_IRQ_MLB_RX, self->sync_read_desc, 0);
8109+ if (err)
8110+ goto start_failed;
8111+
8112+ self->sync_read_skb = skb;
8113+ self->sync_read_handle = map;
8114+ return;
8115+start_failed:
8116+prep_failed:
8117+ dma_unmap_single(DMA_DEV(self), map, SYNC_SKB_SIZE, DMA_FROM_DEVICE);
8118+map_failed:
8119+ dev_kfree_skb(skb);
8120+}
8121+
8122+static void __timbmost_sync_rx_done(struct timbmost *self)
8123+{
8124+ struct sk_buff *skb = self->sync_read_skb;
8125+ int len;
8126+
8127+ BUG_ON(!skb);
8128+
8129+ /* unmap DMA */
8130+ dma_unmap_single(DMA_DEV(self), self->sync_read_handle, SYNC_SKB_SIZE,
8131+ DMA_FROM_DEVICE);
8132+
8133+ /* set the length */
8134+ len = timbdma_stop(DMA_IRQ_MLB_RX);
8135+ skb_put(skb, len);
8136+ /* send the SKB upwards */
8137+ skb->dev = (void *)self->mdev;
8138+ most_cb(skb)->channel_type = CHAN_SYNC;
8139+ /* only one channel is supported... */
8140+ most_cb(skb)->channel = self->sync_channels[RX_CHAN];
8141+ most_recv_frame(skb);
8142+ self->sync_read_skb = NULL;
8143+
8144+ __timbmost_sync_read_wake(self);
8145+}
8146+
8147+static void __timbmost_sync_write_wake(struct timbmost *self)
8148+{
8149+ unsigned long flags;
8150+ int len;
8151+ dma_addr_t map;
8152+ struct sk_buff *skb = self->sync_write_skb;
8153+ u32 isr;
8154+
8155+ dev_dbg(self->mdev->parent, "%s entry\n", __func__);
8156+
8157+ if (!skb) {
8158+ /* check for next SKB */
8159+ skb = skb_dequeue(&self->sync_q);
8160+ if (!skb)
8161+ return;
8162+
8163+ if (skb_dma_map(DMA_DEV(self), skb, DMA_TO_DEVICE)) {
8164+ /* failed to dma map? */
8165+ dev_kfree_skb(skb);
8166+ return;
8167+ }
8168+ /* next dma map to write is the first ... */
8169+ self->sync_write_next_map = -1;
8170+ self->sync_write_skb = skb;
8171+ dev_dbg(self->mdev->parent, "%s: New skb: fragments: %d\n",
8172+ __func__, skb_shinfo(skb)->nr_frags);
8173+ }
8174+
8175+ /* check if there is space in the FIFO */
8176+ spin_lock_irqsave(&self->lock, flags);
8177+ isr = ioread32(self->membase + MLB_REG_ISR);
8178+ if (isr & MLB_WR_I_SYNC_TX_FULL) {
8179+ /* FIFO full enable, almost empty interrupt */
8180+ u32 imr = ioread32(self->membase + MLB_REG_IMR);
8181+ imr |= MLB_WR_I_SYNC_TX_ALMOST_EMPTY;
8182+ iowrite32(imr, self->membase + MLB_REG_IMR);
8183+ }
8184+ spin_unlock_irqrestore(&self->lock, flags);
8185+
8186+ /* exit if the FIFO is full, we will continue when the almost empty
8187+ * interrupt occurs
8188+ */
8189+ if (isr & MLB_WR_I_SYNC_TX_FULL)
8190+ return;
8191+
8192+ /* send next fragment */
8193+ if (self->sync_write_next_map < 0) {
8194+ len = skb_headlen(skb);
8195+ map = skb_shinfo(skb)->dma_head;
8196+ } else {
8197+ len = skb_shinfo(skb)->frags[self->sync_write_next_map].size;
8198+ map = skb_shinfo(skb)->dma_maps[self->sync_write_next_map];
8199+ }
8200+ self->sync_write_next_map++;
8201+ dev_dbg(self->mdev->parent, "%s: Will send %x, len: %d\n",
8202+ __func__, (uint32_t)map, len);
8203+ timbdma_prep_desc(self->sync_write_desc, map, len);
8204+ timbdma_start(DMA_IRQ_MLB_TX, self->sync_write_desc, 0);
8205+}
8206+
8207+static void __timbmost_sync_tx_done(struct timbmost *self)
8208+{
8209+ struct sk_buff *skb = self->sync_write_skb;
8210+
8211+ /* TX done, free current SKB, and check for next */
8212+ BUG_ON(!skb);
8213+
8214+ /* check if this was the last DMA map */
8215+ if (self->sync_write_next_map >= skb_shinfo(skb)->nr_frags) {
8216+
8217+ /* it was the last... */
8218+ skb_dma_unmap(DMA_DEV(self), skb, DMA_TO_DEVICE);
8219+ dev_kfree_skb(skb);
8220+ self->sync_write_skb = NULL;
8221+ }
8222+
8223+ __timbmost_sync_write_wake(self);
8224+}
8225+
8226+static void timbmost_sync_start_write(struct timbmost *self)
8227+{
8228+ unsigned long flags;
8229+ struct sk_buff *skb;
8230+
8231+ spin_lock_irqsave(&self->lock, flags);
8232+ skb = self->sync_write_skb;
8233+ spin_unlock_irqrestore(&self->lock, flags);
8234+
8235+ /* transfer is ongoing */
8236+ if (skb)
8237+ return;
8238+
8239+ __timbmost_sync_write_wake(self);
8240+}
8241+
8242+/* function called in interrupt context by the timberdale DMA engine
8243+ * when a transfer is finished
8244+ */
8245+static int timbmost_dma_irq(u32 flag, void *devid)
8246+{
8247+ struct timbmost *self = (struct timbmost *)devid;
8248+
8249+ if (flag & DMA_IRQ_MLB_RX)
8250+ __timbmost_sync_rx_done(self);
8251+
8252+ if (flag & DMA_IRQ_MLB_TX)
8253+ __timbmost_sync_tx_done(self);
8254+
8255+ return 0;
8256+}
8257+
8258+static irqreturn_t timbmost_irq(int irq, void *devid)
8259+{
8260+ struct timbmost *self = (struct timbmost *)devid;
8261+ u32 isr, imr;
8262+
8263+ isr = ioread32(self->membase + MLB_REG_ISR);
8264+ imr = ioread32(self->membase + MLB_REG_IMR);
8265+
8266+ dev_dbg(self->mdev->parent, "%s: entry, isr: %x, imr: %x\n", __func__,
8267+ isr, imr);
8268+
8269+ /* mask out only enabled interrupts */
8270+ isr &= imr;
8271+
8272+ /* ack */
8273+ iowrite32(isr, self->membase + MLB_REG_ISR);
8274+
8275+ if (isr & MLB_WR_I_SYNC_TX_ALMOST_EMPTY) {
8276+ /* disable the interrupt */
8277+ imr &= ~MLB_WR_I_SYNC_TX_ALMOST_EMPTY;
8278+ iowrite32(imr, self->membase + MLB_REG_IMR);
8279+ __timbmost_sync_write_wake(self);
8280+ }
8281+
8282+ if (isr & MLB_I_ASYNC_TX_READY) {
8283+ /* disable TX interrupts */
8284+ imr &= ~(MLB_I_ASYNC_TX_READY | MLB_I_ASYNC_TX_PROT_ERR);
8285+ iowrite32(imr, self->membase + MLB_REG_IMR);
8286+ /* schedule to send next package */
8287+ timbmost_async_write_wake(self);
8288+ }
8289+
8290+ if (isr & MLB_I_ASYNC_RX_READY)
8291+ /* pass data upstreams */
8292+ __timbmost_async_rx(self);
8293+
8294+ if (isr & MLB_I_CTRL_TX_READY) {
8295+ /* disable TX interrupts */
8296+ imr &= ~(MLB_I_CTRL_TX_READY | MLB_I_CTRL_TX_PROT_ERR);
8297+ iowrite32(imr, self->membase + MLB_REG_IMR);
8298+ /* schedule to send next package */
8299+ timbmost_ctl_write_wake(self);
8300+ }
8301+
8302+ if (isr & MLB_I_CTRL_RX_READY)
8303+ /* pass data upstreams */
8304+ __timbmost_ctl_rx(self);
8305+
8306+ if (isr)
8307+ return IRQ_HANDLED;
8308+ else
8309+ return IRQ_NONE;
8310+}
8311+
8312+static int timbmost_open(struct most_dev *mdev)
8313+{
8314+ struct timbmost *self = (struct timbmost *)mdev->driver_data;
8315+ int err;
8316+
8317+ dev_dbg(mdev->parent, "%s\n", __func__);
8318+
8319+ skb_queue_head_init(&self->ctl_q);
8320+ skb_queue_head_init(&self->sync_q);
8321+ skb_queue_head_init(&self->async_q);
8322+
8323+ spin_lock_init(&self->lock);
8324+
8325+ /* request the GPIO reset pin */
8326+ err = gpio_request(self->reset_pin, DRIVER_NAME);
8327+ if (err) {
8328+ printk(KERN_ERR DRIVER_NAME
8329+ " Failed to request reset pin: %d, err: %d\n",
8330+ self->reset_pin, err);
8331+ return err;
8332+ }
8333+
8334+ __timbmost_hw_reset(self);
8335+
8336+ /* set DMA callback */
8337+ timbdma_set_interruptcb(DMA_IRQ_MLB_RX | DMA_IRQ_MLB_TX,
8338+ timbmost_dma_irq, (void *)self);
8339+
8340+ self->sync_read_desc = timbdma_alloc_desc(SYNC_MAX_DMA_SIZE, 1);
8341+ if (!self->sync_read_desc) {
8342+ err = -ENOMEM;
8343+ goto err_alloc_r_desc;
8344+ }
8345+
8346+ self->sync_write_desc = timbdma_alloc_desc(SYNC_MAX_DMA_SIZE, 1);
8347+ if (!self->sync_write_desc) {
8348+ err = -ENOMEM;
8349+ goto err_alloc_w_desc;
8350+ }
8351+
8352+ /* request IRQ */
8353+ err = request_irq(self->irq, timbmost_irq, IRQF_SHARED, "timb-most",
8354+ self);
8355+ if (err)
8356+ goto err_req_irq;
8357+
8358+ return 0;
8359+
8360+err_req_irq:
8361+ timbdma_free_desc(self->sync_write_desc);
8362+err_alloc_w_desc:
8363+ timbdma_free_desc(self->sync_read_desc);
8364+err_alloc_r_desc:
8365+ gpio_free(self->reset_pin);
8366+ return err;
8367+}
8368+
8369+static void timbmost_stop_sync_dma(struct timbmost *self)
8370+{
8371+ if (self->sync_read_skb) {
8372+ timbdma_stop(DMA_IRQ_MLB_RX);
8373+ dma_unmap_single(DMA_DEV(self), self->sync_read_handle,
8374+ SYNC_SKB_SIZE, DMA_FROM_DEVICE);
8375+ kfree_skb(self->sync_read_skb);
8376+ self->sync_read_skb = NULL;
8377+ }
8378+
8379+ if (self->sync_write_skb) {
8380+ timbdma_stop(DMA_IRQ_MLB_TX);
8381+ skb_dma_unmap(DMA_DEV(self), self->sync_write_skb,
8382+ DMA_TO_DEVICE);
8383+ kfree_skb(self->sync_write_skb);
8384+ self->sync_write_skb = NULL;
8385+ }
8386+}
8387+
8388+static int timbmost_close(struct most_dev *mdev)
8389+{
8390+ struct timbmost *self = (struct timbmost *)mdev->driver_data;
8391+
8392+ dev_dbg(mdev->parent, "%s\n", __func__);
8393+
8394+ /* free IRQ */
8395+ free_irq(self->irq, self);
8396+
8397+ __timbmost_hw_reset(self);
8398+
8399+ /* free GPIO */
8400+ gpio_free(self->reset_pin);
8401+
8402+ /* empty all queues */
8403+ skb_queue_purge(&self->ctl_q);
8404+ skb_queue_purge(&self->sync_q);
8405+ skb_queue_purge(&self->async_q);
8406+
8407+ /* clear DMA callback */
8408+ timbdma_set_interruptcb(DMA_IRQ_MLB_RX | DMA_IRQ_MLB_TX, NULL, NULL);
8409+
8410+ return 0;
8411+}
8412+
8413+static int __timbmost_conf_channel(struct timbmost *self, u8 channel,
8414+ u8 channel_mask)
8415+{
8416+ int register_offset;
8417+ int shift;
8418+ u32 ch_cfg;
8419+
8420+ /* only even channel numbers are allowed */
8421+ if (channel % 2 || channel > 0x3e || channel == 0) {
8422+ printk(KERN_WARNING DRIVER_NAME": Invalid channel: %d\n",
8423+ channel);
8424+ return -EINVAL;
8425+ }
8426+
8427+ channel = (channel / 2) - 1;
8428+ /* the channel conf is spread out over the 7 channel config registers
8429+ * each register configures 5 channels, each reg is 32bit
8430+ */
8431+ register_offset = MLB_REG_CH_CFG_1 + (channel / 5) * 4;
8432+
8433+ /* each register configures 5 channels, 3 bit per channel
8434+ * lowest bits configures highest channel
8435+ */
8436+ shift = (4 - (channel % 5)) * 3;
8437+
8438+ ch_cfg = ioread32(self->membase + register_offset);
8439+ ch_cfg &= ~(0x7 << shift);
8440+ ch_cfg |= (channel_mask & 0x7) << shift;
8441+ iowrite32(ch_cfg, self->membase + register_offset);
8442+ return 0;
8443+}
8444+
8445+static int timbmost_conf_channel(struct most_dev *mdev,
8446+ enum most_chan_type type, u8 channel, u8 flags)
8447+{
8448+ struct timbmost *self = (struct timbmost *)mdev->driver_data;
8449+ unsigned long irq_flags;
8450+ u32 imr, cfg;
8451+ int err = -EINVAL;
8452+ int chan_idx = (flags & MOST_CONF_FLAG_TX) ? TX_CHAN : RX_CHAN;
8453+
8454+ dev_dbg(mdev->parent, "%s: channel: %d, flags: %x\n",
8455+ __func__, channel, flags);
8456+
8457+ if (flags & MOST_CONF_FLAG_UP) {
8458+ switch (type) {
8459+ case CHAN_CTL:
8460+ spin_lock_irqsave(&self->lock, irq_flags);
8461+ /* we only support one channel at the time */
8462+ if (self->ctl_channels[chan_idx])
8463+ goto error;
8464+
8465+ /* reset the FIFO */
8466+ iowrite32((chan_idx == TX_CHAN) ? MLB_FIFO_RST_CTRL_TX :
8467+ MLB_FIFO_RST_CTRL_RX,
8468+ self->membase + MLB_REG_FIFO_RST);
8469+
8470+ err = __timbmost_conf_channel(self, channel,
8471+ (chan_idx == TX_CHAN) ? MLB_CH_CFG_CTRL_TX :
8472+ MLB_CH_CFG_CTRL_RX);
8473+ if (err)
8474+ goto error;
8475+
8476+ if (chan_idx == RX_CHAN) {
8477+ /* enable the receiver */
8478+ cfg = ioread32(self->membase + MLB_REG_CFG);
8479+ cfg |= MLB_CFG_CTRL_RX_EN;
8480+ iowrite32(cfg, self->membase + MLB_REG_CFG);
8481+
8482+ /* enable RX interrupts */
8483+ imr = ioread32(self->membase + MLB_REG_IMR);
8484+ imr |= (MLB_I_CTRL_RX_READY |
8485+ MLB_I_CTRL_RX_PROT_ERR |
8486+ MLB_I_CTRL_RX_CMD_BREAK);
8487+ iowrite32(imr, self->membase + MLB_REG_IMR);
8488+ }
8489+ self->ctl_channels[chan_idx] = channel;
8490+ spin_unlock_irqrestore(&self->lock, irq_flags);
8491+ break;
8492+ case CHAN_SYNC:
8493+ spin_lock_irqsave(&self->lock, irq_flags);
8494+ /* we only support one channel at the time */
8495+ if (self->sync_channels[chan_idx])
8496+ goto error;
8497+
8498+ /* reset the FIFO */
8499+ iowrite32((chan_idx == TX_CHAN) ? MLB_FIFO_RST_SYNC_TX :
8500+ MLB_FIFO_RST_SYNC_RX,
8501+ self->membase + MLB_REG_FIFO_RST);
8502+
8503+ err = __timbmost_conf_channel(self, channel,
8504+ (chan_idx == TX_CHAN) ? MLB_CH_CFG_SYNC_TX :
8505+ MLB_CH_CFG_SYNC_RX);
8506+ if (err)
8507+ goto error;
8508+
8509+ if (chan_idx == RX_CHAN) {
8510+ /* enable the receiver */
8511+ cfg = ioread32(self->membase + MLB_REG_CFG);
8512+ cfg |= MLB_CFG_SYNC_RX_EN;
8513+ iowrite32(cfg, self->membase + MLB_REG_CFG);
8514+
8515+ /* enable prot error interrupts */
8516+ imr = ioread32(self->membase + MLB_REG_IMR);
8517+ imr |= MLB_I_SYNC_RX_PROT_ERR;
8518+ iowrite32(imr, self->membase + MLB_REG_IMR);
8519+ /* start RX DMA */
8520+ __timbmost_sync_read_wake(self);
8521+ }
8522+ self->sync_channels[chan_idx] = channel;
8523+ spin_unlock_irqrestore(&self->lock, irq_flags);
8524+
8525+ break;
8526+ case CHAN_ASYNC:
8527+ spin_lock_irqsave(&self->lock, irq_flags);
8528+ /* we only support one channel at the time */
8529+ if (self->async_channels[chan_idx])
8530+ goto error;
8531+ /* reset the FIFO */
8532+ iowrite32((chan_idx == TX_CHAN) ?
8533+ MLB_FIFO_RST_ASYNC_TX : MLB_FIFO_RST_ASYNC_RX,
8534+ self->membase + MLB_REG_FIFO_RST);
8535+
8536+ err = __timbmost_conf_channel(self, channel,
8537+ (chan_idx == TX_CHAN) ? MLB_CH_CFG_ASYNC_TX :
8538+ MLB_CH_CFG_ASYNC_RX);
8539+ if (err)
8540+ goto error;
8541+
8542+ if (chan_idx == RX_CHAN) {
8543+ /* enable the receiver */
8544+ cfg = ioread32(self->membase + MLB_REG_CFG);
8545+ cfg |= MLB_CFG_ASYNC_RX_EN;
8546+ iowrite32(cfg, self->membase + MLB_REG_CFG);
8547+
8548+ /* enable RX interrupts */
8549+ imr = ioread32(self->membase + MLB_REG_IMR);
8550+ imr |= (MLB_I_ASYNC_RX_READY |
8551+ MLB_I_ASYNC_RX_PROT_ERR |
8552+ MLB_I_ASYNC_RX_CMD_BREAK);
8553+ iowrite32(imr, self->membase + MLB_REG_IMR);
8554+ }
8555+ self->async_channels[chan_idx] = channel;
8556+ spin_unlock_irqrestore(&self->lock, irq_flags);
8557+ break;
8558+ default:
8559+ printk(KERN_WARNING "timbmlb: Uknown channel type\n");
8560+ return -EINVAL;
8561+ }
8562+ } else {
8563+ switch (type) {
8564+ case CHAN_CTL:
8565+ /* stop any ongoing transfer */
8566+ spin_lock_irqsave(&self->lock, irq_flags);
8567+ if (self->ctl_channels[chan_idx] != channel)
8568+ goto error;
8569+
8570+ imr = ioread32(self->membase + MLB_REG_IMR);
8571+ imr &= ~(MLB_I_CTRL_TX_READY |
8572+ MLB_I_CTRL_TX_PROT_ERR |
8573+ MLB_I_CTRL_TX_RX_BREAK |
8574+ MLB_I_CTRL_TX_BUSY_BREAK |
8575+ MLB_I_CTRL_RX_READY |
8576+ MLB_I_CTRL_RX_PROT_ERR |
8577+ MLB_I_CTRL_RX_CMD_BREAK);
8578+ iowrite32(imr, self->membase + MLB_REG_IMR);
8579+
8580+ /* disable CTL RX */
8581+ cfg = ioread32(self->membase + MLB_REG_CFG);
8582+ cfg &= ~MLB_CFG_CTRL_RX_EN;
8583+ iowrite32(cfg, self->membase + MLB_REG_CFG);
8584+
8585+ err = __timbmost_conf_channel(self, channel,
8586+ MLB_CH_CFG_NOT_ALLOCATED);
8587+ spin_unlock_irqrestore(&self->lock, irq_flags);
8588+ skb_queue_purge(&self->ctl_q);
8589+ self->ctl_channels[chan_idx] = 0;
8590+ return err;
8591+ case CHAN_SYNC:
8592+
8593+ /* stop any ongoing transfer */
8594+ spin_lock_irqsave(&self->lock, irq_flags);
8595+ if (self->sync_channels[chan_idx] != channel)
8596+ goto error;
8597+
8598+ /* stop DMA */
8599+ timbmost_stop_sync_dma(self);
8600+ imr = ioread32(self->membase + MLB_REG_IMR);
8601+ imr &= ~MLB_I_SYNC_RX_PROT_ERR;
8602+ iowrite32(imr, self->membase + MLB_REG_IMR);
8603+
8604+ /* disable SYNC TX/RX */
8605+ cfg = ioread32(self->membase + MLB_REG_CFG);
8606+ cfg &= ~(MLB_CFG_SYNC_TX_EN |
8607+ MLB_CFG_SYNC_RX_EN);
8608+ iowrite32(cfg, self->membase + MLB_REG_CFG);
8609+
8610+ err = __timbmost_conf_channel(self, channel,
8611+ MLB_CH_CFG_NOT_ALLOCATED);
8612+ spin_unlock_irqrestore(&self->lock, irq_flags);
8613+ skb_queue_purge(&self->sync_q);
8614+ self->sync_channels[chan_idx] = 0;
8615+ return err;
8616+ case CHAN_ASYNC:
8617+ /* stop any ongoing transfer */
8618+ spin_lock_irqsave(&self->lock, irq_flags);
8619+ if (self->async_channels[chan_idx] != channel)
8620+ goto error;
8621+ imr = ioread32(self->membase + MLB_REG_IMR);
8622+ imr &= ~(MLB_I_ASYNC_TX_READY |
8623+ MLB_I_ASYNC_TX_PROT_ERR |
8624+ MLB_I_ASYNC_TX_RX_BREAK |
8625+ MLB_I_ASYNC_TX_BUSY_BREAK |
8626+ MLB_I_ASYNC_RX_READY |
8627+ MLB_I_ASYNC_RX_PROT_ERR |
8628+ MLB_I_ASYNC_RX_CMD_BREAK);
8629+ iowrite32(imr, self->membase + MLB_REG_IMR);
8630+
8631+ /* disable CTL RX */
8632+ cfg = ioread32(self->membase + MLB_REG_CFG);
8633+ cfg &= ~MLB_CFG_ASYNC_RX_EN;
8634+ iowrite32(cfg, self->membase + MLB_REG_CFG);
8635+
8636+ err = __timbmost_conf_channel(self, channel,
8637+ MLB_CH_CFG_NOT_ALLOCATED);
8638+ spin_unlock_irqrestore(&self->lock, irq_flags);
8639+ skb_queue_purge(&self->async_q);
8640+ self->async_channels[chan_idx] = 0;
8641+ return err;
8642+ default:
8643+ return -EINVAL;
8644+ }
8645+ }
8646+ return 0;
8647+
8648+error:
8649+ spin_unlock_irqrestore(&self->lock, irq_flags);
8650+ return err;
8651+}
8652+
8653+static void timbmost_ctl_write_wake(struct timbmost *self)
8654+{
8655+ unsigned long flags;
8656+ u32 imr;
8657+ u32 isr;
8658+ struct sk_buff *skb;
8659+ int i;
8660+
8661+ dev_dbg(self->mdev->parent, "%s entry\n", __func__);
8662+ __timbmost_dump_regs(self, "Before write");
8663+
8664+ spin_lock_irqsave(&self->lock, flags);
8665+ imr = ioread32(self->membase + MLB_REG_IMR);
8666+ isr = ioread32(self->membase + MLB_REG_ISR);
8667+ spin_unlock_irqrestore(&self->lock, flags);
8668+
8669+ /* check if the hardware is currently writing */
8670+ if (imr & MLB_I_CTRL_TX_READY)
8671+ return;
8672+
8673+ /* check if we have sync */
8674+ if (!(isr & MLB_I_SYNC_LOCK))
8675+ return;
8676+
8677+ skb = skb_dequeue(&self->ctl_q);
8678+ if (!skb)
8679+ return;
8680+
8681+ /* now write to the FIFO */
8682+ for (i = 0; i < skb->len;) {
8683+ u32 word = 0;
8684+ int j;
8685+
8686+ for (j = 0; j < 4 && i < skb->len; j++, i++)
8687+ word |= ((u8 *)skb->data)[i] << j * 8;
8688+
8689+ iowrite32(word, self->membase + MLB_REG_CTRL_TX);
8690+ }
8691+
8692+ /* data is in the FIFO, enable proper interrupts */
8693+ spin_lock_irqsave(&self->lock, flags);
8694+ imr = ioread32(self->membase + MLB_REG_IMR) | MLB_I_CTRL_TX_READY |
8695+ MLB_I_CTRL_TX_PROT_ERR;
8696+ iowrite32(imr, self->membase + MLB_REG_IMR);
8697+ /* start TX */
8698+ iowrite32(MLB_CH_CTRL_CTRL_TX_START, self->membase + MLB_REG_CH_CTRL);
8699+ spin_unlock_irqrestore(&self->lock, flags);
8700+
8701+ kfree_skb(skb);
8702+}
8703+
8704+static void timbmost_async_write_wake(struct timbmost *self)
8705+{
8706+ unsigned long flags;
8707+ u32 imr;
8708+ u32 isr;
8709+ struct sk_buff *skb;
8710+ int i;
8711+
8712+ spin_lock_irqsave(&self->lock, flags);
8713+ imr = ioread32(self->membase + MLB_REG_IMR);
8714+ isr = ioread32(self->membase + MLB_REG_ISR);
8715+ spin_unlock_irqrestore(&self->lock, flags);
8716+
8717+ /* check if the hardware is currently writing */
8718+ if (imr & MLB_I_ASYNC_TX_READY)
8719+ return;
8720+
8721+ /* check if we have sync */
8722+ if (!(isr & MLB_I_SYNC_LOCK))
8723+ return;
8724+
8725+ skb = skb_dequeue(&self->async_q);
8726+ if (!skb)
8727+ return;
8728+
8729+ /* TODO: The FIFO is 32bit not 8bit */
8730+ /* now write to the FIFO */
8731+ for (i = 0; i < skb->len; i++)
8732+ iowrite32(skb->data[i], self->membase + MLB_REG_ASYNC_TX);
8733+
8734+ /* data is in the FIFO, enable proper interrupts */
8735+ spin_lock_irqsave(&self->lock, flags);
8736+ imr = ioread32(self->membase + MLB_REG_IMR) | MLB_I_ASYNC_TX_READY |
8737+ MLB_I_ASYNC_TX_PROT_ERR;
8738+ iowrite32(imr, self->membase + MLB_REG_IMR);
8739+ /* start TX */
8740+ iowrite32(MLB_CH_CTRL_ASYNC_TX_START, self->membase + MLB_REG_CH_CTRL);
8741+ spin_unlock_irqrestore(&self->lock, flags);
8742+
8743+ kfree_skb(skb);
8744+}
8745+
8746+static int timbmost_send(struct sk_buff *skb)
8747+{
8748+ struct most_dev *mdev = (struct most_dev *)skb->dev;
8749+ struct timbmost *self = (struct timbmost *)mdev->driver_data;
8750+
8751+ dev_dbg(mdev->parent, "%s, type: %d\n",
8752+ __func__, most_cb(skb)->channel_type);
8753+
8754+ switch (most_cb(skb)->channel_type) {
8755+ case CHAN_CTL:
8756+ skb_queue_tail(&self->ctl_q, skb);
8757+ timbmost_ctl_write_wake(self);
8758+ break;
8759+ case CHAN_ASYNC:
8760+ skb_queue_tail(&self->async_q, skb);
8761+ timbmost_async_write_wake(self);
8762+ break;
8763+ case CHAN_SYNC:
8764+ skb_queue_tail(&self->sync_q, skb);
8765+ timbmost_sync_start_write(self);
8766+ break;
8767+ default:
8768+ printk(KERN_WARNING "%s: Got unsupported channel type: %d\n",
8769+ __func__, most_cb(skb)->channel_type);
8770+ kfree_skb(skb);
8771+ break;
8772+ }
8773+
8774+ return 0;
8775+}
8776+
8777+static int timbmost_probe(struct platform_device *dev)
8778+{
8779+ int err;
8780+ struct timbmost *self = NULL;
8781+ struct resource *iomem;
8782+ struct timbmlb_platform_data *pdata = dev->dev.platform_data;
8783+
8784+ if (!pdata) {
8785+ printk(KERN_ERR DRIVER_NAME "No platform data supplied\n");
8786+ err = -EINVAL;
8787+ goto err_mem;
8788+ }
8789+
8790+ iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
8791+ if (!iomem) {
8792+ err = -EINVAL;
8793+ goto err_mem;
8794+ }
8795+
8796+ self = kzalloc(sizeof(*self), GFP_KERNEL);
8797+ if (!self) {
8798+ err = -ENOMEM;
8799+ goto err_mem;
8800+ }
8801+
8802+ self->mdev = most_alloc_dev();
8803+ if (!self->mdev) {
8804+ err = -ENOMEM;
8805+ goto err_mem;
8806+ }
8807+
8808+ self->mdev->owner = THIS_MODULE;
8809+ self->mdev->driver_data = self;
8810+ self->mdev->parent = &dev->dev;
8811+ self->mdev->open = timbmost_open;
8812+ self->mdev->close = timbmost_close;
8813+ self->mdev->send = timbmost_send;
8814+ self->mdev->conf_channel = timbmost_conf_channel;
8815+
8816+ if (!request_mem_region(iomem->start,
8817+ resource_size(iomem), "timb-most")) {
8818+ err = -EBUSY;
8819+ goto err_mem;
8820+ }
8821+
8822+ self->membase = ioremap(iomem->start, resource_size(iomem));
8823+ if (!self->membase) {
8824+ printk(KERN_ERR "timbmost: Failed to remap I/O memory\n");
8825+ err = -ENOMEM;
8826+ goto err_ioremap;
8827+ }
8828+
8829+ self->reset_pin = pdata->reset_pin;
8830+
8831+ /* find interrupt */
8832+ self->irq = platform_get_irq(dev, 0);
8833+ if (self->irq < 0) {
8834+ err = self->irq;
8835+ goto err_get_irq;
8836+ }
8837+
8838+ /* register to the MOST layer */
8839+ err = most_register_dev(self->mdev);
8840+ if (err)
8841+ goto err_register;
8842+
8843+
8844+ platform_set_drvdata(dev, self);
8845+
8846+ return 0;
8847+
8848+err_get_irq:
8849+err_register:
8850+ iounmap(self->membase);
8851+err_ioremap:
8852+ release_mem_region(iomem->start, resource_size(iomem));
8853+err_mem:
8854+ if (self) {
8855+ if (self->mdev)
8856+ most_free_dev(self->mdev);
8857+
8858+ timbdma_free_desc(self->sync_read_desc);
8859+ timbdma_free_desc(self->sync_write_desc);
8860+
8861+ kfree(self);
8862+ }
8863+ printk(KERN_ERR "timb-most: Failed to register: %d\n", err);
8864+
8865+ return err;
8866+}
8867+
8868+static int timbmost_remove(struct platform_device *dev)
8869+{
8870+ struct timbmost *self = platform_get_drvdata(dev);
8871+ struct resource *iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
8872+
8873+ most_unregister_dev(self->mdev);
8874+ iounmap(self->membase);
8875+ release_mem_region(iomem->start, resource_size(iomem));
8876+ most_free_dev(self->mdev);
8877+ kfree(self);
8878+ return 0;
8879+}
8880+
8881+static struct platform_driver timbmost_platform_driver = {
8882+ .driver = {
8883+ .name = DRIVER_NAME,
8884+ .owner = THIS_MODULE,
8885+ },
8886+ .probe = timbmost_probe,
8887+ .remove = timbmost_remove,
8888+};
8889+
8890+/*--------------------------------------------------------------------------*/
8891+
8892+static int __init timbmost_init(void)
8893+{
8894+ return platform_driver_register(&timbmost_platform_driver);
8895+}
8896+
8897+static void __exit timbmost_exit(void)
8898+{
8899+ platform_driver_unregister(&timbmost_platform_driver);
8900+}
8901+
8902+module_init(timbmost_init);
8903+module_exit(timbmost_exit);
8904+
8905+MODULE_DESCRIPTION("Timberdale MLB driver");
8906+MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
8907+MODULE_LICENSE("GPL v2");
8908+MODULE_ALIAS("platform:timb-most");
8909+
8910diff -uNr linux-2.6.31/drivers/serial/Kconfig linux-2.6.31.new/drivers/serial/Kconfig
8911--- linux-2.6.31/drivers/serial/Kconfig 2009-10-23 11:18:08.000000000 -0700
8912+++ linux-2.6.31.new/drivers/serial/Kconfig 2009-10-23 11:17:29.000000000 -0700
8913@@ -855,7 +855,7 @@
8914
8915 config SERIAL_UARTLITE
8916 tristate "Xilinx uartlite serial port support"
8917- depends on PPC32 || MICROBLAZE
8918+ depends on PPC32 || MICROBLAZE || MFD_TIMBERDALE
8919 select SERIAL_CORE
8920 help
8921 Say Y here if you want to use the Xilinx uartlite serial controller.
8922diff -uNr linux-2.6.31/drivers/serial/timbuart.c linux-2.6.31.new/drivers/serial/timbuart.c
8923--- linux-2.6.31/drivers/serial/timbuart.c 2009-10-23 11:18:30.000000000 -0700
8924+++ linux-2.6.31.new/drivers/serial/timbuart.c 2009-10-23 11:17:29.000000000 -0700
8925@@ -31,6 +31,7 @@
8926
8927 struct timbuart_port {
8928 struct uart_port port;
8929+ struct uart_driver uart_driver;
8930 struct tasklet_struct tasklet;
8931 int usedma;
8932 u32 last_ier;
8933@@ -410,7 +411,7 @@
8934 .verify_port = timbuart_verify_port
8935 };
8936
8937-static struct uart_driver timbuart_driver = {
8938+static const __devinitconst struct uart_driver timbuart_driver_template = {
8939 .owner = THIS_MODULE,
8940 .driver_name = "timberdale_uart",
8941 .dev_name = "ttyTU",
8942@@ -419,7 +420,7 @@
8943 .nr = 1
8944 };
8945
8946-static int timbuart_probe(struct platform_device *dev)
8947+static int __devinit timbuart_probe(struct platform_device *dev)
8948 {
8949 int err;
8950 struct timbuart_port *uart;
8951@@ -433,6 +434,8 @@
8952 goto err_mem;
8953 }
8954
8955+ uart->uart_driver = timbuart_driver_template;
8956+
8957 uart->usedma = 0;
8958
8959 uart->port.uartclk = 3250000 * 16;
8960@@ -461,11 +464,11 @@
8961
8962 tasklet_init(&uart->tasklet, timbuart_tasklet, (unsigned long)uart);
8963
8964- err = uart_register_driver(&timbuart_driver);
8965+ err = uart_register_driver(&uart->uart_driver);
8966 if (err)
8967 goto err_register;
8968
8969- err = uart_add_one_port(&timbuart_driver, &uart->port);
8970+ err = uart_add_one_port(&uart->uart_driver, &uart->port);
8971 if (err)
8972 goto err_add_port;
8973
8974@@ -474,7 +477,7 @@
8975 return 0;
8976
8977 err_add_port:
8978- uart_unregister_driver(&timbuart_driver);
8979+ uart_unregister_driver(&uart->uart_driver);
8980 err_register:
8981 kfree(uart);
8982 err_mem:
8983@@ -484,13 +487,13 @@
8984 return err;
8985 }
8986
8987-static int timbuart_remove(struct platform_device *dev)
8988+static int __devexit timbuart_remove(struct platform_device *dev)
8989 {
8990 struct timbuart_port *uart = platform_get_drvdata(dev);
8991
8992 tasklet_kill(&uart->tasklet);
8993- uart_remove_one_port(&timbuart_driver, &uart->port);
8994- uart_unregister_driver(&timbuart_driver);
8995+ uart_remove_one_port(&uart->uart_driver, &uart->port);
8996+ uart_unregister_driver(&uart->uart_driver);
8997 kfree(uart);
8998
8999 return 0;
9000diff -uNr linux-2.6.31/drivers/spi/Kconfig linux-2.6.31.new/drivers/spi/Kconfig
9001--- linux-2.6.31/drivers/spi/Kconfig 2009-10-23 11:18:30.000000000 -0700
9002+++ linux-2.6.31.new/drivers/spi/Kconfig 2009-10-23 11:17:32.000000000 -0700
9003@@ -218,8 +218,8 @@
9004 SPI driver for Toshiba TXx9 MIPS SoCs
9005
9006 config SPI_XILINX
9007- tristate "Xilinx SPI controller"
9008- depends on (XILINX_VIRTEX || MICROBLAZE) && EXPERIMENTAL
9009+ tristate "Xilinx SPI controller common module"
9010+ depends on EXPERIMENTAL
9011 select SPI_BITBANG
9012 help
9013 This exposes the SPI controller IP from the Xilinx EDK.
9014@@ -227,6 +227,25 @@
9015 See the "OPB Serial Peripheral Interface (SPI) (v1.00e)"
9016 Product Specification document (DS464) for hardware details.
9017
9018+config SPI_XILINX_OF
9019+ tristate "Xilinx SPI controller OF device"
9020+ depends on SPI_XILINX && XILINX_VIRTEX
9021+ help
9022+ This exposes the SPI controller IP from the Xilinx EDK.
9023+
9024+ See the "OPB Serial Peripheral Interface (SPI) (v1.00e)"
9025+ Product Specification document (DS464) for hardware details.
9026+
9027+config SPI_XILINX_PLTFM
9028+ tristate "Xilinx SPI controller platform device"
9029+ depends on SPI_XILINX
9030+ help
9031+ This exposes the SPI controller IP from the Xilinx EDK.
9032+
9033+ See the "OPB Serial Peripheral Interface (SPI) (v1.00e)"
9034+ Product Specification document (DS464) for hardware details.
9035+
9036+
9037 #
9038 # Add new SPI master controllers in alphabetical order above this line
9039 #
9040diff -uNr linux-2.6.31/drivers/spi/Makefile linux-2.6.31.new/drivers/spi/Makefile
9041--- linux-2.6.31/drivers/spi/Makefile 2009-10-23 11:18:30.000000000 -0700
9042+++ linux-2.6.31.new/drivers/spi/Makefile 2009-10-23 11:17:32.000000000 -0700
9043@@ -30,6 +30,8 @@
9044 obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o
9045 obj-$(CONFIG_SPI_TXX9) += spi_txx9.o
9046 obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o
9047+obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o
9048+obj-$(CONFIG_SPI_XILINX_PLTFM) += xilinx_spi_pltfm.o
9049 obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o
9050 # ... add above this line ...
9051
9052diff -uNr linux-2.6.31/drivers/spi/xilinx_spi.c linux-2.6.31.new/drivers/spi/xilinx_spi.c
9053--- linux-2.6.31/drivers/spi/xilinx_spi.c 2009-10-23 11:18:30.000000000 -0700
9054+++ linux-2.6.31.new/drivers/spi/xilinx_spi.c 2009-10-23 11:17:32.000000000 -0700
9055@@ -14,22 +14,35 @@
9056 #include <linux/module.h>
9057 #include <linux/init.h>
9058 #include <linux/interrupt.h>
9059-#include <linux/platform_device.h>
9060-
9061-#include <linux/of_platform.h>
9062-#include <linux/of_device.h>
9063-#include <linux/of_spi.h>
9064
9065 #include <linux/spi/spi.h>
9066 #include <linux/spi/spi_bitbang.h>
9067 #include <linux/io.h>
9068
9069-#define XILINX_SPI_NAME "xilinx_spi"
9070+#include "xilinx_spi.h"
9071+
9072+struct xilinx_spi {
9073+ /* bitbang has to be first */
9074+ struct spi_bitbang bitbang;
9075+ struct completion done;
9076+ struct resource mem; /* phys mem */
9077+ void __iomem *regs; /* virt. address of the control registers */
9078+ u32 irq;
9079+ u8 *rx_ptr; /* pointer in the Tx buffer */
9080+ const u8 *tx_ptr; /* pointer in the Rx buffer */
9081+ int remaining_bytes; /* the number of bytes left to transfer */
9082+ /* offset to the XSPI regs, these might vary... */
9083+ u8 bits_per_word;
9084+ bool big_endian; /* The device could be accessed big or little
9085+ * endian
9086+ */
9087+};
9088+
9089
9090 /* Register definitions as per "OPB Serial Peripheral Interface (SPI) (v1.00e)
9091 * Product Specification", DS464
9092 */
9093-#define XSPI_CR_OFFSET 0x62 /* 16-bit Control Register */
9094+#define XSPI_CR_OFFSET 0x60 /* Control Register */
9095
9096 #define XSPI_CR_ENABLE 0x02
9097 #define XSPI_CR_MASTER_MODE 0x04
9098@@ -40,8 +53,9 @@
9099 #define XSPI_CR_RXFIFO_RESET 0x40
9100 #define XSPI_CR_MANUAL_SSELECT 0x80
9101 #define XSPI_CR_TRANS_INHIBIT 0x100
9102+#define XSPI_CR_LSB_FIRST 0x200
9103
9104-#define XSPI_SR_OFFSET 0x67 /* 8-bit Status Register */
9105+#define XSPI_SR_OFFSET 0x64 /* Status Register */
9106
9107 #define XSPI_SR_RX_EMPTY_MASK 0x01 /* Receive FIFO is empty */
9108 #define XSPI_SR_RX_FULL_MASK 0x02 /* Receive FIFO is full */
9109@@ -49,8 +63,8 @@
9110 #define XSPI_SR_TX_FULL_MASK 0x08 /* Transmit FIFO is full */
9111 #define XSPI_SR_MODE_FAULT_MASK 0x10 /* Mode fault error */
9112
9113-#define XSPI_TXD_OFFSET 0x6b /* 8-bit Data Transmit Register */
9114-#define XSPI_RXD_OFFSET 0x6f /* 8-bit Data Receive Register */
9115+#define XSPI_TXD_OFFSET 0x68 /* Data Transmit Register */
9116+#define XSPI_RXD_OFFSET 0x6C /* Data Receive Register */
9117
9118 #define XSPI_SSR_OFFSET 0x70 /* 32-bit Slave Select Register */
9119
9120@@ -70,43 +84,72 @@
9121 #define XSPI_INTR_TX_UNDERRUN 0x08 /* TxFIFO was underrun */
9122 #define XSPI_INTR_RX_FULL 0x10 /* RxFIFO is full */
9123 #define XSPI_INTR_RX_OVERRUN 0x20 /* RxFIFO was overrun */
9124+#define XSPI_INTR_TX_HALF_EMPTY 0x40 /* TxFIFO is half empty */
9125
9126 #define XIPIF_V123B_RESETR_OFFSET 0x40 /* IPIF reset register */
9127 #define XIPIF_V123B_RESET_MASK 0x0a /* the value to write */
9128
9129-struct xilinx_spi {
9130- /* bitbang has to be first */
9131- struct spi_bitbang bitbang;
9132- struct completion done;
9133+/* to follow are some functions that does little of big endian read and
9134+ * write depending on the config of the device.
9135+ */
9136+static inline void xspi_write8(struct xilinx_spi *xspi, u32 offs, u8 val)
9137+{
9138+ iowrite8(val, xspi->regs + offs + ((xspi->big_endian) ? 3 : 0));
9139+}
9140
9141- void __iomem *regs; /* virt. address of the control registers */
9142+static inline void xspi_write16(struct xilinx_spi *xspi, u32 offs, u16 val)
9143+{
9144+ if (xspi->big_endian)
9145+ iowrite16be(val, xspi->regs + offs + 2);
9146+ else
9147+ iowrite16(val, xspi->regs + offs);
9148+}
9149
9150- u32 irq;
9151+static inline void xspi_write32(struct xilinx_spi *xspi, u32 offs, u32 val)
9152+{
9153+ if (xspi->big_endian)
9154+ iowrite32be(val, xspi->regs + offs);
9155+ else
9156+ iowrite32(val, xspi->regs + offs);
9157+}
9158
9159- u32 speed_hz; /* SCK has a fixed frequency of speed_hz Hz */
9160+static inline u8 xspi_read8(struct xilinx_spi *xspi, u32 offs)
9161+{
9162+ return ioread8(xspi->regs + offs + ((xspi->big_endian) ? 3 : 0));
9163+}
9164
9165- u8 *rx_ptr; /* pointer in the Tx buffer */
9166- const u8 *tx_ptr; /* pointer in the Rx buffer */
9167- int remaining_bytes; /* the number of bytes left to transfer */
9168-};
9169+static inline u16 xspi_read16(struct xilinx_spi *xspi, u32 offs)
9170+{
9171+ if (xspi->big_endian)
9172+ return ioread16be(xspi->regs + offs + 2);
9173+ else
9174+ return ioread16(xspi->regs + offs);
9175+}
9176+
9177+static inline u32 xspi_read32(struct xilinx_spi *xspi, u32 offs)
9178+{
9179+ if (xspi->big_endian)
9180+ return ioread32be(xspi->regs + offs);
9181+ else
9182+ return ioread32(xspi->regs + offs);
9183+}
9184
9185-static void xspi_init_hw(void __iomem *regs_base)
9186+static void xspi_init_hw(struct xilinx_spi *xspi)
9187 {
9188 /* Reset the SPI device */
9189- out_be32(regs_base + XIPIF_V123B_RESETR_OFFSET,
9190- XIPIF_V123B_RESET_MASK);
9191+ xspi_write32(xspi, XIPIF_V123B_RESETR_OFFSET, XIPIF_V123B_RESET_MASK);
9192 /* Disable all the interrupts just in case */
9193- out_be32(regs_base + XIPIF_V123B_IIER_OFFSET, 0);
9194+ xspi_write32(xspi, XIPIF_V123B_IIER_OFFSET, 0);
9195 /* Enable the global IPIF interrupt */
9196- out_be32(regs_base + XIPIF_V123B_DGIER_OFFSET,
9197- XIPIF_V123B_GINTR_ENABLE);
9198+ xspi_write32(xspi, XIPIF_V123B_DGIER_OFFSET, XIPIF_V123B_GINTR_ENABLE);
9199 /* Deselect the slave on the SPI bus */
9200- out_be32(regs_base + XSPI_SSR_OFFSET, 0xffff);
9201+ xspi_write32(xspi, XSPI_SSR_OFFSET, 0xffff);
9202 /* Disable the transmitter, enable Manual Slave Select Assertion,
9203 * put SPI controller into master mode, and enable it */
9204- out_be16(regs_base + XSPI_CR_OFFSET,
9205- XSPI_CR_TRANS_INHIBIT | XSPI_CR_MANUAL_SSELECT
9206- | XSPI_CR_MASTER_MODE | XSPI_CR_ENABLE);
9207+ xspi_write16(xspi, XSPI_CR_OFFSET,
9208+ XSPI_CR_TRANS_INHIBIT | XSPI_CR_MANUAL_SSELECT |
9209+ XSPI_CR_MASTER_MODE | XSPI_CR_ENABLE | XSPI_CR_TXFIFO_RESET |
9210+ XSPI_CR_RXFIFO_RESET);
9211 }
9212
9213 static void xilinx_spi_chipselect(struct spi_device *spi, int is_on)
9214@@ -115,16 +158,16 @@
9215
9216 if (is_on == BITBANG_CS_INACTIVE) {
9217 /* Deselect the slave on the SPI bus */
9218- out_be32(xspi->regs + XSPI_SSR_OFFSET, 0xffff);
9219+ xspi_write32(xspi, XSPI_SSR_OFFSET, 0xffff);
9220 } else if (is_on == BITBANG_CS_ACTIVE) {
9221 /* Set the SPI clock phase and polarity */
9222- u16 cr = in_be16(xspi->regs + XSPI_CR_OFFSET)
9223+ u16 cr = xspi_read16(xspi, XSPI_CR_OFFSET)
9224 & ~XSPI_CR_MODE_MASK;
9225 if (spi->mode & SPI_CPHA)
9226 cr |= XSPI_CR_CPHA;
9227 if (spi->mode & SPI_CPOL)
9228 cr |= XSPI_CR_CPOL;
9229- out_be16(xspi->regs + XSPI_CR_OFFSET, cr);
9230+ xspi_write16(xspi, XSPI_CR_OFFSET, cr);
9231
9232 /* We do not check spi->max_speed_hz here as the SPI clock
9233 * frequency is not software programmable (the IP block design
9234@@ -132,24 +175,27 @@
9235 */
9236
9237 /* Activate the chip select */
9238- out_be32(xspi->regs + XSPI_SSR_OFFSET,
9239+ xspi_write32(xspi, XSPI_SSR_OFFSET,
9240 ~(0x0001 << spi->chip_select));
9241 }
9242 }
9243
9244 /* spi_bitbang requires custom setup_transfer() to be defined if there is a
9245 * custom txrx_bufs(). We have nothing to setup here as the SPI IP block
9246- * supports just 8 bits per word, and SPI clock can't be changed in software.
9247- * Check for 8 bits per word. Chip select delay calculations could be
9248+ * supports 8 or 16 bits per word, which can not be changed in software.
9249+ * SPI clock can't be changed in software.
9250+ * Check for correct bits per word. Chip select delay calculations could be
9251 * added here as soon as bitbang_work() can be made aware of the delay value.
9252 */
9253 static int xilinx_spi_setup_transfer(struct spi_device *spi,
9254- struct spi_transfer *t)
9255+ struct spi_transfer *t)
9256 {
9257 u8 bits_per_word;
9258+ struct xilinx_spi *xspi = spi_master_get_devdata(spi->master);
9259
9260- bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word;
9261- if (bits_per_word != 8) {
9262+ bits_per_word = (t->bits_per_word) ? t->bits_per_word :
9263+ spi->bits_per_word;
9264+ if (bits_per_word != xspi->bits_per_word) {
9265 dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
9266 __func__, bits_per_word);
9267 return -EINVAL;
9268@@ -160,34 +206,50 @@
9269
9270 static int xilinx_spi_setup(struct spi_device *spi)
9271 {
9272- struct spi_bitbang *bitbang;
9273- struct xilinx_spi *xspi;
9274- int retval;
9275-
9276- xspi = spi_master_get_devdata(spi->master);
9277- bitbang = &xspi->bitbang;
9278-
9279- retval = xilinx_spi_setup_transfer(spi, NULL);
9280- if (retval < 0)
9281- return retval;
9282-
9283+ /* always return 0, we can not check the number of bits.
9284+ * There are cases when SPI setup is called before any driver is
9285+ * there, in that case the SPI core defaults to 8 bits, which we
9286+ * do not support in some cases. But if we return an error, the
9287+ * SPI device would not be registered and no driver can get hold of it
9288+ * When the driver is there, it will call SPI setup again with the
9289+ * correct number of bits per transfer.
9290+ * If a driver setups with the wrong bit number, it will fail when
9291+ * it tries to do a transfer
9292+ */
9293 return 0;
9294 }
9295
9296 static void xilinx_spi_fill_tx_fifo(struct xilinx_spi *xspi)
9297 {
9298 u8 sr;
9299+ u8 wsize;
9300+ if (xspi->bits_per_word == 8)
9301+ wsize = 1;
9302+ else if (xspi->bits_per_word == 16)
9303+ wsize = 2;
9304+ else
9305+ wsize = 4;
9306
9307 /* Fill the Tx FIFO with as many bytes as possible */
9308- sr = in_8(xspi->regs + XSPI_SR_OFFSET);
9309- while ((sr & XSPI_SR_TX_FULL_MASK) == 0 && xspi->remaining_bytes > 0) {
9310+ sr = xspi_read8(xspi, XSPI_SR_OFFSET);
9311+ while ((sr & XSPI_SR_TX_FULL_MASK) == 0 &&
9312+ xspi->remaining_bytes > 0) {
9313 if (xspi->tx_ptr) {
9314- out_8(xspi->regs + XSPI_TXD_OFFSET, *xspi->tx_ptr++);
9315- } else {
9316- out_8(xspi->regs + XSPI_TXD_OFFSET, 0);
9317- }
9318- xspi->remaining_bytes--;
9319- sr = in_8(xspi->regs + XSPI_SR_OFFSET);
9320+ if (wsize == 1)
9321+ xspi_write8(xspi, XSPI_TXD_OFFSET,
9322+ *xspi->tx_ptr);
9323+ else if (wsize == 2)
9324+ xspi_write16(xspi, XSPI_TXD_OFFSET,
9325+ *(u16 *)(xspi->tx_ptr));
9326+ else if (wsize == 4)
9327+ xspi_write32(xspi, XSPI_TXD_OFFSET,
9328+ *(u32 *)(xspi->tx_ptr));
9329+
9330+ xspi->tx_ptr += wsize;
9331+ } else
9332+ xspi_write8(xspi, XSPI_TXD_OFFSET, 0);
9333+ xspi->remaining_bytes -= wsize;
9334+ sr = xspi_read8(xspi, XSPI_SR_OFFSET);
9335 }
9336 }
9337
9338@@ -209,23 +271,22 @@
9339 /* Enable the transmit empty interrupt, which we use to determine
9340 * progress on the transmission.
9341 */
9342- ipif_ier = in_be32(xspi->regs + XIPIF_V123B_IIER_OFFSET);
9343- out_be32(xspi->regs + XIPIF_V123B_IIER_OFFSET,
9344+ ipif_ier = xspi_read32(xspi, XIPIF_V123B_IIER_OFFSET);
9345+ xspi_write32(xspi, XIPIF_V123B_IIER_OFFSET,
9346 ipif_ier | XSPI_INTR_TX_EMPTY);
9347
9348 /* Start the transfer by not inhibiting the transmitter any longer */
9349- cr = in_be16(xspi->regs + XSPI_CR_OFFSET) & ~XSPI_CR_TRANS_INHIBIT;
9350- out_be16(xspi->regs + XSPI_CR_OFFSET, cr);
9351+ cr = xspi_read16(xspi, XSPI_CR_OFFSET) & ~XSPI_CR_TRANS_INHIBIT;
9352+ xspi_write16(xspi, XSPI_CR_OFFSET, cr);
9353
9354 wait_for_completion(&xspi->done);
9355
9356 /* Disable the transmit empty interrupt */
9357- out_be32(xspi->regs + XIPIF_V123B_IIER_OFFSET, ipif_ier);
9358+ xspi_write32(xspi, XIPIF_V123B_IIER_OFFSET, ipif_ier);
9359
9360 return t->len - xspi->remaining_bytes;
9361 }
9362
9363-
9364 /* This driver supports single master mode only. Hence Tx FIFO Empty
9365 * is the only interrupt we care about.
9366 * Receive FIFO Overrun, Transmit FIFO Underrun, Mode Fault, and Slave Mode
9367@@ -237,32 +298,50 @@
9368 u32 ipif_isr;
9369
9370 /* Get the IPIF interrupts, and clear them immediately */
9371- ipif_isr = in_be32(xspi->regs + XIPIF_V123B_IISR_OFFSET);
9372- out_be32(xspi->regs + XIPIF_V123B_IISR_OFFSET, ipif_isr);
9373+ ipif_isr = xspi_read32(xspi, XIPIF_V123B_IISR_OFFSET);
9374+ xspi_write32(xspi, XIPIF_V123B_IISR_OFFSET, ipif_isr);
9375
9376 if (ipif_isr & XSPI_INTR_TX_EMPTY) { /* Transmission completed */
9377 u16 cr;
9378 u8 sr;
9379+ u8 rsize;
9380+ if (xspi->bits_per_word == 8)
9381+ rsize = 1;
9382+ else if (xspi->bits_per_word == 16)
9383+ rsize = 2;
9384+ else
9385+ rsize = 4;
9386
9387 /* A transmit has just completed. Process received data and
9388 * check for more data to transmit. Always inhibit the
9389 * transmitter while the Isr refills the transmit register/FIFO,
9390 * or make sure it is stopped if we're done.
9391 */
9392- cr = in_be16(xspi->regs + XSPI_CR_OFFSET);
9393- out_be16(xspi->regs + XSPI_CR_OFFSET,
9394- cr | XSPI_CR_TRANS_INHIBIT);
9395+ cr = xspi_read16(xspi, XSPI_CR_OFFSET);
9396+ xspi_write16(xspi, XSPI_CR_OFFSET, cr | XSPI_CR_TRANS_INHIBIT);
9397
9398 /* Read out all the data from the Rx FIFO */
9399- sr = in_8(xspi->regs + XSPI_SR_OFFSET);
9400+ sr = xspi_read8(xspi, XSPI_SR_OFFSET);
9401 while ((sr & XSPI_SR_RX_EMPTY_MASK) == 0) {
9402- u8 data;
9403+ u32 data;
9404+ if (rsize == 1)
9405+ data = xspi_read8(xspi, XSPI_RXD_OFFSET);
9406+ else if (rsize == 2)
9407+ data = xspi_read16(xspi, XSPI_RXD_OFFSET);
9408+ else
9409+ data = xspi_read32(xspi, XSPI_RXD_OFFSET);
9410
9411- data = in_8(xspi->regs + XSPI_RXD_OFFSET);
9412 if (xspi->rx_ptr) {
9413- *xspi->rx_ptr++ = data;
9414+ if (rsize == 1)
9415+ *xspi->rx_ptr = data & 0xff;
9416+ else if (rsize == 2)
9417+ *(u16 *)(xspi->rx_ptr) = data & 0xffff;
9418+ else
9419+ *((u32 *)(xspi->rx_ptr)) = data;
9420+ xspi->rx_ptr += rsize;
9421 }
9422- sr = in_8(xspi->regs + XSPI_SR_OFFSET);
9423+
9424+ sr = xspi_read8(xspi, XSPI_SR_OFFSET);
9425 }
9426
9427 /* See if there is more data to send */
9428@@ -271,7 +350,7 @@
9429 /* Start the transfer by not inhibiting the
9430 * transmitter any longer
9431 */
9432- out_be16(xspi->regs + XSPI_CR_OFFSET, cr);
9433+ xspi_write16(xspi, XSPI_CR_OFFSET, cr);
9434 } else {
9435 /* No more data to send.
9436 * Indicate the transfer is completed.
9437@@ -279,44 +358,21 @@
9438 complete(&xspi->done);
9439 }
9440 }
9441-
9442 return IRQ_HANDLED;
9443 }
9444
9445-static int __init xilinx_spi_of_probe(struct of_device *ofdev,
9446- const struct of_device_id *match)
9447+struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem,
9448+ u32 irq, s16 bus_num, u16 num_chipselect, u8 bits_per_word,
9449+ bool big_endian)
9450 {
9451 struct spi_master *master;
9452 struct xilinx_spi *xspi;
9453- struct resource r_irq_struct;
9454- struct resource r_mem_struct;
9455+ int ret = 0;
9456
9457- struct resource *r_irq = &r_irq_struct;
9458- struct resource *r_mem = &r_mem_struct;
9459- int rc = 0;
9460- const u32 *prop;
9461- int len;
9462+ master = spi_alloc_master(dev, sizeof(struct xilinx_spi));
9463
9464- /* Get resources(memory, IRQ) associated with the device */
9465- master = spi_alloc_master(&ofdev->dev, sizeof(struct xilinx_spi));
9466-
9467- if (master == NULL) {
9468- return -ENOMEM;
9469- }
9470-
9471- dev_set_drvdata(&ofdev->dev, master);
9472-
9473- rc = of_address_to_resource(ofdev->node, 0, r_mem);
9474- if (rc) {
9475- dev_warn(&ofdev->dev, "invalid address\n");
9476- goto put_master;
9477- }
9478-
9479- rc = of_irq_to_resource(ofdev->node, 0, r_irq);
9480- if (rc == NO_IRQ) {
9481- dev_warn(&ofdev->dev, "no IRQ found\n");
9482- goto put_master;
9483- }
9484+ if (master == NULL)
9485+ return ERR_PTR(-ENOMEM);
9486
9487 /* the spi->mode bits understood by this driver: */
9488 master->mode_bits = SPI_CPOL | SPI_CPHA;
9489@@ -329,128 +385,73 @@
9490 xspi->bitbang.master->setup = xilinx_spi_setup;
9491 init_completion(&xspi->done);
9492
9493- xspi->irq = r_irq->start;
9494-
9495- if (!request_mem_region(r_mem->start,
9496- r_mem->end - r_mem->start + 1, XILINX_SPI_NAME)) {
9497- rc = -ENXIO;
9498- dev_warn(&ofdev->dev, "memory request failure\n");
9499+ if (!request_mem_region(mem->start, resource_size(mem),
9500+ XILINX_SPI_NAME)) {
9501+ ret = -ENXIO;
9502 goto put_master;
9503 }
9504
9505- xspi->regs = ioremap(r_mem->start, r_mem->end - r_mem->start + 1);
9506+ xspi->regs = ioremap(mem->start, resource_size(mem));
9507 if (xspi->regs == NULL) {
9508- rc = -ENOMEM;
9509- dev_warn(&ofdev->dev, "ioremap failure\n");
9510- goto release_mem;
9511+ ret = -ENOMEM;
9512+ dev_warn(dev, "ioremap failure\n");
9513+ goto map_failed;
9514 }
9515- xspi->irq = r_irq->start;
9516
9517- /* dynamic bus assignment */
9518- master->bus_num = -1;
9519-
9520- /* number of slave select bits is required */
9521- prop = of_get_property(ofdev->node, "xlnx,num-ss-bits", &len);
9522- if (!prop || len < sizeof(*prop)) {
9523- dev_warn(&ofdev->dev, "no 'xlnx,num-ss-bits' property\n");
9524- goto unmap_io;
9525- }
9526- master->num_chipselect = *prop;
9527+ master->bus_num = bus_num;
9528+ master->num_chipselect = num_chipselect;
9529+
9530+ xspi->mem = *mem;
9531+ xspi->irq = irq;
9532+ xspi->bits_per_word = bits_per_word;
9533+ xspi->big_endian = big_endian;
9534
9535 /* SPI controller initializations */
9536- xspi_init_hw(xspi->regs);
9537+ xspi_init_hw(xspi);
9538
9539 /* Register for SPI Interrupt */
9540- rc = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi);
9541- if (rc != 0) {
9542- dev_warn(&ofdev->dev, "irq request failure: %d\n", xspi->irq);
9543+ ret = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi);
9544+ if (ret != 0)
9545 goto unmap_io;
9546- }
9547
9548- rc = spi_bitbang_start(&xspi->bitbang);
9549- if (rc != 0) {
9550- dev_err(&ofdev->dev, "spi_bitbang_start FAILED\n");
9551+ ret = spi_bitbang_start(&xspi->bitbang);
9552+ if (ret != 0) {
9553+ dev_err(dev, "spi_bitbang_start FAILED\n");
9554 goto free_irq;
9555 }
9556
9557- dev_info(&ofdev->dev, "at 0x%08X mapped to 0x%08X, irq=%d\n",
9558- (unsigned int)r_mem->start, (u32)xspi->regs, xspi->irq);
9559-
9560- /* Add any subnodes on the SPI bus */
9561- of_register_spi_devices(master, ofdev->node);
9562-
9563- return rc;
9564+ dev_info(dev, "at 0x%08X mapped to 0x%08X, irq=%d\n",
9565+ (u32)mem->start, (u32)xspi->regs, xspi->irq);
9566+ return master;
9567
9568 free_irq:
9569 free_irq(xspi->irq, xspi);
9570 unmap_io:
9571 iounmap(xspi->regs);
9572-release_mem:
9573- release_mem_region(r_mem->start, resource_size(r_mem));
9574+map_failed:
9575+ release_mem_region(mem->start, resource_size(mem));
9576 put_master:
9577 spi_master_put(master);
9578- return rc;
9579+ return ERR_PTR(ret);
9580 }
9581+EXPORT_SYMBOL(xilinx_spi_init);
9582
9583-static int __devexit xilinx_spi_remove(struct of_device *ofdev)
9584+void xilinx_spi_deinit(struct spi_master *master)
9585 {
9586 struct xilinx_spi *xspi;
9587- struct spi_master *master;
9588- struct resource r_mem;
9589
9590- master = platform_get_drvdata(ofdev);
9591 xspi = spi_master_get_devdata(master);
9592
9593 spi_bitbang_stop(&xspi->bitbang);
9594 free_irq(xspi->irq, xspi);
9595 iounmap(xspi->regs);
9596- if (!of_address_to_resource(ofdev->node, 0, &r_mem))
9597- release_mem_region(r_mem.start, resource_size(&r_mem));
9598- dev_set_drvdata(&ofdev->dev, 0);
9599- spi_master_put(xspi->bitbang.master);
9600-
9601- return 0;
9602-}
9603-
9604-/* work with hotplug and coldplug */
9605-MODULE_ALIAS("platform:" XILINX_SPI_NAME);
9606-
9607-static int __exit xilinx_spi_of_remove(struct of_device *op)
9608-{
9609- return xilinx_spi_remove(op);
9610-}
9611
9612-static struct of_device_id xilinx_spi_of_match[] = {
9613- { .compatible = "xlnx,xps-spi-2.00.a", },
9614- { .compatible = "xlnx,xps-spi-2.00.b", },
9615- {}
9616-};
9617-
9618-MODULE_DEVICE_TABLE(of, xilinx_spi_of_match);
9619-
9620-static struct of_platform_driver xilinx_spi_of_driver = {
9621- .owner = THIS_MODULE,
9622- .name = "xilinx-xps-spi",
9623- .match_table = xilinx_spi_of_match,
9624- .probe = xilinx_spi_of_probe,
9625- .remove = __exit_p(xilinx_spi_of_remove),
9626- .driver = {
9627- .name = "xilinx-xps-spi",
9628- .owner = THIS_MODULE,
9629- },
9630-};
9631-
9632-static int __init xilinx_spi_init(void)
9633-{
9634- return of_register_platform_driver(&xilinx_spi_of_driver);
9635+ release_mem_region(xspi->mem.start, resource_size(&xspi->mem));
9636+ spi_master_put(xspi->bitbang.master);
9637 }
9638-module_init(xilinx_spi_init);
9639+EXPORT_SYMBOL(xilinx_spi_deinit);
9640
9641-static void __exit xilinx_spi_exit(void)
9642-{
9643- of_unregister_platform_driver(&xilinx_spi_of_driver);
9644-}
9645-module_exit(xilinx_spi_exit);
9646 MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
9647 MODULE_DESCRIPTION("Xilinx SPI driver");
9648 MODULE_LICENSE("GPL");
9649+
9650diff -uNr linux-2.6.31/drivers/spi/xilinx_spi.h linux-2.6.31.new/drivers/spi/xilinx_spi.h
9651--- linux-2.6.31/drivers/spi/xilinx_spi.h 1969-12-31 16:00:00.000000000 -0800
9652+++ linux-2.6.31.new/drivers/spi/xilinx_spi.h 2009-10-23 11:17:32.000000000 -0700
9653@@ -0,0 +1,33 @@
9654+/*
9655+ * xilinx_spi.h
9656+ * Copyright (c) 2009 Intel Corporation
9657+ *
9658+ * This program is free software; you can redistribute it and/or modify
9659+ * it under the terms of the GNU General Public License version 2 as
9660+ * published by the Free Software Foundation.
9661+ *
9662+ * This program is distributed in the hope that it will be useful,
9663+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9664+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9665+ * GNU General Public License for more details.
9666+ *
9667+ * You should have received a copy of the GNU General Public License
9668+ * along with this program; if not, write to the Free Software
9669+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
9670+ */
9671+
9672+#ifndef _XILINX_SPI_H_
9673+#define _XILINX_SPI_H_ 1
9674+
9675+#include <linux/spi/spi.h>
9676+#include <linux/spi/spi_bitbang.h>
9677+#include <linux/spi/xilinx_spi.h>
9678+
9679+#define XILINX_SPI_NAME "xilinx_spi"
9680+
9681+struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem,
9682+ u32 irq, s16 bus_num, u16 num_chipselect, u8 bits_per_word,
9683+ bool big_endian);
9684+
9685+void xilinx_spi_deinit(struct spi_master *master);
9686+#endif
9687diff -uNr linux-2.6.31/drivers/spi/xilinx_spi_of.c linux-2.6.31.new/drivers/spi/xilinx_spi_of.c
9688--- linux-2.6.31/drivers/spi/xilinx_spi_of.c 1969-12-31 16:00:00.000000000 -0800
9689+++ linux-2.6.31.new/drivers/spi/xilinx_spi_of.c 2009-10-23 11:17:32.000000000 -0700
9690@@ -0,0 +1,120 @@
9691+/*
9692+ * xilinx_spi_of.c
9693+ *
9694+ * Xilinx SPI controller driver (master mode only)
9695+ *
9696+ * Author: MontaVista Software, Inc.
9697+ * source@mvista.com
9698+ *
9699+ * 2002-2007 (c) MontaVista Software, Inc. This file is licensed under the
9700+ * terms of the GNU General Public License version 2. This program is licensed
9701+ * "as is" without any warranty of any kind, whether express or implied.
9702+ */
9703+
9704+#include <linux/module.h>
9705+#include <linux/init.h>
9706+#include <linux/interrupt.h>
9707+#include <linux/io.h>
9708+#include <linux/platform_device.h>
9709+
9710+#include <linux/of_platform.h>
9711+#include <linux/of_device.h>
9712+#include <linux/of_spi.h>
9713+
9714+#include <linux/spi/spi.h>
9715+#include <linux/spi/spi_bitbang.h>
9716+
9717+#include "xilinx_spi.h"
9718+
9719+
9720+static int __init xilinx_spi_of_probe(struct of_device *ofdev,
9721+ const struct of_device_id *match)
9722+{
9723+ struct resource r_irq_struct;
9724+ struct resource r_mem_struct;
9725+ struct spi_master *master;
9726+
9727+ struct resource *r_irq = &r_irq_struct;
9728+ struct resource *r_mem = &r_mem_struct;
9729+ int rc = 0;
9730+ const u32 *prop;
9731+ int len;
9732+
9733+ rc = of_address_to_resource(ofdev->node, 0, r_mem);
9734+ if (rc) {
9735+ dev_warn(&ofdev->dev, "invalid address\n");
9736+ return rc;
9737+ }
9738+
9739+ rc = of_irq_to_resource(ofdev->node, 0, r_irq);
9740+ if (rc == NO_IRQ) {
9741+ dev_warn(&ofdev->dev, "no IRQ found\n");
9742+ return -ENODEV;
9743+ }
9744+
9745+ /* number of slave select bits is required */
9746+ prop = of_get_property(ofdev->node, "xlnx,num-ss-bits", &len);
9747+ if (!prop || len < sizeof(*prop)) {
9748+ dev_warn(&ofdev->dev, "no 'xlnx,num-ss-bits' property\n");
9749+ return -EINVAL;
9750+ }
9751+ master = xilinx_spi_init(&ofdev->dev, r_mem, r_irq->start, -1, *prop, 8,
9752+ true);
9753+ if (IS_ERR(master))
9754+ return PTR_ERR(master);
9755+
9756+ dev_set_drvdata(&ofdev->dev, master);
9757+
9758+ /* Add any subnodes on the SPI bus */
9759+ of_register_spi_devices(master, ofdev->node);
9760+
9761+ return 0;
9762+}
9763+
9764+static int __devexit xilinx_spi_remove(struct of_device *ofdev)
9765+{
9766+ xilinx_spi_deinit(dev_get_drvdata(&ofdev->dev));
9767+ dev_set_drvdata(&ofdev->dev, 0);
9768+ return 0;
9769+}
9770+
9771+static int __exit xilinx_spi_of_remove(struct of_device *op)
9772+{
9773+ return xilinx_spi_remove(op);
9774+}
9775+
9776+static struct of_device_id xilinx_spi_of_match[] = {
9777+ { .compatible = "xlnx,xps-spi-2.00.a", },
9778+ { .compatible = "xlnx,xps-spi-2.00.b", },
9779+ {}
9780+};
9781+
9782+MODULE_DEVICE_TABLE(of, xilinx_spi_of_match);
9783+
9784+static struct of_platform_driver xilinx_spi_of_driver = {
9785+ .owner = THIS_MODULE,
9786+ .name = "xilinx-xps-spi",
9787+ .match_table = xilinx_spi_of_match,
9788+ .probe = xilinx_spi_of_probe,
9789+ .remove = __exit_p(xilinx_spi_of_remove),
9790+ .driver = {
9791+ .name = "xilinx-xps-spi",
9792+ .owner = THIS_MODULE,
9793+ },
9794+};
9795+
9796+static int __init xilinx_spi_of_init(void)
9797+{
9798+ return of_register_platform_driver(&xilinx_spi_of_driver);
9799+}
9800+module_init(xilinx_spi_of_init);
9801+
9802+static void __exit xilinx_spi_of_exit(void)
9803+{
9804+ of_unregister_platform_driver(&xilinx_spi_of_driver);
9805+}
9806+module_exit(xilinx_spi_of_exit);
9807+MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
9808+MODULE_DESCRIPTION("Xilinx SPI driver");
9809+MODULE_LICENSE("GPL");
9810+
9811diff -uNr linux-2.6.31/drivers/spi/xilinx_spi_pltfm.c linux-2.6.31.new/drivers/spi/xilinx_spi_pltfm.c
9812--- linux-2.6.31/drivers/spi/xilinx_spi_pltfm.c 1969-12-31 16:00:00.000000000 -0800
9813+++ linux-2.6.31.new/drivers/spi/xilinx_spi_pltfm.c 2009-10-23 11:17:32.000000000 -0700
9814@@ -0,0 +1,104 @@
9815+/*
9816+ * xilinx_spi_pltfm.c Support for Xilinx SPI platform devices
9817+ * Copyright (c) 2009 Intel Corporation
9818+ *
9819+ * This program is free software; you can redistribute it and/or modify
9820+ * it under the terms of the GNU General Public License version 2 as
9821+ * published by the Free Software Foundation.
9822+ *
9823+ * This program is distributed in the hope that it will be useful,
9824+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9825+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9826+ * GNU General Public License for more details.
9827+ *
9828+ * You should have received a copy of the GNU General Public License
9829+ * along with this program; if not, write to the Free Software
9830+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
9831+ */
9832+
9833+/* Supports:
9834+ * Xilinx SPI devices as platform devices
9835+ *
9836+ * Inspired by xilinx_spi.c, 2002-2007 (c) MontaVista Software, Inc.
9837+ */
9838+
9839+#include <linux/module.h>
9840+#include <linux/init.h>
9841+#include <linux/interrupt.h>
9842+#include <linux/io.h>
9843+#include <linux/platform_device.h>
9844+
9845+#include <linux/spi/spi.h>
9846+#include <linux/spi/spi_bitbang.h>
9847+#include <linux/spi/xilinx_spi.h>
9848+
9849+#include "xilinx_spi.h"
9850+
9851+static int __devinit xilinx_spi_probe(struct platform_device *dev)
9852+{
9853+ struct xspi_platform_data *pdata;
9854+ struct resource *r;
9855+ int irq;
9856+ struct spi_master *master;
9857+ u8 i;
9858+
9859+ pdata = dev->dev.platform_data;
9860+ if (pdata == NULL)
9861+ return -ENODEV;
9862+
9863+ r = platform_get_resource(dev, IORESOURCE_MEM, 0);
9864+ if (r == NULL)
9865+ return -ENODEV;
9866+
9867+ irq = platform_get_irq(dev, 0);
9868+ if (irq < 0)
9869+ return -ENXIO;
9870+
9871+ master = xilinx_spi_init(&dev->dev, r, irq, dev->id,
9872+ pdata->num_chipselect, pdata->bits_per_word, false);
9873+ if (IS_ERR(master))
9874+ return PTR_ERR(master);
9875+
9876+ for (i = 0; i < pdata->num_devices; i++)
9877+ spi_new_device(master, pdata->devices + i);
9878+
9879+ platform_set_drvdata(dev, master);
9880+ return 0;
9881+}
9882+
9883+static int __devexit xilinx_spi_remove(struct platform_device *dev)
9884+{
9885+ xilinx_spi_deinit(platform_get_drvdata(dev));
9886+ platform_set_drvdata(dev, 0);
9887+
9888+ return 0;
9889+}
9890+
9891+/* work with hotplug and coldplug */
9892+MODULE_ALIAS("platform:" XILINX_SPI_NAME);
9893+
9894+static struct platform_driver xilinx_spi_driver = {
9895+ .probe = xilinx_spi_probe,
9896+ .remove = __devexit_p(xilinx_spi_remove),
9897+ .driver = {
9898+ .name = XILINX_SPI_NAME,
9899+ .owner = THIS_MODULE,
9900+ },
9901+};
9902+
9903+static int __init xilinx_spi_pltfm_init(void)
9904+{
9905+ return platform_driver_register(&xilinx_spi_driver);
9906+}
9907+module_init(xilinx_spi_pltfm_init);
9908+
9909+static void __exit xilinx_spi_pltfm_exit(void)
9910+{
9911+ platform_driver_unregister(&xilinx_spi_driver);
9912+}
9913+module_exit(xilinx_spi_pltfm_exit);
9914+
9915+MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
9916+MODULE_DESCRIPTION("Xilinx SPI platform driver");
9917+MODULE_LICENSE("GPL v2");
9918+
9919diff -uNr linux-2.6.31/include/linux/can/platform/ascb.h linux-2.6.31.new/include/linux/can/platform/ascb.h
9920--- linux-2.6.31/include/linux/can/platform/ascb.h 1969-12-31 16:00:00.000000000 -0800
9921+++ linux-2.6.31.new/include/linux/can/platform/ascb.h 2009-10-23 11:16:56.000000000 -0700
9922@@ -0,0 +1,8 @@
9923+#ifndef _CAN_PLATFORM_ASCB_H_
9924+#define _CAN_PLATFORM_ASCB_H_
9925+
9926+struct ascb_platform_data {
9927+ int gpio_pin;
9928+};
9929+
9930+#endif
9931diff -uNr linux-2.6.31/include/linux/i2c-xiic.h linux-2.6.31.new/include/linux/i2c-xiic.h
9932--- linux-2.6.31/include/linux/i2c-xiic.h 1969-12-31 16:00:00.000000000 -0800
9933+++ linux-2.6.31.new/include/linux/i2c-xiic.h 2009-10-23 11:16:56.000000000 -0700
9934@@ -0,0 +1,31 @@
9935+/*
9936+ * i2c-xiic.h
9937+ * Copyright (c) 2009 Intel Corporation
9938+ *
9939+ * This program is free software; you can redistribute it and/or modify
9940+ * it under the terms of the GNU General Public License version 2 as
9941+ * published by the Free Software Foundation.
9942+ *
9943+ * This program is distributed in the hope that it will be useful,
9944+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9945+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9946+ * GNU General Public License for more details.
9947+ *
9948+ * You should have received a copy of the GNU General Public License
9949+ * along with this program; if not, write to the Free Software
9950+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
9951+ */
9952+
9953+/* Supports:
9954+ * Xilinx IIC
9955+ */
9956+
9957+#ifndef _LINUX_I2C_XIIC_H
9958+#define _LINUX_I2C_XIIC_H
9959+
9960+struct xiic_i2c_platform_data {
9961+ u8 num_devices; /* number of devices in the devices list */
9962+ struct i2c_board_info const *devices; /* devices connected to the bus */
9963+};
9964+
9965+#endif /* _LINUX_I2C_XIIC_H */
9966diff -uNr linux-2.6.31/include/linux/mfd/timbdma.h linux-2.6.31.new/include/linux/mfd/timbdma.h
9967--- linux-2.6.31/include/linux/mfd/timbdma.h 1969-12-31 16:00:00.000000000 -0800
9968+++ linux-2.6.31.new/include/linux/mfd/timbdma.h 2009-10-23 11:16:56.000000000 -0700
9969@@ -0,0 +1,58 @@
9970+/*
9971+ * timbdma.h timberdale FPGA DMA driver defines
9972+ * Copyright (c) 2009 Intel Corporation
9973+ *
9974+ * This program is free software; you can redistribute it and/or modify
9975+ * it under the terms of the GNU General Public License version 2 as
9976+ * published by the Free Software Foundation.
9977+ *
9978+ * This program is distributed in the hope that it will be useful,
9979+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9980+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9981+ * GNU General Public License for more details.
9982+ *
9983+ * You should have received a copy of the GNU General Public License
9984+ * along with this program; if not, write to the Free Software
9985+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
9986+ */
9987+
9988+/* Supports:
9989+ * Timberdale FPGA DMA engine
9990+ */
9991+
9992+#ifndef _TIMBDMA_H
9993+#define _TIMBDMA_H
9994+
9995+#include <linux/spinlock.h>
9996+
9997+
9998+#define DMA_IRQ_UART_RX 0x001
9999+#define DMA_IRQ_UART_TX 0x002
10000+#define DMA_IRQ_MLB_RX 0x004
10001+#define DMA_IRQ_MLB_TX 0x008
10002+#define DMA_IRQ_VIDEO_RX 0x010
10003+#define DMA_IRQ_VIDEO_DROP 0x020
10004+#define DMA_IRQ_SDHCI_RX 0x040
10005+#define DMA_IRQ_SDHCI_TX 0x080
10006+#define DMA_IRQ_ETH_RX 0x100
10007+#define DMA_IRQ_ETH_TX 0x200
10008+#define DMA_IRQS 10
10009+
10010+
10011+typedef int (*timbdma_interruptcb)(u32 flag, void *data);
10012+
10013+
10014+int timbdma_start(u32 flag, void *desc, int bytes_per_row);
10015+
10016+int timbdma_stop(u32 flags);
10017+
10018+void timbdma_set_interruptcb(u32 flags, timbdma_interruptcb icb, void *data);
10019+
10020+void *timbdma_alloc_desc(u32 size, u16 alignment);
10021+
10022+void timbdma_free_desc(void *desc);
10023+
10024+int timbdma_prep_desc(void *desc, dma_addr_t buf, u32 size);
10025+
10026+#endif /* _TIMBDMA_H */
10027+
10028diff -uNr linux-2.6.31/include/linux/most/timbmlb.h linux-2.6.31.new/include/linux/most/timbmlb.h
10029--- linux-2.6.31/include/linux/most/timbmlb.h 1969-12-31 16:00:00.000000000 -0800
10030+++ linux-2.6.31.new/include/linux/most/timbmlb.h 2009-10-23 11:16:56.000000000 -0700
10031@@ -0,0 +1,9 @@
10032+#ifndef __LINUX_MOST_TIMBMLB_H
10033+#define __LINUX_MOST_TIMBMLB_H
10034+
10035+/* Timberdale MLB IP */
10036+struct timbmlb_platform_data {
10037+ int reset_pin; /* pin used for reset of the INIC */
10038+};
10039+
10040+#endif
10041diff -uNr linux-2.6.31/include/linux/socket.h linux-2.6.31.new/include/linux/socket.h
10042--- linux-2.6.31/include/linux/socket.h 2009-10-23 11:18:30.000000000 -0700
10043+++ linux-2.6.31.new/include/linux/socket.h 2009-10-23 11:16:56.000000000 -0700
10044@@ -195,7 +195,8 @@
10045 #define AF_ISDN 34 /* mISDN sockets */
10046 #define AF_PHONET 35 /* Phonet sockets */
10047 #define AF_IEEE802154 36 /* IEEE802154 sockets */
10048-#define AF_MAX 37 /* For now.. */
10049+#define AF_MOST 37 /* Media Oriented Systems Transport */
10050+#define AF_MAX 38 /* For now.. */
10051
10052 /* Protocol families, same as address families. */
10053 #define PF_UNSPEC AF_UNSPEC
10054@@ -235,6 +236,7 @@
10055 #define PF_ISDN AF_ISDN
10056 #define PF_PHONET AF_PHONET
10057 #define PF_IEEE802154 AF_IEEE802154
10058+#define PF_MOST AF_MOST
10059 #define PF_MAX AF_MAX
10060
10061 /* Maximum queue length specifiable by listen. */
10062diff -uNr linux-2.6.31/include/linux/spi/mc33880.h linux-2.6.31.new/include/linux/spi/mc33880.h
10063--- linux-2.6.31/include/linux/spi/mc33880.h 1969-12-31 16:00:00.000000000 -0800
10064+++ linux-2.6.31.new/include/linux/spi/mc33880.h 2009-10-23 11:16:56.000000000 -0700
10065@@ -0,0 +1,10 @@
10066+#ifndef LINUX_SPI_MC33880_H
10067+#define LINUX_SPI_MC33880_H
10068+
10069+struct mc33880_platform_data {
10070+ /* number assigned to the first GPIO */
10071+ unsigned base;
10072+};
10073+
10074+#endif
10075+
10076diff -uNr linux-2.6.31/include/linux/spi/xilinx_spi.h linux-2.6.31.new/include/linux/spi/xilinx_spi.h
10077--- linux-2.6.31/include/linux/spi/xilinx_spi.h 1969-12-31 16:00:00.000000000 -0800
10078+++ linux-2.6.31.new/include/linux/spi/xilinx_spi.h 2009-10-23 11:16:56.000000000 -0700
10079@@ -0,0 +1,19 @@
10080+#ifndef __LINUX_SPI_XILINX_SPI_H
10081+#define __LINUX_SPI_XILINX_SPI_H
10082+
10083+/**
10084+ * struct xspi_platform_data - Platform data of the Xilinx SPI driver
10085+ * @num_chipselect: Number of chip select by the IP
10086+ * @bits_per_word: Number of bits per word. 8/16/32, Note that the DS464
10087+ * only support 8bit SPI.
10088+ * @devices: Devices to add when the driver is probed.
10089+ * @num_devices: Number of devices in the devices array.
10090+ */
10091+struct xspi_platform_data {
10092+ u16 num_chipselect;
10093+ u8 bits_per_word;
10094+ struct spi_board_info *devices;
10095+ u8 num_devices;
10096+};
10097+
10098+#endif /* __LINUX_SPI_XILINX_SPI_H */
10099diff -uNr linux-2.6.31/include/linux/timb_gpio.h linux-2.6.31.new/include/linux/timb_gpio.h
10100--- linux-2.6.31/include/linux/timb_gpio.h 1969-12-31 16:00:00.000000000 -0800
10101+++ linux-2.6.31.new/include/linux/timb_gpio.h 2009-10-23 11:16:56.000000000 -0700
10102@@ -0,0 +1,28 @@
10103+/*
10104+ * timb_gpio.h timberdale FPGA GPIO driver, platform data definition
10105+ * Copyright (c) 2009 Intel Corporation
10106+ *
10107+ * This program is free software; you can redistribute it and/or modify
10108+ * it under the terms of the GNU General Public License version 2 as
10109+ * published by the Free Software Foundation.
10110+ *
10111+ * This program is distributed in the hope that it will be useful,
10112+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10113+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10114+ * GNU General Public License for more details.
10115+ *
10116+ * You should have received a copy of the GNU General Public License
10117+ * along with this program; if not, write to the Free Software
10118+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
10119+ */
10120+
10121+#ifndef _LINUX_TIMB_GPIO_H
10122+#define _LINUX_TIMB_GPIO_H
10123+
10124+struct timbgpio_platform_data {
10125+ int gpio_base;
10126+ int nr_pins;
10127+ int irq_base;
10128+};
10129+
10130+#endif
10131diff -uNr linux-2.6.31/include/media/timb_radio.h linux-2.6.31.new/include/media/timb_radio.h
10132--- linux-2.6.31/include/media/timb_radio.h 1969-12-31 16:00:00.000000000 -0800
10133+++ linux-2.6.31.new/include/media/timb_radio.h 2009-10-23 11:16:55.000000000 -0700
10134@@ -0,0 +1,31 @@
10135+/*
10136+ * timb_radio.h Platform struct for the Timberdale radio driver
10137+ * Copyright (c) 2009 Intel Corporation
10138+ *
10139+ * This program is free software; you can redistribute it and/or modify
10140+ * it under the terms of the GNU General Public License version 2 as
10141+ * published by the Free Software Foundation.
10142+ *
10143+ * This program is distributed in the hope that it will be useful,
10144+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10145+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10146+ * GNU General Public License for more details.
10147+ *
10148+ * You should have received a copy of the GNU General Public License
10149+ * along with this program; if not, write to the Free Software
10150+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
10151+ */
10152+
10153+#ifndef _TIMB_RADIO_
10154+#define _TIMB_RADIO_ 1
10155+
10156+#include <linux/i2c.h>
10157+
10158+struct timb_radio_platform_data {
10159+ int i2c_adapter; /* I2C adapter where the tuner and dsp are attached */
10160+ char tuner[32];
10161+ char dsp[32];
10162+};
10163+
10164+#endif
10165+
10166diff -uNr linux-2.6.31/include/media/timb_video.h linux-2.6.31.new/include/media/timb_video.h
10167--- linux-2.6.31/include/media/timb_video.h 1969-12-31 16:00:00.000000000 -0800
10168+++ linux-2.6.31.new/include/media/timb_video.h 2009-10-23 11:16:55.000000000 -0700
10169@@ -0,0 +1,30 @@
10170+/*
10171+ * timb_video.h Platform struct for the Timberdale video driver
10172+ * Copyright (c) 2009 Intel Corporation
10173+ *
10174+ * This program is free software; you can redistribute it and/or modify
10175+ * it under the terms of the GNU General Public License version 2 as
10176+ * published by the Free Software Foundation.
10177+ *
10178+ * This program is distributed in the hope that it will be useful,
10179+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10180+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10181+ * GNU General Public License for more details.
10182+ *
10183+ * You should have received a copy of the GNU General Public License
10184+ * along with this program; if not, write to the Free Software
10185+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
10186+ */
10187+
10188+#ifndef _TIMB_VIDEO_
10189+#define _TIMB_VIDEO_ 1
10190+
10191+#include <linux/i2c.h>
10192+
10193+struct timb_video_platform_data {
10194+ int i2c_adapter; /* The I2C adapter where the encoder is attached */
10195+ char encoder[32];
10196+};
10197+
10198+#endif
10199+
10200diff -uNr linux-2.6.31/include/media/v4l2-chip-ident.h linux-2.6.31.new/include/media/v4l2-chip-ident.h
10201--- linux-2.6.31/include/media/v4l2-chip-ident.h 2009-10-23 11:18:30.000000000 -0700
10202+++ linux-2.6.31.new/include/media/v4l2-chip-ident.h 2009-10-23 11:16:55.000000000 -0700
10203@@ -129,12 +129,18 @@
10204 V4L2_IDENT_SAA6752HS = 6752,
10205 V4L2_IDENT_SAA6752HS_AC3 = 6753,
10206
10207+ /* modules tef6862: just ident 6862 */
10208+ V4L2_IDENT_TEF6862 = 6862,
10209+
10210 /* module adv7170: just ident 7170 */
10211 V4L2_IDENT_ADV7170 = 7170,
10212
10213 /* module adv7175: just ident 7175 */
10214 V4L2_IDENT_ADV7175 = 7175,
10215
10216+ /* module adv7180: just ident 7180 */
10217+ V4L2_IDENT_ADV7180 = 7180,
10218+
10219 /* module saa7185: just ident 7185 */
10220 V4L2_IDENT_SAA7185 = 7185,
10221
10222@@ -147,6 +153,9 @@
10223 /* module adv7343: just ident 7343 */
10224 V4L2_IDENT_ADV7343 = 7343,
10225
10226+ /* module saa7706h: just ident 7706 */
10227+ V4L2_IDENT_SAA7706H = 7706,
10228+
10229 /* module wm8739: just ident 8739 */
10230 V4L2_IDENT_WM8739 = 8739,
10231
10232diff -uNr linux-2.6.31/include/net/most/async.h linux-2.6.31.new/include/net/most/async.h
10233--- linux-2.6.31/include/net/most/async.h 1969-12-31 16:00:00.000000000 -0800
10234+++ linux-2.6.31.new/include/net/most/async.h 2009-10-23 11:16:55.000000000 -0700
10235@@ -0,0 +1,12 @@
10236+#ifndef __ASYNC_H
10237+#define __ASYNC_H
10238+
10239+struct sockaddr_mostasync {
10240+ sa_family_t most_family;
10241+ unsigned short most_dev;
10242+ unsigned char rx_channel;
10243+ unsigned char tx_channel;
10244+};
10245+
10246+#endif
10247+
10248diff -uNr linux-2.6.31/include/net/most/ctl.h linux-2.6.31.new/include/net/most/ctl.h
10249--- linux-2.6.31/include/net/most/ctl.h 1969-12-31 16:00:00.000000000 -0800
10250+++ linux-2.6.31.new/include/net/most/ctl.h 2009-10-23 11:16:55.000000000 -0700
10251@@ -0,0 +1,12 @@
10252+#ifndef __CTL_H
10253+#define __CTL_H
10254+
10255+struct sockaddr_mostctl {
10256+ sa_family_t most_family;
10257+ unsigned short most_dev;
10258+ unsigned char rx_channel;
10259+ unsigned char tx_channel;
10260+};
10261+
10262+#endif
10263+
10264diff -uNr linux-2.6.31/include/net/most/dev.h linux-2.6.31.new/include/net/most/dev.h
10265--- linux-2.6.31/include/net/most/dev.h 1969-12-31 16:00:00.000000000 -0800
10266+++ linux-2.6.31.new/include/net/most/dev.h 2009-10-23 11:16:55.000000000 -0700
10267@@ -0,0 +1,27 @@
10268+#ifndef __DEV_H
10269+#define __DEV_H
10270+
10271+struct sockaddr_mostdev {
10272+ sa_family_t most_family;
10273+ unsigned short most_dev;
10274+};
10275+
10276+
10277+/* MOST Dev ioctl defines */
10278+#define MOSTDEVUP _IOW('M', 201, int)
10279+#define MOSTDEVDOWN _IOW('M', 202, int)
10280+
10281+#define MOSTGETDEVLIST _IOR('M', 210, int)
10282+
10283+struct most_dev_req {
10284+ uint16_t dev_id;
10285+};
10286+
10287+struct most_dev_list_req {
10288+ uint16_t dev_num;
10289+ struct most_dev_req dev_req[0];
10290+};
10291+
10292+
10293+#endif
10294+
10295diff -uNr linux-2.6.31/include/net/most/most_core.h linux-2.6.31.new/include/net/most/most_core.h
10296--- linux-2.6.31/include/net/most/most_core.h 1969-12-31 16:00:00.000000000 -0800
10297+++ linux-2.6.31.new/include/net/most/most_core.h 2009-10-23 11:16:55.000000000 -0700
10298@@ -0,0 +1,133 @@
10299+#ifndef __MOST_CORE_H
10300+#define __MOST_CORE_H
10301+
10302+#include <net/most/most.h>
10303+
10304+enum most_chan_type {
10305+ CHAN_CTL = 0,
10306+ CHAN_SYNC,
10307+ CHAN_ASYNC,
10308+ CHAN_DEV
10309+};
10310+
10311+#define MOST_CONF_FLAG_UP 0x01
10312+#define MOST_CONF_FLAG_TX 0x02
10313+
10314+enum most_dev_state {
10315+ MOST_DEV_DOWN = 0,
10316+ MOST_DEV_UP
10317+};
10318+
10319+struct most_dev {
10320+
10321+ struct list_head list;
10322+ atomic_t refcnt;
10323+
10324+ char name[8];
10325+
10326+ __u16 id;
10327+ enum most_dev_state state;
10328+
10329+ struct module *owner;
10330+
10331+ struct tasklet_struct rx_task;
10332+ struct tasklet_struct tx_task;
10333+
10334+ struct sk_buff_head rx_q;
10335+ struct sk_buff_head ctl_q;
10336+ struct sk_buff_head async_q;
10337+ struct sk_buff_head sync_q;
10338+
10339+ /* set by the driver */
10340+
10341+ void *driver_data;
10342+ struct device *parent;
10343+
10344+ int (*open)(struct most_dev *mdev);
10345+ int (*close)(struct most_dev *mdev);
10346+ int (*conf_channel)(struct most_dev *mdev, enum most_chan_type type,
10347+ u8 channel, u8 flags);
10348+ int (*send)(struct sk_buff *skb);
10349+ int (*can_send)(struct sk_buff *skb);
10350+};
10351+
10352+#define most_dbg(...) printk(__VA_ARGS__)
10353+
10354+static inline struct most_dev *most_dev_hold(struct most_dev *d)
10355+{
10356+ if (try_module_get(d->owner))
10357+ return d;
10358+ return NULL;
10359+}
10360+
10361+static inline void most_dev_put(struct most_dev *d)
10362+{
10363+ module_put(d->owner);
10364+}
10365+
10366+static inline void most_sched_tx(struct most_dev *mdev)
10367+{
10368+ tasklet_schedule(&mdev->tx_task);
10369+}
10370+
10371+static inline void most_sched_rx(struct most_dev *mdev)
10372+{
10373+ tasklet_schedule(&mdev->rx_task);
10374+}
10375+
10376+static inline int most_recv_frame(struct sk_buff *skb)
10377+{
10378+ struct most_dev *mdev = (struct most_dev *) skb->dev;
10379+
10380+ /* Time stamp */
10381+ __net_timestamp(skb);
10382+
10383+ /* Queue frame for rx task */
10384+ skb_queue_tail(&mdev->rx_q, skb);
10385+ most_sched_rx(mdev);
10386+ return 0;
10387+}
10388+
10389+static inline int __most_configure_channel(struct most_dev *mdev,
10390+ u8 channel_type, u8 channel, u8 up)
10391+{
10392+ if (mdev->state != MOST_DEV_UP)
10393+ return -ENETDOWN;
10394+
10395+ if (mdev->conf_channel)
10396+ if (channel != MOST_NO_CHANNEL)
10397+ return mdev->conf_channel(mdev, channel_type, channel,
10398+ up);
10399+ return 0;
10400+}
10401+
10402+static inline int most_configure_channels(struct most_dev *mdev,
10403+ struct most_sock *sk, u8 up)
10404+{
10405+ int err;
10406+ u8 flags = (up) ? MOST_CONF_FLAG_UP : 0;
10407+
10408+ err = __most_configure_channel(mdev, sk->channel_type, sk->rx_channel,
10409+ flags);
10410+ if (err)
10411+ return err;
10412+
10413+ err = __most_configure_channel(mdev, sk->channel_type, sk->tx_channel,
10414+ flags | MOST_CONF_FLAG_TX);
10415+ if (err)
10416+ __most_configure_channel(mdev, sk->channel_type, sk->rx_channel,
10417+ (up) ? 0 : MOST_CONF_FLAG_UP);
10418+ return err;
10419+}
10420+
10421+struct most_dev *most_alloc_dev(void);
10422+void most_free_dev(struct most_dev *mdev);
10423+int most_register_dev(struct most_dev *mdev);
10424+int most_unregister_dev(struct most_dev *mdev);
10425+
10426+int most_get_dev_list(void __user *arg);
10427+int most_open_dev(u16 dev_id);
10428+int most_close_dev(u16 dev_id);
10429+
10430+#endif
10431+
10432diff -uNr linux-2.6.31/include/net/most/most.h linux-2.6.31.new/include/net/most/most.h
10433--- linux-2.6.31/include/net/most/most.h 1969-12-31 16:00:00.000000000 -0800
10434+++ linux-2.6.31.new/include/net/most/most.h 2009-10-23 11:16:55.000000000 -0700
10435@@ -0,0 +1,110 @@
10436+#ifndef __MOST_H
10437+#define __MOST_H
10438+
10439+#include <net/sock.h>
10440+
10441+#ifndef AF_MOST
10442+#define AF_MOST 37
10443+#define PF_MOST AF_MOST
10444+#endif
10445+
10446+/* Reserve for core and drivers use */
10447+#define MOST_SKB_RESERVE 8
10448+
10449+#define CTL_FRAME_SIZE 32
10450+
10451+#define MOSTPROTO_DEV 0
10452+#define MOSTPROTO_CTL 1
10453+#define MOSTPROTO_SYNC 2
10454+#define MOSTPROTO_ASYNC 3
10455+
10456+#define MOST_NO_CHANNEL 0xFE
10457+
10458+enum {
10459+ MOST_CONNECTED = 1, /* Equal to TCP_ESTABLISHED makes net code happy */
10460+ MOST_OPEN,
10461+ MOST_BOUND,
10462+};
10463+
10464+
10465+struct most_skb_cb {
10466+ __u8 channel_type;
10467+ __u8 channel;
10468+};
10469+#define most_cb(skb) ((struct most_skb_cb *)(skb->cb))
10470+
10471+struct most_sock {
10472+ struct sock sk;
10473+ u8 channel_type;
10474+ u8 rx_channel;
10475+ u8 tx_channel;
10476+ int dev_id;
10477+ struct most_dev *mdev;
10478+};
10479+#define most_sk(sk) ((struct most_sock *)sk)
10480+
10481+static inline struct sock *most_sk_alloc(struct net *net,
10482+ struct proto *pops, u8 channel_type)
10483+{
10484+ struct sock *sk = sk_alloc(net, PF_MOST, GFP_ATOMIC, pops);
10485+ if (sk) {
10486+ most_sk(sk)->channel_type = channel_type;
10487+ most_sk(sk)->dev_id = -1;
10488+ }
10489+
10490+ return sk;
10491+}
10492+static inline struct sk_buff *most_skb_alloc(unsigned int len, gfp_t how)
10493+{
10494+ struct sk_buff *skb = alloc_skb(len + MOST_SKB_RESERVE, how);
10495+
10496+ if (skb)
10497+ skb_reserve(skb, MOST_SKB_RESERVE);
10498+
10499+ return skb;
10500+}
10501+
10502+static inline struct sk_buff *most_skb_send_alloc(struct sock *sk,
10503+ unsigned long len, int nb, int *err)
10504+{
10505+ struct sk_buff *skb =
10506+ sock_alloc_send_skb(sk, len + MOST_SKB_RESERVE, nb, err);
10507+
10508+ if (skb)
10509+ skb_reserve(skb, MOST_SKB_RESERVE);
10510+
10511+ return skb;
10512+}
10513+
10514+struct most_sock_list {
10515+ struct hlist_head head;
10516+ rwlock_t lock;
10517+};
10518+
10519+struct most_dev *most_dev_get(int index);
10520+
10521+int most_sock_register(int proto, struct net_proto_family *ops);
10522+int most_sock_unregister(int proto);
10523+void most_sock_link(struct sock *s);
10524+void most_sock_unlink(struct sock *sk);
10525+
10526+int most_send_to_sock(int dev_id, struct sk_buff *skb);
10527+
10528+/* default implementation of socket operations */
10529+int most_sock_release(struct socket *sock);
10530+int most_sock_bind(struct socket *sock, int dev_id, u8 rx_chan, u8 tx_chan);
10531+int most_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
10532+int most_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
10533+ struct msghdr *msg, size_t len, int flags);
10534+int most_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
10535+ struct msghdr *msg, size_t len);
10536+int most_sock_setsockopt(struct socket *sock, int level, int optname,
10537+ char __user *optval, int len);
10538+int most_sock_getsockopt(struct socket *sock, int level, int optname,
10539+ char __user *optval, int __user *optlen);
10540+
10541+extern int dev_sock_init(void);
10542+extern void dev_sock_cleanup(void);
10543+
10544+#endif /* __MOST_H */
10545+
10546diff -uNr linux-2.6.31/include/net/most/sync.h linux-2.6.31.new/include/net/most/sync.h
10547--- linux-2.6.31/include/net/most/sync.h 1969-12-31 16:00:00.000000000 -0800
10548+++ linux-2.6.31.new/include/net/most/sync.h 2009-10-23 11:16:55.000000000 -0700
10549@@ -0,0 +1,12 @@
10550+#ifndef __SYNC_H
10551+#define __SYNC_H
10552+
10553+struct sockaddr_mostsync {
10554+ sa_family_t most_family;
10555+ unsigned short most_dev;
10556+ unsigned char rx_channel;
10557+ unsigned char tx_channel;
10558+};
10559+
10560+#endif
10561+
10562diff -uNr linux-2.6.31/include/sound/timbi2s.h linux-2.6.31.new/include/sound/timbi2s.h
10563--- linux-2.6.31/include/sound/timbi2s.h 1969-12-31 16:00:00.000000000 -0800
10564+++ linux-2.6.31.new/include/sound/timbi2s.h 2009-10-23 11:16:55.000000000 -0700
10565@@ -0,0 +1,32 @@
10566+/*
10567+ * timbi2s.h timberdale FPGA I2S platform data
10568+ * Copyright (c) 2009 Intel Corporation
10569+ *
10570+ * This program is free software; you can redistribute it and/or modify
10571+ * it under the terms of the GNU General Public License version 2 as
10572+ * published by the Free Software Foundation.
10573+ *
10574+ * This program is distributed in the hope that it will be useful,
10575+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10576+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10577+ * GNU General Public License for more details.
10578+ *
10579+ * You should have received a copy of the GNU General Public License
10580+ * along with this program; if not, write to the Free Software
10581+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
10582+ */
10583+#ifndef __INCLUDE_SOUND_TIMBI2S_H
10584+#define __INCLUDE_SOUND_TIMBI2S_H
10585+
10586+struct timbi2s_bus_data {
10587+ u8 rx;
10588+ u16 sample_rate;
10589+};
10590+
10591+struct timbi2s_platform_data {
10592+ const struct timbi2s_bus_data *busses;
10593+ int num_busses;
10594+ u32 main_clk;
10595+};
10596+
10597+#endif
10598diff -uNr linux-2.6.31/net/Kconfig linux-2.6.31.new/net/Kconfig
10599--- linux-2.6.31/net/Kconfig 2009-10-23 11:18:30.000000000 -0700
10600+++ linux-2.6.31.new/net/Kconfig 2009-10-23 11:17:37.000000000 -0700
10601@@ -235,6 +235,7 @@
10602 source "net/irda/Kconfig"
10603 source "net/bluetooth/Kconfig"
10604 source "net/rxrpc/Kconfig"
10605+source "net/most/Kconfig"
10606
10607 config FIB_RULES
10608 bool
10609diff -uNr linux-2.6.31/net/Makefile linux-2.6.31.new/net/Makefile
10610--- linux-2.6.31/net/Makefile 2009-10-23 11:18:30.000000000 -0700
10611+++ linux-2.6.31.new/net/Makefile 2009-10-23 11:17:36.000000000 -0700
10612@@ -44,6 +44,7 @@
10613 obj-$(CONFIG_DECNET) += decnet/
10614 obj-$(CONFIG_ECONET) += econet/
10615 obj-$(CONFIG_PHONET) += phonet/
10616+obj-$(CONFIG_MOST) += most/
10617 ifneq ($(CONFIG_VLAN_8021Q),)
10618 obj-y += 8021q/
10619 endif
10620diff -uNr linux-2.6.31/net/most/af_most.c linux-2.6.31.new/net/most/af_most.c
10621--- linux-2.6.31/net/most/af_most.c 1969-12-31 16:00:00.000000000 -0800
10622+++ linux-2.6.31.new/net/most/af_most.c 2009-10-23 11:17:37.000000000 -0700
10623@@ -0,0 +1,169 @@
10624+/*
10625+ * af_most.c Support for the MOST address family
10626+ * Copyright (c) 2009 Intel Corporation
10627+ *
10628+ * This program is free software; you can redistribute it and/or modify
10629+ * it under the terms of the GNU General Public License version 2 as
10630+ * published by the Free Software Foundation.
10631+ *
10632+ * This program is distributed in the hope that it will be useful,
10633+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10634+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10635+ * GNU General Public License for more details.
10636+ *
10637+ * You should have received a copy of the GNU General Public License
10638+ * along with this program; if not, write to the Free Software
10639+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
10640+ */
10641+
10642+#include <linux/module.h>
10643+#include <net/most/most.h>
10644+
10645+#define MOST_MAX_PROTO 4
10646+static struct net_proto_family *most_proto[MOST_MAX_PROTO];
10647+static DEFINE_RWLOCK(most_proto_lock);
10648+
10649+#ifdef CONFIG_DEBUG_LOCK_ALLOC
10650+static struct lock_class_key most_lock_key[MOST_MAX_PROTO];
10651+static const char *most_key_strings[MOST_MAX_PROTO] = {
10652+ "sk_lock-AF_MOST-MOSTPROTO_DEV",
10653+ "sk_lock-AF_MOST-MOSTPROTO_CTL",
10654+ "sk_lock-AF_MOST-MOSTPROTO_SYNC",
10655+ "sk_lock-AF_MOST-MOSTPROTO_ASYNC",
10656+};
10657+
10658+static struct lock_class_key most_slock_key[MOST_MAX_PROTO];
10659+static const char *most_slock_key_strings[MOST_MAX_PROTO] = {
10660+ "slock-AF_MOST-MOSTPROTO_DEV",
10661+ "slock-AF_MOST-MOSTPROTO_CTL",
10662+ "slock-AF_MOST-MOSTPROTO_SYNC",
10663+ "slock-AF_MOST-MOSTPROTO_ASYNC",
10664+};
10665+
10666+static inline void most_sock_reclassify_lock(struct socket *sock, int proto)
10667+{
10668+ struct sock *sk = sock->sk;
10669+
10670+ if (!sk)
10671+ return;
10672+
10673+ BUG_ON(sock_owned_by_user(sk));
10674+
10675+ sock_lock_init_class_and_name(sk,
10676+ most_slock_key_strings[proto], &most_slock_key[proto],
10677+ most_key_strings[proto], &most_lock_key[proto]);
10678+}
10679+#else
10680+static inline void most_sock_reclassify_lock(struct socket *sock, int proto)
10681+{
10682+}
10683+#endif
10684+
10685+
10686+int most_sock_register(int proto, struct net_proto_family *ops)
10687+{
10688+ int err = 0;
10689+
10690+ if (proto < 0 || proto >= MOST_MAX_PROTO)
10691+ return -EINVAL;
10692+
10693+ write_lock(&most_proto_lock);
10694+
10695+ if (most_proto[proto])
10696+ err = -EEXIST;
10697+ else
10698+ most_proto[proto] = ops;
10699+
10700+ write_unlock(&most_proto_lock);
10701+
10702+ return err;
10703+}
10704+EXPORT_SYMBOL(most_sock_register);
10705+
10706+int most_sock_unregister(int proto)
10707+{
10708+ int err = 0;
10709+
10710+ if (proto < 0 || proto >= MOST_MAX_PROTO)
10711+ return -EINVAL;
10712+
10713+ write_lock(&most_proto_lock);
10714+
10715+ if (!most_proto[proto])
10716+ err = -ENOENT;
10717+ else
10718+ most_proto[proto] = NULL;
10719+
10720+ write_unlock(&most_proto_lock);
10721+
10722+ return err;
10723+}
10724+EXPORT_SYMBOL(most_sock_unregister);
10725+
10726+static int most_sock_create(struct net *net, struct socket *sock, int proto)
10727+{
10728+ int err;
10729+
10730+ if (net != &init_net)
10731+ return -EAFNOSUPPORT;
10732+
10733+ if (proto < 0 || proto >= MOST_MAX_PROTO)
10734+ return -EINVAL;
10735+
10736+ if (!most_proto[proto])
10737+ request_module("most-proto-%d", proto);
10738+
10739+ err = -EPROTONOSUPPORT;
10740+
10741+ read_lock(&most_proto_lock);
10742+
10743+ if (most_proto[proto] && try_module_get(most_proto[proto]->owner)) {
10744+ err = most_proto[proto]->create(net, sock, proto);
10745+ most_sock_reclassify_lock(sock, proto);
10746+ module_put(most_proto[proto]->owner);
10747+ }
10748+
10749+ read_unlock(&most_proto_lock);
10750+
10751+ return err;
10752+}
10753+
10754+static struct net_proto_family most_sock_family_ops = {
10755+ .owner = THIS_MODULE,
10756+ .family = PF_MOST,
10757+ .create = most_sock_create,
10758+};
10759+
10760+static int __init most_init(void)
10761+{
10762+ int err;
10763+
10764+ err = sock_register(&most_sock_family_ops);
10765+ if (err < 0)
10766+ return err;
10767+
10768+ err = dev_sock_init();
10769+ if (err < 0) {
10770+ sock_unregister(PF_MOST);
10771+ return err;
10772+ }
10773+
10774+ printk(KERN_INFO "MOST is initialized\n");
10775+
10776+ return 0;
10777+}
10778+
10779+static void __exit most_exit(void)
10780+{
10781+ dev_sock_cleanup();
10782+
10783+ sock_unregister(PF_MOST);
10784+}
10785+
10786+subsys_initcall(most_init);
10787+module_exit(most_exit);
10788+
10789+MODULE_DESCRIPTION("MOST Core");
10790+MODULE_LICENSE("GPL v2");
10791+MODULE_ALIAS_NETPROTO(PF_MOST);
10792+
10793diff -uNr linux-2.6.31/net/most/async_sock.c linux-2.6.31.new/net/most/async_sock.c
10794--- linux-2.6.31/net/most/async_sock.c 1969-12-31 16:00:00.000000000 -0800
10795+++ linux-2.6.31.new/net/most/async_sock.c 2009-10-23 11:17:37.000000000 -0700
10796@@ -0,0 +1,154 @@
10797+/*
10798+ * async_sock.c MOST asyncronous socket support
10799+ * Copyright (c) 2009 Intel Corporation
10800+ *
10801+ * This program is free software; you can redistribute it and/or modify
10802+ * it under the terms of the GNU General Public License version 2 as
10803+ * published by the Free Software Foundation.
10804+ *
10805+ * This program is distributed in the hope that it will be useful,
10806+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10807+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10808+ * GNU General Public License for more details.
10809+ *
10810+ * You should have received a copy of the GNU General Public License
10811+ * along with this program; if not, write to the Free Software
10812+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
10813+ */
10814+
10815+/* Supports:
10816+ * Support for MOST asynchronous sockets
10817+ */
10818+
10819+#include <linux/module.h>
10820+#include <net/most/most.h>
10821+#include <net/most/most_core.h>
10822+#include <net/most/async.h>
10823+
10824+static int async_sock_bind(struct socket *sock, struct sockaddr *addr,
10825+ int addr_len)
10826+{
10827+ struct sockaddr_mostasync *aaddr = (struct sockaddr_mostasync *)addr;
10828+
10829+ if (!aaddr || aaddr->most_family != AF_MOST)
10830+ return -EINVAL;
10831+
10832+ return most_sock_bind(sock, aaddr->most_dev, aaddr->rx_channel,
10833+ aaddr->tx_channel);
10834+}
10835+
10836+static int async_sock_getname(struct socket *sock, struct sockaddr *addr,
10837+ int *addr_len, int peer)
10838+{
10839+ struct sockaddr_mostasync *aaddr = (struct sockaddr_mostasync *)addr;
10840+ struct sock *sk = sock->sk;
10841+ struct most_dev *mdev = most_sk(sk)->mdev;
10842+
10843+ if (!mdev)
10844+ return -EBADFD;
10845+
10846+ lock_sock(sk);
10847+
10848+ *addr_len = sizeof(*aaddr);
10849+ aaddr->most_family = AF_MOST;
10850+ aaddr->most_dev = mdev->id;
10851+ aaddr->rx_channel = most_sk(sk)->rx_channel;
10852+ aaddr->tx_channel = most_sk(sk)->tx_channel;
10853+
10854+ release_sock(sk);
10855+ return 0;
10856+}
10857+
10858+
10859+static const struct proto_ops async_sock_ops = {
10860+ .family = PF_MOST,
10861+ .owner = THIS_MODULE,
10862+ .release = most_sock_release,
10863+ .bind = async_sock_bind,
10864+ .getname = async_sock_getname,
10865+ .sendmsg = most_sock_sendmsg,
10866+ .recvmsg = most_sock_recvmsg,
10867+ .ioctl = most_sock_ioctl,
10868+ .poll = datagram_poll,
10869+ .listen = sock_no_listen,
10870+ .shutdown = sock_no_shutdown,
10871+ .setsockopt = most_sock_setsockopt,
10872+ .getsockopt = most_sock_getsockopt,
10873+ .connect = sock_no_connect,
10874+ .socketpair = sock_no_socketpair,
10875+ .accept = sock_no_accept,
10876+ .mmap = sock_no_mmap
10877+};
10878+static struct proto async_sk_proto = {
10879+ .name = "ASYNC",
10880+ .owner = THIS_MODULE,
10881+ .obj_size = sizeof(struct most_sock)
10882+};
10883+
10884+static int async_sock_create(struct net *net, struct socket *sock, int protocol)
10885+{
10886+ struct sock *sk;
10887+
10888+ if (sock->type != SOCK_DGRAM)
10889+ return -ESOCKTNOSUPPORT;
10890+
10891+ sock->ops = &async_sock_ops;
10892+
10893+ sk = most_sk_alloc(net, &async_sk_proto, CHAN_ASYNC);
10894+ if (!sk)
10895+ return -ENOMEM;
10896+
10897+ sock_init_data(sock, sk);
10898+
10899+ sock_reset_flag(sk, SOCK_ZAPPED);
10900+
10901+ sk->sk_protocol = protocol;
10902+
10903+ sock->state = SS_UNCONNECTED;
10904+ sk->sk_state = MOST_OPEN;
10905+
10906+ most_sock_link(sk);
10907+ return 0;
10908+}
10909+
10910+static struct net_proto_family async_sock_family_ops = {
10911+ .family = PF_MOST,
10912+ .owner = THIS_MODULE,
10913+ .create = async_sock_create,
10914+};
10915+
10916+
10917+static int __init async_init(void)
10918+{
10919+ int err;
10920+
10921+ err = proto_register(&async_sk_proto, 0);
10922+ if (err < 0)
10923+ return err;
10924+
10925+ err = most_sock_register(MOSTPROTO_ASYNC, &async_sock_family_ops);
10926+ if (err < 0) {
10927+ printk(KERN_ERR "MOST socket registration failed\n");
10928+ return err;
10929+ }
10930+
10931+ printk(KERN_INFO "MOST asynchronous socket layer initialized\n");
10932+
10933+ return 0;
10934+}
10935+
10936+static void __exit async_exit(void)
10937+{
10938+ if (most_sock_unregister(MOSTPROTO_ASYNC) < 0)
10939+ printk(KERN_ERR "ASYNC socket unregistration failed\n");
10940+
10941+ proto_unregister(&async_sk_proto);
10942+}
10943+
10944+module_init(async_init);
10945+module_exit(async_exit);
10946+
10947+MODULE_DESCRIPTION("Most Asyncronous");
10948+MODULE_LICENSE("GPL v2");
10949+MODULE_ALIAS("most-proto-3");
10950+
10951diff -uNr linux-2.6.31/net/most/ctl_sock.c linux-2.6.31.new/net/most/ctl_sock.c
10952--- linux-2.6.31/net/most/ctl_sock.c 1969-12-31 16:00:00.000000000 -0800
10953+++ linux-2.6.31.new/net/most/ctl_sock.c 2009-10-23 11:17:37.000000000 -0700
10954@@ -0,0 +1,159 @@
10955+/*
10956+ * ctl_sock.c Support for MOST control sockets
10957+ * Copyright (c) 2009 Intel Corporation
10958+ *
10959+ * This program is free software; you can redistribute it and/or modify
10960+ * it under the terms of the GNU General Public License version 2 as
10961+ * published by the Free Software Foundation.
10962+ *
10963+ * This program is distributed in the hope that it will be useful,
10964+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10965+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10966+ * GNU General Public License for more details.
10967+ *
10968+ * You should have received a copy of the GNU General Public License
10969+ * along with this program; if not, write to the Free Software
10970+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
10971+ */
10972+
10973+#include <linux/module.h>
10974+#include <net/most/most.h>
10975+#include <net/most/most_core.h>
10976+#include <net/most/ctl.h>
10977+
10978+
10979+static int ctl_sock_bind(struct socket *sock, struct sockaddr *addr,
10980+ int addr_len)
10981+{
10982+ struct sockaddr_mostctl *caddr = (struct sockaddr_mostctl *) addr;
10983+
10984+ if (!caddr || caddr->most_family != AF_MOST)
10985+ return -EINVAL;
10986+
10987+ return most_sock_bind(sock, caddr->most_dev, caddr->rx_channel,
10988+ caddr->tx_channel);
10989+}
10990+
10991+static int ctl_sock_getname(struct socket *sock, struct sockaddr *addr,
10992+ int *addr_len, int peer)
10993+{
10994+ struct sockaddr_mostctl *caddr = (struct sockaddr_mostctl *) addr;
10995+ struct sock *sk = sock->sk;
10996+ struct most_dev *mdev = most_sk(sk)->mdev;
10997+
10998+ if (!mdev)
10999+ return -EBADFD;
11000+
11001+ lock_sock(sk);
11002+
11003+ *addr_len = sizeof(*caddr);
11004+ caddr->most_family = AF_MOST;
11005+ caddr->most_dev = mdev->id;
11006+ caddr->rx_channel = most_sk(sk)->rx_channel;
11007+ caddr->tx_channel = most_sk(sk)->tx_channel;
11008+
11009+ release_sock(sk);
11010+ return 0;
11011+}
11012+
11013+int ctl_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
11014+ struct msghdr *msg, size_t len)
11015+{
11016+ if (len != CTL_FRAME_SIZE)
11017+ return -EINVAL;
11018+
11019+ return most_sock_sendmsg(iocb, sock, msg, len);
11020+}
11021+
11022+static const struct proto_ops ctl_sock_ops = {
11023+ .family = PF_MOST,
11024+ .owner = THIS_MODULE,
11025+ .release = most_sock_release,
11026+ .bind = ctl_sock_bind,
11027+ .getname = ctl_sock_getname,
11028+ .sendmsg = most_sock_sendmsg,
11029+ .recvmsg = most_sock_recvmsg,
11030+ .ioctl = most_sock_ioctl,
11031+ .poll = datagram_poll,
11032+ .listen = sock_no_listen,
11033+ .shutdown = sock_no_shutdown,
11034+ .setsockopt = most_sock_setsockopt,
11035+ .getsockopt = most_sock_getsockopt,
11036+ .connect = sock_no_connect,
11037+ .socketpair = sock_no_socketpair,
11038+ .accept = sock_no_accept,
11039+ .mmap = sock_no_mmap
11040+};
11041+static struct proto ctl_sk_proto = {
11042+ .name = "CTL",
11043+ .owner = THIS_MODULE,
11044+ .obj_size = sizeof(struct most_sock)
11045+};
11046+
11047+static int ctl_sock_create(struct net *net, struct socket *sock, int protocol)
11048+{
11049+ struct sock *sk;
11050+
11051+ if (sock->type != SOCK_RAW)
11052+ return -ESOCKTNOSUPPORT;
11053+
11054+ sock->ops = &ctl_sock_ops;
11055+
11056+ sk = most_sk_alloc(net, &ctl_sk_proto, CHAN_CTL);
11057+ if (!sk)
11058+ return -ENOMEM;
11059+
11060+ sock_init_data(sock, sk);
11061+
11062+ sock_reset_flag(sk, SOCK_ZAPPED);
11063+
11064+ sk->sk_protocol = protocol;
11065+
11066+ sock->state = SS_UNCONNECTED;
11067+ sk->sk_state = MOST_OPEN;
11068+
11069+ most_sock_link(sk);
11070+ return 0;
11071+}
11072+
11073+static struct net_proto_family ctl_sock_family_ops = {
11074+ .family = PF_MOST,
11075+ .owner = THIS_MODULE,
11076+ .create = ctl_sock_create,
11077+};
11078+
11079+
11080+static int __init ctl_init(void)
11081+{
11082+ int err;
11083+
11084+ err = proto_register(&ctl_sk_proto, 0);
11085+ if (err < 0)
11086+ return err;
11087+
11088+ err = most_sock_register(MOSTPROTO_CTL, &ctl_sock_family_ops);
11089+ if (err < 0) {
11090+ printk(KERN_ERR "MOST socket registration failed\n");
11091+ return err;
11092+ }
11093+
11094+ printk(KERN_INFO "MOST control socket layer initialized\n");
11095+
11096+ return 0;
11097+}
11098+
11099+static void __exit ctl_exit(void)
11100+{
11101+ if (most_sock_unregister(MOSTPROTO_CTL) < 0)
11102+ printk(KERN_ERR "Control socket unregistration failed\n");
11103+
11104+ proto_unregister(&ctl_sk_proto);
11105+}
11106+
11107+module_init(ctl_init);
11108+module_exit(ctl_exit);
11109+
11110+MODULE_DESCRIPTION("Most Control");
11111+MODULE_LICENSE("GPL v2");
11112+MODULE_ALIAS("most-proto-1");
11113+
11114diff -uNr linux-2.6.31/net/most/dev_sock.c linux-2.6.31.new/net/most/dev_sock.c
11115--- linux-2.6.31/net/most/dev_sock.c 1969-12-31 16:00:00.000000000 -0800
11116+++ linux-2.6.31.new/net/most/dev_sock.c 2009-10-23 11:17:37.000000000 -0700
11117@@ -0,0 +1,170 @@
11118+/*
11119+ * dev_sock.c Device MOST sockets, to control the underlaying devices
11120+ * Copyright (c) 2009 Intel Corporation
11121+ *
11122+ * This program is free software; you can redistribute it and/or modify
11123+ * it under the terms of the GNU General Public License version 2 as
11124+ * published by the Free Software Foundation.
11125+ *
11126+ * This program is distributed in the hope that it will be useful,
11127+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11128+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11129+ * GNU General Public License for more details.
11130+ *
11131+ * You should have received a copy of the GNU General Public License
11132+ * along with this program; if not, write to the Free Software
11133+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
11134+ */
11135+
11136+#include <linux/module.h>
11137+#include <net/most/most.h>
11138+#include <net/most/most_core.h>
11139+#include <net/most/dev.h>
11140+
11141+/* Ioctls that require bound socket */
11142+static inline int dev_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
11143+ unsigned long arg)
11144+{
11145+ return -ENOSYS;
11146+}
11147+
11148+static int dev_sock_ioctl(struct socket *sock, unsigned int cmd,
11149+ unsigned long arg)
11150+{
11151+ void __user *argp = (void __user *) arg;
11152+
11153+ switch (cmd) {
11154+ case MOSTDEVUP:
11155+ return most_open_dev(arg & 0xffff);
11156+ case MOSTDEVDOWN:
11157+ return most_close_dev(arg & 0xffff);
11158+ case MOSTGETDEVLIST:
11159+ return most_get_dev_list(argp);
11160+ default:
11161+ return -EINVAL;
11162+ }
11163+}
11164+
11165+static int dev_sock_bind(struct socket *sock, struct sockaddr *addr,
11166+ int addr_len)
11167+{
11168+ return -ENOSYS;
11169+}
11170+
11171+static int dev_sock_getname(struct socket *sock, struct sockaddr *addr,
11172+ int *addr_len, int peer)
11173+{
11174+ struct sockaddr_mostdev *daddr = (struct sockaddr_mostdev *) addr;
11175+ struct sock *sk = sock->sk;
11176+ struct most_dev *mdev = most_sk(sk)->mdev;
11177+
11178+ if (!mdev)
11179+ return -EBADFD;
11180+
11181+ lock_sock(sk);
11182+
11183+ *addr_len = sizeof(*daddr);
11184+ daddr->most_family = AF_MOST;
11185+ daddr->most_dev = mdev->id;
11186+
11187+ release_sock(sk);
11188+ return 0;
11189+}
11190+
11191+static int dev_sock_setsockopt(struct socket *sock, int level, int optname,
11192+ char __user *optval, int len)
11193+{
11194+ return -ENOSYS;
11195+}
11196+
11197+static int dev_sock_getsockopt(struct socket *sock, int level, int optname,
11198+ char __user *optval, int __user *optlen)
11199+{
11200+ return -ENOSYS;
11201+}
11202+
11203+static const struct proto_ops dev_sock_ops = {
11204+ .family = PF_MOST,
11205+ .owner = THIS_MODULE,
11206+ .release = most_sock_release,
11207+ .bind = dev_sock_bind,
11208+ .getname = dev_sock_getname,
11209+ .sendmsg = sock_no_sendmsg,
11210+ .recvmsg = sock_no_recvmsg,
11211+ .ioctl = dev_sock_ioctl,
11212+ .poll = sock_no_poll,
11213+ .listen = sock_no_listen,
11214+ .shutdown = sock_no_shutdown,
11215+ .setsockopt = dev_sock_setsockopt,
11216+ .getsockopt = dev_sock_getsockopt,
11217+ .connect = sock_no_connect,
11218+ .socketpair = sock_no_socketpair,
11219+ .accept = sock_no_accept,
11220+ .mmap = sock_no_mmap
11221+};
11222+static struct proto dev_sk_proto = {
11223+ .name = "DEV",
11224+ .owner = THIS_MODULE,
11225+ .obj_size = sizeof(struct most_sock)
11226+};
11227+
11228+static int dev_sock_create(struct net *net, struct socket *sock, int protocol)
11229+{
11230+ struct sock *sk;
11231+
11232+ if (sock->type != SOCK_RAW)
11233+ return -ESOCKTNOSUPPORT;
11234+
11235+ sock->ops = &dev_sock_ops;
11236+
11237+ sk = most_sk_alloc(net, &dev_sk_proto, CHAN_DEV);
11238+ if (!sk)
11239+ return -ENOMEM;
11240+
11241+ sock_init_data(sock, sk);
11242+
11243+ sock_reset_flag(sk, SOCK_ZAPPED);
11244+
11245+ sk->sk_protocol = protocol;
11246+
11247+ sock->state = SS_UNCONNECTED;
11248+ sk->sk_state = MOST_OPEN;
11249+
11250+ most_sock_link(sk);
11251+ return 0;
11252+}
11253+
11254+static struct net_proto_family dev_sock_family_ops = {
11255+ .family = PF_MOST,
11256+ .owner = THIS_MODULE,
11257+ .create = dev_sock_create,
11258+};
11259+
11260+
11261+int __init dev_sock_init(void)
11262+{
11263+ int err;
11264+
11265+ err = proto_register(&dev_sk_proto, 0);
11266+ if (err < 0)
11267+ return err;
11268+
11269+ err = most_sock_register(MOSTPROTO_DEV, &dev_sock_family_ops);
11270+ if (err < 0) {
11271+ printk(KERN_ERR "MOST socket registration failed\n");
11272+ return err;
11273+ }
11274+
11275+ printk(KERN_INFO "MOST device socket layer initialized\n");
11276+
11277+ return 0;
11278+}
11279+
11280+void __exit dev_sock_cleanup(void)
11281+{
11282+ if (most_sock_unregister(MOSTPROTO_DEV) < 0)
11283+ printk(KERN_ERR "Device socket unregistration failed\n");
11284+
11285+ proto_unregister(&dev_sk_proto);
11286+}
11287+
11288diff -uNr linux-2.6.31/net/most/Kconfig linux-2.6.31.new/net/most/Kconfig
11289--- linux-2.6.31/net/most/Kconfig 1969-12-31 16:00:00.000000000 -0800
11290+++ linux-2.6.31.new/net/most/Kconfig 2009-10-23 11:17:37.000000000 -0700
11291@@ -0,0 +1,38 @@
11292+#
11293+# Media Oriented Systems Transport (MOST) network layer core configuration
11294+#
11295+
11296+menuconfig MOST
11297+ depends on NET
11298+ tristate "MOST bus subsystem support"
11299+ ---help---
11300+ Media Oriented Systems Transport (MOST) is a multimedia
11301+ communications protocol in the automotive industry.
11302+
11303+ If you want MOST support you should say Y here.
11304+
11305+config MOST_CTL
11306+ tristate "Support for Control data over MOST"
11307+ depends on MOST
11308+ default N
11309+ ---help---
11310+ Support for the control channel of the MOST bus.
11311+
11312+config MOST_ASYNC
11313+ tristate "Support for Asynchronous data over MOST"
11314+ depends on MOST
11315+ default N
11316+ ---help---
11317+ Support for the asyncronous channel of the MOST bus. Normally
11318+ used for software download od file transfers.
11319+
11320+config MOST_SYNC
11321+ tristate "Support for Synchronous data over MOST"
11322+ depends on MOST
11323+ default N
11324+ ---help---
11325+ Support for synchronous channles of the MOST bus. Normally used
11326+ for streaming media such as audio and video.
11327+
11328+
11329+source "drivers/net/most/Kconfig"
11330diff -uNr linux-2.6.31/net/most/Makefile linux-2.6.31.new/net/most/Makefile
11331--- linux-2.6.31/net/most/Makefile 1969-12-31 16:00:00.000000000 -0800
11332+++ linux-2.6.31.new/net/most/Makefile 2009-10-23 11:17:37.000000000 -0700
11333@@ -0,0 +1,15 @@
11334+#
11335+# Makefile for the Linux Media Oriented Systems Transport core.
11336+#
11337+
11338+obj-$(CONFIG_MOST) += most.o
11339+most-objs := af_most.o most_core.o most_sock.o dev_sock.o
11340+
11341+obj-$(CONFIG_MOST_CTL) += ctl.o
11342+ctl-objs := ctl_sock.o
11343+
11344+obj-$(CONFIG_MOST_SYNC) += sync.o
11345+sync-objs := sync_sock.o
11346+
11347+obj-$(CONFIG_MOST_ASYNC) += async.o
11348+async-objs := async_sock.o
11349diff -uNr linux-2.6.31/net/most/most_core.c linux-2.6.31.new/net/most/most_core.c
11350--- linux-2.6.31/net/most/most_core.c 1969-12-31 16:00:00.000000000 -0800
11351+++ linux-2.6.31.new/net/most/most_core.c 2009-10-23 11:17:37.000000000 -0700
11352@@ -0,0 +1,287 @@
11353+/*
11354+ * most_core.c The MOST core functions
11355+ * Copyright (c) 2009 Intel Corporation
11356+ *
11357+ * This program is free software; you can redistribute it and/or modify
11358+ * it under the terms of the GNU General Public License version 2 as
11359+ * published by the Free Software Foundation.
11360+ *
11361+ * This program is distributed in the hope that it will be useful,
11362+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11363+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11364+ * GNU General Public License for more details.
11365+ *
11366+ * You should have received a copy of the GNU General Public License
11367+ * along with this program; if not, write to the Free Software
11368+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
11369+ */
11370+
11371+#include <linux/kernel.h>
11372+#include <linux/slab.h>
11373+#include <linux/module.h>
11374+
11375+#include <net/most/most_core.h>
11376+#include <net/most/dev.h>
11377+
11378+/* MOST device list */
11379+LIST_HEAD(most_dev_list);
11380+DEFINE_RWLOCK(most_dev_list_lock);
11381+
11382+
11383+int most_open_dev(u16 dev_id)
11384+{
11385+ struct most_dev *mdev = most_dev_get(dev_id);
11386+ int err = 0;
11387+
11388+ if (!mdev)
11389+ return -ENODEV;
11390+
11391+ most_dbg("%s: %s, state: %d\n", __func__, mdev->name, mdev->state);
11392+
11393+ if (mdev->state == MOST_DEV_UP)
11394+ err = -EALREADY;
11395+
11396+ if (!err)
11397+ err = mdev->open(mdev);
11398+ if (!err)
11399+ mdev->state = MOST_DEV_UP;
11400+
11401+ most_dev_put(mdev);
11402+ most_dbg("%s: %s, state: %d, err: %d\n", __func__,
11403+ mdev->name, mdev->state, err);
11404+ return err;
11405+}
11406+
11407+static int __most_close_dev(struct most_dev *mdev)
11408+{
11409+ int err = 0;
11410+
11411+ most_dbg("%s: %s, state: %d\n", __func__, mdev ? mdev->name : "nil",
11412+ mdev ? mdev->state : -1);
11413+
11414+ if (!mdev)
11415+ return -ENODEV;
11416+
11417+ if (mdev->state == MOST_DEV_DOWN)
11418+ err = -EALREADY;
11419+
11420+ if (!err)
11421+ err = mdev->close(mdev);
11422+ if (!err)
11423+ mdev->state = MOST_DEV_DOWN;
11424+
11425+ most_dev_put(mdev);
11426+ most_dbg("%s: %s, state: %d, err: %d\n", __func__,
11427+ mdev->name, mdev->state, err);
11428+ return err;
11429+}
11430+
11431+int most_close_dev(u16 dev_id)
11432+{
11433+ return __most_close_dev(most_dev_get(dev_id));
11434+}
11435+
11436+int most_get_dev_list(void __user *arg)
11437+{
11438+ struct most_dev_list_req *dl;
11439+ struct most_dev_req *dr;
11440+ struct list_head *p;
11441+ int n = 0, size, err;
11442+ u16 dev_num;
11443+
11444+ if (get_user(dev_num, (u16 __user *) arg))
11445+ return -EFAULT;
11446+
11447+ if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
11448+ return -EINVAL;
11449+
11450+ size = sizeof(*dl) + dev_num * sizeof(*dr);
11451+
11452+ dl = kzalloc(size, GFP_KERNEL);
11453+ if (!dl)
11454+ return -ENOMEM;
11455+
11456+ dr = dl->dev_req;
11457+
11458+ read_lock_bh(&most_dev_list_lock);
11459+ list_for_each(p, &most_dev_list) {
11460+ struct most_dev *mdev;
11461+ mdev = list_entry(p, struct most_dev, list);
11462+ (dr + n)->dev_id = mdev->id;
11463+ if (++n >= dev_num)
11464+ break;
11465+ }
11466+ read_unlock_bh(&most_dev_list_lock);
11467+
11468+ dl->dev_num = n;
11469+ size = sizeof(*dl) + n * sizeof(*dr);
11470+
11471+ err = copy_to_user(arg, dl, size);
11472+ kfree(dl);
11473+
11474+ return err ? -EFAULT : 0;
11475+}
11476+
11477+static int most_send_frame(struct sk_buff *skb)
11478+{
11479+ struct most_dev *mdev = (struct most_dev *) skb->dev;
11480+
11481+ if (!mdev) {
11482+ kfree_skb(skb);
11483+ return -ENODEV;
11484+ }
11485+
11486+ most_dbg("%s: %s type %d len %d\n", __func__, mdev->name,
11487+ most_cb(skb)->channel_type, skb->len);
11488+
11489+ /* Get rid of skb owner, prior to sending to the driver. */
11490+ skb_orphan(skb);
11491+
11492+ return mdev->send(skb);
11493+}
11494+
11495+static void most_send_queue(struct sk_buff_head *q)
11496+{
11497+ struct sk_buff *skb;
11498+
11499+ while ((skb = skb_dequeue(q))) {
11500+ struct most_dev *mdev = (struct most_dev *)skb->dev;
11501+
11502+ most_dbg("%s: skb %p len %d\n", __func__, skb, skb->len);
11503+
11504+ if (!mdev->can_send || mdev->can_send(skb))
11505+ most_send_frame(skb);
11506+ else {
11507+ most_dbg("%s, could not send frame, requeueing\n",
11508+ __func__);
11509+ skb_queue_tail(q, skb);
11510+ break;
11511+ }
11512+ }
11513+}
11514+
11515+static void most_tx_task(unsigned long arg)
11516+{
11517+ struct most_dev *mdev = (struct most_dev *) arg;
11518+
11519+ most_dbg("%s: %s\n", __func__, mdev->name);
11520+
11521+ most_send_queue(&mdev->ctl_q);
11522+ most_send_queue(&mdev->sync_q);
11523+ most_send_queue(&mdev->async_q);
11524+}
11525+
11526+static void most_rx_task(unsigned long arg)
11527+{
11528+ struct most_dev *mdev = (struct most_dev *) arg;
11529+ struct sk_buff *skb = skb_dequeue(&mdev->rx_q);
11530+
11531+ most_dbg("%s: %s\n", __func__, mdev->name);
11532+
11533+ while (skb) {
11534+ /* Send to the sockets */
11535+ most_send_to_sock(mdev->id, skb);
11536+ kfree_skb(skb);
11537+ skb = skb_dequeue(&mdev->rx_q);
11538+ }
11539+}
11540+
11541+
11542+/* Get MOST device by index.
11543+ * Device is held on return. */
11544+struct most_dev *most_dev_get(int index)
11545+{
11546+ struct most_dev *mdev = NULL;
11547+ struct list_head *p;
11548+
11549+ if (index < 0)
11550+ return NULL;
11551+
11552+ read_lock(&most_dev_list_lock);
11553+ list_for_each(p, &most_dev_list) {
11554+ struct most_dev *d = list_entry(p, struct most_dev, list);
11555+ if (d->id == index) {
11556+ mdev = most_dev_hold(d);
11557+ break;
11558+ }
11559+ }
11560+ read_unlock(&most_dev_list_lock);
11561+ return mdev;
11562+}
11563+EXPORT_SYMBOL(most_dev_get);
11564+
11565+
11566+/* Alloc MOST device */
11567+struct most_dev *most_alloc_dev(void)
11568+{
11569+ struct most_dev *mdev;
11570+
11571+ mdev = kzalloc(sizeof(struct most_dev), GFP_KERNEL);
11572+ if (!mdev)
11573+ return NULL;
11574+
11575+ mdev->state = MOST_DEV_DOWN;
11576+
11577+ return mdev;
11578+}
11579+EXPORT_SYMBOL(most_alloc_dev);
11580+
11581+
11582+void most_free_dev(struct most_dev *mdev)
11583+{
11584+ kfree(mdev);
11585+}
11586+EXPORT_SYMBOL(most_free_dev);
11587+
11588+
11589+/* Register MOST device */
11590+int most_register_dev(struct most_dev *mdev)
11591+{
11592+ struct list_head *head = &most_dev_list, *p;
11593+ int id = 0;
11594+
11595+ if (!mdev->open || !mdev->close || !mdev->send || !mdev->owner)
11596+ return -EINVAL;
11597+
11598+ write_lock_bh(&most_dev_list_lock);
11599+
11600+ /* Find first available device id */
11601+ list_for_each(p, &most_dev_list) {
11602+ if (list_entry(p, struct most_dev, list)->id != id)
11603+ break;
11604+ head = p; id++;
11605+ }
11606+
11607+ sprintf(mdev->name, "most%d", id);
11608+ mdev->id = id;
11609+ list_add(&mdev->list, head);
11610+
11611+ tasklet_init(&mdev->rx_task, most_rx_task, (unsigned long) mdev);
11612+ tasklet_init(&mdev->tx_task, most_tx_task, (unsigned long) mdev);
11613+
11614+ skb_queue_head_init(&mdev->rx_q);
11615+ skb_queue_head_init(&mdev->ctl_q);
11616+ skb_queue_head_init(&mdev->sync_q);
11617+ skb_queue_head_init(&mdev->async_q);
11618+
11619+ write_unlock_bh(&most_dev_list_lock);
11620+ return 0;
11621+}
11622+EXPORT_SYMBOL(most_register_dev);
11623+
11624+int most_unregister_dev(struct most_dev *mdev)
11625+{
11626+ int ret = 0;
11627+ most_dbg("%s: %s: state: %d\n", __func__, mdev->name, mdev->state);
11628+
11629+ if (mdev->state != MOST_DEV_DOWN)
11630+ ret = __most_close_dev(mdev);
11631+
11632+ write_lock_bh(&most_dev_list_lock);
11633+ list_del(&mdev->list);
11634+ write_unlock_bh(&most_dev_list_lock);
11635+
11636+ return ret;
11637+}
11638+EXPORT_SYMBOL(most_unregister_dev);
11639+
11640diff -uNr linux-2.6.31/net/most/most_sock.c linux-2.6.31.new/net/most/most_sock.c
11641--- linux-2.6.31/net/most/most_sock.c 1969-12-31 16:00:00.000000000 -0800
11642+++ linux-2.6.31.new/net/most/most_sock.c 2009-10-23 11:17:37.000000000 -0700
11643@@ -0,0 +1,315 @@
11644+/*
11645+ * most_sock.c Generic functions for MOST sockets
11646+ * Copyright (c) 2009 Intel Corporation
11647+ *
11648+ * This program is free software; you can redistribute it and/or modify
11649+ * it under the terms of the GNU General Public License version 2 as
11650+ * published by the Free Software Foundation.
11651+ *
11652+ * This program is distributed in the hope that it will be useful,
11653+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11654+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11655+ * GNU General Public License for more details.
11656+ *
11657+ * You should have received a copy of the GNU General Public License
11658+ * along with this program; if not, write to the Free Software
11659+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
11660+ */
11661+
11662+#include <linux/module.h>
11663+#include <net/most/most_core.h>
11664+
11665+static struct most_sock_list most_sk_list = {
11666+ .lock = __RW_LOCK_UNLOCKED(ctl_sk_list.lock)
11667+};
11668+
11669+void most_sock_link(struct sock *sk)
11670+{
11671+ write_lock_bh(&most_sk_list.lock);
11672+ sk_add_node(sk, &most_sk_list.head);
11673+ write_unlock_bh(&most_sk_list.lock);
11674+}
11675+EXPORT_SYMBOL(most_sock_link);
11676+
11677+void most_sock_unlink(struct sock *sk)
11678+{
11679+ write_lock_bh(&most_sk_list.lock);
11680+ sk_del_node_init(sk);
11681+ write_unlock_bh(&most_sk_list.lock);
11682+}
11683+EXPORT_SYMBOL(most_sock_unlink);
11684+
11685+static int channel_in_use(int dev_id, u8 channel)
11686+{
11687+ struct sock *sk;
11688+ struct hlist_node *node;
11689+
11690+ read_lock_bh(&most_sk_list.lock);
11691+
11692+ sk_for_each(sk, node, &most_sk_list.head)
11693+ if (most_sk(sk)->dev_id == dev_id &&
11694+ sk->sk_state == MOST_BOUND &&
11695+ (most_sk(sk)->rx_channel == channel ||
11696+ most_sk(sk)->tx_channel == channel))
11697+ goto found;
11698+
11699+ sk = NULL;
11700+found:
11701+ read_unlock_bh(&most_sk_list.lock);
11702+
11703+ return sk != NULL;
11704+}
11705+
11706+int most_send_to_sock(int dev_id, struct sk_buff *skb)
11707+{
11708+ struct sock *sk;
11709+ struct hlist_node *node;
11710+
11711+ read_lock(&most_sk_list.lock);
11712+ sk_for_each(sk, node, &most_sk_list.head) {
11713+ if (most_sk(sk)->dev_id == dev_id &&
11714+ most_sk(sk)->channel_type == most_cb(skb)->channel_type
11715+ && most_sk(sk)->rx_channel == most_cb(skb)->channel &&
11716+ sk->sk_state == MOST_BOUND) {
11717+
11718+ struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
11719+ if (nskb)
11720+ if (sock_queue_rcv_skb(sk, nskb))
11721+ kfree_skb(nskb);
11722+ }
11723+
11724+ }
11725+ read_unlock(&most_sk_list.lock);
11726+
11727+ return 0;
11728+}
11729+EXPORT_SYMBOL(most_send_to_sock);
11730+
11731+int most_sock_release(struct socket *sock)
11732+{
11733+ struct sock *sk = sock->sk;
11734+ struct most_dev *mdev;
11735+
11736+ most_dbg("%s: sock %p sk %p\n", __func__, sock, sk);
11737+
11738+ if (!sk)
11739+ return 0;
11740+
11741+ mdev = most_sk(sk)->mdev;
11742+
11743+ most_sock_unlink(sk);
11744+
11745+ if (mdev) {
11746+ if (sk->sk_state == MOST_BOUND)
11747+ most_configure_channels(mdev, most_sk(sk), 0);
11748+
11749+ most_dev_put(mdev);
11750+ }
11751+
11752+ sock_orphan(sk);
11753+ sock_put(sk);
11754+ return 0;
11755+}
11756+EXPORT_SYMBOL(most_sock_release);
11757+
11758+int most_sock_bind(struct socket *sock, int dev_id, u8 rx_chan, u8 tx_chan)
11759+{
11760+ struct sock *sk = sock->sk;
11761+ struct most_dev *mdev = NULL;
11762+ int err = 0;
11763+
11764+ most_dbg("%s: sock %p sk %p, rx: %d, tx: %d\n",
11765+ __func__, sock, sk, rx_chan, tx_chan);
11766+
11767+ lock_sock(sk);
11768+
11769+ if (sk->sk_state != MOST_OPEN) {
11770+ err = -EBADFD;
11771+ goto done;
11772+ }
11773+
11774+ if (most_sk(sk)->mdev) {
11775+ err = -EALREADY;
11776+ goto done;
11777+ }
11778+
11779+ if (channel_in_use(dev_id, rx_chan) ||
11780+ channel_in_use(dev_id, tx_chan)) {
11781+ err = -EADDRINUSE;
11782+ goto done;
11783+ } else {
11784+ most_sk(sk)->rx_channel = rx_chan;
11785+ most_sk(sk)->tx_channel = tx_chan;
11786+ }
11787+
11788+ mdev = most_dev_get(dev_id);
11789+ if (!mdev) {
11790+ err = -ENODEV;
11791+ goto done;
11792+ }
11793+
11794+ err = most_configure_channels(mdev, most_sk(sk), 1);
11795+ if (err) {
11796+ most_dev_put(mdev);
11797+ goto done;
11798+ }
11799+
11800+ most_sk(sk)->mdev = mdev;
11801+ most_sk(sk)->dev_id = mdev->id;
11802+
11803+ sk->sk_state = MOST_BOUND;
11804+
11805+done:
11806+ release_sock(sk);
11807+ return err;
11808+}
11809+EXPORT_SYMBOL(most_sock_bind);
11810+
11811+
11812+int most_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
11813+{
11814+ most_dbg("%s\n", __func__);
11815+ return -EINVAL;
11816+}
11817+EXPORT_SYMBOL(most_sock_ioctl);
11818+
11819+int most_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
11820+ struct msghdr *msg, size_t len, int flags)
11821+{
11822+ int noblock = flags & MSG_DONTWAIT;
11823+ struct sock *sk = sock->sk;
11824+ struct sk_buff *skb;
11825+ int copied, err;
11826+
11827+ most_dbg("%s\n", __func__);
11828+
11829+ if (most_sk(sk)->rx_channel == MOST_NO_CHANNEL)
11830+ return -EOPNOTSUPP;
11831+
11832+ if (flags & (MSG_OOB))
11833+ return -EOPNOTSUPP;
11834+
11835+ if (sk->sk_state != MOST_BOUND)
11836+ return 0;
11837+
11838+ skb = skb_recv_datagram(sk, flags, noblock, &err);
11839+ if (!skb)
11840+ return err;
11841+
11842+ msg->msg_namelen = 0;
11843+
11844+ copied = skb->len;
11845+ if (len < copied) {
11846+ msg->msg_flags |= MSG_TRUNC;
11847+ copied = len;
11848+ }
11849+
11850+ skb_reset_transport_header(skb);
11851+ err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
11852+
11853+ skb_free_datagram(sk, skb);
11854+
11855+ return err ? : copied;
11856+}
11857+EXPORT_SYMBOL(most_sock_recvmsg);
11858+
11859+int most_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
11860+ struct msghdr *msg, size_t len)
11861+{
11862+ struct sock *sk = sock->sk;
11863+ struct most_dev *mdev;
11864+ struct sk_buff *skb;
11865+ int err;
11866+
11867+ most_dbg("%s: sock %p sk %p, channeltype: %d\n",
11868+ __func__, sock, sk, most_sk(sk)->channel_type);
11869+
11870+ if (most_sk(sk)->tx_channel == MOST_NO_CHANNEL)
11871+ return -EOPNOTSUPP;
11872+
11873+ if (msg->msg_flags & MSG_OOB)
11874+ return -EOPNOTSUPP;
11875+
11876+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
11877+ return -EINVAL;
11878+
11879+ lock_sock(sk);
11880+
11881+ mdev = most_sk(sk)->mdev;
11882+ if (!mdev) {
11883+ err = -EBADFD;
11884+ goto done;
11885+ }
11886+
11887+ skb = sock_alloc_send_skb(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
11888+ if (!skb)
11889+ goto done;
11890+
11891+ most_cb(skb)->channel = most_sk(sk)->tx_channel;
11892+ most_cb(skb)->channel_type = most_sk(sk)->channel_type;
11893+
11894+ if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
11895+ err = -EFAULT;
11896+ goto drop;
11897+ }
11898+
11899+ skb->dev = (void *) mdev;
11900+
11901+ skb_queue_tail(&mdev->ctl_q, skb);
11902+ most_sched_tx(mdev);
11903+
11904+ err = len;
11905+
11906+done:
11907+ release_sock(sk);
11908+ return err;
11909+
11910+drop:
11911+ kfree_skb(skb);
11912+ goto done;
11913+}
11914+EXPORT_SYMBOL(most_sock_sendmsg);
11915+
11916+int most_sock_setsockopt(struct socket *sock, int level, int optname,
11917+ char __user *optval, int len)
11918+{
11919+ struct sock *sk = sock->sk;
11920+ int err = 0;
11921+
11922+ most_dbg("%s: sk %p", __func__, sk);
11923+
11924+ lock_sock(sk);
11925+
11926+ switch (optname) {
11927+ default:
11928+ err = -ENOPROTOOPT;
11929+ break;
11930+ }
11931+
11932+ release_sock(sk);
11933+ return err;
11934+}
11935+EXPORT_SYMBOL(most_sock_setsockopt);
11936+
11937+
11938+int most_sock_getsockopt(struct socket *sock, int level, int optname,
11939+ char __user *optval, int __user *optlen)
11940+{
11941+ struct sock *sk = sock->sk;
11942+ int err = 0;
11943+
11944+ most_dbg("%s: sk %p", __func__, sk);
11945+
11946+ lock_sock(sk);
11947+
11948+ switch (optname) {
11949+ default:
11950+ err = -ENOPROTOOPT;
11951+ break;
11952+ }
11953+
11954+ release_sock(sk);
11955+ return err;
11956+}
11957+EXPORT_SYMBOL(most_sock_getsockopt);
11958+
11959diff -uNr linux-2.6.31/net/most/sync_sock.c linux-2.6.31.new/net/most/sync_sock.c
11960--- linux-2.6.31/net/most/sync_sock.c 1969-12-31 16:00:00.000000000 -0800
11961+++ linux-2.6.31.new/net/most/sync_sock.c 2009-10-23 11:17:37.000000000 -0700
11962@@ -0,0 +1,150 @@
11963+/*
11964+ * sync_sock.c Support for MOST synchronous sockets
11965+ * Copyright (c) 2009 Intel Corporation
11966+ *
11967+ * This program is free software; you can redistribute it and/or modify
11968+ * it under the terms of the GNU General Public License version 2 as
11969+ * published by the Free Software Foundation.
11970+ *
11971+ * This program is distributed in the hope that it will be useful,
11972+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11973+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11974+ * GNU General Public License for more details.
11975+ *
11976+ * You should have received a copy of the GNU General Public License
11977+ * along with this program; if not, write to the Free Software
11978+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
11979+ */
11980+
11981+#include <linux/module.h>
11982+#include <net/most/most.h>
11983+#include <net/most/most_core.h>
11984+#include <net/most/sync.h>
11985+
11986+static int sync_sock_bind(struct socket *sock, struct sockaddr *addr,
11987+ int addr_len)
11988+{
11989+ struct sockaddr_mostsync *saddr = (struct sockaddr_mostsync *)addr;
11990+
11991+ if (!saddr || saddr->most_family != AF_MOST)
11992+ return -EINVAL;
11993+
11994+ return most_sock_bind(sock, saddr->most_dev, saddr->rx_channel,
11995+ saddr->tx_channel);
11996+}
11997+
11998+static int sync_sock_getname(struct socket *sock, struct sockaddr *addr,
11999+ int *addr_len, int peer)
12000+{
12001+ struct sockaddr_mostsync *saddr = (struct sockaddr_mostsync *)addr;
12002+ struct sock *sk = sock->sk;
12003+ struct most_dev *mdev = most_sk(sk)->mdev;
12004+
12005+ if (!mdev)
12006+ return -EBADFD;
12007+
12008+ lock_sock(sk);
12009+
12010+ *addr_len = sizeof(*saddr);
12011+ saddr->most_family = AF_MOST;
12012+ saddr->most_dev = mdev->id;
12013+ saddr->rx_channel = most_sk(sk)->rx_channel;
12014+ saddr->tx_channel = most_sk(sk)->tx_channel;
12015+
12016+ release_sock(sk);
12017+ return 0;
12018+}
12019+
12020+
12021+static const struct proto_ops sync_sock_ops = {
12022+ .family = PF_MOST,
12023+ .owner = THIS_MODULE,
12024+ .release = most_sock_release,
12025+ .bind = sync_sock_bind,
12026+ .getname = sync_sock_getname,
12027+ .sendmsg = most_sock_sendmsg,
12028+ .recvmsg = most_sock_recvmsg,
12029+ .ioctl = most_sock_ioctl,
12030+ .poll = datagram_poll,
12031+ .listen = sock_no_listen,
12032+ .shutdown = sock_no_shutdown,
12033+ .setsockopt = most_sock_setsockopt,
12034+ .getsockopt = most_sock_getsockopt,
12035+ .connect = sock_no_connect,
12036+ .socketpair = sock_no_socketpair,
12037+ .accept = sock_no_accept,
12038+ .mmap = sock_no_mmap
12039+};
12040+static struct proto sync_sk_proto = {
12041+ .name = "SYNC",
12042+ .owner = THIS_MODULE,
12043+ .obj_size = sizeof(struct most_sock)
12044+};
12045+
12046+static int sync_sock_create(struct net *net, struct socket *sock, int protocol)
12047+{
12048+ struct sock *sk;
12049+
12050+ if (sock->type != SOCK_STREAM)
12051+ return -ESOCKTNOSUPPORT;
12052+
12053+ sock->ops = &sync_sock_ops;
12054+
12055+ sk = most_sk_alloc(net, &sync_sk_proto, CHAN_SYNC);
12056+ if (!sk)
12057+ return -ENOMEM;
12058+
12059+ sock_init_data(sock, sk);
12060+
12061+ sock_reset_flag(sk, SOCK_ZAPPED);
12062+
12063+ sk->sk_protocol = protocol;
12064+
12065+ sock->state = SS_UNCONNECTED;
12066+ sk->sk_state = MOST_OPEN;
12067+
12068+ most_sock_link(sk);
12069+ return 0;
12070+}
12071+
12072+static struct net_proto_family sync_sock_family_ops = {
12073+ .family = PF_MOST,
12074+ .owner = THIS_MODULE,
12075+ .create = sync_sock_create,
12076+};
12077+
12078+
12079+static int __init sync_init(void)
12080+{
12081+ int err;
12082+
12083+ err = proto_register(&sync_sk_proto, 0);
12084+ if (err < 0)
12085+ return err;
12086+
12087+ err = most_sock_register(MOSTPROTO_SYNC, &sync_sock_family_ops);
12088+ if (err < 0) {
12089+ printk(KERN_ERR "MOST socket registration failed\n");
12090+ return err;
12091+ }
12092+
12093+ printk(KERN_INFO "MOST synchronous socket layer initialized\n");
12094+
12095+ return 0;
12096+}
12097+
12098+static void __exit sync_exit(void)
12099+{
12100+ if (most_sock_unregister(MOSTPROTO_SYNC) < 0)
12101+ printk(KERN_ERR "SYNC socket unregistration failed\n");
12102+
12103+ proto_unregister(&sync_sk_proto);
12104+}
12105+
12106+module_init(sync_init);
12107+module_exit(sync_exit);
12108+
12109+MODULE_DESCRIPTION("Most Syncronous");
12110+MODULE_LICENSE("GPL v2");
12111+MODULE_ALIAS("most-proto-2");
12112+
12113diff -uNr linux-2.6.31/sound/drivers/Kconfig linux-2.6.31.new/sound/drivers/Kconfig
12114--- linux-2.6.31/sound/drivers/Kconfig 2009-10-23 11:18:30.000000000 -0700
12115+++ linux-2.6.31.new/sound/drivers/Kconfig 2009-10-23 11:16:57.000000000 -0700
12116@@ -182,4 +182,17 @@
12117 The default time-out value in seconds for AC97 automatic
12118 power-save mode. 0 means to disable the power-save mode.
12119
12120+config SND_TIMBERDALE_I2S
12121+ tristate "The timberdale FPGA I2S driver"
12122+ depends on MFD_TIMBERDALE && HAS_IOMEM
12123+ default y
12124+ help
12125+ Say Y here to enable driver for the I2S block found within the
12126+ Timberdale FPGA.
12127+ There is support for up to 8 I2S channels, in either transmitter
12128+ or receiver mode.
12129+
12130+ To compile this driver as a module, choose M here: the module
12131+ will be called snd-timbi2s.
12132+
12133 endif # SND_DRIVERS
12134diff -uNr linux-2.6.31/sound/drivers/Makefile linux-2.6.31.new/sound/drivers/Makefile
12135--- linux-2.6.31/sound/drivers/Makefile 2009-10-23 11:18:30.000000000 -0700
12136+++ linux-2.6.31.new/sound/drivers/Makefile 2009-10-23 11:16:57.000000000 -0700
12137@@ -10,6 +10,7 @@
12138 snd-serial-u16550-objs := serial-u16550.o
12139 snd-virmidi-objs := virmidi.o
12140 snd-ml403-ac97cr-objs := ml403-ac97cr.o pcm-indirect2.o
12141+snd-timbi2s-objs := timbi2s.o
12142
12143 # Toplevel Module Dependency
12144 obj-$(CONFIG_SND_DUMMY) += snd-dummy.o
12145@@ -19,5 +20,6 @@
12146 obj-$(CONFIG_SND_MTS64) += snd-mts64.o
12147 obj-$(CONFIG_SND_PORTMAN2X4) += snd-portman2x4.o
12148 obj-$(CONFIG_SND_ML403_AC97CR) += snd-ml403-ac97cr.o
12149+obj-$(CONFIG_SND_TIMBERDALE_I2S) += snd-timbi2s.o
12150
12151 obj-$(CONFIG_SND) += opl3/ opl4/ mpu401/ vx/ pcsp/
12152diff -uNr linux-2.6.31/sound/drivers/timbi2s.c linux-2.6.31.new/sound/drivers/timbi2s.c
12153--- linux-2.6.31/sound/drivers/timbi2s.c 1969-12-31 16:00:00.000000000 -0800
12154+++ linux-2.6.31.new/sound/drivers/timbi2s.c 2009-10-23 11:16:57.000000000 -0700
12155@@ -0,0 +1,755 @@
12156+/*
12157+ * timbi2s.c timberdale FPGA I2S driver
12158+ * Copyright (c) 2009 Intel Corporation
12159+ *
12160+ * This program is free software; you can redistribute it and/or modify
12161+ * it under the terms of the GNU General Public License version 2 as
12162+ * published by the Free Software Foundation.
12163+ *
12164+ * This program is distributed in the hope that it will be useful,
12165+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12166+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12167+ * GNU General Public License for more details.
12168+ *
12169+ * You should have received a copy of the GNU General Public License
12170+ * along with this program; if not, write to the Free Software
12171+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
12172+ */
12173+
12174+/* Supports:
12175+ * Timberdale FPGA I2S
12176+ *
12177+ */
12178+
12179+#include <linux/io.h>
12180+#include <linux/interrupt.h>
12181+#include <linux/platform_device.h>
12182+#include <sound/core.h>
12183+#include <sound/pcm.h>
12184+#include <sound/pcm_params.h>
12185+#include <sound/initval.h>
12186+#include <sound/timbi2s.h>
12187+
12188+#define DRIVER_NAME "timb-i2s"
12189+
12190+#define MAX_BUSSES 8
12191+
12192+#define TIMBI2S_REG_VER 0x00
12193+#define TIMBI2S_REG_UIR 0x04
12194+
12195+#define TIMBI2S_BUS_PRESCALE 0x00
12196+#define TIMBI2S_BUS_ICLR 0x04
12197+#define TIMBI2S_BUS_IPR 0x08
12198+#define TIMBI2S_BUS_ISR 0x0c
12199+#define TIMBI2S_BUS_IER 0x10
12200+
12201+
12202+#define TIMBI2S_IRQ_TX_FULL 0x01
12203+#define TIMBI2S_IRQ_TX_ALMOST_FULL 0x02
12204+#define TIMBI2S_IRQ_TX_ALMOST_EMPTY 0x04
12205+#define TIMBI2S_IRQ_TX_EMPTY 0x08
12206+
12207+#define TIMBI2S_IRQ_RX_FULL 0x10
12208+#define TIMBI2S_IRQ_RX_ALMOST_FULL 0x20
12209+#define TIMBI2S_IRQ_RX_ALMOST_EMPTY 0x40
12210+#define TIMBI2S_IRQ_RX_NOT_EMPTY 0x80
12211+
12212+#define TIMBI2S_BUS_ICOR 0x14
12213+#define TIMBI2S_ICOR_TX_ENABLE 0x00000001
12214+#define TIMBI2S_ICOR_RX_ENABLE 0x00000002
12215+#define TIMBI2S_ICOR_LFIFO_RST 0x00000004
12216+#define TIMBI2S_ICOR_RFIFO_RST 0x00000008
12217+#define TIMBI2S_ICOR_FIFO_RST (TIMBI2S_ICOR_LFIFO_RST | TIMBI2S_ICOR_RFIFO_RST)
12218+#define TIMBI2S_ICOR_SOFT_RST 0x00000010
12219+#define TIMBI2S_ICOR_WORD_SEL_LEFT_SHIFT 8
12220+#define TIMBI2S_ICOR_WORD_SEL_LEFT_MASK (0xff << 8)
12221+#define TIMBI2S_ICOR_WORD_SEL_RIGHT_SHIFT 16
12222+#define TIMBI2S_ICOR_WORD_SEL_RIGHT_MASK (0xff << 16)
12223+#define TIMBI2S_ICOR_CLK_MASTER 0x10000000
12224+#define TIMBI2S_ICOR_RX_ID 0x20000000
12225+#define TIMBI2S_ICOR_TX_ID 0x40000000
12226+#define TIMBI2S_ICOR_WORD_SEL 0x80000000
12227+#define TIMBI2S_BUS_FIFO 0x18
12228+
12229+#define TIMBI2S_BUS_REG_AREA_SIZE (TIMBI2S_BUS_FIFO - \
12230+ TIMBI2S_BUS_PRESCALE + 4)
12231+#define TIMBI2S_FIRST_BUS_AREA_OFS 0x08
12232+
12233+struct timbi2s_bus {
12234+ u32 flags;
12235+ u32 prescale;
12236+ struct snd_pcm *pcm;
12237+ struct snd_card *card;
12238+ struct snd_pcm_substream *substream;
12239+ unsigned buf_pos;
12240+ spinlock_t lock; /* mutual exclusion */
12241+ u16 sample_rate;
12242+};
12243+
12244+#define BUS_RX 0x200
12245+#define BUS_MASTER 0x100
12246+#define BUS_INDEX_MASK 0xff
12247+#define BUS_INDEX(b) ((b)->flags & BUS_INDEX_MASK)
12248+#define BUS_IS_MASTER(b) ((b)->flags & BUS_MASTER)
12249+#define BUS_IS_RX(b) ((b)->flags & BUS_RX)
12250+
12251+#define SET_BUS_INDEX(b, id) ((b)->flags = ((b)->flags & ~BUS_INDEX_MASK) | id)
12252+#define SET_BUS_MASTER(b) ((b)->flags |= BUS_MASTER)
12253+#define SET_BUS_RX(b) ((b)->flags |= BUS_RX)
12254+
12255+#define TIMBI2S_BUS_OFFSET(bus) (TIMBI2S_FIRST_BUS_AREA_OFS + \
12256+ TIMBI2S_BUS_REG_AREA_SIZE * BUS_INDEX(bus))
12257+
12258+struct timbi2s {
12259+ void __iomem *membase;
12260+ int irq;
12261+ struct tasklet_struct tasklet;
12262+ u32 main_clk;
12263+ unsigned num_busses;
12264+ struct timbi2s_bus busses[0];
12265+};
12266+
12267+#define BITS_PER_CHANNEL 16
12268+#define NUM_CHANNELS 2
12269+
12270+#define SAMPLE_SIZE ((NUM_CHANNELS * BITS_PER_CHANNEL) / 8)
12271+#define NUM_PERIODS 32
12272+#define NUM_SAMPLES 256
12273+
12274+static struct snd_pcm_hardware timbi2s_rx_hw = {
12275+ .info = (SNDRV_PCM_INFO_MMAP
12276+ | SNDRV_PCM_INFO_MMAP_VALID
12277+ | SNDRV_PCM_INFO_INTERLEAVED),
12278+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
12279+ .rates = SNDRV_PCM_RATE_44100,
12280+ .rate_min = 44100,
12281+ .rate_max = 44100,
12282+ .channels_min = 2, /* only stereo */
12283+ .channels_max = 2,
12284+ .buffer_bytes_max = NUM_PERIODS * SAMPLE_SIZE * NUM_SAMPLES,
12285+ .period_bytes_min = SAMPLE_SIZE * NUM_SAMPLES,
12286+ .period_bytes_max = SAMPLE_SIZE * NUM_SAMPLES,
12287+ .periods_min = NUM_PERIODS,
12288+ .periods_max = NUM_PERIODS,
12289+};
12290+
12291+static struct snd_pcm_hardware timbi2s_tx_hw = {
12292+ .info = (SNDRV_PCM_INFO_MMAP
12293+ | SNDRV_PCM_INFO_MMAP_VALID
12294+ | SNDRV_PCM_INFO_INTERLEAVED),
12295+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
12296+ .rates = SNDRV_PCM_RATE_8000,
12297+ .rate_min = 8000,
12298+ .rate_max = 8000,
12299+ .channels_min = 2, /* only stereo */
12300+ .channels_max = 2,
12301+ .buffer_bytes_max = NUM_PERIODS * SAMPLE_SIZE * NUM_SAMPLES,
12302+ .period_bytes_min = SAMPLE_SIZE * NUM_SAMPLES,
12303+ .period_bytes_max = SAMPLE_SIZE * NUM_SAMPLES,
12304+ .periods_min = NUM_PERIODS,
12305+ .periods_max = NUM_PERIODS,
12306+};
12307+
12308+static inline void timbi2s_bus_write(struct timbi2s_bus *bus, u32 val, u32 reg)
12309+{
12310+ struct timbi2s *i2s = snd_pcm_chip(bus->card);
12311+
12312+ iowrite32(val, i2s->membase + TIMBI2S_BUS_OFFSET(bus) + reg);
12313+}
12314+
12315+static inline u32 timbi2s_bus_read(struct timbi2s_bus *bus, u32 reg)
12316+{
12317+ struct timbi2s *i2s = snd_pcm_chip(bus->card);
12318+
12319+ return ioread32(i2s->membase + TIMBI2S_BUS_OFFSET(bus) + reg);
12320+}
12321+
12322+static u32 timbi2s_calc_prescale(u32 main_clk, u32 sample_rate)
12323+{
12324+ u32 halfbit_rate = sample_rate * BITS_PER_CHANNEL * NUM_CHANNELS * 2;
12325+ return main_clk / halfbit_rate;
12326+}
12327+
12328+static int timbi2s_open(struct snd_pcm_substream *substream)
12329+{
12330+ struct timbi2s_bus *bus = snd_pcm_substream_chip(substream);
12331+ struct snd_card *card = bus->card;
12332+ struct snd_pcm_runtime *runtime = substream->runtime;
12333+ dev_dbg(snd_card_get_device_link(card),
12334+ "%s: Entry, substream: %p, bus: %d\n", __func__, substream,
12335+ BUS_INDEX(bus));
12336+
12337+ if (BUS_IS_RX(bus)) {
12338+ runtime->hw = timbi2s_rx_hw;
12339+ if (bus->sample_rate == 8000) {
12340+ runtime->hw.rates = SNDRV_PCM_RATE_8000;
12341+ runtime->hw.rate_min = 8000;
12342+ runtime->hw.rate_max = 8000;
12343+ }
12344+ } else
12345+ runtime->hw = timbi2s_tx_hw;
12346+
12347+ bus->substream = substream;
12348+
12349+ return 0;
12350+}
12351+
12352+static int timbi2s_close(struct snd_pcm_substream *substream)
12353+{
12354+ struct timbi2s_bus *bus = snd_pcm_substream_chip(substream);
12355+ struct snd_card *card = bus->card;
12356+ dev_dbg(snd_card_get_device_link(card),
12357+ "%s: Entry, substream: %p, bus: %d\n", __func__, substream,
12358+ BUS_INDEX(bus));
12359+
12360+ bus->substream = NULL;
12361+
12362+ return 0;
12363+}
12364+
12365+static int timbi2s_hw_params(struct snd_pcm_substream *substream,
12366+ struct snd_pcm_hw_params *hw_params)
12367+{
12368+ struct timbi2s_bus *bus = snd_pcm_substream_chip(substream);
12369+ struct snd_card *card = bus->card;
12370+ struct timbi2s *i2s = snd_pcm_chip(card);
12371+ int err;
12372+
12373+ dev_dbg(snd_card_get_device_link(card),
12374+ "%s: Entry, substream: %p, bus: %d\n", __func__,
12375+ substream, BUS_INDEX(bus));
12376+
12377+ bus->prescale = timbi2s_calc_prescale(i2s->main_clk,
12378+ params_rate(hw_params));
12379+
12380+ err = snd_pcm_lib_malloc_pages(substream,
12381+ params_buffer_bytes(hw_params));
12382+ if (err < 0)
12383+ return err;
12384+
12385+ dev_dbg(snd_card_get_device_link(card),
12386+ "%s: Rate: %d, format: %d\n", __func__, params_rate(hw_params),
12387+ params_format(hw_params));
12388+
12389+ return 0;
12390+}
12391+
12392+static int timbi2s_hw_free(struct snd_pcm_substream *substream)
12393+{
12394+ struct timbi2s_bus *bus = snd_pcm_substream_chip(substream);
12395+ struct snd_card *card = bus->card;
12396+ unsigned long flags;
12397+
12398+ dev_dbg(snd_card_get_device_link(card),
12399+ "%s: Entry, substream: %p\n", __func__, substream);
12400+
12401+ spin_lock_irqsave(&bus->lock, flags);
12402+ /* disable interrupts */
12403+ timbi2s_bus_write(bus, 0, TIMBI2S_BUS_IER);
12404+ spin_unlock_irqrestore(&bus->lock, flags);
12405+
12406+ /* disable TX and RX */
12407+ timbi2s_bus_write(bus, TIMBI2S_ICOR_FIFO_RST | TIMBI2S_ICOR_SOFT_RST,
12408+ TIMBI2S_BUS_ICOR);
12409+
12410+ return snd_pcm_lib_free_pages(substream);
12411+}
12412+
12413+static int timbi2s_prepare(struct snd_pcm_substream *substream)
12414+{
12415+ struct timbi2s_bus *bus = snd_pcm_substream_chip(substream);
12416+ struct snd_card *card = bus->card;
12417+ struct snd_pcm_runtime *runtime = substream->runtime;
12418+ u32 data;
12419+
12420+ dev_dbg(snd_card_get_device_link(card),
12421+ "%s: Entry, substream: %p, bus: %d, buffer: %d, period: %d\n",
12422+ __func__, substream,
12423+ BUS_INDEX(bus), (int)snd_pcm_lib_buffer_bytes(substream),
12424+ (int)snd_pcm_lib_period_bytes(substream));
12425+
12426+ if (runtime->dma_addr & 3 || runtime->buffer_size & 3) {
12427+ dev_err(snd_card_get_device_link(card),
12428+ "%s: Only word aligned data allowed\n", __func__);
12429+ return -EINVAL;
12430+ }
12431+
12432+ if (runtime->channels != NUM_CHANNELS) {
12433+ dev_err(snd_card_get_device_link(card),
12434+ "%s: Number of channels unsupported %d\n", __func__,
12435+ runtime->channels);
12436+ return -EINVAL;
12437+ }
12438+
12439+ /* reset */
12440+ timbi2s_bus_write(bus, TIMBI2S_ICOR_FIFO_RST | TIMBI2S_ICOR_SOFT_RST,
12441+ TIMBI2S_BUS_ICOR);
12442+
12443+ /* only masters have prescaling, don't write if not needed */
12444+ if (BUS_IS_MASTER(bus))
12445+ timbi2s_bus_write(bus, bus->prescale, TIMBI2S_BUS_PRESCALE);
12446+
12447+ /* write word select */
12448+ data = ((BITS_PER_CHANNEL << TIMBI2S_ICOR_WORD_SEL_LEFT_SHIFT) &
12449+ TIMBI2S_ICOR_WORD_SEL_LEFT_MASK) |
12450+ ((BITS_PER_CHANNEL << TIMBI2S_ICOR_WORD_SEL_RIGHT_SHIFT) &
12451+ TIMBI2S_ICOR_WORD_SEL_RIGHT_MASK);
12452+ timbi2s_bus_write(bus, data, TIMBI2S_BUS_ICOR);
12453+
12454+ bus->buf_pos = 0;
12455+
12456+ return 0;
12457+}
12458+
12459+static int
12460+timbi2s_playback_trigger(struct snd_pcm_substream *substream, int cmd)
12461+{
12462+ struct timbi2s_bus *bus = snd_pcm_substream_chip(substream);
12463+ struct snd_card *card = bus->card;
12464+ unsigned long flags;
12465+ u32 data;
12466+
12467+ dev_dbg(snd_card_get_device_link(card),
12468+ "%s: Entry, substream: %p, bus: %d, cmd: %d\n", __func__,
12469+ substream, BUS_INDEX(bus), cmd);
12470+
12471+ switch (cmd) {
12472+ case SNDRV_PCM_TRIGGER_START:
12473+ dev_dbg(snd_card_get_device_link(card),
12474+ "%s: Got TRIGGER_START command\n", __func__);
12475+
12476+ /* start */
12477+ data = timbi2s_bus_read(bus, TIMBI2S_BUS_ICOR);
12478+ data |= TIMBI2S_ICOR_TX_ENABLE;
12479+ timbi2s_bus_write(bus, data, TIMBI2S_BUS_ICOR);
12480+
12481+ /* enable interrupts */
12482+ timbi2s_bus_write(bus, TIMBI2S_IRQ_TX_ALMOST_EMPTY,
12483+ TIMBI2S_BUS_IER);
12484+ dev_dbg(snd_card_get_device_link(card),
12485+ "%s: ISR: %x, ICOR: %x\n", __func__,
12486+ timbi2s_bus_read(bus, TIMBI2S_BUS_ISR),
12487+ timbi2s_bus_read(bus, TIMBI2S_BUS_ICOR));
12488+ break;
12489+ case SNDRV_PCM_TRIGGER_STOP:
12490+ dev_dbg(snd_card_get_device_link(card),
12491+ "%s: Got TRIGGER_STOP command\n", __func__);
12492+
12493+ spin_lock_irqsave(&bus->lock, flags);
12494+ /* disable interrupts */
12495+ timbi2s_bus_write(bus, 0, TIMBI2S_BUS_IER);
12496+ spin_unlock_irqrestore(&bus->lock, flags);
12497+
12498+ /* reset */
12499+ data = timbi2s_bus_read(bus, TIMBI2S_BUS_ICOR);
12500+ data &= ~TIMBI2S_ICOR_TX_ENABLE;
12501+
12502+ timbi2s_bus_write(bus, data, TIMBI2S_BUS_ICOR);
12503+ break;
12504+ default:
12505+ dev_dbg(snd_card_get_device_link(card),
12506+ "%s: Got unsupported command\n", __func__);
12507+
12508+ return -EINVAL;
12509+ }
12510+
12511+ return 0;
12512+}
12513+
12514+static int
12515+timbi2s_capture_trigger(struct snd_pcm_substream *substream, int cmd)
12516+{
12517+ struct timbi2s_bus *bus = snd_pcm_substream_chip(substream);
12518+ struct snd_card *card = bus->card;
12519+ unsigned long flags;
12520+
12521+ dev_dbg(snd_card_get_device_link(card),
12522+ "%s: Entry, substream: %p, bus: %d, cmd: %d\n", __func__,
12523+ substream, BUS_INDEX(bus), cmd);
12524+
12525+ switch (cmd) {
12526+ case SNDRV_PCM_TRIGGER_START:
12527+ dev_dbg(snd_card_get_device_link(card),
12528+ "%s: Got TRIGGER_START command\n", __func__);
12529+
12530+ timbi2s_bus_write(bus, TIMBI2S_ICOR_RX_ENABLE |
12531+ TIMBI2S_ICOR_FIFO_RST, TIMBI2S_BUS_ICOR);
12532+
12533+ timbi2s_bus_write(bus, TIMBI2S_IRQ_RX_ALMOST_FULL,
12534+ TIMBI2S_BUS_IER);
12535+ break;
12536+ case SNDRV_PCM_TRIGGER_STOP:
12537+ dev_dbg(snd_card_get_device_link(card),
12538+ "%s: Got TRIGGER_STOP command\n", __func__);
12539+ /* disable interrupts */
12540+ spin_lock_irqsave(&bus->lock, flags);
12541+ timbi2s_bus_write(bus, 0, TIMBI2S_BUS_IER);
12542+ spin_unlock_irqrestore(&bus->lock, flags);
12543+ /* Stop RX */
12544+ timbi2s_bus_write(bus, 0, TIMBI2S_BUS_ICOR);
12545+ break;
12546+ default:
12547+ dev_dbg(snd_card_get_device_link(card),
12548+ "%s: Got unsupported command\n", __func__);
12549+
12550+ return -EINVAL;
12551+ }
12552+
12553+ return 0;
12554+}
12555+
12556+static snd_pcm_uframes_t
12557+timbi2s_pointer(struct snd_pcm_substream *substream)
12558+{
12559+ struct timbi2s_bus *bus = snd_pcm_substream_chip(substream);
12560+ struct snd_card *card = bus->card;
12561+ snd_pcm_uframes_t ret;
12562+
12563+ dev_dbg(snd_card_get_device_link(card),
12564+ "%s: Entry, substream: %p\n", __func__, substream);
12565+
12566+ ret = bytes_to_frames(substream->runtime, bus->buf_pos);
12567+ if (ret >= substream->runtime->buffer_size)
12568+ ret -= substream->runtime->buffer_size;
12569+
12570+ return ret;
12571+}
12572+
12573+static struct snd_pcm_ops timbi2s_playback_ops = {
12574+ .open = timbi2s_open,
12575+ .close = timbi2s_close,
12576+ .ioctl = snd_pcm_lib_ioctl,
12577+ .hw_params = timbi2s_hw_params,
12578+ .hw_free = timbi2s_hw_free,
12579+ .prepare = timbi2s_prepare,
12580+ .trigger = timbi2s_playback_trigger,
12581+ .pointer = timbi2s_pointer,
12582+};
12583+
12584+static struct snd_pcm_ops timbi2s_capture_ops = {
12585+ .open = timbi2s_open,
12586+ .close = timbi2s_close,
12587+ .ioctl = snd_pcm_lib_ioctl,
12588+ .hw_params = timbi2s_hw_params,
12589+ .hw_free = timbi2s_hw_free,
12590+ .prepare = timbi2s_prepare,
12591+ .trigger = timbi2s_capture_trigger,
12592+ .pointer = timbi2s_pointer,
12593+};
12594+
12595+static void timbi2s_irq_process_rx(struct timbi2s_bus *bus)
12596+{
12597+ struct snd_pcm_runtime *runtime = bus->substream->runtime;
12598+ u32 buffer_size = snd_pcm_lib_buffer_bytes(bus->substream);
12599+ u32 ipr = timbi2s_bus_read(bus, TIMBI2S_BUS_IPR);
12600+ int i;
12601+
12602+ dev_dbg(snd_card_get_device_link(bus->card),
12603+ "%s: Entry, bus: %d, IPR %x\n", __func__, BUS_INDEX(bus), ipr);
12604+
12605+ for (i = 0; i < NUM_SAMPLES; i++) {
12606+ *(u32 *)(runtime->dma_area + bus->buf_pos) =
12607+ timbi2s_bus_read(bus, TIMBI2S_BUS_FIFO);
12608+ bus->buf_pos += SAMPLE_SIZE;
12609+ bus->buf_pos %= buffer_size;
12610+ }
12611+
12612+ timbi2s_bus_write(bus, ipr, TIMBI2S_BUS_ICLR);
12613+
12614+ /* inform ALSA that a period was received */
12615+ snd_pcm_period_elapsed(bus->substream);
12616+}
12617+
12618+static void timbi2s_irq_process_tx(struct timbi2s_bus *bus)
12619+{
12620+ struct snd_pcm_runtime *runtime = bus->substream->runtime;
12621+ u32 buffer_size = snd_pcm_lib_buffer_bytes(bus->substream);
12622+ u32 ipr = timbi2s_bus_read(bus, TIMBI2S_BUS_IPR);
12623+ int i;
12624+
12625+ dev_dbg(snd_card_get_device_link(bus->card),
12626+ "%s: Entry, bus: %d, IPR %x\n", __func__, BUS_INDEX(bus), ipr);
12627+
12628+ for (i = 0; i < NUM_SAMPLES; i++) {
12629+ timbi2s_bus_write(bus,
12630+ *(u32 *)(runtime->dma_area + bus->buf_pos),
12631+ TIMBI2S_BUS_FIFO);
12632+ bus->buf_pos += SAMPLE_SIZE;
12633+ bus->buf_pos %= buffer_size;
12634+ }
12635+
12636+ dev_dbg(snd_card_get_device_link(bus->card), "%s: ISR: %x, ICOR: %x\n",
12637+ __func__, timbi2s_bus_read(bus, TIMBI2S_BUS_ISR),
12638+ timbi2s_bus_read(bus, TIMBI2S_BUS_ICOR));
12639+
12640+ timbi2s_bus_write(bus, ipr, TIMBI2S_BUS_ICLR);
12641+
12642+ /* inform ALSA that a period was received */
12643+ snd_pcm_period_elapsed(bus->substream);
12644+}
12645+
12646+static void timbi2s_tasklet(unsigned long arg)
12647+{
12648+ struct snd_card *card = (struct snd_card *)arg;
12649+ struct timbi2s *i2s = snd_pcm_chip(card);
12650+ u32 uir = ioread32(i2s->membase + TIMBI2S_REG_UIR);
12651+ unsigned i;
12652+
12653+ dev_dbg(snd_card_get_device_link(card), "%s: Entry, UIR %x\n",
12654+ __func__, uir);
12655+
12656+ for (i = 0; i < i2s->num_busses; i++)
12657+ if (uir & (1 << i)) {
12658+ struct timbi2s_bus *bus = i2s->busses + i;
12659+ if (BUS_IS_RX(bus))
12660+ timbi2s_irq_process_rx(bus);
12661+ else
12662+ timbi2s_irq_process_tx(bus);
12663+ }
12664+
12665+ enable_irq(i2s->irq);
12666+}
12667+
12668+static irqreturn_t timbi2s_irq(int irq, void *devid)
12669+{
12670+ struct timbi2s *i2s = devid;
12671+
12672+ tasklet_schedule(&i2s->tasklet);
12673+ disable_irq_nosync(i2s->irq);
12674+
12675+ return IRQ_HANDLED;
12676+}
12677+
12678+static int timbi2s_setup_busses(struct snd_card *card,
12679+ struct platform_device *pdev)
12680+{
12681+ const struct timbi2s_platform_data *pdata = pdev->dev.platform_data;
12682+ unsigned i;
12683+
12684+ dev_dbg(&pdev->dev, "%s: Entry, no busses: %d, busses: %p\n", __func__,
12685+ pdata->num_busses, pdata->busses);
12686+
12687+ for (i = 0; i < pdata->num_busses; i++) {
12688+ int capture = pdata->busses[i].rx;
12689+ int err;
12690+ u32 ctl;
12691+ struct timbi2s *i2s = snd_pcm_chip(card);
12692+ struct timbi2s_bus *bus = i2s->busses + i;
12693+
12694+ dev_dbg(&pdev->dev, "%s: Setting up bus: %d\n", __func__, i);
12695+
12696+ SET_BUS_INDEX(bus, i);
12697+ bus->sample_rate = pdata->busses[i].sample_rate;
12698+ bus->card = card;
12699+ /* prescaling only applies to master busses, we use the
12700+ * knowledge of that to identify the direction later
12701+ * eg, bus->prescale != 0 -> master bus
12702+ */
12703+ if (capture)
12704+ SET_BUS_RX(bus);
12705+
12706+ spin_lock_init(&bus->lock);
12707+
12708+ if (bus->sample_rate != 44100 && bus->sample_rate != 8000) {
12709+ dev_err(&pdev->dev,
12710+ "Unsupported bitrate: %d\n", bus->sample_rate);
12711+ return -EINVAL;
12712+ }
12713+
12714+ dev_dbg(&pdev->dev, "%s: Will check HW direction on bus: %d\n",
12715+ __func__, BUS_INDEX(bus));
12716+
12717+ /* check that the HW agrees with the direction */
12718+ ctl = timbi2s_bus_read(bus, TIMBI2S_BUS_ICOR);
12719+ if ((capture && !(ctl & TIMBI2S_ICOR_RX_ID)) ||
12720+ (!capture && !(ctl & TIMBI2S_ICOR_TX_ID))) {
12721+ dev_dbg(&pdev->dev,
12722+ "HW and platform data disagree on direction\n");
12723+ return -EINVAL;
12724+ }
12725+
12726+ dev_dbg(&pdev->dev, "%s: Will create PCM channel for bus: %d\n",
12727+ __func__, BUS_INDEX(bus));
12728+ err = snd_pcm_new(card, card->shortname, i, !capture,
12729+ capture, &bus->pcm);
12730+ if (err) {
12731+ dev_dbg(&pdev->dev, "%s, Failed to create pcm: %d\n",
12732+ __func__, err);
12733+ return err;
12734+ }
12735+
12736+ if (capture)
12737+ snd_pcm_set_ops(bus->pcm, SNDRV_PCM_STREAM_CAPTURE,
12738+ &timbi2s_capture_ops);
12739+ if (!capture)
12740+ snd_pcm_set_ops(bus->pcm, SNDRV_PCM_STREAM_PLAYBACK,
12741+ &timbi2s_playback_ops);
12742+
12743+ dev_dbg(&pdev->dev, "%s: Will preallocate buffers to bus: %d\n",
12744+ __func__, BUS_INDEX(bus));
12745+
12746+ err = snd_pcm_lib_preallocate_pages_for_all(bus->pcm,
12747+ SNDRV_DMA_TYPE_CONTINUOUS,
12748+ snd_dma_continuous_data(GFP_KERNEL),
12749+ NUM_SAMPLES * NUM_PERIODS * SAMPLE_SIZE * 2,
12750+ NUM_SAMPLES * NUM_PERIODS * SAMPLE_SIZE * 2);
12751+ if (err) {
12752+ dev_dbg(&pdev->dev, "%s, Failed to create pcm: %d\n",
12753+ __func__, err);
12754+
12755+ return err;
12756+ }
12757+
12758+ bus->pcm->private_data = bus;
12759+ bus->pcm->info_flags = 0;
12760+ strcpy(bus->pcm->name, card->shortname);
12761+ i2s->num_busses++;
12762+ }
12763+
12764+ return 0;
12765+}
12766+
12767+static int __devinit timbi2s_probe(struct platform_device *pdev)
12768+{
12769+ int err;
12770+ int irq;
12771+ struct timbi2s *i2s;
12772+ struct resource *iomem;
12773+ const struct timbi2s_platform_data *pdata = pdev->dev.platform_data;
12774+ struct snd_card *card;
12775+ u32 ver;
12776+
12777+ if (!pdata) {
12778+ err = -ENODEV;
12779+ goto out;
12780+ }
12781+
12782+ if (pdata->num_busses > MAX_BUSSES) {
12783+ err = -EINVAL;
12784+ goto out;
12785+ }
12786+
12787+ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
12788+ if (!iomem) {
12789+ err = -ENODEV;
12790+ goto out;
12791+ }
12792+
12793+ irq = platform_get_irq(pdev, 0);
12794+ if (irq < 0) {
12795+ err = -ENODEV;
12796+ goto out;
12797+ }
12798+
12799+ err = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
12800+ THIS_MODULE, sizeof(struct timbi2s) +
12801+ sizeof(struct timbi2s_bus) * pdata->num_busses, &card);
12802+ if (err)
12803+ goto out;
12804+
12805+ strcpy(card->driver, "Timberdale I2S");
12806+ strcpy(card->shortname, "Timberdale I2S");
12807+ sprintf(card->longname, "Timberdale I2S Driver");
12808+
12809+ snd_card_set_dev(card, &pdev->dev);
12810+
12811+ i2s = snd_pcm_chip(card);
12812+
12813+ if (!request_mem_region(iomem->start, resource_size(iomem),
12814+ DRIVER_NAME)) {
12815+ err = -EBUSY;
12816+ goto err_region;
12817+ }
12818+
12819+ i2s->membase = ioremap(iomem->start, resource_size(iomem));
12820+ if (!i2s->membase) {
12821+ err = -ENOMEM;
12822+ goto err_ioremap;
12823+ }
12824+
12825+ err = timbi2s_setup_busses(card, pdev);
12826+ if (err)
12827+ goto err_setup;
12828+
12829+ tasklet_init(&i2s->tasklet, timbi2s_tasklet, (unsigned long)card);
12830+ i2s->irq = irq;
12831+ i2s->main_clk = pdata->main_clk;
12832+
12833+ err = request_irq(irq, timbi2s_irq, 0, DRIVER_NAME, i2s);
12834+ if (err)
12835+ goto err_request_irq;
12836+
12837+ err = snd_card_register(card);
12838+ if (err)
12839+ goto err_register;
12840+
12841+ platform_set_drvdata(pdev, card);
12842+
12843+ ver = ioread32(i2s->membase + TIMBI2S_REG_VER);
12844+
12845+ printk(KERN_INFO
12846+ "Driver for Timberdale I2S (ver: %d.%d) successfully probed.\n",
12847+ ver >> 16 , ver & 0xffff);
12848+
12849+ return 0;
12850+
12851+err_register:
12852+ free_irq(irq, card);
12853+err_request_irq:
12854+err_setup:
12855+ iounmap(i2s->membase);
12856+err_ioremap:
12857+ release_mem_region(iomem->start, resource_size(iomem));
12858+err_region:
12859+ snd_card_free(card);
12860+out:
12861+ printk(KERN_ERR DRIVER_NAME": Failed to register: %d\n", err);
12862+
12863+ return err;
12864+}
12865+
12866+static int __devexit timbi2s_remove(struct platform_device *pdev)
12867+{
12868+ struct snd_card *card = platform_get_drvdata(pdev);
12869+ struct timbi2s *i2s = snd_pcm_chip(card);
12870+ struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
12871+
12872+ tasklet_kill(&i2s->tasklet);
12873+ free_irq(i2s->irq, i2s);
12874+
12875+ iounmap(i2s->membase);
12876+ release_mem_region(iomem->start, resource_size(iomem));
12877+ snd_card_free(card);
12878+
12879+ platform_set_drvdata(pdev, 0);
12880+ return 0;
12881+}
12882+
12883+static struct platform_driver timbi2s_platform_driver = {
12884+ .driver = {
12885+ .name = DRIVER_NAME,
12886+ .owner = THIS_MODULE,
12887+ },
12888+ .probe = timbi2s_probe,
12889+ .remove = __devexit_p(timbi2s_remove),
12890+};
12891+
12892+/*--------------------------------------------------------------------------*/
12893+
12894+static int __init timbi2s_init(void)
12895+{
12896+ return platform_driver_register(&timbi2s_platform_driver);
12897+}
12898+
12899+static void __exit timbi2s_exit(void)
12900+{
12901+ platform_driver_unregister(&timbi2s_platform_driver);
12902+}
12903+
12904+module_init(timbi2s_init);
12905+module_exit(timbi2s_exit);
12906+
12907+MODULE_ALIAS("platform:"DRIVER_NAME);
12908+MODULE_DESCRIPTION("Timberdale I2S bus driver");
12909+MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
12910+MODULE_LICENSE("GPL v2");