Root/target/linux/lantiq/patches-3.0/0013-MIPS-lantiq-adds-FALC-ON-spi-driver.patch

1From 2bd534c30688bcb3f70f1816fbcff813fc746103 Mon Sep 17 00:00:00 2001
2From: John Crispin <blogic@openwrt.org>
3Date: Sat, 27 Aug 2011 18:12:26 +0200
4Subject: [PATCH 13/24] MIPS: lantiq: adds FALC-ON spi driver
5
6The external bus unit (EBU) found on the FALC-ON SoC has spi emulation that is
7designed for serial flash access.
8
9Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
10Signed-off-by: John Crispin <blogic@openwrt.org>
11---
12 arch/mips/lantiq/falcon/devices.c | 12 +-
13 arch/mips/lantiq/falcon/devices.h | 4 +
14 arch/mips/lantiq/falcon/mach-easy98000.c | 27 ++
15 drivers/spi/Kconfig | 4 +
16 drivers/spi/Makefile | 1 +
17 drivers/spi/spi-falcon.c | 477 ++++++++++++++++++++++++++++++
18 6 files changed, 523 insertions(+), 2 deletions(-)
19 create mode 100644 drivers/spi/spi-falcon.c
20
21Index: linux-3.0.3/arch/mips/lantiq/falcon/devices.c
22===================================================================
23--- linux-3.0.3.orig/arch/mips/lantiq/falcon/devices.c 2011-10-05 12:30:34.584838403 +0200
24+++ linux-3.0.3/arch/mips/lantiq/falcon/devices.c 2011-10-05 12:42:58.696870214 +0200
25@@ -129,7 +129,7 @@
26 
27 /* i2c */
28 static struct resource falcon_i2c_resources[] = {
29- MEM_RES("i2c", GPON_I2C_BASE,GPON_I2C_END),
30+ MEM_RES("i2c", LTQ_I2C_BASE_ADDR, LTQ_I2C_SIZE),
31     IRQ_RES("i2c_lb", FALCON_IRQ_I2C_LBREQ),
32     IRQ_RES("i2c_b", FALCON_IRQ_I2C_BREQ),
33     IRQ_RES("i2c_err", FALCON_IRQ_I2C_I2C_ERR),
34@@ -140,10 +140,18 @@
35 {
36     platform_device_register_simple("i2c-falcon", 0,
37     falcon_i2c_resources, ARRAY_SIZE(falcon_i2c_resources));
38- sys1_hw_activate(ACTS_I2C_ACT);
39+ ltq_sysctl_activate(SYSCTL_SYS1, ACTS_I2C_ACT);
40 }
41 
42-void __init falcon_register_crypto(void)
43+/* spi flash */
44+static struct platform_device ltq_spi = {
45+ .name = "falcon_spi",
46+ .num_resources = 0,
47+};
48+
49+void __init
50+falcon_register_spi_flash(struct spi_board_info *data)
51 {
52- platform_device_register_simple("ltq_falcon_deu", 0, NULL, 0);
53+ spi_register_board_info(data, 1);
54+ platform_device_register(&ltq_spi);
55 }
56Index: linux-3.0.3/arch/mips/lantiq/falcon/devices.h
57===================================================================
58--- linux-3.0.3.orig/arch/mips/lantiq/falcon/devices.h 2011-10-05 12:30:34.584838403 +0200
59+++ linux-3.0.3/arch/mips/lantiq/falcon/devices.h 2011-10-05 12:30:34.600838405 +0200
60@@ -11,11 +11,15 @@
61 #ifndef _FALCON_DEVICES_H__
62 #define _FALCON_DEVICES_H__
63 
64+#include <linux/spi/spi.h>
65+#include <linux/spi/flash.h>
66+
67 #include "../devices.h"
68 
69 extern void falcon_register_nand(void);
70 extern void falcon_register_gpio(void);
71 extern void falcon_register_gpio_extra(void);
72 extern void falcon_register_i2c(void);
73+extern void falcon_register_spi_flash(struct spi_board_info *data);
74 
75 #endif
76Index: linux-3.0.3/arch/mips/lantiq/falcon/mach-easy98000.c
77===================================================================
78--- linux-3.0.3.orig/arch/mips/lantiq/falcon/mach-easy98000.c 2011-10-05 12:30:34.552838402 +0200
79+++ linux-3.0.3/arch/mips/lantiq/falcon/mach-easy98000.c 2011-10-05 12:30:34.600838405 +0200
80@@ -40,6 +40,21 @@
81     .parts = easy98000_nor_partitions,
82 };
83 
84+static struct flash_platform_data easy98000_spi_flash_platform_data = {
85+ .name = "sflash",
86+ .parts = easy98000_nor_partitions,
87+ .nr_parts = ARRAY_SIZE(easy98000_nor_partitions)
88+};
89+
90+static struct spi_board_info easy98000_spi_flash_data __initdata = {
91+ .modalias = "m25p80",
92+ .bus_num = 0,
93+ .chip_select = 0,
94+ .max_speed_hz = 10 * 1000 * 1000,
95+ .mode = SPI_MODE_3,
96+ .platform_data = &easy98000_spi_flash_platform_data
97+};
98+
99 /* setup gpio based spi bus/device for access to the eeprom on the board */
100 #define SPI_GPIO_MRST 102
101 #define SPI_GPIO_MTSR 103
102@@ -93,6 +108,13 @@
103 }
104 
105 static void __init
106+easy98000sf_init(void)
107+{
108+ easy98000_init_common();
109+ falcon_register_spi_flash(&easy98000_spi_flash_data);
110+}
111+
112+static void __init
113 easy98000nand_init(void)
114 {
115     easy98000_init_common();
116@@ -104,6 +126,11 @@
117             "EASY98000 Eval Board",
118             easy98000_init);
119 
120+MIPS_MACHINE(LANTIQ_MACH_EASY98000SF,
121+ "EASY98000SF",
122+ "EASY98000 Eval Board (Serial Flash)",
123+ easy98000sf_init);
124+
125 MIPS_MACHINE(LANTIQ_MACH_EASY98000NAND,
126             "EASY98000NAND",
127             "EASY98000 Eval Board (NAND Flash)",
128Index: linux-3.0.3/drivers/spi/Kconfig
129===================================================================
130--- linux-3.0.3.orig/drivers/spi/Kconfig 2011-10-05 12:30:33.608838362 +0200
131+++ linux-3.0.3/drivers/spi/Kconfig 2011-10-05 12:41:56.864867570 +0200
132@@ -219,6 +219,10 @@
133       This drivers supports the MPC52xx SPI controller in master SPI
134       mode.
135 
136+config SPI_FALCON
137+ tristate "Falcon SPI controller support"
138+ depends on SOC_FALCON
139+
140 config SPI_MPC52xx_PSC
141     tristate "Freescale MPC52xx PSC SPI controller"
142     depends on PPC_MPC52xx && EXPERIMENTAL
143Index: linux-3.0.3/drivers/spi/Makefile
144===================================================================
145--- linux-3.0.3.orig/drivers/spi/Makefile 2011-10-05 12:30:33.608838362 +0200
146+++ linux-3.0.3/drivers/spi/Makefile 2011-10-05 12:41:56.884867571 +0200
147@@ -56,6 +56,7 @@
148 obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o
149 obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o
150 obj-$(CONFIG_SPI_NUC900) += spi_nuc900.o
151+obj-$(CONFIG_SPI_FALCON) += spi-falcon.o
152 
153 # special build for s3c24xx spi driver with fiq support
154 spi_s3c24xx_hw-y := spi_s3c24xx.o
155Index: linux-3.0.3/drivers/spi/spi-falcon.c
156===================================================================
157--- /dev/null 1970-01-01 00:00:00.000000000 +0000
158+++ linux-3.0.3/drivers/spi/spi-falcon.c 2011-10-05 12:30:34.600838405 +0200
159@@ -0,0 +1,477 @@
160+/*
161+ * This program is free software; you can redistribute it and/or modify it
162+ * under the terms of the GNU General Public License version 2 as published
163+ * by the Free Software Foundation.
164+ *
165+ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
166+ */
167+
168+#include <linux/module.h>
169+#include <linux/device.h>
170+#include <linux/platform_device.h>
171+#include <linux/spi/spi.h>
172+#include <linux/delay.h>
173+#include <linux/workqueue.h>
174+
175+#include <lantiq_soc.h>
176+
177+#define DRV_NAME "falcon_spi"
178+
179+#define FALCON_SPI_XFER_BEGIN (1 << 0)
180+#define FALCON_SPI_XFER_END (1 << 1)
181+
182+/* Bus Read Configuration Register0 */
183+#define LTQ_BUSRCON0 0x00000010
184+/* Bus Write Configuration Register0 */
185+#define LTQ_BUSWCON0 0x00000018
186+/* Serial Flash Configuration Register */
187+#define LTQ_SFCON 0x00000080
188+/* Serial Flash Time Register */
189+#define LTQ_SFTIME 0x00000084
190+/* Serial Flash Status Register */
191+#define LTQ_SFSTAT 0x00000088
192+/* Serial Flash Command Register */
193+#define LTQ_SFCMD 0x0000008C
194+/* Serial Flash Address Register */
195+#define LTQ_SFADDR 0x00000090
196+/* Serial Flash Data Register */
197+#define LTQ_SFDATA 0x00000094
198+/* Serial Flash I/O Control Register */
199+#define LTQ_SFIO 0x00000098
200+/* EBU Clock Control Register */
201+#define LTQ_EBUCC 0x000000C4
202+
203+/* Dummy Phase Length */
204+#define SFCMD_DUMLEN_OFFSET 16
205+#define SFCMD_DUMLEN_MASK 0x000F0000
206+/* Chip Select */
207+#define SFCMD_CS_OFFSET 24
208+#define SFCMD_CS_MASK 0x07000000
209+/* field offset */
210+#define SFCMD_ALEN_OFFSET 20
211+#define SFCMD_ALEN_MASK 0x00700000
212+/* SCK Rise-edge Position */
213+#define SFTIME_SCKR_POS_OFFSET 8
214+#define SFTIME_SCKR_POS_MASK 0x00000F00
215+/* SCK Period */
216+#define SFTIME_SCK_PER_OFFSET 0
217+#define SFTIME_SCK_PER_MASK 0x0000000F
218+/* SCK Fall-edge Position */
219+#define SFTIME_SCKF_POS_OFFSET 12
220+#define SFTIME_SCKF_POS_MASK 0x0000F000
221+/* Device Size */
222+#define SFCON_DEV_SIZE_A23_0 0x03000000
223+#define SFCON_DEV_SIZE_MASK 0x0F000000
224+/* Read Data Position */
225+#define SFTIME_RD_POS_MASK 0x000F0000
226+/* Data Output */
227+#define SFIO_UNUSED_WD_MASK 0x0000000F
228+/* Command Opcode mask */
229+#define SFCMD_OPC_MASK 0x000000FF
230+/* dlen bytes of data to write */
231+#define SFCMD_DIR_WRITE 0x00000100
232+/* Data Length offset */
233+#define SFCMD_DLEN_OFFSET 9
234+/* Command Error */
235+#define SFSTAT_CMD_ERR 0x20000000
236+/* Access Command Pending */
237+#define SFSTAT_CMD_PEND 0x00400000
238+/* Frequency set to 100MHz. */
239+#define EBUCC_EBUDIV_SELF100 0x00000001
240+/* Serial Flash */
241+#define BUSRCON0_AGEN_SERIAL_FLASH 0xF0000000
242+/* 8-bit multiplexed */
243+#define BUSRCON0_PORTW_8_BIT_MUX 0x00000000
244+/* Serial Flash */
245+#define BUSWCON0_AGEN_SERIAL_FLASH 0xF0000000
246+/* Chip Select after opcode */
247+#define SFCMD_KEEP_CS_KEEP_SELECTED 0x00008000
248+
249+struct falcon_spi {
250+ u32 sfcmd; /* for caching of opcode, direction, ... */
251+ struct spi_master *master;
252+};
253+
254+int
255+falcon_spi_xfer(struct spi_device *spi,
256+ struct spi_transfer *t,
257+ unsigned long flags)
258+{
259+ struct device *dev = &spi->dev;
260+ struct falcon_spi *priv = spi_master_get_devdata(spi->master);
261+ const u8 *txp = t->tx_buf;
262+ u8 *rxp = t->rx_buf;
263+ unsigned int bytelen = ((8 * t->len + 7) / 8);
264+ unsigned int len, alen, dumlen;
265+ u32 val;
266+ enum {
267+ state_init,
268+ state_command_prepare,
269+ state_write,
270+ state_read,
271+ state_disable_cs,
272+ state_end
273+ } state = state_init;
274+
275+ do {
276+ switch (state) {
277+ case state_init: /* detect phase of upper layer sequence */
278+ {
279+ /* initial write ? */
280+ if (flags & FALCON_SPI_XFER_BEGIN) {
281+ if (!txp) {
282+ dev_err(dev,
283+ "BEGIN without tx data!\n");
284+ return -1;
285+ }
286+ /*
287+ * Prepare the parts of the sfcmd register,
288+ * which should not
289+ * change during a sequence!
290+ * Only exception are the length fields,
291+ * especially alen and dumlen.
292+ */
293+
294+ priv->sfcmd = ((spi->chip_select
295+ << SFCMD_CS_OFFSET)
296+ & SFCMD_CS_MASK);
297+ priv->sfcmd |= SFCMD_KEEP_CS_KEEP_SELECTED;
298+ priv->sfcmd |= *txp;
299+ txp++;
300+ bytelen--;
301+ if (bytelen) {
302+ /* more data:
303+ * maybe address and/or dummy */
304+ state = state_command_prepare;
305+ break;
306+ } else {
307+ dev_dbg(dev, "write cmd %02X\n",
308+ priv->sfcmd & SFCMD_OPC_MASK);
309+ }
310+ }
311+ /* continued write ? */
312+ if (txp && bytelen) {
313+ state = state_write;
314+ break;
315+ }
316+ /* read data? */
317+ if (rxp && bytelen) {
318+ state = state_read;
319+ break;
320+ }
321+ /* end of sequence? */
322+ if (flags & FALCON_SPI_XFER_END)
323+ state = state_disable_cs;
324+ else
325+ state = state_end;
326+ break;
327+ }
328+ case state_command_prepare: /* collect tx data for
329+ address and dummy phase */
330+ {
331+ /* txp is valid, already checked */
332+ val = 0;
333+ alen = 0;
334+ dumlen = 0;
335+ while (bytelen > 0) {
336+ if (alen < 3) {
337+ val = (val<<8)|(*txp++);
338+ alen++;
339+ } else if ((dumlen < 15) && (*txp == 0)) {
340+ /*
341+ * assume dummy bytes are set to 0
342+ * from upper layer
343+ */
344+ dumlen++;
345+ txp++;
346+ } else
347+ break;
348+ bytelen--;
349+ }
350+ priv->sfcmd &= ~(SFCMD_ALEN_MASK | SFCMD_DUMLEN_MASK);
351+ priv->sfcmd |= (alen << SFCMD_ALEN_OFFSET) |
352+ (dumlen << SFCMD_DUMLEN_OFFSET);
353+ if (alen > 0)
354+ ltq_ebu_w32(val, LTQ_SFADDR);
355+
356+ dev_dbg(dev, "write cmd %02X, alen=%d "
357+ "(addr=%06X) dumlen=%d\n",
358+ priv->sfcmd & SFCMD_OPC_MASK,
359+ alen, val, dumlen);
360+
361+ if (bytelen > 0) {
362+ /* continue with write */
363+ state = state_write;
364+ } else if (flags & FALCON_SPI_XFER_END) {
365+ /* end of sequence? */
366+ state = state_disable_cs;
367+ } else {
368+ /* go to end and expect another
369+ * call (read or write) */
370+ state = state_end;
371+ }
372+ break;
373+ }
374+ case state_write:
375+ {
376+ /* txp still valid */
377+ priv->sfcmd |= SFCMD_DIR_WRITE;
378+ len = 0;
379+ val = 0;
380+ do {
381+ if (bytelen--)
382+ val |= (*txp++) << (8 * len++);
383+ if ((flags & FALCON_SPI_XFER_END)
384+ && (bytelen == 0)) {
385+ priv->sfcmd &=
386+ ~SFCMD_KEEP_CS_KEEP_SELECTED;
387+ }
388+ if ((len == 4) || (bytelen == 0)) {
389+ ltq_ebu_w32(val, LTQ_SFDATA);
390+ ltq_ebu_w32(priv->sfcmd
391+ | (len<<SFCMD_DLEN_OFFSET),
392+ LTQ_SFCMD);
393+ len = 0;
394+ val = 0;
395+ priv->sfcmd &= ~(SFCMD_ALEN_MASK
396+ | SFCMD_DUMLEN_MASK);
397+ }
398+ } while (bytelen);
399+ state = state_end;
400+ break;
401+ }
402+ case state_read:
403+ {
404+ /* read data */
405+ priv->sfcmd &= ~SFCMD_DIR_WRITE;
406+ do {
407+ if ((flags & FALCON_SPI_XFER_END)
408+ && (bytelen <= 4)) {
409+ priv->sfcmd &=
410+ ~SFCMD_KEEP_CS_KEEP_SELECTED;
411+ }
412+ len = (bytelen > 4) ? 4 : bytelen;
413+ bytelen -= len;
414+ ltq_ebu_w32(priv->sfcmd
415+ |(len<<SFCMD_DLEN_OFFSET), LTQ_SFCMD);
416+ priv->sfcmd &= ~(SFCMD_ALEN_MASK
417+ | SFCMD_DUMLEN_MASK);
418+ do {
419+ val = ltq_ebu_r32(LTQ_SFSTAT);
420+ if (val & SFSTAT_CMD_ERR) {
421+ /* reset error status */
422+ dev_err(dev, "SFSTAT: CMD_ERR "
423+ "(%x)\n", val);
424+ ltq_ebu_w32(SFSTAT_CMD_ERR,
425+ LTQ_SFSTAT);
426+ return -1;
427+ }
428+ } while (val & SFSTAT_CMD_PEND);
429+ val = ltq_ebu_r32(LTQ_SFDATA);
430+ do {
431+ *rxp = (val & 0xFF);
432+ rxp++;
433+ val >>= 8;
434+ len--;
435+ } while (len);
436+ } while (bytelen);
437+ state = state_end;
438+ break;
439+ }
440+ case state_disable_cs:
441+ {
442+ priv->sfcmd &= ~SFCMD_KEEP_CS_KEEP_SELECTED;
443+ ltq_ebu_w32(priv->sfcmd | (0 << SFCMD_DLEN_OFFSET),
444+ LTQ_SFCMD);
445+ val = ltq_ebu_r32(LTQ_SFSTAT);
446+ if (val & SFSTAT_CMD_ERR) {
447+ /* reset error status */
448+ dev_err(dev, "SFSTAT: CMD_ERR (%x)\n", val);
449+ ltq_ebu_w32(SFSTAT_CMD_ERR, LTQ_SFSTAT);
450+ return -1;
451+ }
452+ state = state_end;
453+ break;
454+ }
455+ case state_end:
456+ break;
457+ }
458+ } while (state != state_end);
459+
460+ return 0;
461+}
462+
463+static int
464+falcon_spi_setup(struct spi_device *spi)
465+{
466+ struct device *dev = &spi->dev;
467+ const u32 ebuclk = CLOCK_100M;
468+ unsigned int i;
469+ unsigned long flags;
470+
471+ dev_dbg(dev, "setup\n");
472+
473+ if (spi->master->bus_num > 0 || spi->chip_select > 0)
474+ return -ENODEV;
475+
476+ spin_lock_irqsave(&ebu_lock, flags);
477+
478+ if (ebuclk < spi->max_speed_hz) {
479+ /* set EBU clock to 100 MHz */
480+ ltq_sys1_w32_mask(0, EBUCC_EBUDIV_SELF100, LTQ_EBUCC);
481+ i = 1; /* divider */
482+ } else {
483+ /* set EBU clock to 50 MHz */
484+ ltq_sys1_w32_mask(EBUCC_EBUDIV_SELF100, 0, LTQ_EBUCC);
485+
486+ /* search for suitable divider */
487+ for (i = 1; i < 7; i++) {
488+ if (ebuclk / i <= spi->max_speed_hz)
489+ break;
490+ }
491+ }
492+
493+ /* setup period of serial clock */
494+ ltq_ebu_w32_mask(SFTIME_SCKF_POS_MASK
495+ | SFTIME_SCKR_POS_MASK
496+ | SFTIME_SCK_PER_MASK,
497+ (i << SFTIME_SCKR_POS_OFFSET)
498+ | (i << (SFTIME_SCK_PER_OFFSET + 1)),
499+ LTQ_SFTIME);
500+
501+ /* set some bits of unused_wd, to not trigger HOLD/WP
502+ * signals on non QUAD flashes */
503+ ltq_ebu_w32((SFIO_UNUSED_WD_MASK & (0x8 | 0x4)), LTQ_SFIO);
504+
505+ ltq_ebu_w32(BUSRCON0_AGEN_SERIAL_FLASH | BUSRCON0_PORTW_8_BIT_MUX,
506+ LTQ_BUSRCON0);
507+ ltq_ebu_w32(BUSWCON0_AGEN_SERIAL_FLASH, LTQ_BUSWCON0);
508+ /* set address wrap around to maximum for 24-bit addresses */
509+ ltq_ebu_w32_mask(SFCON_DEV_SIZE_MASK, SFCON_DEV_SIZE_A23_0, LTQ_SFCON);
510+
511+ spin_unlock_irqrestore(&ebu_lock, flags);
512+
513+ return 0;
514+}
515+
516+static int
517+falcon_spi_transfer(struct spi_device *spi, struct spi_message *m)
518+{
519+ struct falcon_spi *priv = spi_master_get_devdata(spi->master);
520+ struct spi_transfer *t;
521+ unsigned long spi_flags;
522+ unsigned long flags;
523+ int ret = 0;
524+
525+ priv->sfcmd = 0;
526+ m->actual_length = 0;
527+
528+ spi_flags = FALCON_SPI_XFER_BEGIN;
529+ list_for_each_entry(t, &m->transfers, transfer_list) {
530+ if (list_is_last(&t->transfer_list, &m->transfers))
531+ spi_flags |= FALCON_SPI_XFER_END;
532+
533+ spin_lock_irqsave(&ebu_lock, flags);
534+ ret = falcon_spi_xfer(spi, t, spi_flags);
535+ spin_unlock_irqrestore(&ebu_lock, flags);
536+
537+ if (ret)
538+ break;
539+
540+ m->actual_length += t->len;
541+
542+ if (t->delay_usecs || t->cs_change)
543+ BUG();
544+
545+ spi_flags = 0;
546+ }
547+
548+ m->status = ret;
549+ m->complete(m->context);
550+
551+ return 0;
552+}
553+
554+static void
555+falcon_spi_cleanup(struct spi_device *spi)
556+{
557+ struct device *dev = &spi->dev;
558+
559+ dev_dbg(dev, "cleanup\n");
560+}
561+
562+static int __devinit
563+falcon_spi_probe(struct platform_device *pdev)
564+{
565+ struct device *dev = &pdev->dev;
566+ struct falcon_spi *priv;
567+ struct spi_master *master;
568+ int ret;
569+
570+ dev_dbg(dev, "probing\n");
571+
572+ master = spi_alloc_master(&pdev->dev, sizeof(*priv));
573+ if (!master) {
574+ dev_err(dev, "no memory for spi_master\n");
575+ return -ENOMEM;
576+ }
577+
578+ priv = spi_master_get_devdata(master);
579+ priv->master = master;
580+
581+ master->mode_bits = SPI_MODE_3;
582+ master->num_chipselect = 1;
583+ master->bus_num = 0;
584+
585+ master->setup = falcon_spi_setup;
586+ master->transfer = falcon_spi_transfer;
587+ master->cleanup = falcon_spi_cleanup;
588+
589+ platform_set_drvdata(pdev, priv);
590+
591+ ret = spi_register_master(master);
592+ if (ret)
593+ spi_master_put(master);
594+
595+ return ret;
596+}
597+
598+static int __devexit
599+falcon_spi_remove(struct platform_device *pdev)
600+{
601+ struct device *dev = &pdev->dev;
602+ struct falcon_spi *priv = platform_get_drvdata(pdev);
603+
604+ dev_dbg(dev, "removed\n");
605+
606+ spi_unregister_master(priv->master);
607+
608+ return 0;
609+}
610+
611+static struct platform_driver falcon_spi_driver = {
612+ .probe = falcon_spi_probe,
613+ .remove = __devexit_p(falcon_spi_remove),
614+ .driver = {
615+ .name = DRV_NAME,
616+ .owner = THIS_MODULE
617+ }
618+};
619+
620+static int __init
621+falcon_spi_init(void)
622+{
623+ return platform_driver_register(&falcon_spi_driver);
624+}
625+
626+static void __exit
627+falcon_spi_exit(void)
628+{
629+ platform_driver_unregister(&falcon_spi_driver);
630+}
631+
632+module_init(falcon_spi_init);
633+module_exit(falcon_spi_exit);
634+
635+MODULE_LICENSE("GPL");
636+MODULE_DESCRIPTION("Lantiq Falcon SPI controller driver");
637Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
638===================================================================
639--- linux-3.0.3.orig/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h 2011-10-05 12:38:16.176858136 +0200
640+++ linux-3.0.3/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h 2011-10-05 12:39:54.936862358 +0200
641@@ -48,6 +48,10 @@
642 
643 #define LTQ_EBU_MODCON 0x000C
644 
645+/* I2C */
646+#define LTQ_I2C_BASE_ADDR 0x1E200000
647+#define LTQ_I2C_SIZE 0x00010000
648+
649 /* GPIO */
650 #define LTQ_GPIO0_BASE_ADDR 0x1D810000
651 #define LTQ_GPIO0_SIZE 0x0080
652@@ -92,6 +96,7 @@
653 
654 /* Activation Status Register */
655 #define ACTS_ASC1_ACT 0x00000800
656+#define ACTS_I2C_ACT 0x00004000
657 #define ACTS_P0 0x00010000
658 #define ACTS_P1 0x00010000
659 #define ACTS_P2 0x00020000
660

Archive Download this file



interactive