[Armadeus-commitlog] SF.net SVN: armadeus: [766] trunk/target/linux/modules
Brought to you by:
sszy
|
From: <Fa...@us...> - 2008-03-04 09:11:07
|
Revision: 766
http://armadeus.svn.sourceforge.net/armadeus/?rev=766&view=rev
Author: FabM
Date: 2008-03-04 01:11:14 -0800 (Tue, 04 Mar 2008)
Log Message:
-----------
[TARGET] driver for bus_led IP
Added Paths:
-----------
trunk/target/linux/modules/led/
trunk/target/linux/modules/led/Kconfig
trunk/target/linux/modules/led/Makefile
trunk/target/linux/modules/led/README
trunk/target/linux/modules/led/TODO
trunk/target/linux/modules/led/led.c
trunk/target/linux/modules/led/led.h
Added: trunk/target/linux/modules/led/Kconfig
===================================================================
--- trunk/target/linux/modules/led/Kconfig (rev 0)
+++ trunk/target/linux/modules/led/Kconfig 2008-03-04 09:11:14 UTC (rev 766)
@@ -0,0 +1,8 @@
+#
+#
+
+config ARMADEUS_LED_DRIVER
+ tristate "Led driver"
+ default n
+ depends on ARMADEUS_DRIVERS
+ ---help---
Added: trunk/target/linux/modules/led/Makefile
===================================================================
--- trunk/target/linux/modules/led/Makefile (rev 0)
+++ trunk/target/linux/modules/led/Makefile 2008-03-04 09:11:14 UTC (rev 766)
@@ -0,0 +1,32 @@
+#
+# Makefile for the Armadeus bus_led drivers
+#
+
+# Part executed when called from kernel build system:
+ifneq ($(KERNELRELEASE),)
+
+obj-$(CONFIG_ARMADEUS_GPIO_DRIVER) += led.o
+
+led := led.o
+
+# Part executed when called from standard make in this directory:
+# (preferably use Makefile in parent directory)
+else
+
+BASE_DIR="../../../../buildroot/"
+REL=`grep "BR2_PACKAGE_LINUX_VERSION=" $(BASE_DIR).config | \
+ sed "s/BR2_PACKAGE_LINUX_VERSION=\\"//" | sed "s/\\"//"`
+ARMADEUS_KERNEL_DIR=$(BASE_DIR)build_arm/linux-$(REL)
+KDIR := $(ARMADEUS_KERNEL_DIR)
+PWD := $(shell pwd)
+
+default:
+ $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
+ cp led.ko /tftpboot/
+
+clean:
+ rm -f *.*o \
+ rm -f Module.symvers
+
+endif
+
Property changes on: trunk/target/linux/modules/led/Makefile
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/target/linux/modules/led/README
===================================================================
--- trunk/target/linux/modules/led/README (rev 0)
+++ trunk/target/linux/modules/led/README 2008-03-04 09:11:14 UTC (rev 766)
@@ -0,0 +1,16 @@
+Driver for fpga IP bus_led -> armadeus/firmware/led/
+Fabien Marteau <fab...@ar...>
+
+To use it configure fpga with bus_led then insert led.ko with insmod :
+>insmod led.ko
+
+watch dmesg :
+LED: MAJOR: 253 MINOR: 0
+Led module insered
+
+then make a character file with wright major and minor number :
+>mknod led c 253 0
+
+Then led can be switched on/off writing a character in nod file,
+only LSB will switch led, 1 will switch off led and 0 will
+witch on. To read value, just read the file.
Added: trunk/target/linux/modules/led/TODO
===================================================================
--- trunk/target/linux/modules/led/TODO (rev 0)
+++ trunk/target/linux/modules/led/TODO 2008-03-04 09:11:14 UTC (rev 766)
@@ -0,0 +1 @@
+ - a proper sysfs entry
Added: trunk/target/linux/modules/led/led.c
===================================================================
--- trunk/target/linux/modules/led/led.c (rev 0)
+++ trunk/target/linux/modules/led/led.c 2008-03-04 09:11:14 UTC (rev 766)
@@ -0,0 +1,173 @@
+/* Driver for bus_led IP
+ * Fabien Marteau <fab...@ar...>
+ * 4 march 2008
+ */
+
+#include "led.h"
+
+ssize_t led_read(struct file *fildes, char __user *buff, size_t count, loff_t *offp){
+ struct led_dev *ldev = fildes->private_data;
+ void * virt_addr;
+ u16 data=0;
+ ssize_t retval = 0;
+
+ PDEBUG( "offset %d, count %d\n",(int)*offp,(int)count);
+ if(down_interruptible(&ldev->sem)) /* take mutex */
+ return -ERESTARTSYS;
+ if(*offp >= 1){ /* offset must be 0 or 1 */
+ goto out;
+ }
+ if(*offp + count >= 1) /* Only one word can be read */
+ count = 1 - *offp;
+
+ virt_addr = ioremap(IMX_CS1_PHYS,1);/* translate hardware address to virtual */
+ if(virt_addr==NULL){
+ printk(KERN_WARNING "ioremap error\n");
+ return -EFAULT;
+ }
+ PDEBUG("Virtual fpga adress : %lx\n",(long int)virt_addr);
+ PDEBUG("Real fpga adress : %lx\n",(long int)IMX_CS1_PHYS);
+ // rmb();
+ data = ioread16(virt_addr);/* read the led value */
+ PDEBUG( "Value read : %x\n",data);
+
+ iounmap(virt_addr);
+
+ /* return data for user */
+ if(copy_to_user(buff,&data,2)){
+ retval = -EFAULT;
+ goto out;
+ }
+
+ *offp = *offp + count;
+ retval = 1;
+
+out:
+ up(&ldev->sem); /* free mutex */
+ PDEBUG("Return value %d\n",(int)retval);
+ return retval;
+}
+
+ssize_t led_write(struct file *fildes, const char __user *buff,size_t count, loff_t *offp){
+ struct led_dev *ldev = fildes->private_data;
+ void * virt_addr;
+ u16 data;
+ ssize_t retval = -ENOMEM;
+
+
+ PDEBUG("offset %d, count %d\n",(int)*offp,(int)count);
+ if(down_interruptible(&ldev->sem))
+ return -ERESTARTSYS;
+ if(*offp != 0){ /* offset must be 0 */
+ goto out;
+ }
+ if(count != 1) /* Only one word can be read */
+ count = 1;
+
+ virt_addr = ioremap(IMX_CS1_PHYS,1);/* translate hardware address to virtual */
+ if(virt_addr==NULL){
+ printk(KERN_WARNING "ioremap error\n");
+ return -EFAULT;
+ }
+ PDEBUG("Virtual fpga adress : %lx\n",(long int)virt_addr);
+ PDEBUG( "Real fpga adress : %lx\n",(long int)IMX_CS1_PHYS);
+ // rmb();
+ if(copy_from_user(&data,buff,2)){
+ retval = -EFAULT;
+ goto out;
+ }
+ PDEBUG( "user buff value %d\n",(int)data);
+ data = data;
+ iowrite16(data,virt_addr);/* read the led value */
+ iounmap(virt_addr);
+ PDEBUG( "Value wrote : %x\n",data);
+
+
+out:
+ up(&ldev->sem);
+ return retval;
+}
+
+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;
+}
+
+int led_release(struct inode *inode, struct file *filp){
+ PDEBUG( "Led released\n");
+ return 0;
+}
+
+static int __init led_init(void){
+
+ int result; /* error return */
+ int led_major,led_minor;
+
+ led_major = 253;
+ led_minor = 0;
+ mem = NULL;
+
+ /* Allocate a private structure and reference it as driver's data */
+ sdev = (struct led_dev *)kmalloc(sizeof(struct led_dev),GFP_KERNEL);
+ if(sdev == NULL){
+ printk(KERN_WARNING "LED: unable to allocate private structure\n");
+ return -ENOMEM;
+ }
+
+ /* initiate mutex for accessing led */
+ init_MUTEX(&sdev->sem);
+
+ /* Get the major and minor device numbers */
+ if(led_major){
+ devno = MKDEV(led_major,led_minor);
+ result = register_chrdev_region(devno, N_DEV,"led");
+ }else{
+ result = alloc_chrdev_region(&devno,led_minor,N_DEV,"led");
+ led_major = MAJOR(devno);
+ }
+ printk(KERN_INFO "LED: MAJOR: %d MINOR: %d\n",MAJOR(devno),MINOR(devno));
+ if(result < 0){
+ printk(KERN_WARNING "LED: can't get major %d\n",led_major);
+ }
+
+ /* Init the cdev structure */
+ cdev_init(&sdev->cdev,&led_fops);
+ sdev->cdev.owner = THIS_MODULE;
+
+ /* Add the device to the kernel, connecting cdev to major/minor number */
+ result = cdev_add(&sdev->cdev,devno,1);
+ if(result < 0)printk(KERN_WARNING "LED: can't add cdev\n");
+
+
+ /* Requested I/O memory */
+ mem = request_mem_region(LED_BASE_ADDR,LED_LENGTH,"led");
+ if(mem == NULL)
+ printk(KERN_ERR "LED: Error memory allocation\n");
+
+
+
+ printk(KERN_INFO "Led module insered\n");
+ return 0;
+}
+
+static void __exit led_exit(void){
+
+ /* delete the cdev structure */
+ cdev_del(&sdev->cdev);
+
+ /* Free the allocated memory */
+ kfree(sdev);
+
+ /* Release I/O memories */
+ release_mem_region(LED_BASE_ADDR,LED_LENGTH);
+
+ /* free major and minor number */
+ unregister_chrdev_region(devno,N_DEV);
+ printk(KERN_INFO "Led module deleted\n");
+}
+
+module_init(led_init);
+module_exit(led_exit);
Added: trunk/target/linux/modules/led/led.h
===================================================================
--- trunk/target/linux/modules/led/led.h (rev 0)
+++ trunk/target/linux/modules/led/led.h 2008-03-04 09:11:14 UTC (rev 766)
@@ -0,0 +1,95 @@
+/* Driver for bus_led IP
+ * Fabien Marteau <fab...@ar...>
+ * 4 march 2008
+ */
+
+
+#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>
+
+/* linux device model */
+#include <linux/kobject.h>
+#include <linux/sysfs.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>
+
+/* hardware addresses */
+#include <asm/hardware.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
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Fabien Marteau - ARMadeus Systems");
+MODULE_DESCRIPTION("Led device driver");
+
+/* cdev struct */
+struct led_dev{
+ struct cdev cdev; /* Char device structure */
+ struct semaphore sem; /* Mutex */
+};
+
+/* major and minor number */
+#define N_DEV 1
+static dev_t devno; /* to store Major and minor numbers */
+struct led_dev *sdev;
+
+/* Fpga base address for led */
+#define LED_BASE_ADDR 0x12000000
+#define LED_LENGTH 1
+struct resource *mem; /* pointer to fpga led */
+
+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,
+};
+
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|