[Armadeus-commitlog] SF.net SVN: armadeus:[1109] trunk/target/linux/modules/fpga
Brought to you by:
sszy
|
From: <Fa...@us...> - 2009-03-03 16:20:48
|
Revision: 1109
http://armadeus.svn.sourceforge.net/armadeus/?rev=1109&view=rev
Author: FabM
Date: 2009-03-03 16:20:44 +0000 (Tue, 03 Mar 2009)
Log Message:
-----------
[LINUX] Drivers for wishbone_example are ready
Modified Paths:
--------------
trunk/target/linux/modules/fpga/wishbone_example/Kconfig
trunk/target/linux/modules/fpga/wishbone_example/Makefile
trunk/target/linux/modules/fpga/wishbone_example/wb_button/Kconfig
trunk/target/linux/modules/fpga/wishbone_example/wb_button/Makefile
trunk/target/linux/modules/fpga/wishbone_example/wb_button/button.h
trunk/target/linux/modules/fpga/wishbone_example/wb_button/testbutton.c
Added Paths:
-----------
trunk/target/linux/modules/fpga/wishbone_example/wb_button/board_buttons.c
trunk/target/linux/modules/fpga/wishbone_example/wb_button/gbutton.c
trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/
trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/Kconfig
trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/Makefile
trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/README
trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/main.c
trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/test.c
trunk/target/linux/modules/fpga/wishbone_example/wb_led/
trunk/target/linux/modules/fpga/wishbone_example/wb_led/Kconfig
trunk/target/linux/modules/fpga/wishbone_example/wb_led/Makefile
trunk/target/linux/modules/fpga/wishbone_example/wb_led/board_leds.c
trunk/target/linux/modules/fpga/wishbone_example/wb_led/g_led.c
trunk/target/linux/modules/fpga/wishbone_example/wb_led/led.h
trunk/target/linux/modules/fpga/wishbone_example/wb_led/s_led.c
trunk/target/linux/modules/fpga/wishbone_example/wb_led/testled.c
Removed Paths:
-------------
trunk/target/linux/modules/fpga/others/Wb_led/
trunk/target/linux/modules/fpga/wishbone_example/wb_button/Wb_button/
Modified: trunk/target/linux/modules/fpga/wishbone_example/Kconfig
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/Kconfig 2009-03-03 16:03:26 UTC (rev 1108)
+++ trunk/target/linux/modules/fpga/wishbone_example/Kconfig 2009-03-03 16:20:44 UTC (rev 1109)
@@ -5,11 +5,14 @@
#
#
-config WISHBONE_EXAMPLE_DRIVERS
- tristate "Drivers for wishbone example"
+config ARMADEUS_WISHBONE_EXAMPLE_DRIVERS
+ boolean "Drivers for wishbone example"
default n
depends on ARMADEUS_FPGA_DRIVERS
---help---
Drivers used for wishbone example design that can be
found in firmware/wishbone_example/
+source "drivers/armadeus/fpga/wishbone_example/wb_button/Kconfig"
+source "drivers/armadeus/fpga/wishbone_example/wb_led/Kconfig"
+source "drivers/armadeus/fpga/wishbone_example/wb_irq_mngr/Kconfig"
Modified: trunk/target/linux/modules/fpga/wishbone_example/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/Makefile 2009-03-03 16:03:26 UTC (rev 1108)
+++ trunk/target/linux/modules/fpga/wishbone_example/Makefile 2009-03-03 16:20:44 UTC (rev 1109)
@@ -8,21 +8,10 @@
ifneq ($(KERNELRELEASE),)
# Part executed when called from kernel build system:
-obj-$(CONFIG_WISHBONE_EXAMPLE_DRIVERS) +=
+obj-$(CONFIG_ARMADEUS_WISHBONE_EXAMPLE_DRIVERS) += wb_button/ wb_irq_mngr/ wb_led/
else
-# Part executed when called from standard make in this directory:
-
-BASE_DIR:=../../../../buildroot/
-REL:=$(shell grep "BR2_PACKAGE_LINUX_VERSION=" $(BASE_DIR).config | sed -e 's/BR2_PACKAGE_LINUX_VERSION=//' | sed -e 's/"//g')
-#
-ARMADEUS_KERNEL_DIR:=$(BASE_DIR)build_arm/linux-$(REL)
-ifeq ($(LINUX_DIR),)
-LINUX_DIR:=$(ARMADEUS_KERNEL_DIR)
-endif
-PWD:= $(shell pwd)
-
default:
echo "Your Linux source dir is: $(LINUX_DIR)"
$(MAKE) -C $(LINUX_DIR) SUBDIRS=$(PWD) zImage modules
@@ -35,5 +24,15 @@
echo "Installing Armadeus drivers..."
$(MAKE) -C $(LINUX_DIR) SUBDIRS=$(PWD) INSTALL_MOD_PATH=$(TARGET_DIR) modules_install
+clean:
+ rm -f *.*o \
+ rm -f *.mod.c \
+ rm -f *.cmd \
+ rm -f *.o.d \
+ rm -f *.order \
+ rm -f .*.cmd \
+ rm -rf .tmp_versions \
+ rm -f Module.symvers
+
endif
Modified: trunk/target/linux/modules/fpga/wishbone_example/wb_button/Kconfig
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/wb_button/Kconfig 2009-03-03 16:03:26 UTC (rev 1108)
+++ trunk/target/linux/modules/fpga/wishbone_example/wb_button/Kconfig 2009-03-03 16:20:44 UTC (rev 1109)
@@ -1,8 +1,8 @@
#
#
-config ARMADEUS_BUTTON_DRIVER
+config ARMADEUS_WISHBONE_EXAMPLE_BUTTON_DRIVER
tristate "Wishbone Button driver"
- default n
- depends on ARMADEUS_FPGA_OTHERS_DRIVERS
+ default m
+ depends on ARMADEUS_WISHBONE_EXAMPLE_DRIVERS
---help---
Modified: trunk/target/linux/modules/fpga/wishbone_example/wb_button/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/wb_button/Makefile 2009-03-03 16:03:26 UTC (rev 1108)
+++ trunk/target/linux/modules/fpga/wishbone_example/wb_button/Makefile 2009-03-03 16:20:44 UTC (rev 1109)
@@ -4,30 +4,32 @@
ifneq ($(KERNELRELEASE),)
-obj-$(CONFIG_ARMADEUS_BUTTON_DRIVER) += button.o
+obj-$(CONFIG_ARMADEUS_WISHBONE_EXAMPLE_BUTTON_DRIVER) += board_buttons.o gbutton.o
-# Part executed when called from standard make in this directory:
-# (preferably use Makefile in parent directory)
-
else
+
ARMADEUS_BASE_DIR=../../../../../..
include $(ARMADEUS_BASE_DIR)/Makefile.in
-KDIR := $(ARMADEUS_LINUX_DIR)
-PWD := $(shell pwd)
+KDIR := $(ARMADEUS_LINUX_DIR)
+PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
- -cp button.ko /tftpboot/
test:
~/armadeus/buildroot/build_arm/staging_dir/bin/arm-linux-gcc testbutton.c -o testbutton
chmod 755 testbutton
- cp testbutton /tftpboot/
clean:
rm -f *.*o \
+ rm -f *.mod.c \
+ rm -f *.cmd \
+ rm -f *.o.d \
+ rm -f *.order \
+ rm -f .*.cmd \
+ rm -rf .tmp_versions \
rm -f Module.symvers
endif
Added: trunk/target/linux/modules/fpga/wishbone_example/wb_button/board_buttons.c
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/wb_button/board_buttons.c (rev 0)
+++ trunk/target/linux/modules/fpga/wishbone_example/wb_button/board_buttons.c 2009-03-03 16:20:44 UTC (rev 1109)
@@ -0,0 +1,82 @@
+/*
+ ***********************************************************************
+ *
+ * (c) Copyright 2008 Armadeus project
+ * Fabien Marteau <fab...@ar...>
+ * Specific button driver for generic button driver
+ *
+ * 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, 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/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+#include <linux/config.h>
+#endif
+
+/* form module/drivers */
+#include <linux/init.h>
+#include <linux/module.h>
+
+/* for platform device */
+#include <linux/platform_device.h>
+
+#include "button.h"
+
+#define BUTTON0_IRQ IRQ_FPGA(0)
+
+
+static struct plat_button_port plat_button0_data={
+ .name = "BUTTON0",
+ .interrupt_number=BUTTON0_IRQ,
+ .num=0,
+ .membase = (void *)(ARMADEUS_FPGA_BASE_ADDR_VIRT +
+ 0xc),
+ .idnum=3,
+ .idoffset=0x00 * (16 /8)
+};
+
+
+static struct platform_device plat_button0_device={
+ .name = "button",
+ .id=0,
+ .dev={
+ .platform_data = &plat_button0_data
+ },
+};
+
+
+static int __init board_button_init(void)
+{
+ int ret = -1;
+ ret = platform_device_register(&plat_button0_device);
+ if(ret<0)return ret;
+
+ return ret;
+}
+
+static void __exit board_button_exit(void)
+{
+ platform_device_unregister(&plat_button0_device);
+
+}
+
+module_init(board_button_init);
+module_exit(board_button_exit);
+
+MODULE_AUTHOR("Fabien Marteau <fab...@ar...>");
+MODULE_DESCRIPTION("Board specific button driver");
+MODULE_LICENSE("GPL");
+
Modified: trunk/target/linux/modules/fpga/wishbone_example/wb_button/button.h
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/wb_button/button.h 2009-03-03 16:03:26 UTC (rev 1108)
+++ trunk/target/linux/modules/fpga/wishbone_example/wb_button/button.h 2009-03-03 16:20:44 UTC (rev 1109)
@@ -25,8 +25,6 @@
#ifndef __BUTTON_H__
#define __BUTTON_H__
-#include "button_specific.h"
-
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
#include <linux/config.h>
@@ -49,14 +47,19 @@
/* readw() writew() */
#include <asm/io.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
/* hardware addresses */
-#include <asm/hardware.h>
+# include <asm/hardware.h>
+# include <asm/semaphore.h>
+#else
+# include <mach/hardware.h>
+# include <linux/semaphore.h>
+#endif
/* interruptions */
#include <linux/interrupt.h>
#include <asm/irq.h>
#include <linux/wait.h>
-#include <asm/semaphore.h>
/* measure time */
#include <linux/jiffies.h>
@@ -78,47 +81,19 @@
# define PDEBUG(fmt,args...) /* no debbuging message */
#endif
+#define BUTTON_NUMBER 1
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Fabien Marteau <fab...@ar...> - ARMadeus Systems");
-MODULE_DESCRIPTION("button device driver");
+#define BUTTON_REG_OFFSET (0x02)
+#define BUTTON_ID_OFFSET (0x00)
-/* main device structure */
-struct button_dev{
- struct cdev cdev; /* Char device structure */
- struct semaphore sem; /* Mutex */
- void * fpga_virtual_base_address; /* fpga register base address*/
- wait_queue_head_t button_queue;
- u8 reading;
+/* platform device */
+struct plat_button_port{
+ const char *name; /*instance name */
+ int interrupt_number; /* interrupt_number */
+ int num; /* instance number */
+ void * membase; /* ioremap base address */
+ int idnum; /* identity number */
+ int idoffset; /* identity relative address */
+ struct button_dev *sdev; /* struct for main device structure*/
};
-/* major and minor number */
-
-#define N_DEV 1
-static dev_t devno; /* to store Major and minor numbers */
-static struct button_dev *buttondev;
-#define BUTTON_LENGTH 1
-struct resource *mem; /* pointer to fpga button */
-
-
-/* to read write button register */
-ssize_t button_read(struct file *fildes, char __user *buff,
- size_t count, loff_t *offp);
-
-int button_open(struct inode *inode, struct file *filp);
-
-int button_release(struct inode *, struct file *filp);
-
-struct file_operations button_fops = {
- .owner = THIS_MODULE,
- .read = button_read,
- .open = button_open,
- .release = button_release,
-};
-
-static irqreturn_t fpga_interrupt(int irq,void *stuff,struct pt_regs *reg);
-
-static void free_all(void);
-
-static ssize_t button_fpga_read(void * addr, u16 *data , struct button_dev *dev);
-static ssize_t button_fpga_write(void * addr, u16 *data, struct button_dev *dev);
Added: trunk/target/linux/modules/fpga/wishbone_example/wb_button/gbutton.c
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/wb_button/gbutton.c (rev 0)
+++ trunk/target/linux/modules/fpga/wishbone_example/wb_button/gbutton.c 2009-03-03 16:20:44 UTC (rev 1109)
@@ -0,0 +1,369 @@
+/*
+ ***********************************************************************
+ *
+ * (c) Copyright 2008 Armadeus project
+ * Fabien Marteau <fab...@ar...>
+ * Generic driver for Wishbone button IP
+ *
+ * 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, 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/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+#include <linux/config.h>
+#endif
+
+/* form module/drivers */
+#include <linux/init.h>
+#include <linux/module.h>
+
+/* for file operations */
+#include <linux/fs.h>
+#include <linux/cdev.h>
+
+/* copy_to_user function */
+#include <asm/uaccess.h>
+
+/* request_mem_region */
+#include <linux/ioport.h>
+
+/* readw() writew() */
+#include <asm/io.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+/* hardware addresses */
+# include <asm/hardware.h>
+#else
+# include <mach/hardware.h>
+#endif
+
+
+/* for platform device */
+#include <linux/platform_device.h>
+
+/* button */
+#include "button.h"
+
+
+/* for debugging messages*/
+//#define BUTTON_DEBUG
+
+#undef PDEBUG
+#ifdef BUTTON_DEBUG
+# ifdef __KERNEL__
+/* for kernel spage */
+# define PDEBUG(fmt,args...) printk(KERN_DEBUG "BUTTON : " fmt, ##args)
+# else
+/* for user space */
+# define PDEBUG(fmt,args...) printk(stderr, fmt, ##args)
+# endif
+#else
+# define PDEBUG(fmt,args...) /* no debbuging message */
+#endif
+
+/********************************
+ * main device structure
+ * ******************************/
+struct button_dev{
+ char *name; /* name of the instance */
+ struct cdev cdev; /* char device structure */
+ struct semaphore sem; /* mutex */
+ void * membase; /* base address for instance */
+ dev_t devno; /* to store Major and minor numbers */
+ u8 read_in_wait; /* user is waiting for value to read */
+};
+
+/***********************************
+ * characters file /dev operations
+ * *********************************/
+ssize_t button_read(struct file *fildes, char __user *buff,
+ size_t count, loff_t *offp)
+{
+ struct button_dev *ldev = fildes->private_data;
+ u16 data=0;
+ ssize_t retval = 0;
+
+ ldev->read_in_wait = 1;
+
+ if(*offp + count >= 1) /* Only one word can be read */
+ count = 1 - *offp;
+
+ if((retval=down_interruptible(&ldev->sem))<0)
+ {
+ goto out;
+ }
+
+ data=ioread16(ldev->membase+BUTTON_REG_OFFSET);
+ PDEBUG("Read %d at 0x%x\n",data,(unsigned int)ldev->membase+BUTTON_REG_OFFSET);
+
+ /* return data for user */
+ if(copy_to_user(buff,&data,2)){
+ printk(KERN_WARNING "read : copy to user data error\n");
+ retval = -EFAULT;
+ goto out;
+ }
+
+ *offp = *offp + count;
+ retval = 1;
+
+out:
+ ldev->read_in_wait = 0;
+ return retval;
+}
+
+
+int button_open(struct inode *inode, struct file *filp){
+ /* Allocate and fill any data structure to be put in filp->private_data */
+ filp->private_data = container_of(inode->i_cdev,struct button_dev, cdev);
+ return 0;
+}
+
+int button_release(struct inode *inode, struct file *filp)
+{
+ struct button_dev *dev;
+
+ dev = container_of(inode->i_cdev,struct button_dev,cdev);
+ filp->private_data=NULL;
+
+ return 0;
+}
+
+
+static struct file_operations button_fops = {
+ .owner = THIS_MODULE,
+ .read = button_read,
+ .open = button_open,
+ .release = button_release,
+};
+
+/**********************************
+ * irq management
+ * awake read process
+ * ********************************/
+
+static irqreturn_t button_interrupt(int irq,void *dev_id){
+ struct button_dev *ldev = dev_id;
+ /* wake up reading process */
+ if(ldev->read_in_wait)up(&ldev->sem);
+ /* acknowledge irq_mngr */
+ return IRQ_HANDLED;
+}
+
+/**********************************
+ * driver probe
+ **********************************/
+static int button_probe(struct platform_device *pdev)
+{
+ struct plat_button_port *dev = pdev->dev.platform_data;
+
+ int result = 0; /* error return */
+ int button_major,button_minor;
+ u16 data;
+ struct button_dev *sdev;
+
+ PDEBUG("Button probing\n");
+ PDEBUG("Register %s num %d\n",dev->name,dev->num);
+
+ /**************************/
+ /* check if ID is correct */
+ /**************************/
+ data = ioread16(dev->membase+BUTTON_ID_OFFSET);
+ if(data != dev->idnum){
+ result = -1;
+ printk(KERN_WARNING "For %s id:%d doesn't match "
+ "with id read %d,\n is device present ?\n",
+ dev->name,dev->idnum,data);
+ goto error_id;
+ }
+
+ /********************************************/
+ /* allocate memory for sdev structure */
+ /********************************************/
+ sdev = kmalloc(sizeof(struct button_dev),GFP_KERNEL);
+ if(!sdev){
+ result = -ENOMEM;
+ goto error_sdev_alloc;
+ }
+ dev->sdev = sdev;
+ sdev->membase = dev->membase;
+ sdev->name = (char *)kmalloc((1+strlen(dev->name))*sizeof(char),
+ GFP_KERNEL);
+ if (sdev->name == NULL) {
+ printk("Kmalloc name space error\n");
+ goto error_name_alloc;
+ }
+ if (strncpy(sdev->name,dev->name,1+strlen(dev->name)) < 0) {
+ printk("copy error");
+ goto error_name_copy;
+ }
+
+ /******************************************/
+ /* Get the major and minor device numbers */
+ /******************************************/
+ button_major = 251;
+ button_minor = dev->num;
+
+ PDEBUG("%s:Get the major and minor device numbers\n",dev->name);
+ if (button_major) {
+ sdev->devno = MKDEV(button_major, button_minor);
+ result = register_chrdev_region(sdev->devno, 1,dev->name);
+ } else {
+ result = alloc_chrdev_region(&sdev->devno,
+ button_minor,
+ 1,
+ dev->name);
+ button_major = MAJOR(sdev->devno);
+ }
+ if (result < 0) {
+ printk(KERN_WARNING "%s: can't get major %d\n",
+ dev->name,button_major);
+ goto error_devno;
+ }
+ printk(KERN_INFO "%s: MAJOR: %d MINOR: %d\n",
+ dev->name,
+ MAJOR(sdev->devno),
+ MINOR(sdev->devno));
+
+ /* initiate mutex locked */
+ sdev->read_in_wait = 0;
+ init_MUTEX_LOCKED(&sdev->sem);
+
+ /****************************/
+ /* Init the cdev structure */
+ /****************************/
+ PDEBUG("Init the cdev structure\n");
+ cdev_init(&sdev->cdev,&button_fops);
+ sdev->cdev.owner = THIS_MODULE;
+ sdev->cdev.ops = &button_fops;
+
+ /* Add the device to the kernel, connecting cdev to major/minor number */
+ PDEBUG("%s: Add the device to the kernel, "
+ "connecting cdev to major/minor number \n",dev->name);
+ result = cdev_add(&sdev->cdev,sdev->devno,1);
+ if(result < 0){
+ printk(KERN_WARNING "%s: can't add cdev\n",dev->name);
+ goto error_cdev_add;
+ }
+
+ /* irq registering */
+ result = request_irq(dev->interrupt_number,
+ button_interrupt,
+ IRQF_SAMPLE_RANDOM,
+ sdev->name,
+ sdev);
+ if(result < 0){
+ printk(KERN_ERR "Can't register irq %d\n",
+ dev->interrupt_number);
+ goto request_irq_error;
+ }
+ printk(KERN_INFO "button: irq registered : %d\n",
+ dev->interrupt_number);
+
+ /* OK module inserted ! */
+ printk(KERN_INFO "%s insered\n",dev->name);
+ return 0;
+
+ /*********************/
+ /* Errors management */
+ /*********************/
+ /* freeing irq */
+ free_irq(dev->interrupt_number,sdev);
+request_irq_error:
+ /* delete the cdev structure */
+ cdev_del(&sdev->cdev);
+ PDEBUG("%s:cdev deleted\n",dev->name);
+error_cdev_add:
+ /* free major and minor number */
+ unregister_chrdev_region(sdev->devno,1);
+ printk(KERN_INFO "%s: Led deleted\n",dev->name);
+error_devno:
+error_name_copy:
+ kfree(sdev->name);
+error_name_alloc:
+ kfree(sdev);
+error_sdev_alloc:
+ printk(KERN_ERR "%s: not inserted\n", dev->name);
+error_id:
+ return result;
+}
+
+static int __devexit button_remove(struct platform_device *pdev)
+{
+ struct plat_button_port *dev = pdev->dev.platform_data;
+ struct button_dev *sdev = (*dev).sdev;
+ /* freeing irq */
+ free_irq(dev->interrupt_number,sdev);
+//request_irq_error:
+ /* delete the cdev structure */
+ cdev_del(&sdev->cdev);
+ PDEBUG("%s:cdev deleted\n",dev->name);
+//error_cdev_add:
+ /* free major and minor number */
+ unregister_chrdev_region(sdev->devno,1);
+ printk(KERN_INFO "%s: Led deleted\n",dev->name);
+//error_devno:
+//error_name_copy:
+ kfree(sdev->name);
+//error_name_alloc:
+ kfree(sdev);
+//error_sdev_alloc:
+ printk(KERN_INFO "%s: deleted with success\n", dev->name);
+//error_id:
+ return 0;
+
+}
+
+static struct platform_driver plat_button_driver =
+{
+ .probe = button_probe,
+ .remove = __devexit_p(button_remove),
+ .driver =
+ {
+ .name = "button",
+ .owner = THIS_MODULE,
+ },
+};
+
+/**********************************
+ * Module management
+ **********************************/
+static int __init button_init(void)
+{
+ int ret;
+
+ PDEBUG("Platform driver name %s",plat_button_driver.driver.name);
+ ret = platform_driver_register(&plat_button_driver);
+ if (ret) {
+ printk(KERN_ERR "Platform driver register error\n");
+ return ret;
+ }
+ return 0;
+}
+
+static void __exit button_exit(void)
+{
+ platform_driver_unregister(&plat_button_driver);
+}
+
+module_init(button_init);
+module_exit(button_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Fabien Marteau <fab...@ar...> "
+ "- ARMadeus Systems");
+MODULE_DESCRIPTION("button device generic driver");
+
+
Modified: trunk/target/linux/modules/fpga/wishbone_example/wb_button/testbutton.c
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/wb_button/testbutton.c 2009-03-03 16:03:26 UTC (rev 1108)
+++ trunk/target/linux/modules/fpga/wishbone_example/wb_button/testbutton.c 2009-03-03 16:20:44 UTC (rev 1109)
@@ -1,5 +1,3 @@
-
- * ***********************************************************************
/* a program to write/read values on fpga address map
* Fabien Marteau <fab...@ar...>
* 7 april 2008
@@ -27,10 +25,6 @@
**********************************************************************
*/
-
- *
- */
-
#include <stdio.h>
#include <stdlib.h>
@@ -63,7 +57,7 @@
printf( "Testing button driver\n" );
if(argc < 2){
- perror("invalid arguments number\ntestled <button_filename>\n");
+ perror("invalide arguments number\ntestled <button_filename>\n");
exit(EXIT_FAILURE);
}
@@ -93,3 +87,4 @@
close(fled);
exit(0);
}
+
Added: trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/Kconfig
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/Kconfig (rev 0)
+++ trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/Kconfig 2009-03-03 16:20:44 UTC (rev 1109)
@@ -0,0 +1,14 @@
+
+#
+# Armadeus custom drivers configuration
+#
+#
+
+#
+config ARMADEUS_WISHBONE_EXAMPLE_IRQ_MNGR_DRIVER
+ tristate "IRQ manager with wishbone interface"
+ default m
+ depends on ARMADEUS_WISHBONE_EXAMPLE_DRIVERS
+ ---help---
+
+
Added: trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/Makefile (rev 0)
+++ trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/Makefile 2009-03-03 16:20:44 UTC (rev 1109)
@@ -0,0 +1,34 @@
+#
+# Makefile for the Armadeus FPGA OpenCore IRQ manager IP
+#
+
+ifneq ($(KERNELRELEASE),)
+
+# Part executed when called from kernel build system:
+
+obj-$(CONFIG_ARMADEUS_WISHBONE_EXAMPLE_IRQ_MNGR_DRIVER) += irq_ocore.o test.o
+irq_ocore-objs := main.o
+
+else
+
+ARMADEUS_BASE_DIR=../../../../../..
+include $(ARMADEUS_BASE_DIR)/Makefile.in
+
+KDIR := $(ARMADEUS_LINUX_DIR)
+PWD := $(shell pwd)
+
+default:
+ $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
+
+clean:
+ rm -f *.*o \
+ rm -f *.mod.c \
+ rm -f *.cmd \
+ rm -f *.o.d \
+ rm -f *.order \
+ rm -f .*.cmd \
+ rm -rf .tmp_versions \
+ rm -f Module.symvers
+
+endif
+
Property changes on: trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/Makefile
___________________________________________________________________
Added: svn:executable
+ *
Added: trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/README
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/README (rev 0)
+++ trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/README 2009-03-03 16:20:44 UTC (rev 1109)
@@ -0,0 +1,8 @@
+To compile this driver from here:
+---------------------------------
+ make ARCH=arm CROSS_COMPILE=$PWD/../../../../../buildroot/build_arm/staging_dir/bin/arm-linux-
+
+To install this driver:
+-----------------------
+Copy resulting *.ko files on your target rootfs
+
Added: trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/main.c
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/main.c (rev 0)
+++ trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/main.c 2009-03-03 16:20:44 UTC (rev 1109)
@@ -0,0 +1,192 @@
+/*
+ * Driver for the IRQ manager loaded in FPGA of the Armadeus boards
+ *
+ * (C) Copyright 2008 Armadeus Systems
+ * Author: Julien Boibessot <jul...@ar...>
+ *
+ * Inspired of linux/arch/arm/mach-imx/irq.c
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+# include <asm/hardware.h>
+# include <asm/arch/irqs.h>
+#else
+# include <mach/hardware.h>
+# include <mach/irqs.h>
+#endif
+#include <asm/irq.h>
+#include <asm/io.h> // readb() & Co
+
+#include <asm/mach/irq.h>
+
+#if 0
+#define DEBUG_FPGA_IRQ(fmt,args...) printk(KERN_DEBUG "IRQ_MNGR: " fmt,##args)
+#else
+#define DEBUG_FPGA_IRQ(fmt...) do { } while (0)
+#endif
+
+#define IRQ_MNGR_BASE (0x0)
+#define ID (1)
+#define ID_OFFSET (0x02 *(16/8))
+
+
+#define NB_IT (16)
+
+#define FPGA_IMR (APF9328_FPGA_VIRT + IRQ_MNGR_BASE + 0x00) /* Interrupt Mask Register */
+#define FPGA_ISR (APF9328_FPGA_VIRT + IRQ_MNGR_BASE + 0x02) /* Interrupt Status Register */
+
+
+static int
+imx_fpga_irq_type(unsigned int _irq, unsigned int type)
+{
+ return 0;
+}
+
+static void
+imx_fpga_ack_irq(unsigned int irq)
+{
+ int shadow;
+
+ shadow = 1 << ((irq - IRQ_FPGA_START) % NB_IT);
+ DEBUG_FPGA_IRQ("%s: irq %d ack:0x%x\n", __FUNCTION__, irq, shadow);
+ writew( shadow, FPGA_ISR );
+
+ /* if last IT ack GPIO global IRQ */
+ if( readw(FPGA_ISR) == 0 )
+ ISR(IRQ_TO_REG(APF9328_FPGA_IRQ)) = 1 << (APF9328_FPGA_IRQ - IRQ_GPIOA(0));
+}
+
+static void
+imx_fpga_mask_irq(unsigned int irq)
+{
+ int shadow;
+
+ shadow = readw(FPGA_IMR);
+ shadow &= ~( 1 << ((irq - IRQ_FPGA_START) % NB_IT));
+ DEBUG_FPGA_IRQ("%s: irq %d mask:0x%x\n", __FUNCTION__, irq, shadow);
+ writew( shadow, FPGA_IMR );
+}
+
+static void
+imx_fpga_unmask_irq(unsigned int irq)
+{
+ int shadow;
+
+ shadow = readw(FPGA_IMR);
+ shadow |= 1 << ((irq - IRQ_FPGA_START) % NB_IT);
+ DEBUG_FPGA_IRQ("%s: irq %d mask:0x%x\n", __FUNCTION__, irq, shadow);
+ writew( shadow, FPGA_IMR );
+}
+
+static void
+imx_fpga_handler(unsigned int mask, unsigned int irq,
+ struct irq_desc *desc)
+{
+ DEBUG_FPGA_IRQ("%s: mask:0x%x\n", __FUNCTION__, mask);
+ desc = irq_desc + irq;
+ while (mask) {
+ if (mask & 1) {
+ DEBUG_FPGA_IRQ("handling irq %d\n", irq);
+ desc_handle_irq(irq, desc);
+ }
+ irq++;
+ desc++;
+ mask >>= 1;
+ }
+}
+
+static void
+imx_fpga_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
+{
+ unsigned int mask, irq;
+
+ mask = readw(FPGA_ISR);
+ irq = IRQ_FPGA_START;
+ imx_fpga_handler(mask, irq, desc);
+}
+
+static struct irq_chip imx_fpga_chip = {
+ .name = "FPGA",
+ .ack = imx_fpga_ack_irq,
+ .mask = imx_fpga_mask_irq,
+ .unmask = imx_fpga_unmask_irq,
+ .set_type = imx_fpga_irq_type,
+};
+
+
+static int __init ocore_irq_mng_init(void)
+{
+ unsigned int irq;
+ u16 data;
+ int result=0;
+
+ DEBUG_FPGA_IRQ("Initializing FPGA IRQs\n");
+
+ /**************************/
+ /* check if ID is correct */
+ /**************************/
+ data = ioread16(APF9328_FPGA_VIRT+IRQ_MNGR_BASE+ID_OFFSET);
+ if(data != ID)
+ {
+ result = -1;
+ printk(KERN_WARNING "For irq_mngr id:%d doesn't match with id read %d,\n is device present ?\n",ID,data);
+ goto error_id;
+ }
+
+ /* Mask all interrupts initially */
+ writew(0, FPGA_IMR);
+
+ for (irq = IRQ_FPGA(0); irq < IRQ_FPGA(NB_IT-1); irq++) {
+ set_irq_chip_and_handler( irq, &imx_fpga_chip, handle_edge_irq );
+ set_irq_flags(irq, IRQF_VALID);
+ }
+ set_irq_chained_handler(APF9328_FPGA_IRQ, imx_fpga_demux_handler);
+
+ DEBUG_FPGA_IRQ("IRQs initialized\n");
+
+ return 0;
+error_id:
+ return result;
+}
+
+static void __exit ocore_irq_mng_exit(void)
+{
+ unsigned int irq;
+ for (irq = IRQ_FPGA(0); irq < IRQ_FPGA(NB_IT-1); irq++) {
+ set_irq_chip( irq, NULL);
+ set_irq_handler(irq,NULL);
+ set_irq_flags(irq, 0);
+ }
+ set_irq_chained_handler(APF9328_FPGA_IRQ, NULL);
+
+ DEBUG_FPGA_IRQ("%s\n", __FUNCTION__);
+}
+
+module_init(ocore_irq_mng_init);
+module_exit(ocore_irq_mng_exit);
+
+MODULE_AUTHOR("Julien Boibessot, <jul...@ar...>");
+MODULE_DESCRIPTION("Armadeus OpenCore IRQ manager");
+MODULE_LICENSE("GPL");
Added: trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/test.c
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/test.c (rev 0)
+++ trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/test.c 2009-03-03 16:20:44 UTC (rev 1109)
@@ -0,0 +1,81 @@
+/*
+ * Driver to test OpenCore IRQ manager driver
+ *
+ * Copyright (C) 2008 Armadeus Systems
+ * Author: Julien Boibessot <jul...@ar...>
+ *
+ * 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, 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/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+#include <linux/config.h>
+#endif
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+
+
+/* Module's parameters: */
+static int interrupt=IRQ_FPGA(3);
+module_param(interrupt, int, 0000);
+MODULE_PARM_DESC(interrupt, "IT to request");
+
+#define DRIVER_NAME "IRQ test module"
+
+
+static irqreturn_t fpga_interrupt(int irq,void *dev_id,struct pt_regs *reg)
+{
+ printk(KERN_ERR "FPGA IT n°%d\n", irq);
+
+ return IRQ_HANDLED;
+}
+
+unsigned int data;
+
+static int __init irq_mng_test_init(void)
+{
+ int result;
+
+ /* IRQ registering */
+ if( (result=request_irq( interrupt, (irq_handler_t)fpga_interrupt, /*IRQF_SHARED*/0, "ocore_irq_test", &data)) < 0 )
+ {
+ printk(KERN_ERR "Can't request IRQ n°%d\n", interrupt);
+ goto error;
+ }
+
+ printk(KERN_INFO DRIVER_NAME " inserted (IRQ %d reserved), be sure to have correspondig IP loaded in the FPGA !\n", interrupt);
+ return 0;
+
+error:
+ return result;
+}
+
+static void __exit irq_mng_test_exit(void)
+{
+ printk(DRIVER_NAME " unloaded\n");
+ free_irq(interrupt, 0); /* still a bug here ! */
+}
+
+
+module_init(irq_mng_test_init);
+module_exit(irq_mng_test_exit);
+
+MODULE_AUTHOR("Julien Boibessot, <jul...@ar...>");
+MODULE_DESCRIPTION("OpenCore IRQ manager IP's test driver");
+MODULE_LICENSE("GPL");
Added: trunk/target/linux/modules/fpga/wishbone_example/wb_led/Kconfig
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/wb_led/Kconfig (rev 0)
+++ trunk/target/linux/modules/fpga/wishbone_example/wb_led/Kconfig 2009-03-03 16:20:44 UTC (rev 1109)
@@ -0,0 +1,9 @@
+#
+#
+
+config ARMADEUS_WISHBONE_EXAMPLE_LED_DRIVER
+ tristate "Wishbone Led driver"
+ default m
+ depends on ARMADEUS_WISHBONE_EXAMPLE_DRIVERS
+ ---help---
+ blink a led
Added: trunk/target/linux/modules/fpga/wishbone_example/wb_led/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/wb_led/Makefile (rev 0)
+++ trunk/target/linux/modules/fpga/wishbone_example/wb_led/Makefile 2009-03-03 16:20:44 UTC (rev 1109)
@@ -0,0 +1,36 @@
+#
+# Makefile for the Armadeus FPGA led driver
+#
+
+ifneq ($(KERNELRELEASE),)
+
+obj-$(CONFIG_ARMADEUS_WISHBONE_EXAMPLE_LED_DRIVER) += board_leds.o g_led.o
+
+else
+
+ARMADEUS_BASE_DIR=../../../../../..
+include $(ARMADEUS_BASE_DIR)/Makefile.in
+
+KDIR := $(ARMADEUS_LINUX_DIR)
+PWD := $(shell pwd)
+
+
+default:
+ $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
+
+test:
+ ~/armadeus/buildroot/build_arm/staging_dir/bin/arm-linux-gcc -Wall testled.c -o testled
+ chmod 755 testled
+
+clean:
+ rm -f *.*o \
+ rm -f *.mod.c \
+ rm -f *.cmd \
+ rm -f *.o.d \
+ rm -f *.order \
+ rm -f .*.cmd \
+ rm -rf .tmp_versions \
+ rm -f Module.symvers
+
+endif
+
Property changes on: trunk/target/linux/modules/fpga/wishbone_example/wb_led/Makefile
___________________________________________________________________
Added: svn:executable
+ *
Added: trunk/target/linux/modules/fpga/wishbone_example/wb_led/board_leds.c
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/wb_led/board_leds.c (rev 0)
+++ trunk/target/linux/modules/fpga/wishbone_example/wb_led/board_leds.c 2009-03-03 16:20:44 UTC (rev 1109)
@@ -0,0 +1,83 @@
+/*
+ ***********************************************************************
+ *
+ * (c) Copyright 2008 Armadeus project
+ * Fabien Marteau <fab...@ar...>
+ * Specific led driver for generic led driver
+ *
+ * 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, 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/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+#include <linux/config.h>
+#endif
+
+/* form module/drivers */
+#include <linux/init.h>
+#include <linux/module.h>
+
+/* for platform device */
+#include <linux/platform_device.h>
+
+#include"led.h"
+
+static struct plat_led_port plat_led0_data = {
+ .name = "LED0",
+ .num=0,
+ .membase = (void *)(ARMADEUS_FPGA_BASE_ADDR_VIRT + 0x8),
+ .idnum=2,
+ .idoffset=0x01 * (16 /8)
+};
+
+
+void plat_led_release(struct device *dev){
+ PDEBUG("device %s .released\n",dev->bus_id);
+}
+
+static struct platform_device plat_led0_device = {
+ .name = "led",
+ .id=0,
+ .dev={
+ .release = plat_led_release,
+ .platform_data=&plat_led0_data},
+};
+
+
+static int __init sled_init(void)
+{
+ int ret=-1;
+ ret = platform_device_register(&plat_led0_device);
+ if(ret<0)return ret;
+
+ PDEBUG("*led inserted*\n");
+ return ret;
+}
+
+static void __exit sled_exit(void)
+{
+ printk(KERN_WARNING "deleting board_leds\n");
+ platform_device_unregister(&plat_led0_device);
+
+}
+
+module_init(sled_init);
+module_exit(sled_exit);
+
+MODULE_AUTHOR("Fabien Marteau <fab...@ar...>");
+MODULE_DESCRIPTION("Driver to blink blink some leds");
+MODULE_LICENSE("GPL");
+
Added: trunk/target/linux/modules/fpga/wishbone_example/wb_led/g_led.c
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/wb_led/g_led.c (rev 0)
+++ trunk/target/linux/modules/fpga/wishbone_example/wb_led/g_led.c 2009-03-03 16:20:44 UTC (rev 1109)
@@ -0,0 +1,360 @@
+/*
+ ***********************************************************************
+ *
+ * (c) Copyright 2008 Armadeus project
+ * Fabien Marteau <fab...@ar...>
+ * Generic driver for Wishbone led IP
+ *
+ * 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, 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/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+#include <linux/config.h>
+#endif
+
+/* form module/drivers */
+#include <linux/init.h>
+#include <linux/module.h>
+
+/* for file operations */
+#include <linux/fs.h>
+#include <linux/cdev.h>
+
+/* copy_to_user function */
+#include <asm/uaccess.h>
+
+/* request_mem_region */
+#include <linux/ioport.h>
+
+/* readw() writew() */
+#include <asm/io.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+/* hardware addresses */
+# include <asm/hardware.h>
+#else
+# include <mach/hardware.h>
+#endif
+
+
+/* for platform device */
+#include <linux/platform_device.h>
+
+/* led */
+#include "led.h"
+
+
+/* for debugging messages*/
+//#define LED_DEBUG
+
+#undef PDEBUG
+#ifdef LED_DEBUG
+# ifdef __KERNEL__
+/* for kernel spage */
+# define PDEBUG(fmt,args...) printk(KERN_DEBUG "LED : " fmt, ##args)
+# else
+/* for user space */
+# define PDEBUG(fmt,args...) printk(stderr, fmt, ##args)
+# endif
+#else
+# define PDEBUG(fmt,args...) /* no debbuging message */
+#endif
+
+/*************************/
+/* main device structure */
+/*************************/
+struct led_dev{
+ char *name; /* the name of the instance */
+ int loaded_led_num;/* number of the led, depends on load order*/
+ struct cdev cdev;/* Char device structure */
+ void * membase; /* base address for instance */
+ dev_t devno; /* to store Major and minor numbers */
+};
+
+/******************************/
+/* to read write led register */
+/******************************/
+ssize_t led_read(struct file *fildes, char __user *buff,
+ size_t count, loff_t *offp);
+
+ssize_t led_write(struct file *fildes, const char __user *
+ buff,size_t count, loff_t *offp);
+int led_open(struct inode *inode, struct file *filp);
+
+int led_release(struct inode *, struct file *filp);
+
+struct file_operations led_fops = {
+ .owner = THIS_MODULE,
+ .read = led_read,
+ .write = led_write,
+ .open = led_open,
+ .release = led_release,
+};
+
+/***********************************
+ * characters file /dev operations
+ * *********************************/
+ssize_t led_read(struct file *fildes, char __user *buff,
+ size_t count, loff_t *offp){
+ struct led_dev *sdev = fildes->private_data;
+ u16 data=0;
+ PDEBUG("Read value\n");
+ if(*offp != 0 ){ /* offset must be 0 */
+ PDEBUG("offset %d\n",(int)*offp);
+ return 0;
+ }
+
+ PDEBUG("count %d\n",count);
+ if(count > 2){ /* 16bits max*/
+ count = 2;
+ }
+
+ data = ioread16(sdev->membase+LED_REG_OFFSET);
+ PDEBUG("Read %d at %x\n",data,(int)(sdev->membase+LED_REG_OFFSET));
+
+ /* return data for user */
+ if(copy_to_user(buff,&data,count)){
+ printk(KERN_WARNING "read : copy to user data error\n");
+ return -EFAULT;
+ }
+ return count;
+}
+
+ssize_t led_write(struct file *fildes, const char __user *
+ buff,size_t count, loff_t *offp){
+ struct led_dev *sdev = fildes->private_data;
+ u16 data=0;
+
+ if(*offp != 0){ /* offset must be 0 */
+ PDEBUG("offset %d\n",(int)*offp);
+ return 0;
+ }
+
+ PDEBUG("count %d\n",count);
+ if(count > 2){ /* 16 bits max)*/
+ count = 2;
+ }
+
+ if(copy_from_user(&data,buff,count)){
+ printk(KERN_WARNING "write : copy from user error\n");
+ return -EFAULT;
+ }
+
+ PDEBUG("Write %d at %x\n",
+ data,
+ (int)(sdev->membase+LED_REG_OFFSET));
+ iowrite16(data,sdev->membase+LED_REG_OFFSET);
+
+ return count;
+}
+
+int led_open(struct inode *inode, struct file *filp){
+ /* Allocate and fill any data structure to be put in filp->private_data */
+ filp->private_data = container_of(inode->i_cdev,struct led_dev, cdev);
+ PDEBUG( "Led opened\n");
+ return 0;
+}
+
+/* ******************************
+ * Init and release functions
+ * ******************************/
+int led_release(struct inode *inode, struct file *filp)
+{
+ struct led_dev *dev;
+
+ dev = container_of(inode->i_cdev,struct led_dev,cdev);
+ PDEBUG( "%s: released\n",dev->name);
+ filp->private_data=NULL;
+
+ return 0;
+}
+
+/**********************************
+ * driver probe
+ **********************************/
+static int led_probe(struct platform_device *pdev)
+{
+ struct plat_led_port *dev = pdev->dev.platform_data;
+
+ int result = 0; /* error return */
+ int led_major,led_minor;
+ u16 data;
+ struct led_dev *sdev;
+
+ PDEBUG("Led probing\n");
+ PDEBUG("Register %s num %d\n",dev->name,dev->num);
+
+ /**************************/
+ /* check if ID is correct */
+ /**************************/
+ data = ioread16(dev->membase+dev->idoffset);
+ if(data != dev->idnum){
+ result = -1;
+ printk(KERN_WARNING "For %s id:%d doesn't match with "
+ "id read %d,\n is device present ?\n",
+ dev->name,dev->idnum,data);
+ goto error_id;
+ }
+
+ /********************************************/
+ /* allocate memory for sdev structure */
+ /********************************************/
+ sdev = kmalloc(sizeof(struct led_dev),GFP_KERNEL);
+ if(!sdev){
+ result = -ENOMEM;
+ goto error_sdev_alloc;
+ }
+ dev->sdev = sdev;
+ sdev->membase = dev->membase;
+ sdev->name = (char *)kmalloc((1+strlen(dev->name))*sizeof(char),
+ GFP_KERNEL);
+ if (sdev->name == NULL) {
+ printk("Kmalloc name space error\n");
+ goto error_name_alloc;
+ }
+ if (strncpy(sdev->name,dev->name,1+strlen(dev->name)) < 0) {
+ printk("copy error");
+ goto error_name_copy;
+ }
+
+ /******************************************/
+ /* Get the major and minor device numbers */
+ /******************************************/
+
+ led_major = 252;
+ led_minor = dev->num ;/* num come from plat_led_port data structure */
+
+ PDEBUG("%s:Get the major and minor device numbers\n",dev->name);
+ if (led_major) {
+ sdev->devno = MKDEV(led_major, led_minor);
+ result = register_chrdev_region(sdev->devno, 1,dev->name);
+ } else {
+ result = alloc_chrdev_region(&sdev->devno, led_minor, 1, dev->name);
+ led_major = MAJOR(sdev->devno);
+ }
+ if (result < 0) {
+ printk(KERN_WARNING "%s: can't get major %d\n",dev->name,led_major);
+ goto error_devno;
+ }
+ printk(KERN_INFO "%s: MAJOR: %d MINOR: %d\n",
+ dev->name,
+ MAJOR(sdev->devno),
+ MINOR(sdev->devno));
+
+ /****************************/
+ /* Init the cdev structure */
+ /****************************/
+ PDEBUG("Init the cdev structure\n");
+ cdev_init(&sdev->cdev, &led_fops);
+ sdev->cdev.owner = THIS_MODULE;
+ sdev->cdev.ops = &led_fops;
+
+ /* Add the device to the kernel, connecting cdev to major/minor number */
+ PDEBUG("%s:Add the device to the kernel, "
+ "connecting cdev to major/minor number \n", dev->name);
+ result = cdev_add(&sdev->cdev, sdev->devno, 1);
+ if (result) {
+ printk(KERN_WARNING "%s: can't add cdev\n", dev->name);
+ goto error_cdev_add;
+ }
+
+ /* initialize led value */
+ data=1;
+ iowrite16(data,sdev->membase);
+ PDEBUG("Wrote %x at %x\n", data,(int)( sdev->membase+LED_REG_OFFSET));
+
+ /* OK module inserted ! */
+ printk(KERN_INFO "Led module %s insered\n", dev->name);
+ return 0;
+
+ /*********************/
+ /* Errors management */
+ /*********************/
+ /* delete the cdev structure */
+ cdev_del(&sdev->cdev);
+ PDEBUG("%s:cdev deleted\n",dev->name);
+error_cdev_add:
+ /* free major and minor number */
+ unregister_chrdev_region(sdev->devno,1);
+ printk(KERN_INFO "%s: Led deleted\n",dev->name);
+error_devno:
+error_name_copy:
+ kfree(sdev->name);
+error_name_alloc:
+ kfree(sdev);
+error_sdev_alloc:
+ printk(KERN_ERR "%s: not inserted\n", dev->name);
+error_id:
+ return result;
+}
+
+static int __devexit led_remove(struct platform_device *pdev)
+{
+ struct plat_led_port *dev = pdev->dev.platform_data;
+ struct led_dev *sdev = (*dev).sdev;
+ PDEBUG("Unregister %s, number %d\n",dev->name,dev->num);
+ /* delete the cdev structure */
+ PDEBUG("cdev name : %s\n",sdev->name);
+ cdev_del(&sdev->cdev);
+ PDEBUG("%s:cdev deleted\n",dev->name);
+ /*error_cdev_add:*/
+ /* free major and minor number */
+ unregister_chrdev_region(sdev->devno,1);
+ /*error_devno:*/
+ /*error_name_copy:*/
+ kfree(sdev->name);
+ /*error_name_alloc:*/
+ kfree(sdev);
+ /*error_sdev_alloc:*/
+ printk(KERN_INFO "%s: deleted with success\n", dev->name);
+ return 0;
+}
+
+static struct platform_driver plat_led_driver = {
+ .probe = led_probe,
+ .remove = __devexit_p(led_remove),
+ .driver = {
+ .name = "led",
+ .owner = THIS_MODULE,
+ },
+};
+
+/**********************************
+ * Module management
+ **********************************/
+static int __init led_init(void)
+{
+ int ret;
+
+ PDEBUG("Platform driver name %s\n", plat_led_driver.driver.name);
+ ret = platform_driver_register(&plat_led_driver);
+ return ret;
+}
+
+static void led_exit(void)
+{
+ platform_driver_unregister(&plat_led_driver);
+ PDEBUG("driver unregistered\n");
+}
+
+module_init(led_init);
+module_exit(led_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Fabien Marteau <fab...@ar...>-ARMadeus Systems");
+MODULE_DESCRIPTION("Led device driver");
+
Added: trunk/target/linux/modules/fpga/wishbone_example/wb_led/led.h
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/wb_led/led.h (rev 0)
+++ trunk/target/linux/modules/fpga/wishbone_example/wb_led/led.h 2009-03-03 16:20:44 UTC (rev 1109)
@@ -0,0 +1,98 @@
+/*
+ ***********************************************************************
+ *
+ * (c) Copyright 2007 Armadeus project
+ * Fabien Marteau <fab...@ar...>
+ * Driver for Wishbone led IP
+ *
+ * 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, 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.
+ **********************************************************************
+ */
+
+
+#ifndef __LED_H__
+#define __LED_H__
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+#include <linux/config.h>
+#endif
+
+/* form module/drivers */
+#include <linux/init.h>
+#include <linux/module.h>
+
+/* for file operations */
+#include <linux/fs.h>
+#include <linux/cdev.h>
+
+/* copy_to_user function */
+#include <asm/uaccess.h>
+
+/* request_mem_region */
+#include <linux/ioport.h>
+
+/* readw() writew() */
+#include <asm/io.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+/* hardware addresses */
+# include <asm/hardware.h>
+#else
+# include <mach/hardware.h>
+#endif
+
+
+/* for platform device */
+#include <linux/platform_device.h>
+
+#endif
+
+/* for debugging messages*/
+#define LED_DEBUG
+
+#undef PDEBUG
+#ifdef LED_DEBUG
+# ifdef __KERNEL__
+ /* for kernel spage */
+# define PDEBUG(fmt,args...) printk(KERN_DEBUG "LED : " fmt, ##args)
+# else
+ /* for user space */
+# define PDEBUG(fmt,args...) printk(stderr, fmt, ##args)
+# endif
+#else
+# define PDEBUG(fmt,args...) /* no debbuging message */
+#endif
+
+
+#define FPGA_BASE_ADDR IMX_CS1_PHYS
+#define FPGA_MEM_SIZE IMX_CS1_SIZE
+
+#define LED_NUMBER 1
+
+#define LED_REG_OFFSET (0x00)
+#define LED_ID_OFFSET (0x02)
+
+/* platform device */
+struct plat_led_port{
+ const char *name; /* instance name */
+ int num; /* instance number */
+ void *membase; /* virtual base address */
+ int idnum; /* identity number */
+ int idoffset; /* identity relative address */
+ struct led_dev *sdev; /* struct for main device structure*/
+};
+
+
Added: trunk/target/linux/modules/fpga/wishbone_example/wb_led/s_led.c
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/wb_led/s_led.c (rev 0)
+++ trunk/target/linux/modules/fpga/wishbone_example/wb_led/s_led.c 2009-03-03 16:20:44 UTC (rev 1109)
@@ -0,0 +1,77 @@
+/*
+ ***********************************************************************
+ *
+ * (c) Copyright 2008 Armadeus project
+ * Fabien Marteau <fab...@ar...>
+ * Specific led driver for generic led driver
+ *
+ * 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, 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/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+#include <linux/config.h>
+#endif
+
+/* form module/drivers */
+#include <linux/init.h>
+#include <linux/module.h>
+
+/* for platform device */
+#include <linux/platform_device.h>
+
+#include"led.h"
+
+
+static struct plat_led_port plat_led_data[] = {
+ {
+ .name = "led0",
+ .num = 0,
+ .membase = 0x04
+ },
+ {
+ .name = "led1",
+ .num = 1,
+ .membase = 0x06
+ },
+ { },
+};
+
+static struct platform_device plat_led_device = {
+ .name = "led",
+ .id = 0,
+ .dev = {
+ .platform_data = plat_led_data
+ },
+};
+
+static int __init sled_init(void)
+{
+ return platform_device_register(&plat_led_device);
+}
+
+static void __exit sled_exit(void)
+{
+ platform_device_unregister(&plat_led_device);
+}
+
+module_init(sled_init);
+module_exit(sled_exit);
+
+MODULE_AUTHOR("Fabien Marteau <fab...@ar...>");
+MODULE_DESCRIPTION("Driver to blink blink some leds");
+MODULE_LICENSE("GPL");
+
Added: trunk/target/linux/modules/fpga/wishbone_example/wb_led/testled.c
===================================================================
--- trunk/target/linux/modules/fpga/wishbone_example/wb_led/testled.c (rev 0)
+++ trunk/target/linux/modules/fpga/wishbone_example/wb_led/testled.c 2009-03-03 16:20:44 UTC (rev 1109)
@@ -0,0 +1,132 @@
+/* a program to write/read values on fpga address map
+ * Fabien Marteau <fab...@ar...>
+ * 7 april 2008
+ * fpgaaccess.h
+ *
+ * (c) Copyright 2008 Armadeus project
+ * Fabien Marteau <fab...@ar...>
+ *
+ * A simple driver for reading and writing on
+ * fpga throught a character file /dev/fpgaaccess
+ *
+ * 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, 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 <stdio.h>
+#include <stdlib.h>
+
+/* file management */
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/* as name said */
+#include <signal.h>
+
+/* sleep */
+#include <unistd.h>
+
+int fled;
+
+void quit(int pouet){
+ close(fled);
+ exit(0);
+}
+
+int main(int argc, char *argv[])
+{
+ unsigned short i,j;
+
+ /* quit when Ctrl-C pressed */
+ signal(SIGINT, quit);
+
+ j=0;
+
+ printf( "Testing led driver\n" );
+
+ if(argc < 2){
+ perror("invalid arguments number\ntestled <led_filename>\n");
+ exit(EXIT_FAILURE);
+ }
+
+ while(1){
+ i = (i==0)?1:0;
+ fflush(stdout);
+
+ fled=open(argv[1],O_RDWR);
+ if(fled<0){
+ perror("can't open file \n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* read value */
+ if(read(fled,&j,2)<0){
+ perror("read error\n");
+ exit(EXIT_FAILURE);
+ }
+ printf("Read %d\n",j);
+ close(fled);
+ sleep(1);
+
+ fled=open(argv[1],O_RDWR);
+ if(fled<0){
+ perror("can't open file \n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* write value */
+ j = 0;
+ if(write(fled,&j,2)<=0){
+ perror("write error\n");
+ exit(EXIT_FAILURE);
+ }
+ close(fled);
+ printf("Write 0\n");
+ sleep(1);
+
+ fled=open(argv[1],O_RDWR);
+ if(fled<0){
+ perror("can't open file \n");
+ exit(EXIT_FAILURE);
+ }
+ /* read value */
+ if(read(fled,&j,2)<0){
+ perror("read error\n");
+ exit(EXIT_FAILURE);
+ }
+ close(fled);
+ printf("Read %d\n",j);
+ sleep(1);
+
+ fled=open(argv[1],O_RDWR);
+ if(fled<0){
+ perror("can't open file \n");
+ exit(EXIT_FAILURE);
+ }
+ /* write value */
+ j = 1;
+ if(write(fled,&j,2)<=0){
+ perror("write error\n");
+ exit(EXIT_FAILURE);
+ }
+ close(fled);
+ printf("Write 1\n");
+ sleep(1);
+
+ }
+
+ close(fled);
+ exit(0);
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|