📄 2.6.20-rc1-at91.patch.gz
字号:
+ }++ maplist = kmalloc (pgcount * sizeof (struct page *), GFP_KERNEL);++ if (!maplist) {+ kfree(list);+ return -ENOMEM;+ }+ flush_cache_all();+ down_read(&mm->mmap_sem);+ err= get_user_pages(current, mm, (unsigned long)buf, pgcount, 1, 0, maplist, NULL);+ up_read(&mm->mmap_sem);++ if (err < 0) {+ kfree(list);+ kfree(maplist);+ return err;+ }+ pgcount = err;++#ifdef DEBUG_SPIDEV+ printk("spidev_rd_rw: %i %i\n", count, pgcount);+#endif++ /* Set default return value = transfer length */+ res = count;++ /*+ * At this point, the virtual area buf[0] .. buf[count-1] will have+ * corresponding pages mapped in the physical memory and locked until+ * we unmap the kiobuf. The pages cannot be swapped out or moved+ * around.+ */+ ofs = (unsigned long) buf & (PAGE_SIZE -1);+ pagelen = PAGE_SIZE - ofs;+ if (count < pagelen)+ pagelen = count;++ for (i = 0; i < pgcount; i++) {+ flush_dcache_page(maplist[i]);++ list->tx[i] = list->rx[i] = page_address(maplist[i]) + ofs;+ list->txlen[i] = list->rxlen[i] = pagelen;++#ifdef DEBUG_SPIDEV+ printk(" %i: %x (%i)\n", i, list->tx[i], list->txlen[i]);+#endif++ ofs = 0; /* all subsequent transfers start at beginning of a page */+ count = count - pagelen;+ pagelen = (count < PAGE_SIZE) ? count : PAGE_SIZE;+ }+ list->nr_transfers = pgcount;++ /* Perform transfer on SPI bus */+ spi_access_bus(spi_device);+ spi_transfer(list);+ spi_release_bus(spi_device);++ while (pgcount--) {+ page_cache_release (maplist[pgcount]);+ }+ flush_cache_all();++ kfree(maplist);+ kfree(list);++ return res;+}++static int spidev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)+{+ int spi_device = MINOR(inode->i_rdev);++ if (spi_device >= NR_SPI_DEVICES)+ return -ENODEV;++ // TODO: This interface can be used to configure the SPI bus.+ // Configurable options could include: Speed, Clock Polarity, Clock Phase++ switch(cmd) {+ default:+ return -ENOIOCTLCMD;+ }+}++/*+ * Open the SPI device+ */+static int spidev_open(struct inode *inode, struct file *file)+{+ unsigned int spi_device = MINOR(inode->i_rdev);++ if (spi_device >= NR_SPI_DEVICES)+ return -ENODEV;++ /*+ * 'private_data' is actually a pointer, but we overload it with the+ * value we want to store.+ */+ file->private_data = (void *)spi_device;++ return 0;+}++/*+ * Close the SPI device+ */+static int spidev_close(struct inode *inode, struct file *file)+{+ return 0;+}++/* ......................................................................... */++static struct file_operations spidev_fops = {+ .owner = THIS_MODULE,+ .llseek = no_llseek,+ .read = spidev_rd_wr,+ .write = (int (*) (struct file *file, const char *buf, size_t count, loff_t *offset))spidev_rd_wr,+ .ioctl = spidev_ioctl,+ .open = spidev_open,+ .release = spidev_close,+};++/*+ * Install the SPI /dev interface driver+ */+static int __init at91_spidev_init(void)+{+#ifdef CONFIG_DEVFS_FS+ int i;+#endif++ if (register_chrdev(SPI_MAJOR, "spi", &spidev_fops)) {+ printk(KERN_ERR "at91_spidev: Unable to get major %d for SPI bus\n", SPI_MAJOR);+ return -EIO;+ }++#ifdef CONFIG_DEVFS_FS+ devfs_mk_dir("spi");+ for (i = 0; i < NR_SPI_DEVICES; i++) {+ devfs_mk_cdev(MKDEV(SPI_MAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR, "spi/%d",i);+ }+#endif+ printk(KERN_INFO "AT91 SPI driver loaded\n");++ return 0;+}++/*+ * Remove the SPI /dev interface driver+ */+static void __exit at91_spidev_exit(void)+{+#ifdef CONFIG_DEVFS_FS+ int i;+ for (i = 0; i < NR_SPI_DEVICES; i++) {+ devfs_remove("spi/%d", i);+ }++ devfs_remove("spi");+#endif++ if (unregister_chrdev(SPI_MAJOR, "spi")) {+ printk(KERN_ERR "at91_spidev: Unable to release major %d for SPI bus\n", SPI_MAJOR);+ return;+ }+}++module_init(at91_spidev_init);+module_exit(at91_spidev_exit);++MODULE_LICENSE("GPL")+MODULE_AUTHOR("Andrew Victor")+MODULE_DESCRIPTION("SPI /dev interface for Atmel AT91RM9200")diff -urN -x CVS linux-2.6.20-rc1.orig/drivers/i2c/busses/Kconfig linux-2.6/drivers/i2c/busses/Kconfig--- linux-2.6.20-rc1.orig/drivers/i2c/busses/Kconfig Fri Dec 15 08:36:05 2006+++ linux-2.6/drivers/i2c/busses/Kconfig Thu Dec 14 15:54:21 2006@@ -527,6 +527,14 @@ This driver can also be built as a module. If so, the module will be called i2c-voodoo3. +config I2C_PCA+ tristate "PCA9564"+ depends on I2C+ select I2C_ALGOPCA+ help+ This driver support the Philips PCA 9564 Parallel bus to I2C+ bus controller.+ config I2C_PCA_ISA tristate "PCA9564 on an ISA bus" depends on I2Cdiff -urN -x CVS linux-2.6.20-rc1.orig/drivers/i2c/busses/Makefile linux-2.6/drivers/i2c/busses/Makefile--- linux-2.6.20-rc1.orig/drivers/i2c/busses/Makefile Fri Dec 15 08:36:05 2006+++ linux-2.6/drivers/i2c/busses/Makefile Thu Dec 14 15:55:17 2006@@ -27,6 +27,7 @@ obj-$(CONFIG_I2C_OMAP) += i2c-omap.o obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o+obj-$(CONFIG_I2C_PCA) += i2c-pca.o obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o obj-$(CONFIG_I2C_PNX) += i2c-pnx.odiff -urN -x CVS linux-2.6.20-rc1.orig/drivers/i2c/busses/i2c-pca.c linux-2.6/drivers/i2c/busses/i2c-pca.c--- linux-2.6.20-rc1.orig/drivers/i2c/busses/i2c-pca.c Thu Jan 1 02:00:00 1970+++ linux-2.6/drivers/i2c/busses/i2c-pca.c Mon Oct 16 16:10:42 2006@@ -0,0 +1,202 @@+/*+ * Platform driver for PCA9564 I2C bus controller.+ *+ * (C) 2006 Andrew Victor+ *+ * Based on i2c-pca-isa.c driver for PCA9564 on ISA boards+ * Copyright (C) 2004 Arcom Control Systems+ *+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation; either version 2 of the License, or+ * (at your option) any later version.+ *+ * This program is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ * GNU General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License+ * along with this program; if not, write to the Free Software+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.+ */++#include <linux/kernel.h>+#include <linux/module.h>+#include <linux/moduleparam.h>+#include <linux/delay.h>+#include <linux/init.h>+#include <linux/interrupt.h>+#include <linux/wait.h>+#include <linux/platform_device.h>++#include <linux/i2c.h>+#include <linux/i2c-algo-pca.h>++#include <asm/io.h>++#include "../algos/i2c-algo-pca.h"++#define PCA_OWN_ADDRESS 0x55 /* our address for slave mode */+#define PCA_CLOCK I2C_PCA_CON_59kHz++//#define DEBUG_IO++#define PCA_IO_SIZE 4++static void __iomem *base_addr;+static int irq;+static wait_queue_head_t pca_wait;++static int pca_getown(struct i2c_algo_pca_data *adap)+{+ return PCA_OWN_ADDRESS;+}++static int pca_getclock(struct i2c_algo_pca_data *adap)+{+ return PCA_CLOCK;+}++static void pca_writebyte(struct i2c_algo_pca_data *adap, int reg, int val)+{+#ifdef DEBUG_IO+ static char *names[] = { "T/O", "DAT", "ADR", "CON" };+ printk("*** write %s at %#lx <= %#04x\n", names[reg], (unsigned long) base_addr+reg, val);+#endif+ outb(val, base_addr+reg);+}++static int pca_readbyte(struct i2c_algo_pca_data *adap, int reg)+{+ int res = inb(base_addr+reg);+#ifdef DEBUG_IO+ {+ static char *names[] = { "STA", "DAT", "ADR", "CON" };+ printk("*** read %s => %#04x\n", names[reg], res);+ }+#endif+ return res;+}++static int pca_waitforinterrupt(struct i2c_algo_pca_data *adap)+{+ int ret = 0;++ if (irq > -1) {+ ret = wait_event_interruptible(pca_wait,+ pca_readbyte(adap, I2C_PCA_CON) & I2C_PCA_CON_SI);+ } else {+ while ((pca_readbyte(adap, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0)+ udelay(100);+ }+ return ret;+}++static irqreturn_t pca_handler(int this_irq, void *dev_id)+{+ wake_up_interruptible(&pca_wait);+ return IRQ_HANDLED;+}++static struct i2c_algo_pca_data pca_i2c_data = {+ .get_own = pca_getown,+ .get_clock = pca_getclock,+ .write_byte = pca_writebyte,+ .read_byte = pca_readbyte,+ .wait_for_interrupt = pca_waitforinterrupt,+};++static struct i2c_adapter pca_i2c_ops = {+ .owner = THIS_MODULE,+ .id = I2C_HW_A_PLAT,+ .algo_data = &pca_i2c_data,+ .name = "PCA9564",+};++static int __devinit pca_i2c_probe(struct platform_device *pdev)+{+ struct resource *res;++ init_waitqueue_head(&pca_wait);++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);+ if (!res)+ return -ENODEV;++ if (!request_mem_region(res->start, PCA_IO_SIZE, "PCA9564"))+ return -ENXIO;++ base_addr = ioremap(res->start, PCA_IO_SIZE);+ if (base_addr == NULL)+ goto out_region;++ irq = platform_get_irq(pdev, 0);+ if (irq > -1) {+ if (request_irq(irq, pca_handler, 0, "pca9564", NULL) < 0) {+ printk(KERN_ERR "i2c-pca: Request irq%d failed\n", irq);+ goto out_remap;+ }+ }++ if (i2c_pca_add_bus(&pca_i2c_ops) < 0) {+ printk(KERN_ERR "i2c-pca: Failed to add i2c bus\n");+ goto out_irq;+ }++ return 0;++ out_irq:+ if (irq > -1)+ free_irq(irq, &pca_i2c_ops);++ out_remap:+ iounmap(base_addr);++ out_region:+ release_mem_region(res->start, PCA_IO_SIZE);+ return -ENODEV;+}++static int __devexit pca_i2c_remove(struct platform_device *pdev)+{+ struct resource *res;++ i2c_pca_del_bus(&pca_i2c_ops);++ if (irq > 0)+ free_irq(irq, NULL);++ iounmap(base_addr);++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);+ release_mem_region(res->start, PCA_IO_SIZE);++ return 0;+}++static struct platform_driver pca_i2c_driver = {+ .probe = pca_i2c_probe,+ .remove = __devexit_p(pca_i2c_remove),+ .driver = {+ .name = "pca9564",+ .owner = THIS_MODULE,+ },+};++static int __init pca_i2c_init(void)+{+ return platform_driver_register(&pca_i2c_driver);+}++static void __exit pca_i2c_exit(void)+{+ platform_driver_unregister(&pca_i2c_driver);+}++module_init(pca_i2c_init);+module_exit(pca_i2c_exit);++MODULE_AUTHOR("Andrew Victor");+MODULE_DESCRIPTION("PCA9564 platform driver");+MODULE_LICENSE("GPL");diff -urN -x CVS linux-2.6.20-rc1.orig/drivers/leds/Kconfig linux-2.6/drivers/leds/Kconfig--- linux-2.6.20-rc1.orig/drivers/leds/Kconfig Fri Dec 15 08:36:07 2006+++ linux-2.6/drivers/leds/Kconfig Thu Dec 14 15:13:56 2006@@ -76,6 +76,13 @@ This option enables support for the Soekris net4801 and net4826 error LED. +config LEDS_AT91+ tristate "LED support using AT91 GPIOs"+ depends on LEDS_CLASS && ARCH_AT91 && !LEDS+ help+ This option enables support for LEDs connected to GPIO lines+ on AT91-based boards.+ config LEDS_WRAP tristate "LED Support for the WRAP series LEDs" depends on LEDS_CLASS && SCx200_GPIOdiff -urN -x CVS linux-2.6.20-rc1.orig/drivers/leds/Makefile linux-2.6/drivers/leds/Makefile--- linux-2.6.20-rc1.orig/drivers/leds/Makefile Fri Dec 15 08:36:07 2006+++ linux-2.6/drivers/leds/Makefile Thu Dec 14 15:13:22 2006@@ -14,6 +14,7 @@ obj-$(C
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -