initial merge for vhdl support on the foxboard
authorJohn Crispin <john@openwrt.org>
Sun, 17 Jun 2007 02:53:53 +0000 (02:53 +0000)
committerJohn Crispin <john@openwrt.org>
Sun, 17 Jun 2007 02:53:53 +0000 (02:53 +0000)
SVN-Revision: 7652

target/linux/etrax-2.6/config/profile-vhdl_no_fb [new file with mode: 0644]
target/linux/etrax-2.6/patches/cris/019-vhdl.patch [new file with mode: 0644]
target/linux/etrax-2.6/patches/cris/020-syscalls.patch [new file with mode: 0644]
target/linux/etrax-2.6/profiles/100-generic.mk [new file with mode: 0644]
target/linux/etrax-2.6/profiles/101-vhdl-nofb.mk [new file with mode: 0644]

diff --git a/target/linux/etrax-2.6/config/profile-vhdl_no_fb b/target/linux/etrax-2.6/config/profile-vhdl_no_fb
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/target/linux/etrax-2.6/patches/cris/019-vhdl.patch b/target/linux/etrax-2.6/patches/cris/019-vhdl.patch
new file mode 100644 (file)
index 0000000..95478f8
--- /dev/null
@@ -0,0 +1,4836 @@
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/foxbone/foxbone.c linux-2.6.19.2/drivers/fox-vhdl/foxbone/foxbone.c
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/foxbone/foxbone.c     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/foxbone/foxbone.c  2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,533 @@
++/*  
++  foxbone.c
++  Linux Kernel Driver for FoxBone on FOX VHDL Board 
++  (based on FoxBone protocol interface specifications rel 0.7)    
++  For more info see: http://www.acmesystems.it/?id=120
++  Author: John Crispin
++  Copyright (C) 2006 Phrozen (http://www.phrozen.biz)
++  
++  This 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 example 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.
++    
++  To have a copy of the GNU General Public License write to the Free Software
++  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++*/
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/ioport.h>
++#include <linux/version.h>
++#include <linux/init.h>
++#include <asm/uaccess.h>
++#include <asm/io.h>
++#include <linux/vmalloc.h>
++#include <linux/ioport.h>
++#include <linux/init.h>
++#include <linux/genhd.h>
++#include <linux/spinlock.h>
++#include <linux/autoconf.h>
++#include <linux/interrupt.h>
++#include <asm/etraxgpio.h>
++#include <asm/arch/svinto.h>
++#include <asm/io.h>
++#include <asm/system.h>
++#include <asm/irq.h>
++#include <asm/arch/io_interface_mux.h>
++
++
++#include "foxbone.h"
++#include "foxbone_userspace.h"
++
++
++#define Fox_line_Read                 (1<<1)
++#define Fox_line_WriteData            (1<<2)
++#define Fox_line_Reset                (1<<3)
++#define Fox_line_WriteAddress         (1<<4)
++
++#define FOX_CLEAR_LINES                       (~(0x00FFFF00 | Fox_line_Read | Fox_line_WriteAddress | Fox_line_WriteData))
++
++#define DEV_NAME                      "foxbone"
++#define DEV_MAJOR                     14
++
++spinlock_t foxbone_lock_var = SPIN_LOCK_UNLOCKED;
++unsigned long foxbone_irq_flags;
++// is the userspce device enables ?
++unsigned char foxbone_userspace_is_open = 0;
++
++// are we processing interrupts ? (during fpga_flash the ints are not allowed to be handles
++unsigned char foxbone_allow_int;
++
++// the shadow of which ints are enabled
++unsigned int foxbone_shadow_int_high = 0;
++unsigned int foxbone_shadow_int_low = 0;
++
++// the following four variables get filled when the foxbone driver is started
++// they hold the release and the the application words
++unsigned int FOXBONE_release = 0;
++unsigned int FOXBONE_application1 = 0;
++unsigned int FOXBONE_application2 = 0;
++unsigned int FOXBONE_application3 = 0;
++
++
++
++FOXINT_CALLBACK foxint_callbacks[32];
++
++unsigned int foxbone_read(unsigned int add);
++void foxbone_write(unsigned int add, unsigned int data);
++
++static irqreturn_t foxbone_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs);
++
++unsigned int foxbone_interrupt_enabled = 0;
++
++
++      
++void FOX_delay(unsigned int d){
++      while(d--){
++              unsigned int i = 0;
++              for(i = 0; i < 32000; i++){
++                      i*=2;
++                      i/=2;
++              };
++      };
++};
++
++
++void foxbone_lock(void){
++      spin_lock_irqsave(&foxbone_lock_var, foxbone_irq_flags);
++
++};
++
++void foxbone_unlock(void){
++      spin_unlock_irqrestore(&foxbone_lock_var, foxbone_irq_flags);
++
++};
++
++int foxbone_register_interrupt(unsigned char irq, FOXINT_CALLBACK callback){
++      if(irq > 31){
++              printk("foxbone: trying to register invalid interrupt\n");
++              return 0;
++      };
++      if(!foxbone_interrupt_enabled){
++              foxbone_interrupt_enabled = 1;
++              printk("foxbone: starting interrupt system\n");                         
++              int err;
++              if ((err = request_irq(PA_IRQ_NBR, foxbone_pa_interrupt, SA_INTERRUPT | SA_SHIRQ, "foxbone", 123))){
++                      printk("foxbone: request_irq failed: Error %d\n",err);
++                      return ;
++              }
++              printk("foxbone: request_irq success -> irq: %ld\n",PA_IRQ_NBR);
++              *R_IRQ_MASK1_SET = IO_STATE(R_IRQ_MASK1_SET, pa0, set); 
++      };      
++      
++      printk("foxbone: new int %d registered\n", irq);
++      foxint_callbacks[irq] = callback;
++      if(irq < 15){
++              foxbone_shadow_int_high |= (1<<irq);
++              foxbone_write(0x08, foxbone_shadow_int_high);
++      } else {
++              foxbone_shadow_int_high |= (1<<15);
++              foxbone_write(0x08, foxbone_shadow_int_high);
++              foxbone_shadow_int_low |= (1<<(irq-16));
++              foxbone_write(0x09, foxbone_shadow_int_low);
++      };
++      return 1;       
++};
++
++
++void foxbone_unregister_interrupt(unsigned char irq){
++      if(irq > 31){
++              printk("foxbone: trying to unregister invalid interrupt\n");
++              return ;
++      };
++      printk("foxbone: interrupt %d unregistered\n", irq);
++      if(irq < 15){
++              foxbone_shadow_int_high &= ~(1<<irq);
++              foxbone_write(0x08, foxbone_shadow_int_high);
++      } else {
++              foxbone_shadow_int_low &= ~(1<<(irq-16));
++              foxbone_write(0x09, foxbone_shadow_int_low);
++
++              if(!foxbone_shadow_int_low){
++                      foxbone_shadow_int_high &= ~(1<<15);
++                      foxbone_write(0x08, foxbone_shadow_int_high);
++              };
++      };
++};
++
++#if 0
++#define DBG_INT(x) x
++#else
++#define DBG_INT(x)
++#endif
++
++// this is the bottom half of our interrupt handler
++static void foxbone_handle_interrupt(void){
++      if(foxbone_allow_int){
++              foxbone_lock();
++              unsigned int irq_high, irq_low, i;
++              DBG_INT(printk("Int handler");)
++              if(*R_PORT_PA_DATA & (1)){
++                      irq_high = foxbone_read(0x08);
++                      DBG_INT(printk("Got high_int %d\n", irq_high);)
++                      for(i = 0; i < 15; i++){
++                              if(irq_high & (1<<i)){
++                                      DBG_INT(printk("Go high_int %d\n",i);)
++                                      if(foxint_callbacks[i]){
++                                              foxint_callbacks[i](i);
++                                      };
++                              };
++                      };
++                      if(irq_high & (0x8000)){
++                              irq_low = foxbone_read(0x09);
++                              DBG_INT(printk("Got low_int %d\n", irq_low);)
++                              for(i = 0; i < 16; i++){
++                                      if(irq_low & (1<<i)){
++                                              DBG_INT(printk("Go low_int %d\n", i);)
++                                              if(foxint_callbacks[i+16]){
++                                                      foxint_callbacks[i+16](i+16);
++                                              };
++                                      };
++                              };
++
++                      };
++              };
++              foxbone_unlock();
++      };
++};
++
++// this is the top half of our interrupt handler
++static void tasklet_foxbone_int(unsigned long data);
++DECLARE_TASKLET(tl_foxint_descr, tasklet_foxbone_int, 0L);
++static void tasklet_foxbone_int(unsigned long data){
++      
++      DBG_INT(printk("got an int\n");)
++      foxbone_handle_interrupt();
++      
++}; 
++
++
++static irqreturn_t
++foxbone_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{     
++      unsigned long tmp;
++      
++      /* Find what PA interrupts are active */
++      tmp = (*R_IRQ_READ1);
++//    printk("_____%ud",*R_IRQ_READ1);
++      /* Find those that we have enabled */
++//    tmp &= (1 << R_IRQ_MASK1_SET__pa0__BITNR);
++
++      /* Clear them.. */
++      // *R_IRQ_MASK1_CLR = tmp;
++      //(1 << R_IRQ_MASK1_SET__pa0__BITNR);
++      
++      tasklet_schedule(&tl_foxint_descr);
++      // *R_IRQ_MASK1_SET = IO_STATE(R_IRQ_MASK1_SET, pa0, set);
++      
++        return IRQ_RETVAL(1);
++}
++
++
++static void foxbone_bus_in(void){
++      // turn all the iog8-15 pins into outputs
++      genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g8_15dir);
++      *R_GEN_CONFIG = genconfig_shadow;
++      
++      // turn all the iog16-23 pins into outputs
++      genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g16_23dir);
++      *R_GEN_CONFIG = genconfig_shadow;       
++};
++
++static void foxbone_bus_out(void){
++      // turn all the iog8-15 pins into outputs
++      genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g8_15dir);
++      *R_GEN_CONFIG = genconfig_shadow;
++      
++      // turn all the iog16-23 pins into outputs
++      genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g16_23dir);
++      *R_GEN_CONFIG = genconfig_shadow;       
++};
++
++void foxbone_reset(unsigned char reset){
++      if(reset){
++              *R_PORT_G_DATA = port_g_data_shadow |= Fox_line_Reset;
++      } else {
++              *R_PORT_G_DATA = port_g_data_shadow &= ~Fox_line_Reset;
++      };
++};
++
++static void foxbone_setadd(unsigned long address){
++      *R_PORT_G_DATA = port_g_data_shadow &= FOX_CLEAR_LINES;
++
++      *R_PORT_G_DATA = port_g_data_shadow |= (address << 8)| Fox_line_WriteAddress;
++
++      *R_PORT_G_DATA = port_g_data_shadow &= ~Fox_line_WriteAddress; 
++};
++
++
++static unsigned int foxbone_read_data(unsigned char next){
++      unsigned int data;
++      *R_PORT_G_DATA = port_g_data_shadow &= FOX_CLEAR_LINES;
++
++      foxbone_bus_in();
++      
++      *R_PORT_G_DATA = port_g_data_shadow |= Fox_line_Read;
++      
++      // do the reading now
++      data =  *R_PORT_G_DATA;
++      data =  *R_PORT_G_DATA;
++      
++      // now return the Fox_line_ReadData to low state to idle the bus from the FPGA side
++      *R_PORT_G_DATA = port_g_data_shadow &= ~Fox_line_Read;
++      foxbone_bus_out();
++      return ((unsigned int)((data&0x00FFFF00)>>8));
++}
++
++
++static unsigned int foxbone_write_data(unsigned int data, unsigned char next) {
++      // clear all address/data/control bits
++      *R_PORT_G_DATA = port_g_data_shadow &= FOX_CLEAR_LINES; 
++
++      *R_PORT_G_DATA = port_g_data_shadow |= (data << 8)| Fox_line_WriteData;
++      *R_PORT_G_DATA = port_g_data_shadow &= ~Fox_line_WriteData;
++      
++      return 0;
++}
++
++void foxbone_write(unsigned int add, unsigned int data){
++      foxbone_setadd(add);
++      foxbone_write_data(data, 0);
++};
++
++unsigned int foxbone_read(unsigned int add){
++      foxbone_setadd(add);
++      return foxbone_read_data(0);
++};
++
++void foxbone_write_next(unsigned data){
++      foxbone_write_data(data, 1);
++};
++
++unsigned int foxbone_read_next(void){
++      return foxbone_read_data(1);
++};
++
++void foxbone_bulk_write(unsigned int *data, unsigned int length, unsigned int add){
++      unsigned int i;
++      foxbone_write(add, *data);
++      unsigned long def_val = (port_g_data_shadow & 0xff0000ff) | Fox_line_WriteData;
++      for(i = 1; i < length; i++){    
++              *R_PORT_G_DATA = port_g_data_shadow = def_val | data[i]<<8;
++              *R_PORT_G_DATA = port_g_data_shadow &= ~Fox_line_WriteData;
++      };
++};
++
++void foxbone_bulk_read(unsigned int *data, unsigned int length, unsigned int add){
++      //printk("Get data from %d %d\n", add, length);
++      unsigned int i;
++      for(i = 0; i < length; i++){    
++              if(i == 0){
++                      data[i] = foxbone_read(add);
++              } else {
++                      data[i] = foxbone_read_next();
++              };
++      };
++      
++};
++
++void foxbone_initialise_bus(void){
++      memset(foxint_callbacks, 0, sizeof(FOXINT_CALLBACK)*32);
++
++      // clear all address/data/control bits
++      *R_PORT_G_DATA = port_g_data_shadow &= FOX_CLEAR_LINES; 
++      foxbone_reset(0);
++      int i;
++      for(i = 0; i < 32000; i++){
++              i++;
++              i--;
++      };
++      foxbone_reset(1);
++      
++      foxbone_bus_out();
++      
++      FOXBONE_release = foxbone_read(0x04);
++      FOXBONE_application1 = foxbone_read(0x05);
++      FOXBONE_application2 = foxbone_read(0x06);
++      FOXBONE_application3 = foxbone_read(0x07);
++      printk("foxbone : release = 0x%04x\n", FOXBONE_release);
++      printk("foxbone : application word 1 = 0x%04x\n", FOXBONE_application1);
++      printk("foxbone : application word 2 = 0x%04x\n", FOXBONE_application2);        
++      printk("foxbone : application word 3 = 0x%04x\n", FOXBONE_application3);
++
++      
++};
++
++
++static ssize_t foxbone_userspace_write(struct file * file, const char * buffer, size_t count, loff_t *offset){        
++      if(count > (64 * 1024)){
++              printk("foxbone: trying to bulk write too much data\n");
++              return 1;
++      };
++      unsigned int *bulk_data = (unsigned int) kmalloc(count, GFP_KERNEL);
++      
++      copy_from_user((char*) bulk_data, buffer, count);
++      
++      foxbone_bulk_write(&bulk_data[2], bulk_data[1], bulk_data[0]);
++      
++      kfree(bulk_data);       
++      return 0;
++};
++
++
++static ssize_t foxbone_userspace_read(struct file *file, char *buffer, size_t count, loff_t *offset){
++      if(count > (64 * 1024)){
++              printk("foxbone: trying to bulk read too much data\n");
++              return 0;
++      };
++      
++      // find out which register we want to read
++      unsigned int bulk_data_info[2];
++      copy_from_user((char*) bulk_data_info, buffer, 8);
++              
++      // read the data
++      unsigned int *bulk_data = (unsigned int)kmalloc(count, GFP_KERNEL);
++              
++      foxbone_bulk_read(&bulk_data[0], bulk_data_info[1], bulk_data_info[0]);
++      
++      copy_to_user((char*)buffer, (char*)bulk_data, count);
++      
++      kfree(bulk_data);
++      
++      return count / 4;
++};
++
++// the app has send us some control data
++static int foxbone_userspace_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg){
++      int retval = 0;
++      FOXBONE_WRITE fb_write;
++      switch (cmd) {
++              case IOCTL_FOXBONE_INIT_BUS:
++                      foxbone_initialise_bus();
++                      break;
++                      
++              case IOCTL_FOXBONE_WRITE_REG:
++                      copy_from_user((FOXBONE_WRITE*)&fb_write, (FOXBONE_WRITE*)arg, sizeof(fb_write));
++                      foxbone_write(fb_write.reg, fb_write.data);
++                      break;
++              
++              case IOCTL_FOXBONE_READ_REG:
++                      retval = foxbone_read(arg);
++                      break;
++              
++              case IOCTL_FOXBONE_WRITE_NEXT:
++                      copy_from_user((FOXBONE_WRITE*)&fb_write, (FOXBONE_WRITE*)arg, sizeof(fb_write));
++                      foxbone_write_next(fb_write.data);
++                      break;
++              
++              case IOCTL_FOXBONE_READ_NEXT:
++                      retval = foxbone_read_next();
++                      break;
++
++              case IOCTL_FOXBONE_INTERRUPTS:
++                      foxbone_allow_int = arg;
++                      break;
++                              
++              default:
++                      printk("foxbone_userspace : unknown ioctl\n");
++                      break;          
++      }
++      return retval;
++};
++
++
++
++static int foxbone_userspace_open(struct inode *inode, struct file *file){
++      // Which minor device is the user trying to access ?
++      unsigned int dev_minor = MINOR(inode->i_rdev);
++      
++      // we only supprt minor 0 at the moment
++      if(dev_minor !=  0){
++              printk("foxbone_userspace : trying to access unknown minor device -> %d\n", dev_minor);
++              return -ENODEV;
++      }
++      
++      // check if another app is currently using the device
++      if(foxbone_userspace_is_open) {
++              printk("foxbone_userspace : Device with minor ID %d already in use\n", dev_minor);
++              return -EBUSY;
++      }
++      
++      return 0;
++};
++
++
++// gets called when an app closes the device
++static int foxbone_userspace_close(struct inode * inode, struct file * file){
++
++      foxbone_userspace_is_open = 0;
++      
++      return 0;
++};
++
++// so the kernel knows which functions to access for a given operation
++struct file_operations foxbone_userspace_fops = {
++        ioctl:          foxbone_userspace_ioctl,
++      write:          foxbone_userspace_write,
++      read:           foxbone_userspace_read,
++        open:           foxbone_userspace_open,
++        release:        foxbone_userspace_close
++};
++
++
++// module gets loaded into kernel / char dev is registered
++static int foxbone_userspace_init(void){
++      // flame the kprintk
++      printk("foxbone_userspace : FOX-VHDL userspace access module\n");
++      
++      // register the character device
++      if(register_chrdev(DEV_MAJOR, DEV_NAME, &foxbone_userspace_fops)) {
++              printk( "fpga_mod.ko : Error whilst opening %s (%d)\n", DEV_NAME, DEV_MAJOR);
++              return( -ENODEV );
++      };
++      
++      foxbone_userspace_is_open = 0;
++      printk("foxbone_userspace : Device %s registered for major ID %d\n", DEV_NAME, DEV_MAJOR);
++      return 0;
++}
++
++
++// we are done so shut everything down
++static void foxbone_userspace_exit(void){
++      // tell the kernel that the device is not needed anymore
++      unregister_chrdev(DEV_MAJOR, DEV_NAME);
++      
++}
++
++
++static int __init foxbone_init(void){
++      printk("foxbone : FOX-VHDL FOXBONE access module started\n");
++      foxbone_initialise_bus();
++      foxbone_allow_int = 1;
++      foxbone_userspace_init();
++      return 0;
++}
++
++
++static void __exit foxbone_exit(void){
++      printk( "foxbone : Cleanup\n" );
++      foxbone_userspace_exit();
++}
++
++module_init (foxbone_init);
++module_exit (foxbone_exit);
++
++
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/foxbone/foxbone.h linux-2.6.19.2/drivers/fox-vhdl/foxbone/foxbone.h
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/foxbone/foxbone.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/foxbone/foxbone.h  2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,21 @@
++// prototypes for foxbone compliant modules
++
++typedef void (*FOXINT_CALLBACK) (unsigned int);
++
++extern unsigned int FOXBONE_release;
++extern unsigned int FOXBONE_application1;
++extern unsigned int FOXBONE_application2;
++extern unsigned int FOXBONE_application3;
++
++void foxbone_write(unsigned int add, unsigned int data);
++
++unsigned int foxbone_read(unsigned int add);
++
++void foxbone_write_next(unsigned data);
++
++unsigned int foxbone_read_next(void);
++
++void foxbone_initialise_bus(void);
++void foxbone_unregister_interrupt(unsigned char irq);
++int foxbone_register_interrupt(unsigned char irq, FOXINT_CALLBACK callback);
++void foxbone_reset(unsigned char reset);
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/foxbone/foxbone_syscalls.c linux-2.6.19.2/drivers/fox-vhdl/foxbone/foxbone_syscalls.c
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/foxbone/foxbone_syscalls.c    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/foxbone/foxbone_syscalls.c 2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,155 @@
++/*  
++  foxbone_syscalls.c
++  Linux Kernel syscalls for FoxBone on FOX VHDL Board 
++  (based on FoxBone protocol interface specifications rel 0.7)    
++  For more info see: http://www.acmesystems.it/?id=120
++  Author: John Crispin
++  Copyright (C) 2006 Phrozen (http://www.phrozen.biz)
++  
++  This 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 example 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.
++    
++  To have a copy of the GNU General Public License write to the Free Software
++  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++*/
++
++
++#include <linux/kernel.h>
++#include <asm/uaccess.h>
++#include <linux/foxbone_syscalls.h>
++#include "foxbone.h"
++
++asmlinkage unsigned short int sys_foxboneread(unsigned short int reg){
++      return foxbone_read(reg);
++};
++
++asmlinkage void sys_foxbonewrite(unsigned short int reg, unsigned short int value){
++      foxbone_write(reg, value);
++};
++
++asmlinkage void sys_foxbonebulkread(unsigned short int reg, unsigned short int *value, unsigned int length){
++      unsigned int i;
++      unsigned int *buffer = kmalloc(length * 2, GFP_KERNEL);
++      *buffer = foxbone_read(reg);
++      for(i = 1; i < length; i++){
++              buffer[i] = foxbone_read_next();
++      };
++      copy_to_user(value, buffer, length * 2);
++      kfree(buffer);  
++      
++};
++
++asmlinkage void sys_foxbonebulkwrite(unsigned short int reg, unsigned short int *value, unsigned int length){
++      unsigned int i;
++      unsigned int *buffer = kmalloc(length * 2, GFP_KERNEL);
++      copy_from_user(buffer, value, length * 2);
++      foxbone_write(reg, *buffer);
++      for(i = 1; i < length; i++){
++              foxbone_write_next(buffer[i]);
++      };
++      kfree(buffer);  
++};
++
++
++/*
++      interrupt handling from userspace
++*/
++
++typedef struct _FOX_INT {
++      unsigned char enabled;
++      unsigned char count;
++      unsigned char wakeup;
++      wait_queue_head_t wait_queue;
++} FOX_INT;
++
++
++FOX_INT syscall_interrupts[32];
++
++
++void foxbone_interrupt_callback(unsigned int interrupt){
++      //printk("GOT INT %d\n", irq_no);
++      if(syscall_interrupts[interrupt].enabled){
++              syscall_interrupts[interrupt].count ++;
++              if(syscall_interrupts[interrupt].wakeup){
++                      wake_up_interruptible(&syscall_interrupts[interrupt].wait_queue);
++              };
++      };      
++};
++
++
++asmlinkage void sys_foxboneintreg(unsigned long int interrupt, unsigned char state){
++      if(interrupt > 31){
++              interrupt = 31;
++      };
++      if(state){
++              foxbone_register_interrupt(interrupt, foxbone_interrupt_callback);
++              syscall_interrupts[interrupt].enabled = 1;
++              syscall_interrupts[interrupt].count = 0;
++              init_waitqueue_head(&syscall_interrupts[interrupt].wait_queue);
++      } else {
++              foxbone_unregister_interrupt(interrupt);
++              syscall_interrupts[interrupt].enabled = 0;              
++      };
++};
++
++
++asmlinkage unsigned int sys_foxboneintcheck( unsigned long int interrupt){
++      unsigned int retval = 0xffff;
++      if(interrupt > 31){
++              interrupt = 31;
++      };      
++      if(syscall_interrupts[interrupt].enabled){
++              retval = syscall_interrupts[interrupt].count;
++              syscall_interrupts[interrupt].count = 0;
++      };
++      return retval;
++};
++
++
++asmlinkage unsigned int sys_foxboneintwait(unsigned long int interrupt, unsigned char timeout){
++      unsigned int retval = 0xffff;
++      if(interrupt > 31){
++              interrupt = 31;
++      };
++      if(syscall_interrupts[interrupt].enabled){
++              syscall_interrupts[interrupt].wakeup = 1;
++              syscall_interrupts[interrupt].count = 0;
++              interruptible_sleep_on_timeout(&syscall_interrupts[interrupt].wait_queue, timeout*HZ);
++              if(syscall_interrupts[interrupt].count != 0){
++                      retval = syscall_interrupts[interrupt].count;
++              };
++              syscall_interrupts[interrupt].count = 0;
++              syscall_interrupts[interrupt].wakeup = 0;
++      };
++      return retval;
++};
++
++
++asmlinkage void sys_foxbonereset(unsigned short int reg){
++      foxbone_reset(0);
++      int i;
++      for(i = 0; i < 32000; i++){
++              i++;
++              i--;
++      };
++      foxbone_reset(1);
++};
++
++static int __init foxbone_syscall_init(void){
++      memset(syscall_interrupts, 0, sizeof(FOX_INT) * 32);
++      return 0;
++}
++
++
++static void __exit foxbone_syscall_exit(void){
++}
++
++module_init (foxbone_syscall_init);
++module_exit (foxbone_syscall_exit);
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/foxbone/foxbone_userspace.h linux-2.6.19.2/drivers/fox-vhdl/foxbone/foxbone_userspace.h
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/foxbone/foxbone_userspace.h   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/foxbone/foxbone_userspace.h        2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,17 @@
++// These are the ioctls for accessing /dev/foxbone
++
++#define IOCTL_FOXBONE_INIT_BUS                0x3341
++#define IOCTL_FOXBONE_WRITE_REG       0x3342
++#define IOCTL_FOXBONE_READ_REG        0x3343
++#define IOCTL_FOXBONE_WRITE_NEXT      0x3344
++#define IOCTL_FOXBONE_READ_NEXT       0x3345
++#define IOCTL_FOXBONE_INTERRUPTS      0x3346
++
++// the data structure used to write a register
++typedef struct _FOXBONE_WRITE {
++      unsigned int reg;
++      unsigned int data;
++} FOXBONE_WRITE; 
++
++
++
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/foxbone/Makefile linux-2.6.19.2/drivers/fox-vhdl/foxbone/Makefile
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/foxbone/Makefile      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/foxbone/Makefile   2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,2 @@
++obj-$(CONFIG_FOXBONE)          += foxbone.o
++obj-$(CONFIG_FOXBONE)          += foxbone_syscalls.o
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_event/foxbone.h linux-2.6.19.2/drivers/fox-vhdl/fox_event/foxbone.h
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_event/foxbone.h   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_event/foxbone.h        2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,16 @@
++// prototypes for foxbone compliant modules
++
++extern unsigned int FOXBONE_release;
++extern unsigned int FOXBONE_application1;
++extern unsigned int FOXBONE_application2;
++extern unsigned int FOXBONE_application3;
++
++void foxbone_write(unsigned int add, unsigned int data);
++
++unsigned int foxbone_read(unsigned int add);
++
++void foxbone_write_next(unsigned data);
++
++unsigned int foxbone_read_next(void);
++
++void foxbone_initialise_bus(void);
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_event/fox_event.c linux-2.6.19.2/drivers/fox-vhdl/fox_event/fox_event.c
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_event/fox_event.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_event/fox_event.c      2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,170 @@
++/*  
++  fox_event.c
++  Linux Kernel Driver for FoxBone EventCounter on FOX VHDL Board 
++  (based on FoxBone protocol interface specifications rel 0.7)    
++  For more info see: http://www.acmesystems.it/?id=120
++  Author: John Crispin
++  Copyright (C) 2006 Phrozen (http://www.phrozen.biz)
++  
++  This 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 example 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.
++    
++  To have a copy of the GNU General Public License write to the Free Software
++  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++*/
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/ioport.h>
++#include <linux/version.h>
++#include <linux/init.h>
++#include <asm/uaccess.h>
++#include <asm/io.h>
++#include <linux/vmalloc.h>
++#include <linux/ioport.h>  
++#include <linux/init.h>
++#include <linux/genhd.h>
++
++#define DEV_NAME                      "event"
++#define DEV_MAJOR                     193
++
++#include "foxbone.h"
++
++unsigned char foxevent_is_open = 0;
++
++
++#define IOCTL_FOXBONE_EVENT_SET_ALARM 0x4745
++#define IOCTL_FOXBONE_EVENT_GET_COUNT 0x4746
++#define IOCTL_FOXBONE_EVENT_GET_ALARM 0x4747
++#define IOCTL_FOXBONE_EVENT_RESET_ALARM       0x4748
++
++// the app has send us some control data
++static int module_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg){
++      //copy_to_user((char*)arg, (char*)&audio_data, sizeof(AUDIO_DATA));
++      //copy_from_user((char*)&mp3_beep, (char*)arg, sizeof(MP3_BEEP));
++      int retval = 0;
++      unsigned int current_io = 0;
++      switch (cmd) {
++              case IOCTL_FOXBONE_EVENT_SET_ALARM:
++                      foxbone_write(0x0040, 0);
++                      foxbone_write(0x0041, arg);
++                      foxbone_write(0x0040, 3);
++                      break;
++      
++              case IOCTL_FOXBONE_EVENT_GET_COUNT:
++                      retval = foxbone_read(0x0042);
++                      break;
++              
++              case IOCTL_FOXBONE_EVENT_GET_ALARM:
++                      retval = foxbone_read(0x0043);
++                      break;
++                      
++              case IOCTL_FOXBONE_EVENT_RESET_ALARM:
++                      current_io = foxbone_read(0x0040);
++                      current_io &= ~(1<<1);
++                      foxbone_write(0x0040, 0);
++                      current_io |= (1<<1);
++                      foxbone_write(0x0040, 0);
++                      break;
++                      
++              default:
++                      printk("fox_event: unknown ioctl\n");
++                      break;                  
++      }
++
++      return retval;
++};
++
++
++
++static int module_open(struct inode *inode, struct file *file){
++      // Which minor device is the user trying to access ?
++      unsigned int dev_minor = MINOR(inode->i_rdev);
++      
++      // we only supprt minor 0 at the moment
++      if(dev_minor !=  0){
++              printk("fox_event: trying to access unknown minor device -> %d\n", dev_minor);
++              return -ENODEV;
++      }
++      
++      // check if another app is currently using the device
++      if(foxevent_is_open) {
++              printk("fox_event: Device with minor ID %d already in use\n", dev_minor);
++              return -EBUSY;
++      }
++      
++      // more flaming
++      printk("fox_event: Minor %d has been opened\n", dev_minor);
++      return 0;
++};
++
++
++// gets called when an app closes the device
++static int module_close(struct inode * inode, struct file * file){
++      // Which minor device is the user trying to access ?
++      unsigned int dev_minor = MINOR(inode->i_rdev);
++      
++      // remember that the device has been closed
++      foxevent_is_open = 0;
++      
++      
++      // more flaming
++      printk("fox_event: Minor %d has been closed\n", dev_minor);
++      
++      return 0;
++};
++
++// so the kernel knows which functions to access for a given operation
++struct file_operations foxevent_module_fops = {
++        ioctl:         module_ioctl,
++        open:          module_open,
++        release:       module_close
++};
++
++
++// module gets loaded into kernel / char dev is registered
++static int __init mod_init(void){
++      // flame the kprintk
++      printk("fox_event: FOX-VHDL FPGA io module\n");
++      //printk("fox_event: Made by K. John '2B|!2B' Crispin (john@phrozen.org)\n");
++      //printk("fox_event: Starting ...\n");
++      
++      // register the character device
++      if(register_chrdev(DEV_MAJOR, DEV_NAME, &foxevent_module_fops)) {
++              printk( "fox_event: Error whilst opening %s (%d)\n", DEV_NAME, DEV_MAJOR);
++              return( -ENODEV );
++      };
++      
++
++      // remember that the driver has been opened
++      foxevent_is_open = 0;
++      printk("fox_event: Device %s registered for major ID %d\n", DEV_NAME, DEV_MAJOR);
++      return 0;
++}
++
++
++// we are done so shut everything down
++static void __exit mod_exit(void){
++      printk( "fox_event: Cleanup\n" );
++      // tell the kernel that the device is not needed anymore
++      unregister_chrdev(DEV_MAJOR, DEV_NAME);
++      
++}
++
++module_init (mod_init);
++module_exit (mod_exit);
++
++
++
++
++
++
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_event/Makefile linux-2.6.19.2/drivers/fox-vhdl/fox_event/Makefile
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_event/Makefile    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_event/Makefile 2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1 @@
++obj-$(CONFIG_FOXBONE_EVENT)          += fox_event.o
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_fpga_flash/Makefile linux-2.6.19.2/drivers/fox-vhdl/fox_fpga_flash/Makefile
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_fpga_flash/Makefile       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_fpga_flash/Makefile    2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,2 @@
++obj-$(CONFIG_FOX_FPGA)          += dpa3palg.oo dpalg.oo dpjtag2.oo dpjtag.oo dpuncomp.oo dpuser.oo fpga_module.oo
++
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_fpga_flash/MakefileORI linux-2.6.19.2/drivers/fox-vhdl/fox_fpga_flash/MakefileORI
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_fpga_flash/MakefileORI    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_fpga_flash/MakefileORI 2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1 @@
++obj-$(CONFIG_FOX_FPGA)          += dpa3palg.o dpalg.o dpjtag2.o dpjtag.o dpuncomp.o dpuser.o fpga_module.o
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_io/foxbone.h linux-2.6.19.2/drivers/fox-vhdl/fox_io/foxbone.h
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_io/foxbone.h      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_io/foxbone.h   2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,16 @@
++// prototypes for foxbone compliant modules
++
++extern unsigned int FOXBONE_release;
++extern unsigned int FOXBONE_application1;
++extern unsigned int FOXBONE_application2;
++extern unsigned int FOXBONE_application3;
++
++void foxbone_write(unsigned int add, unsigned int data);
++
++unsigned int foxbone_read(unsigned int add);
++
++void foxbone_write_next(unsigned data);
++
++unsigned int foxbone_read_next(void);
++
++void foxbone_initialise_bus(void);
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_io/fox_io.c linux-2.6.19.2/drivers/fox-vhdl/fox_io/fox_io.c
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_io/fox_io.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_io/fox_io.c    2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,164 @@
++/*  
++  fox_io.c
++  Linux Kernel Driver for FoxBone I/O on FOX VHDL Board 
++  (based on FoxBone protocol interface specifications rel 0.7)    
++  For more info see: http://www.acmesystems.it/?id=120
++  Author: John Crispin
++  Copyright (C) 2006 Phrozen (http://www.phrozen.biz)
++  
++  This 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 example 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.
++    
++  To have a copy of the GNU General Public License write to the Free Software
++  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++*/
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/ioport.h>
++#include <linux/version.h>
++#include <linux/init.h>
++#include <asm/uaccess.h>
++#include <asm/io.h>
++#include <linux/vmalloc.h>
++#include <linux/ioport.h>  
++#include <linux/init.h>
++#include <linux/genhd.h>
++
++#define DEV_NAME                      "foxio"
++#define DEV_MAJOR                     190
++
++#include "foxbone.h"
++
++unsigned char foxio_is_open = 0;
++
++
++#define IOCTL_FOXBONE_IO_SET          0x4545
++#define IOCTL_FOXBONE_IO_CLR          0x4546
++#define IOCTL_FOXBONE_IO_GET          0x4547
++
++// the app has send us some control data
++static int module_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg){
++      //copy_to_user((char*)arg, (char*)&audio_data, sizeof(AUDIO_DATA));
++      //copy_from_user((char*)&mp3_beep, (char*)arg, sizeof(MP3_BEEP));
++      int retval = 0;
++      unsigned int current_io = 0;
++      switch (cmd) {
++              case IOCTL_FOXBONE_IO_SET:
++                      current_io = foxbone_read(0x0014);
++                      current_io |= (1<<arg);
++                      foxbone_write(0x0014, current_io);
++                      break;
++      
++              case IOCTL_FOXBONE_IO_CLR:
++                      current_io = foxbone_read(0x0014);
++                      current_io &= ~(1<<arg);
++                      foxbone_write(0x0014, current_io);
++                      break;
++              
++              case IOCTL_FOXBONE_IO_GET:
++                      retval = foxbone_read(0x0015);
++                      break;
++              
++                      
++              default:
++                      printk("fox_io: unknown ioctl\n");
++                      break;                  
++      }
++
++      return retval;
++};
++
++
++
++static int module_open(struct inode *inode, struct file *file){
++      // Which minor device is the user trying to access ?
++      unsigned int dev_minor = MINOR(inode->i_rdev);
++      
++      // we only supprt minor 0 at the moment
++      if(dev_minor !=  0){
++              printk("fox_io: trying to access unknown minor device -> %d\n", dev_minor);
++              return -ENODEV;
++      }
++      
++      // check if another app is currently using the device
++      if(foxio_is_open) {
++              printk("fox_io: Device with minor ID %d already in use\n", dev_minor);
++              return -EBUSY;
++      }
++      
++      // more flaming
++      printk("fox_io: Minor %d has been opened\n", dev_minor);
++      return 0;
++};
++
++
++// gets called when an app closes the device
++static int module_close(struct inode * inode, struct file * file){
++      // Which minor device is the user trying to access ?
++      unsigned int dev_minor = MINOR(inode->i_rdev);
++      
++      // remember that the device has been closed
++      foxio_is_open = 0;
++      
++      
++      // more flaming
++      printk("fox_io: Minor %d has been closed\n", dev_minor);
++      
++      return 0;
++};
++
++// so the kernel knows which functions to access for a given operation
++struct file_operations foxio_module_fops = {
++        ioctl:         module_ioctl,
++        open:          module_open,
++        release:       module_close
++};
++
++
++// module gets loaded into kernel / char dev is registered
++static int __init mod_init(void){
++      // flame the kprintk
++      printk("fox_io: FOX-VHDL FPGA io module\n");
++      //printk("fox_io: Made by K. John '2B|!2B' Crispin (john@phrozen.org)\n");
++      //printk("fox_io: Starting ...\n");
++      
++      // register the character device
++      if(register_chrdev(DEV_MAJOR, DEV_NAME, &foxio_module_fops)) {
++              printk( "fox_io: Error whilst opening %s (%d)\n", DEV_NAME, DEV_MAJOR);
++              return( -ENODEV );
++      };
++      
++
++      // remember that the driver has been opened
++      foxio_is_open = 0;
++      printk("fox_io: Device %s registered for major ID %d\n", DEV_NAME, DEV_MAJOR);
++      return 0;
++}
++
++
++// we are done so shut everything down
++static void __exit mod_exit(void){
++      printk( "fox_io: Cleanup\n" );
++      // tell the kernel that the device is not needed anymore
++      unregister_chrdev(DEV_MAJOR, DEV_NAME);
++      
++}
++
++module_init (mod_init);
++module_exit (mod_exit);
++
++
++
++
++
++
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_io/Makefile linux-2.6.19.2/drivers/fox-vhdl/fox_io/Makefile
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_io/Makefile       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_io/Makefile    2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1 @@
++obj-$(CONFIG_FOXBONE_IO)          += fox_io.o
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_loopback/foxbone.h linux-2.6.19.2/drivers/fox-vhdl/fox_loopback/foxbone.h
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_loopback/foxbone.h        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_loopback/foxbone.h     2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,16 @@
++// prototypes for foxbone compliant modules
++
++extern unsigned int FOXBONE_release;
++extern unsigned int FOXBONE_application1;
++extern unsigned int FOXBONE_application2;
++extern unsigned int FOXBONE_application3;
++
++void foxbone_write(unsigned int add, unsigned int data);
++
++unsigned int foxbone_read(unsigned int add);
++
++void foxbone_write_next(unsigned data);
++
++unsigned int foxbone_read_next(void);
++
++void foxbone_initialise_bus(void);
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_loopback/fox_loopback.c linux-2.6.19.2/drivers/fox-vhdl/fox_loopback/fox_loopback.c
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_loopback/fox_loopback.c   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_loopback/fox_loopback.c        2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,154 @@
++/*  
++  fox_loopback.c
++  Linux Kernel Driver for FoxBone Loopback Register on FOX VHDL Board 
++  (based on FoxBone protocol interface specifications rel 0.7)    
++  For more info see: http://www.acmesystems.it/?id=120
++  Author: John Crispin
++  Copyright (C) 2006 Phrozen (http://www.phrozen.biz)
++  
++  This 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 example 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.
++    
++  To have a copy of the GNU General Public License write to the Free Software
++  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++*/
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/ioport.h>
++#include <linux/version.h>
++#include <linux/init.h>
++#include <asm/uaccess.h>
++#include <asm/io.h>
++#include <linux/vmalloc.h>
++#include <linux/ioport.h>  
++#include <linux/init.h>
++#include <linux/genhd.h>
++
++#define DEV_NAME                      "loopback"
++#define DEV_MAJOR                     192
++
++#include "foxbone.h"
++
++unsigned char foxloopback_is_open = 0;
++
++
++#define IOCTL_FOXBONE_LOOPBACK_SET            0x4045
++#define IOCTL_FOXBONE_LOOPBACK_GET            0x4046
++
++// the app has send us some control data
++static int module_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg){
++      //copy_to_user((char*)arg, (char*)&audio_data, sizeof(AUDIO_DATA));
++      //copy_from_user((char*)&mp3_beep, (char*)arg, sizeof(MP3_BEEP));
++      int retval = 0;
++      unsigned int current_io = 0;
++      switch (cmd) {
++              case IOCTL_FOXBONE_LOOPBACK_SET:
++                      foxbone_write(0x0013, arg);
++                      break;
++              
++              case IOCTL_FOXBONE_LOOPBACK_GET:
++                      retval = foxbone_read(0x0013);
++                      break;          
++                      
++              default:
++                      printk("fox_loopback: unknown ioctl\n");
++                      break;                  
++      }
++
++      return retval;
++};
++
++
++
++static int module_open(struct inode *inode, struct file *file){
++      // Which minor device is the user trying to access ?
++      unsigned int dev_minor = MINOR(inode->i_rdev);
++      
++      // we only supprt minor 0 at the moment
++      if(dev_minor !=  0){
++              printk("fox_loopback: trying to access unknown minor device -> %d\n", dev_minor);
++              return -ENODEV;
++      }
++      
++      // check if another app is currently using the device
++      if(foxloopback_is_open) {
++              printk("fox_loopback: Device with minor ID %d already in use\n", dev_minor);
++              return -EBUSY;
++      }
++      
++      // more flaming
++      printk("fox_loopback: Minor %d has been opened\n", dev_minor);
++      return 0;
++};
++
++
++// gets called when an app closes the device
++static int module_close(struct inode * inode, struct file * file){
++      // Which minor device is the user trying to access ?
++      unsigned int dev_minor = MINOR(inode->i_rdev);
++      
++      // remember that the device has been closed
++      foxloopback_is_open = 0;
++      
++      
++      // more flaming
++      printk("fox_loopback: Minor %d has been closed\n", dev_minor);
++      
++      return 0;
++};
++
++// so the kernel knows which functions to access for a given operation
++struct file_operations foxloopback_module_fops = {
++        ioctl:         module_ioctl,
++        open:          module_open,
++        release:       module_close
++};
++
++
++// module gets loaded into kernel / char dev is registered
++static int __init mod_init(void){
++      // flame the kprintk
++      printk("fox_loopback: FOX-VHDL FPGA io module\n");
++      //printk("fox_loopback: Made by K. John '2B|!2B' Crispin (john@phrozen.org)\n");
++      //printk("fox_loopback: Starting ...\n");
++      
++      // register the character device
++      if(register_chrdev(DEV_MAJOR, DEV_NAME, &foxloopback_module_fops)) {
++              printk( "fox_loopback: Error whilst opening %s (%d)\n", DEV_NAME, DEV_MAJOR);
++              return( -ENODEV );
++      };
++      
++
++      // remember that the driver has been opened
++      foxloopback_is_open = 0;
++      printk("fox_loopback: Device %s registered for major ID %d\n", DEV_NAME, DEV_MAJOR);
++      return 0;
++}
++
++
++// we are done so shut everything down
++static void __exit mod_exit(void){
++      printk( "fox_loopback: Cleanup\n" );
++      // tell the kernel that the device is not needed anymore
++      unregister_chrdev(DEV_MAJOR, DEV_NAME);
++      
++}
++
++module_init (mod_init);
++module_exit (mod_exit);
++
++
++
++
++
++
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_loopback/Makefile linux-2.6.19.2/drivers/fox-vhdl/fox_loopback/Makefile
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_loopback/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_loopback/Makefile      2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1 @@
++obj-$(CONFIG_FOXBONE_LOOPBACK)          += fox_loopback.o
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_multiply/foxbone.h linux-2.6.19.2/drivers/fox-vhdl/fox_multiply/foxbone.h
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_multiply/foxbone.h        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_multiply/foxbone.h     2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,16 @@
++// prototypes for foxbone compliant modules
++
++extern unsigned int FOXBONE_release;
++extern unsigned int FOXBONE_application1;
++extern unsigned int FOXBONE_application2;
++extern unsigned int FOXBONE_application3;
++
++void foxbone_write(unsigned int add, unsigned int data);
++
++unsigned int foxbone_read(unsigned int add);
++
++void foxbone_write_next(unsigned data);
++
++unsigned int foxbone_read_next(void);
++
++void foxbone_initialise_bus(void);
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_multiply/fox_multiply.c linux-2.6.19.2/drivers/fox-vhdl/fox_multiply/fox_multiply.c
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_multiply/fox_multiply.c   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_multiply/fox_multiply.c        2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,172 @@
++/*  
++  fox_multiply.c
++  Linux Kernel Driver for FoxBone 32x32 fast multiplier on FOX VHDL Board 
++  (based on FoxBone protocol interface specifications rel 0.7)    
++  For more info see: http://www.acmesystems.it/?id=120
++  Author: John Crispin
++  Copyright (C) 2006 Phrozen (http://www.phrozen.biz)
++  
++  This 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 example 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.
++    
++  To have a copy of the GNU General Public License write to the Free Software
++  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++*/
++
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/ioport.h>
++#include <linux/version.h>
++#include <linux/init.h>
++#include <asm/uaccess.h>
++#include <asm/io.h>
++#include <linux/vmalloc.h>
++#include <linux/ioport.h>  
++#include <linux/init.h>
++#include <linux/genhd.h>
++
++#define DEV_NAME                      "multiply"
++#define DEV_MAJOR                     194
++
++#include "foxbone.h"
++
++unsigned char foxmultiply_is_open = 0;
++
++
++#define IOCTL_FOXBONE_MUTIPLY         0x4945
++
++// the app has send us some control data
++static int module_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg){
++      long data[3], i;
++      int retval = 0;
++      switch (cmd) {
++              case IOCTL_FOXBONE_MUTIPLY:
++                      copy_from_user((char*)&data[0], (char*)arg, sizeof(long)  * 3);
++                      data[2] = jiffies;
++                      printk("%ld, %ld\n", data[0], data[1]);
++                      //for(i = 0; i < 1024*1024; i++){
++                              foxbone_write(0x0021, (data[0]>>16)&0xffff);
++                              foxbone_write(0x0020, data[0]&0xffff);
++                              foxbone_write(0x0023, (data[1]>>16)&0xffff);
++                              foxbone_write(0x0022, data[1]&0xffff);
++                              data[0] = foxbone_read(0x0025);
++                              data[0] = (data[0] << 16) + foxbone_read(0x0024);
++                              data[1] = foxbone_read(0x0027);
++                              data[1] = (data[1] << 16) + foxbone_read(0x0026);
++                              /*printk("%4x\n", foxbone_read(0x0020));
++                              printk("%4x\n", foxbone_read(0x0021));
++                              printk("%4x\n", foxbone_read(0x0022));
++                              printk("%4x\n", foxbone_read(0x0023));
++                              
++                              printk("%4x\n", foxbone_read(0x0024));
++                              printk("%4x\n", foxbone_read(0x0025));
++                              printk("%4x\n", foxbone_read(0x0026));
++                              printk("%4x\n", foxbone_read(0x0027));
++                              */              
++                      //};
++                      data[2] = jiffies - data[2];
++                      copy_to_user((char*)arg, (char*)&data[0], sizeof(unsigned long) * 3);
++                      break;
++      
++              default:
++                      printk("fox_multiply: unknown ioctl\n");
++                      break;                  
++      }
++
++      return retval;
++};
++
++
++
++static int module_open(struct inode *inode, struct file *file){
++      // Which minor device is the user trying to access ?
++      unsigned int dev_minor = MINOR(inode->i_rdev);
++      
++      // we only supprt minor 0 at the moment
++      if(dev_minor !=  0){
++              printk("fox_multiply: trying to access unknown minor device -> %d\n", dev_minor);
++              return -ENODEV;
++      }
++      
++      // check if another app is currently using the device
++      if(foxmultiply_is_open) {
++              printk("fox_multiply: Device with minor ID %d already in use\n", dev_minor);
++              return -EBUSY;
++      }
++      
++      // more flaming
++      //printk("fox_multiply: Minor %d has been opened\n", dev_minor);
++      return 0;
++};
++
++
++// gets called when an app closes the device
++static int module_close(struct inode * inode, struct file * file){
++      // Which minor device is the user trying to access ?
++      // unsigned int dev_minor = MINOR(inode->i_rdev);
++      
++      // remember that the device has been closed
++      foxmultiply_is_open = 0;
++      
++      
++      // more flaming
++      //printk("fox_multiply: Minor %d has been closed\n", dev_minor);
++      
++      return 0;
++};
++
++// so the kernel knows which functions to access for a given operation
++struct file_operations foxmultiply_module_fops = {
++        ioctl:         module_ioctl,
++        open:          module_open,
++        release:       module_close
++};
++
++
++// module gets loaded into kernel / char dev is registered
++static int __init mod_init(void){
++      // flame the kprintk
++      printk("fox_multiply: FOX-VHDL FPGA multiplier module\n");
++      //printk("fox_multiply: Made by K. John '2B|!2B' Crispin (john@phrozen.org)\n");
++      //printk("fox_multiply: Starting ...\n");
++      
++      // register the character device
++      if(register_chrdev(DEV_MAJOR, DEV_NAME, &foxmultiply_module_fops)) {
++              printk( "fox_multiply: Error whilst opening %s (%d)\n", DEV_NAME, DEV_MAJOR);
++              return( -ENODEV );
++      };
++      
++
++      // remember that the driver has been opened
++      foxmultiply_is_open = 0;
++      printk("fox_multiply: Device %s registered for major ID %d\n", DEV_NAME, DEV_MAJOR);
++      return 0;
++}
++
++
++// we are done so shut everything down
++static void __exit mod_exit(void){
++      printk( "fox_multiply: Cleanup\n" );
++      // tell the kernel that the device is not needed anymore
++      unregister_chrdev(DEV_MAJOR, DEV_NAME);
++      
++}
++
++module_init (mod_init);
++module_exit (mod_exit);
++
++
++
++
++
++
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_multiply/Makefile linux-2.6.19.2/drivers/fox-vhdl/fox_multiply/Makefile
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_multiply/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_multiply/Makefile      2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1 @@
++obj-$(CONFIG_FOXBONE_MULTIPLY)          += fox_multiply.o
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_pwm/foxbone.h linux-2.6.19.2/drivers/fox-vhdl/fox_pwm/foxbone.h
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_pwm/foxbone.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_pwm/foxbone.h  2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,16 @@
++// prototypes for foxbone compliant modules
++
++extern unsigned int FOXBONE_release;
++extern unsigned int FOXBONE_application1;
++extern unsigned int FOXBONE_application2;
++extern unsigned int FOXBONE_application3;
++
++void foxbone_write(unsigned int add, unsigned int data);
++
++unsigned int foxbone_read(unsigned int add);
++
++void foxbone_write_next(unsigned data);
++
++unsigned int foxbone_read_next(void);
++
++void foxbone_initialise_bus(void);
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_pwm/fox_pwm.c linux-2.6.19.2/drivers/fox-vhdl/fox_pwm/fox_pwm.c
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_pwm/fox_pwm.c     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_pwm/fox_pwm.c  2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,180 @@
++/*  
++  fox_pwm.c
++  Linux Kernel Driver for FoxBone 16 channel PWM generator on FOX VHDL Board 
++  (based on FoxBone protocol interface specifications rel 0.7)    
++  For more info see: http://www.acmesystems.it/?id=120
++  Author: John Crispin
++  Copyright (C) 2006 Phrozen (http://www.phrozen.biz)
++  
++  This 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 example 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.
++    
++  To have a copy of the GNU General Public License write to the Free Software
++  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++*/
++
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/ioport.h>
++#include <linux/version.h>
++#include <linux/init.h>
++#include <asm/uaccess.h>
++#include <asm/io.h>
++#include <linux/vmalloc.h>
++#include <linux/ioport.h>  
++#include <linux/init.h>
++#include <linux/genhd.h>
++
++#define DEV_NAME                      "pwm"
++#define DEV_MAJOR                     15
++
++#include "foxbone.h"
++
++unsigned char foxpwm_is_open = 0;
++
++
++#define IOCTL_PWM_ENABLE      0x2310
++#define IOCTL_PWM_DISABLE     0x2311
++#define IOCTL_PWM_CHANNEL_BASE        0x2320
++#define IOCTL_PWM_CHANNEL0    0x2320
++#define IOCTL_PWM_CHANNEL1    0x2321
++#define IOCTL_PWM_CHANNEL2    0x2322
++#define IOCTL_PWM_CHANNEL3    0x2323
++#define IOCTL_PWM_CHANNEL4    0x2324
++#define IOCTL_PWM_CHANNEL5    0x2325
++#define IOCTL_PWM_CHANNEL6    0x2326
++#define IOCTL_PWM_CHANNEL7    0x2327
++#define IOCTL_PWM_CHANNEL8    0x2328
++#define IOCTL_PWM_CHANNEL9    0x2329
++#define IOCTL_PWM_CHANNELA    0x232a
++#define IOCTL_PWM_CHANNELB    0x232b
++#define IOCTL_PWM_CHANNELC    0x232c
++#define IOCTL_PWM_CHANNELD    0x232d
++#define IOCTL_PWM_CHANNELE    0x232e
++#define IOCTL_PWM_CHANNELF    0x232f
++
++
++// the app has send us some control data
++static int module_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg){
++      //copy_to_user((char*)arg, (char*)&audio_data, sizeof(AUDIO_DATA));
++      //copy_from_user((char*)&mp3_beep, (char*)arg, sizeof(MP3_BEEP));
++      int retval = 0;
++      unsigned int current_pwm;
++      if((cmd >= IOCTL_PWM_CHANNEL0) && (cmd <= IOCTL_PWM_CHANNELF)){
++              foxbone_write(0x0050 + (cmd - IOCTL_PWM_CHANNEL_BASE), arg);
++      } else {
++              switch (cmd) {
++                      case IOCTL_PWM_ENABLE:
++                              current_pwm = foxbone_read(0x0060);
++                              current_pwm |= (1<<arg);
++                              foxbone_write(0x0060, current_pwm);
++                              break;
++                      
++                      case IOCTL_PWM_DISABLE:
++                              current_pwm = foxbone_read(0x0060);
++                              current_pwm &= ~(1<<arg);
++                              foxbone_write(0x0060, current_pwm);
++                              break;
++                      
++                      default:
++                              printk("fox_pwm: unknown ioctl\n");
++                              break;                  
++              }
++      };
++      return retval;
++};
++
++
++
++static int module_open(struct inode *inode, struct file *file){
++      // Which minor device is the user trying to access ?
++      unsigned int dev_minor = MINOR(inode->i_rdev);
++      
++      // we only supprt minor 0 at the moment
++      if(dev_minor !=  0){
++              printk("fox_pwm: trying to access unknown minor device -> %d\n", dev_minor);
++              return -ENODEV;
++      }
++      
++      // check if another app is currently using the device
++      if(foxpwm_is_open) {
++              printk("fox_pwm: Device with minor ID %d already in use\n", dev_minor);
++              return -EBUSY;
++      }
++      
++      // more flaming
++      printk("fox_pwm: Minor %d has been opened\n", dev_minor);
++      return 0;
++};
++
++
++// gets called when an app closes the device
++static int module_close(struct inode * inode, struct file * file){
++      // Which minor device is the user trying to access ?
++      unsigned int dev_minor = MINOR(inode->i_rdev);
++      
++      // remember that the device has been closed
++      foxpwm_is_open = 0;
++      
++      
++      // more flaming
++      printk("fox_pwm: Minor %d has been closed\n", dev_minor);
++      
++      return 0;
++};
++
++// so the kernel knows which functions to access for a given operation
++struct file_operations foxpwm_module_fops = {
++        ioctl:         module_ioctl,
++        open:          module_open,
++        release:       module_close
++};
++
++
++// module gets loaded into kernel / char dev is registered
++static int __init mod_init(void){
++      // flame the kprintk
++      printk("fox_pwm: FOX-VHDL FPGA PWM module\n");
++      //printk("fox_pwm: Made by K. John '2B|!2B' Crispin (john@phrozen.org)\n");
++      //printk("fox_pwm: Starting ...\n");
++      
++      // register the character device
++      if(register_chrdev(DEV_MAJOR, DEV_NAME, &foxpwm_module_fops)) {
++              printk( "fox_pwm: Error whilst opening %s (%d)\n", DEV_NAME, DEV_MAJOR);
++              return( -ENODEV );
++      };
++      
++
++      // remember that the driver has been opened
++      foxpwm_is_open = 0;
++      printk("fox_pwm: Device %s registered for major ID %d\n", DEV_NAME, DEV_MAJOR);
++      return 0;
++}
++
++
++// we are done so shut everything down
++static void __exit mod_exit(void){
++      printk( "fox_pwm: Cleanup\n" );
++      // tell the kernel that the device is not needed anymore
++      unregister_chrdev(DEV_MAJOR, DEV_NAME);
++      
++}
++
++module_init (mod_init);
++module_exit (mod_exit);
++
++
++
++
++
++
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_pwm/Makefile linux-2.6.19.2/drivers/fox-vhdl/fox_pwm/Makefile
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_pwm/Makefile      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_pwm/Makefile   2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1 @@
++obj-$(CONFIG_FOXBONE_PWM)          += fox_pwm.o
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_timebase/foxbone.h linux-2.6.19.2/drivers/fox-vhdl/fox_timebase/foxbone.h
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_timebase/foxbone.h        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_timebase/foxbone.h     2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,16 @@
++// prototypes for foxbone compliant modules
++
++extern unsigned int FOXBONE_release;
++extern unsigned int FOXBONE_application1;
++extern unsigned int FOXBONE_application2;
++extern unsigned int FOXBONE_application3;
++
++void foxbone_write(unsigned int add, unsigned int data);
++
++unsigned int foxbone_read(unsigned int add);
++
++void foxbone_write_next(unsigned data);
++
++unsigned int foxbone_read_next(void);
++
++void foxbone_initialise_bus(void);
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_timebase/fox_timebase.c linux-2.6.19.2/drivers/fox-vhdl/fox_timebase/fox_timebase.c
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_timebase/fox_timebase.c   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_timebase/fox_timebase.c        2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,168 @@
++/*  
++  fox_timebase.c
++  Linux Kernel Driver for FoxBone TimeBase on FOX VHDL Board 
++  (based on FoxBone protocol interface specifications rel 0.7)    
++  For more info see: http://www.acmesystems.it/?id=120
++  Author: John Crispin
++  Copyright (C) 2006 Phrozen (http://www.phrozen.biz)
++  
++  This 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 example 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.
++    
++  To have a copy of the GNU General Public License write to the Free Software
++  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++*/
++
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/ioport.h>
++#include <linux/version.h>
++#include <linux/init.h>
++#include <asm/uaccess.h>
++#include <asm/io.h>
++#include <linux/vmalloc.h>
++#include <linux/ioport.h>  
++#include <linux/init.h>
++#include <linux/genhd.h>
++
++#define DEV_NAME                      "timebase"
++#define DEV_MAJOR                     191
++
++#include "foxbone.h"
++
++unsigned char foxtimebase_is_open = 0;
++
++
++#define IOCTL_FOXBONE_TIMEBASE_ENABLE         0x4645
++#define IOCTL_FOXBONE_TIMEBASE_DISABLE                0x4646
++#define IOCTL_FOXBONE_TIMEBASE_SETLO          0x4647
++#define IOCTL_FOXBONE_TIMEBASE_SETHI          0x4648
++
++// the app has send us some control data
++static int module_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg){
++      //copy_to_user((char*)arg, (char*)&audio_data, sizeof(AUDIO_DATA));
++      //copy_from_user((char*)&mp3_beep, (char*)arg, sizeof(MP3_BEEP));
++      int retval = 0;
++      switch (cmd) {
++              case IOCTL_FOXBONE_TIMEBASE_ENABLE:
++                      foxbone_write(0x0100, 0x01);
++                      break;
++                      
++              case IOCTL_FOXBONE_TIMEBASE_DISABLE:
++                      foxbone_write(0x0100, 0x00);
++                      break;
++      
++              case IOCTL_FOXBONE_TIMEBASE_SETLO:
++                      foxbone_write(0x0100, 0x00);
++                      foxbone_write(0x0102, arg);
++                      foxbone_write(0x0100, 0x01);
++                      break;
++                      
++              case IOCTL_FOXBONE_TIMEBASE_SETHI:
++                      foxbone_write(0x0100, 0x00);
++                      foxbone_write(0x0103, arg);
++                      foxbone_write(0x0100, 0x01);
++                      break;
++                      
++              default:
++                      printk("fox_timebase: unknown ioctl\n");
++                      break;                  
++      }
++
++      return retval;
++};
++
++
++
++static int module_open(struct inode *inode, struct file *file){
++      // Which minor device is the user trying to access ?
++      unsigned int dev_minor = MINOR(inode->i_rdev);
++      
++      // we only supprt minor 0 at the moment
++      if(dev_minor !=  0){
++              printk("fox_timebase: trying to access unknown minor device -> %d\n", dev_minor);
++              return -ENODEV;
++      }
++      
++      // check if another app is currently using the device
++      if(foxtimebase_is_open) {
++              printk("fox_timebase: Device with minor ID %d already in use\n", dev_minor);
++              return -EBUSY;
++      }
++      
++      // more flaming
++      printk("fox_timebase: Minor %d has been opened\n", dev_minor);
++      return 0;
++};
++
++
++// gets called when an app closes the device
++static int module_close(struct inode * inode, struct file * file){
++      // Which minor device is the user trying to access ?
++      unsigned int dev_minor = MINOR(inode->i_rdev);
++      
++      // remember that the device has been closed
++      foxtimebase_is_open = 0;
++      
++      
++      // more flaming
++      printk("fox_timebase: Minor %d has been closed\n", dev_minor);
++      
++      return 0;
++};
++
++// so the kernel knows which functions to access for a given operation
++struct file_operations foxtimebase_module_fops = {
++        ioctl:         module_ioctl,
++        open:          module_open,
++        release:       module_close
++};
++
++
++// module gets loaded into kernel / char dev is registered
++static int __init mod_init(void){
++      // flame the kprintk
++      printk("fox_timebase: FOX-VHDL FPGA timebase module\n");
++      //printk("fox_timebase: Made by K. John '2B|!2B' Crispin (john@phrozen.org)\n");
++      //printk("fox_timebase: Starting ...\n");
++      
++      // register the character device
++      if(register_chrdev(DEV_MAJOR, DEV_NAME, &foxtimebase_module_fops)) {
++              printk( "fox_timebase: Error whilst opening %s (%d)\n", DEV_NAME, DEV_MAJOR);
++              return( -ENODEV );
++      };
++      
++
++      // remember that the driver has been opened
++      foxtimebase_is_open = 0;
++      printk("fox_timebase: Device %s registered for major ID %d\n", DEV_NAME, DEV_MAJOR);
++      return 0;
++}
++
++
++// we are done so shut everything down
++static void __exit mod_exit(void){
++      printk( "fox_timebase: Cleanup\n" );
++      // tell the kernel that the device is not needed anymore
++      unregister_chrdev(DEV_MAJOR, DEV_NAME);
++      
++}
++
++module_init (mod_init);
++module_exit (mod_exit);
++
++
++
++
++
++
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_timebase/Makefile linux-2.6.19.2/drivers/fox-vhdl/fox_timebase/Makefile
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_timebase/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_timebase/Makefile      2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1 @@
++obj-$(CONFIG_FOXBONE_TIMEBASE)          += fox_timebase.o
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_vhdl_fb/fb.bak linux-2.6.19.2/drivers/fox-vhdl/fox_vhdl_fb/fb.bak
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_vhdl_fb/fb.bak    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_vhdl_fb/fb.bak 2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,661 @@
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/mm.h>
++#include <linux/tty.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++
++#include <asm/uaccess.h>
++#include <linux/fb.h>
++#include <linux/init.h>
++
++#include "foxbone.h"
++
++
++#if 0
++#define DBG(x) x
++#else
++#define DBG(x) 
++#endif
++
++
++
++// software delay
++void FOXVHDL_delay(int ms) {
++      int i,a;
++      int delayvar=10;
++      
++      for (a=0;a<ms;a++) {
++              for (i=0;i<35;i++) {
++                      delayvar*=2;        
++                      delayvar/=2;
++              } 
++      }
++}  
++
++
++
++/*
++||
++||    FOXVHDL CTL functions
++||
++*/
++
++
++static unsigned char FOXVHDL_current_bank = 0xff;
++
++static unsigned char blitting = 1;
++
++static unsigned char refreshrate = 6;
++
++
++
++unsigned int FOXVHDL_translate_BGR(unsigned char blue, unsigned char green, unsigned char red) {
++      // translate the three color passed in a single 16 bit color word
++      unsigned int result = ((blue>>3)<<11) | ((green>>2)<<5) | (red>>3);
++      return result;
++}
++
++
++
++
++// wait until the videostate pin has the wanted value
++void FOXVHDL_wait_videostate(unsigned char wait_state){
++/*    unsigned char vid_state = 0;
++      unsigned int max_error = 0xffff;
++      //printk("Start wait\n");
++      do {
++              vid_state = FOXVHDL_get_bit_B(Fox_line_VideoState);
++              max_error--;
++      } while((vid_state != wait_state)&&(max_error > 10));
++      */
++      DBG(if(max_error < 11){printk("Stop wait\n");};)
++};
++      
++
++// choose the bank that we want to display
++// OG5 == 0 --> Bank0
++// OG5 == 1 --> Bank1
++void FOXVHDL_set_bank(unsigned char bank){
++      DBG(printk("%d, %d\n",FOXVHDL_current_bank, bank);)
++      if(FOXVHDL_current_bank == bank){
++              return;
++      };
++      
++      DBG(printk("FOXVHDL_set_bank\n");)
++      
++      FOXVHDL_current_bank = bank;
++      foxbone_write(0x7001, FOXVHDL_current_bank);    
++      
++      
++};
++
++
++// blit the bank
++void FOXVHDL_swap_bank(void){
++      FOXVHDL_set_bank((FOXVHDL_current_bank)?(0):(1));       
++};
++
++
++// initialise the I/O pins
++void FOXVHDL_init(void){
++      DBG(printk("FOXVHDL_init\n");)
++      
++      FOXVHDL_current_bank = 0;
++      
++      FOXVHDL_set_bank(1);
++      
++};
++
++/*
++||
++||    FOXVHDL IMAGE FUNCTIONS
++||
++*/
++#define Fox_line_WriteData        (1<<2)
++
++void FOXVHDL_blit(unsigned short int *image){
++      unsigned long i;
++      unsigned int fb_ctl_reg;
++      
++      if(blitting){
++              // reset the address pointer
++              fb_ctl_reg = foxbone_read(0x7001);
++              fb_ctl_reg |= (1<<4);
++              foxbone_write(0x7001, fb_ctl_reg);
++              fb_ctl_reg &= ~(1<<4);
++              foxbone_write(0x7001, fb_ctl_reg);
++                               
++              foxbone_write(0x7000, image[0]);
++              genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g8_15dir);
++              *R_GEN_CONFIG = genconfig_shadow;
++              genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g16_23dir);
++              *R_GEN_CONFIG = genconfig_shadow;       
++
++              for(i = 1; i < 640 * 400; i++){
++
++                      *R_PORT_G_DATA = port_g_data_shadow = 
++                                              (port_g_data_shadow & 0xff0000ff) | image[i]<<8;
++                      *R_PORT_G_DATA = port_g_data_shadow |= Fox_line_WriteData;
++                      *R_PORT_G_DATA = port_g_data_shadow &= ~Fox_line_WriteData;
++              };
++              for(i = 0; i <6144; i++){
++                      foxbone_write_next(0);
++              };
++              FOXVHDL_swap_bank();
++      };
++};
++
++
++
++
++
++
++/*
++||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++||
++||                                                                            FRAMEBUFFER CODE
++||
++||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++
++*/
++
++
++
++
++#define VIDEOMEMSIZE  (640 * 400 * 2) //512K
++
++static void *videomemory;
++static u_long videomemorysize = VIDEOMEMSIZE;
++
++static unsigned char fb_started = 0;
++
++static struct fb_var_screeninfo foxfb_default __initdata = {
++      .xres =         640,
++      .yres =         400,
++      .xres_virtual = 640,
++      .yres_virtual = 400,
++      .bits_per_pixel = 16,
++      .red =          { 0, 5, 0 },
++      .green =        { 5, 6, 0 },
++      .blue =         { 11, 5, 0 },
++      .activate =     FB_ACTIVATE_NOW,
++      .height =       -1,
++      .width =        -1,
++      .vmode =        FB_VMODE_NONINTERLACED,
++};
++
++static struct fb_fix_screeninfo foxfb_fix __initdata = {
++      .id =           "FOX-VHDL FB",
++      .type =         FB_TYPE_PACKED_PIXELS,
++      .visual =       FB_VISUAL_TRUECOLOR,
++      .xpanstep =     1,
++      .ypanstep =     1,
++      .ywrapstep =    1,
++      .accel =        FB_ACCEL_NONE,
++};
++
++static int foxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
++static int foxfb_set_par(struct fb_info *info);
++static int foxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info);
++static int foxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
++static int foxfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
++static void foxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
++static void foxfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
++static void foxfb_imageblit(struct fb_info *info, const struct fb_image *image);
++
++static int foxfb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
++
++static struct fb_ops foxfb_ops = {
++      .fb_check_var   = foxfb_check_var,
++      .fb_set_par             = foxfb_set_par,
++      .fb_setcolreg   = foxfb_setcolreg,
++
++      .fb_pan_display = foxfb_pan_display,
++      .fb_fillrect    = foxfb_fillrect, //cfb_fillrect,
++      .fb_copyarea    = foxfb_copyarea, //cfb_copyarea,
++      .fb_imageblit   = foxfb_imageblit,//cfb_imageblit,
++      .fb_mmap                = foxfb_mmap,
++      .fb_ioctl               = foxfb_ioctl,
++};
++
++// this function is defined in fbmem.c
++extern int fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
++
++// this should be a free one
++#define FOX_FBIOGET_SCREEN    0x4642
++#define FOX_FBBLIT            0x4643
++#define FOX_FB_RATE           0x4645
++#define FOX_FB_TFT            0x4646
++static int foxfb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){
++      void __user *argp = (void __user *)arg;
++      unsigned int fb_ctl_reg;
++      switch(cmd){
++              // this assumes that arg points to a VIDEOMEMSIZE area of memory in user space
++              case FOX_FBIOGET_SCREEN:
++                      if(copy_to_user(argp, videomemory, VIDEOMEMSIZE)){
++                              return 0;
++                      } else {
++                              return -1;
++                      };
++              case FOX_FBBLIT:
++                      fb_ctl_reg = foxbone_read(0x7001);
++                      if(arg){
++                              printk("Enable FB\n");
++                              fb_ctl_reg &= ~(1<<1);
++                      } else {
++                              printk("Disable FB\n");
++                              fb_ctl_reg |= (1<<1);
++                      };              
++                      blitting = arg;
++                      foxbone_write(0x7001, fb_ctl_reg);
++                      break;
++              case FOX_FB_RATE:
++                      if((arg > 9) || (arg < 1)){
++                              printk("fb0 : Illegal refreshrate\n");
++                              break;
++                      };
++                      refreshrate = arg;
++                      printk("fb0 : new refreshrate\n");
++                      break;
++              case FOX_FB_TFT:
++                      fb_ctl_reg = foxbone_read(0x7001);
++                      if(arg){
++                              printk("Enable TFT\n");
++                              fb_ctl_reg |= (1<<3);
++                      } else {
++                              printk("Disable TFT\n");
++                              fb_ctl_reg &= ~(1<<3);
++                      };
++                      foxbone_write(0x7001, fb_ctl_reg);
++                      break;
++              default:
++                      return fb_ioctl(inode, file, cmd, arg);         
++      };
++      return 0;
++};
++
++// TODO add our own optimized code here
++static void foxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect){
++      cfb_fillrect(info, rect);
++};
++
++
++// TODO add our own optimized code here
++static void foxfb_copyarea(struct fb_info *info, const struct fb_copyarea *area){
++      cfb_copyarea(info, area);
++};
++
++// TODO add our own optimized code here
++static void foxfb_imageblit(struct fb_info *info, const struct fb_image *image){
++      cfb_imageblit(info, image);
++};
++
++
++/*
++ *  Internal routines
++ */
++
++static u_long get_line_length(int xres_virtual, int bpp)
++{
++      u_long length;
++
++      length = xres_virtual * bpp;
++      length = (length + 31) & ~31;
++      length >>= 3;
++      return (length);
++}
++
++    /*
++     *  Setting the video mode has been split into two parts.
++     *  First part, xxxfb_check_var, must not write anything
++     *  to hardware, it should only verify and adjust var.
++     *  This means it doesn't alter par but it does use hardware
++     *  data from it to check this var. 
++     */
++
++static int foxfb_check_var(struct fb_var_screeninfo *var,
++                       struct fb_info *info)
++{
++      u_long line_length;
++
++      if (var->vmode & FB_VMODE_CONUPDATE) {
++              var->vmode |= FB_VMODE_YWRAP;
++              var->xoffset = info->var.xoffset;
++              var->yoffset = info->var.yoffset;
++      }
++
++      var->xres = 640;
++      var->yres = 400;
++      
++      var->bits_per_pixel = 16;
++      
++      if (var->xres_virtual < var->xoffset + var->xres)
++              var->xres_virtual = var->xoffset + var->xres;
++      if (var->yres_virtual < var->yoffset + var->yres)
++              var->yres_virtual = var->yoffset + var->yres;
++
++      line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
++      if (line_length * var->yres_virtual > videomemorysize)
++              return -ENOMEM;
++
++      var->red.offset = 0;
++      var->red.length = 5;
++      var->green.offset = 5;
++      var->green.length = 6;
++      var->blue.offset = 11;
++      var->blue.length = 5;
++      var->transp.offset = 0;
++      var->transp.length = 0;
++      var->red.msb_right = 0;
++      var->green.msb_right = 0;
++      var->blue.msb_right = 0;
++      var->transp.msb_right = 0;
++
++      return 0;
++}
++
++
++
++/* This routine actually sets the video mode. It's in here where we
++ * the hardware state info->par and fix which can be affected by the 
++ * change in par. For this driver it doesn't do much. 
++ */
++static int foxfb_set_par(struct fb_info *info){
++      info->fix.line_length = get_line_length(info->var.xres_virtual, info->var.bits_per_pixel);
++      return 0;
++}
++
++/*
++ *  Set a single color register. The values supplied are already
++ *  rounded down to the hardware's capabilities (according to the
++ *  entries in the var structure). Return != 0 for invalid regno.
++ */
++
++
++static int foxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info){
++      if (regno >= 256)       /* no. of hw registers */
++              return 1;
++
++      /* grayscale works only partially under directcolor */
++      if (info->var.grayscale) {
++              /* grayscale = 0.30*R + 0.59*G + 0.11*B */
++              red = green = blue =
++                  (red * 77 + green * 151 + blue * 28) >> 8;
++      }
++
++      /* Directcolor:
++       *   var->{color}.offset contains start of bitfield
++       *   var->{color}.length contains length of bitfield
++       *   {hardwarespecific} contains width of RAMDAC
++       *   cmap[X] is programmed to (X << red.offset) | (X << green.offset) | (X << blue.offset)
++       *   RAMDAC[X] is programmed to (red, green, blue)
++       * 
++       * Pseudocolor:
++       *    uses offset = 0 && length = RAMDAC register width.
++       *    var->{color}.offset is 0
++       *    var->{color}.length contains widht of DAC
++       *    cmap is not used
++       *    RAMDAC[X] is programmed to (red, green, blue)
++       * Truecolor:
++       *    does not use DAC. Usually 3 are present.
++       *    var->{color}.offset contains start of bitfield
++       *    var->{color}.length contains length of bitfield
++       *    cmap is programmed to (red << red.offset) | (green << green.offset) |
++       *                      (blue << blue.offset) | (transp << transp.offset)
++       *    RAMDAC does not exist
++       */
++#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
++      switch (info->fix.visual) {
++      case FB_VISUAL_TRUECOLOR:
++      case FB_VISUAL_PSEUDOCOLOR:
++              red = CNVT_TOHW(red, info->var.red.length);
++              green = CNVT_TOHW(green, info->var.green.length);
++              blue = CNVT_TOHW(blue, info->var.blue.length);
++              transp = CNVT_TOHW(transp, info->var.transp.length);
++              break;
++      case FB_VISUAL_DIRECTCOLOR:
++              red = CNVT_TOHW(red, 8);        /* expect 8 bit DAC */
++              green = CNVT_TOHW(green, 8);
++              blue = CNVT_TOHW(blue, 8);
++              /* hey, there is bug in transp handling... */
++              transp = CNVT_TOHW(transp, 8);
++              break;
++      }
++#undef CNVT_TOHW
++      /* Truecolor has hardware independent palette */
++      if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
++              u32 v;
++
++              if (regno >= 16)
++                      return 1;
++
++              v = (red << info->var.red.offset) |
++                  (green << info->var.green.offset) |
++                  (blue << info->var.blue.offset) |
++                  (transp << info->var.transp.offset);
++              switch (info->var.bits_per_pixel) {
++              case 8:
++                      break;
++              case 16:
++                      ((u32 *) (info->pseudo_palette))[regno] = v;
++                      break;
++              case 24:
++              case 32:
++                      ((u32 *) (info->pseudo_palette))[regno] = v;
++                      break;
++              }
++              return 0;
++      }
++      return 0;
++}
++
++    /*
++     *  Pan or Wrap the Display
++     *
++     *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
++     */
++
++static int foxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info){
++      if (var->vmode & FB_VMODE_YWRAP) {
++              if (var->yoffset < 0
++                  || var->yoffset >= info->var.yres_virtual
++                  || var->xoffset)
++                      return -EINVAL;
++      } else {
++              if (var->xoffset + var->xres > info->var.xres_virtual ||
++                  var->yoffset + var->yres > info->var.yres_virtual)
++                      return -EINVAL;
++      }
++      info->var.xoffset = var->xoffset;
++      info->var.yoffset = var->yoffset;
++      if (var->vmode & FB_VMODE_YWRAP)
++              info->var.vmode |= FB_VMODE_YWRAP;
++      else
++              info->var.vmode &= ~FB_VMODE_YWRAP;
++      return 0;
++}
++
++/*
++ *  Most drivers don't need their own mmap function 
++ */
++
++static int foxfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma){
++        unsigned long page, pos;
++        unsigned long start = vma->vm_start;
++        unsigned long size  = vma->vm_end-vma->vm_start;
++        printk("mmap : %ld %ld\n", size, info->fix.smem_len);
++      //if (size > info->fix.smem_len){
++        //       return -EINVAL;
++      //}
++        printk("MMAP2\n");
++      pos = (unsigned long) info->screen_base;
++        while (size > 0) {
++                page = page_to_pfn(vmalloc_to_page((void *)pos));
++              if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
++                      return -EAGAIN;
++              start += PAGE_SIZE;
++              pos += PAGE_SIZE;
++              if (size > PAGE_SIZE)
++                      size -= PAGE_SIZE;
++              else
++                      size = 0;
++        }
++        return 0;
++}
++
++
++
++
++
++// our timer
++struct timer_list foxfb_timer;
++
++
++// the prototype for the callback
++static void foxfb_timer_callback(unsigned long ptr);
++
++
++// setup the mmc timer
++static void foxfb_timer_setup(void){
++      init_timer(&foxfb_timer);
++      foxfb_timer.function = foxfb_timer_callback;
++      foxfb_timer.data = 0;
++      foxfb_timer.expires = jiffies + ( HZ / refreshrate);
++      add_timer(&foxfb_timer);        
++};
++
++
++// the timer callback function that detects if the card status has changed
++static void foxfb_timer_callback(unsigned long ptr){
++      del_timer(&foxfb_timer);
++      FOXVHDL_blit(videomemory);
++      foxfb_timer_setup();
++};
++
++
++static void foxfb_platform_release(struct device *device){
++      // This is called when the reference count goes to zero.
++}
++
++
++static int __init foxfb_probe(struct platform_device *dev){
++      struct fb_info *info;
++      int retval = -ENOMEM;
++
++      if (!(videomemory = vmalloc(videomemorysize)))
++              return retval;
++              
++      memset(videomemory, 0, videomemorysize);
++
++      info = framebuffer_alloc(sizeof(u32) * 256, &dev->dev);
++      if (!info)
++              goto err;
++
++      info->screen_base = (char*)videomemory;
++      info->fbops = &foxfb_ops;
++      info->fix.smem_len = videomemorysize;
++      retval = fb_find_mode(&info->var, info, NULL,
++                            NULL, 0, NULL, 8);
++
++      if (!retval || (retval == 4))
++              info->var = foxfb_default;
++
++      info->fix = foxfb_fix;
++      info->pseudo_palette = info->par;
++      info->par = NULL;
++      info->flags = FBINFO_FLAG_DEFAULT;
++
++      retval = fb_alloc_cmap(&info->cmap, 256, 0);
++      if (retval < 0)
++              goto err1;
++
++      retval = register_framebuffer(info);
++      if (retval < 0)
++              goto err2;
++      platform_set_drvdata(dev, info);
++
++      printk(KERN_INFO
++             "fb%d: FOX-VHDL frame buffer device, using %ldK of video memory\n",
++             info->node, videomemorysize >> 10);
++      
++      
++      //FOXVHDL_blit(videomemory);  
++      foxfb_timer_setup();
++      return 0;
++err2:
++      fb_dealloc_cmap(&info->cmap);
++err1:
++      framebuffer_release(info);
++err:
++      vfree(videomemory);
++      return retval;
++}
++
++static int foxfb_remove(struct platform_device *dev)
++{
++      struct fb_info *info = platform_get_drvdata(dev);
++
++      if (info) {
++              unregister_framebuffer(info);
++              vfree(videomemory);
++              framebuffer_release(info);
++      }
++      return 0;
++}
++
++static struct platform_driver foxfb_driver = {
++      .probe  = foxfb_probe,
++      .remove = foxfb_remove,
++      .driver = {
++              .name   = "foxfb",
++      },
++};
++
++static struct platform_device foxfb_device = {
++      .name   = "foxfb",
++      .id     = 0,
++      .dev    = {
++              .release = foxfb_platform_release,
++      }
++};
++
++static int __init foxfb_init(void)
++{
++      int ret = 0;
++      refreshrate = 8;
++      printk(KERN_INFO "fb: Initialising framebuffer\n");
++      
++      FOXVHDL_init();
++
++      ret = platform_driver_register(&foxfb_driver);
++
++      if (!ret) {
++              ret = platform_device_register(&foxfb_device);
++              if (ret)
++                      platform_driver_unregister(&foxfb_driver);
++      }       
++      fb_started = 1;
++      return ret;
++}
++
++static void __exit foxfb_exit(void)
++{
++      platform_device_unregister(&foxfb_device);
++      platform_driver_unregister(&foxfb_driver);
++}
++
++module_exit(foxfb_exit);
++module_init(foxfb_init);
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("K. John '2B|!2B' Crispin");
++MODULE_DESCRIPTION("FOX-VHDL Framebuffer Driver");
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_vhdl_fb/foxbone.h linux-2.6.19.2/drivers/fox-vhdl/fox_vhdl_fb/foxbone.h
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_vhdl_fb/foxbone.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_vhdl_fb/foxbone.h      2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,20 @@
++// prototypes for foxbone compliant modules
++
++extern unsigned int FOXBONE_release;
++extern unsigned int FOXBONE_application1;
++extern unsigned int FOXBONE_application2;
++extern unsigned int FOXBONE_application3;
++
++void foxbone_write(unsigned int add, unsigned int data);
++
++unsigned int foxbone_read(unsigned int add);
++
++void foxbone_write_next(unsigned data);
++
++unsigned int foxbone_read_next(void);
++
++void foxbone_initialise_bus(void);
++
++void foxbone_lock(void);
++
++void foxbone_unlock(void);
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_vhdl_fb/foxvhdlfb.c linux-2.6.19.2/drivers/fox-vhdl/fox_vhdl_fb/foxvhdlfb.c
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_vhdl_fb/foxvhdlfb.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_vhdl_fb/foxvhdlfb.c    2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,691 @@
++/*  
++  foxvhdlfb.c
++  Linux Kernel Driver for FoxBone FrameBuffer on FOX VHDL Board 
++  (based on FoxBone protocol interface specifications rel 0.7)    
++  For more info see: http://www.acmesystems.it/?id=120
++  Author: John Crispin
++  Copyright (C) 2006 Phrozen (http://www.phrozen.biz)
++  
++  This 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 example 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.
++    
++  To have a copy of the GNU General Public License write to the Free Software
++  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++*/
++
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/mm.h>
++#include <linux/tty.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++
++#include <asm/uaccess.h>
++#include <linux/fb.h>
++#include <linux/init.h>
++
++#include "foxbone.h"
++
++
++#if 0
++#define DBG(x) x
++#else
++#define DBG(x) 
++#endif
++
++
++/*
++||
++||    FOXVHDL CTL functions
++||
++*/
++
++
++static unsigned char FOXVHDL_current_bank = 0xff;
++
++static unsigned char blitting = 1;
++
++static unsigned char refreshrate = 6;
++
++
++
++unsigned int FOXVHDL_translate_BGR(unsigned char blue, unsigned char green, unsigned char red) {
++      // translate the three color passed in a single 16 bit color word
++      unsigned int result = ((blue>>3)<<11) | ((green>>2)<<5) | (red>>3);
++      return result;
++}
++
++
++
++
++// wait until the videostate pin has the wanted value
++void FOXVHDL_wait_videostate(unsigned char wait_state){
++/*    unsigned char vid_state = 0;
++      unsigned int max_error = 0xffff;
++      //printk("Start wait\n");
++      do {
++              vid_state = FOXVHDL_get_bit_B(Fox_line_VideoState);
++              max_error--;
++      } while((vid_state != wait_state)&&(max_error > 10));
++      */
++      DBG(if(max_error < 11){printk("Stop wait\n");};)
++};
++      
++
++// choose the bank that we want to display
++// OG5 == 0 --> Bank0
++// OG5 == 1 --> Bank1
++void FOXVHDL_set_bank(unsigned char bank){
++      DBG(printk("%d, %d\n",FOXVHDL_current_bank, bank);)
++      if(FOXVHDL_current_bank == bank){
++              return;
++      };
++      
++      DBG(printk("FOXVHDL_set_bank\n");)
++      
++      FOXVHDL_current_bank = bank;
++      foxbone_write(0x7001, FOXVHDL_current_bank);    
++      
++      
++};
++
++
++// blit the bank
++void FOXVHDL_swap_bank(void){
++      FOXVHDL_set_bank((FOXVHDL_current_bank)?(0):(1));       
++};
++
++
++// initialise the I/O pins
++void FOXVHDL_init(void){
++      DBG(printk("FOXVHDL_init\n");)
++      
++      FOXVHDL_current_bank = 0;
++      
++      FOXVHDL_set_bank(1);
++      
++};
++
++/*
++||
++||    FOXVHDL IMAGE FUNCTIONS
++||
++*/
++#define Fox_line_WriteData        (1<<2)
++
++// for performance reasons, we do not use the foxbone access functions here
++// we rather use an optimised algorithm. blitting now only takes about 6 ms. 
++// meaning we can that effectivley achieve 17 frame. however the refresh rate by
++// default is 4 fps
++
++#if 0
++#define DBG_TIMER(x) x
++#else
++#define DBG_TIMER(x) 
++#endif
++
++#if 0
++#define DOUBLE_DATA_RATE
++#endif
++
++void FOXVHDL_blit(unsigned short int *image){
++      unsigned long i;
++      unsigned int fb_ctl_reg;
++      
++      if(blitting){
++              foxbone_lock();
++              DBG_TIMER(unsigned long j = jiffies;)
++              // reset the address pointer
++              fb_ctl_reg = foxbone_read(0x7001);
++              fb_ctl_reg |= (1<<4);
++              foxbone_write(0x7001, fb_ctl_reg);
++              fb_ctl_reg &= ~(1<<4);
++              foxbone_write(0x7001, fb_ctl_reg);
++                               
++              foxbone_write(0x7000, image[0]);
++              genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g8_15dir);
++              *R_GEN_CONFIG = genconfig_shadow;
++              genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g16_23dir);
++              *R_GEN_CONFIG = genconfig_shadow;       
++              
++              *R_PORT_G_DATA = port_g_data_shadow = (port_g_data_shadow & 0xff0000ff);
++              
++
++#ifdef DOUBLE_DATA_RATE
++      
++              unsigned long def_val = (port_g_data_shadow & 0xff0000ff);
++              for(i = 1; i < 640 * 400; i+=2){
++                      *R_PORT_G_DATA = port_g_data_shadow = def_val | image[i]<<8 | Fox_line_WriteData;
++                      *R_PORT_G_DATA = port_g_data_shadow = def_val | image[i+1]<<8;
++              };
++              *R_PORT_G_DATA = port_g_data_shadow &= ~Fox_line_WriteData;
++              
++#else 
++      
++              unsigned long def_val = (port_g_data_shadow & 0xff0000ff) | Fox_line_WriteData;
++              for(i = 1; i < 640 * 400; i++){ 
++                      *R_PORT_G_DATA = port_g_data_shadow = def_val | image[i]<<8;
++                      *R_PORT_G_DATA = port_g_data_shadow &= ~Fox_line_WriteData;
++              };
++#endif                        
++              foxbone_unlock();
++              FOXVHDL_swap_bank();
++              DBG_TIMER(printk("%ld\n", jiffies - j);)
++              
++      };
++};
++
++
++
++
++
++
++/*
++||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++||
++||                                                                            FRAMEBUFFER CODE
++||
++||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++
++*/
++
++
++
++
++#define VIDEOMEMSIZE  (640 * 400 * 2) //512K
++
++static void *videomemory;
++static u_long videomemorysize = VIDEOMEMSIZE;
++
++static unsigned char fb_started = 0;
++
++static unsigned char fb_update = 0;
++
++static unsigned char fb_mmap_enable = 0;
++
++static struct fb_var_screeninfo foxfb_default __initdata = {
++      .xres =         640,
++      .yres =         400,
++      .xres_virtual = 640,
++      .yres_virtual = 400,
++      .bits_per_pixel = 16,
++      .red =          { 0, 5, 0 },
++      .green =        { 5, 6, 0 },
++      .blue =         { 11, 5, 0 },
++      .activate =     FB_ACTIVATE_NOW,
++      .height =       -1,
++      .width =        -1,
++      .vmode =        FB_VMODE_NONINTERLACED,
++};
++
++static struct fb_fix_screeninfo foxfb_fix __initdata = {
++      .id =           "FOX-VHDL FB",
++      .type =         FB_TYPE_PACKED_PIXELS,
++      .visual =       FB_VISUAL_TRUECOLOR,
++      .xpanstep =     1,
++      .ypanstep =     1,
++      .ywrapstep =    1,
++      .accel =        FB_ACCEL_NONE,
++};
++
++static int foxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
++static int foxfb_set_par(struct fb_info *info);
++static int foxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info);
++static int foxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
++static int foxfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
++static void foxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
++static void foxfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
++static void foxfb_imageblit(struct fb_info *info, const struct fb_image *image);
++
++static int foxfb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
++
++static struct fb_ops foxfb_ops = {
++      .fb_check_var   = foxfb_check_var,
++      .fb_set_par             = foxfb_set_par,
++      .fb_setcolreg   = foxfb_setcolreg,
++
++      .fb_pan_display = foxfb_pan_display,
++      .fb_fillrect    = foxfb_fillrect, //cfb_fillrect,
++      .fb_copyarea    = foxfb_copyarea, //cfb_copyarea,
++      .fb_imageblit   = foxfb_imageblit,//cfb_imageblit,
++      .fb_mmap        = foxfb_mmap,
++      .fb_ioctl       = foxfb_ioctl,
++};
++
++// this function is defined in fbmem.c
++extern int fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
++
++// this should be a free one
++#define FOX_FBIOGET_SCREEN    0x4642
++#define FOX_FBBLIT            0x4643
++#define FOX_FB_RATE           0x4645
++#define FOX_FB_TFT            0x4646
++static int foxfb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){
++      void __user *argp = (void __user *)arg;
++      unsigned int fb_ctl_reg;
++      switch(cmd){
++              // this assumes that arg points to a VIDEOMEMSIZE area of memory in user space
++              case FOX_FBIOGET_SCREEN:
++                      if(copy_to_user(argp, videomemory, VIDEOMEMSIZE)){
++                              return 0;
++                      } else {
++                              return -1;
++                      };
++              case FOX_FBBLIT:
++                      fb_ctl_reg = foxbone_read(0x7001);
++                      if(arg){
++                              printk("Enable FB\n");
++                              fb_ctl_reg &= ~(1<<1);
++                      } else {
++                              printk("Disable FB\n");
++                              fb_ctl_reg |= (1<<1);
++                      };              
++                      blitting = arg;
++                      foxbone_write(0x7001, fb_ctl_reg);
++                      break;
++              case FOX_FB_RATE:
++                      if((arg > 9) || (arg < 1)){
++                              printk("fb0 : Illegal refreshrate\n");
++                              break;
++                      };
++                      refreshrate = arg;
++                      printk("fb0 : new refreshrate\n");
++                      break;
++              case FOX_FB_TFT:
++                      fb_ctl_reg = foxbone_read(0x7001);
++                      if(arg){
++                              printk("Enable TFT\n");
++                              fb_ctl_reg |= (1<<3);
++                      } else {
++                              printk("Disable TFT\n");
++                              fb_ctl_reg &= ~(1<<3);
++                      };
++                      foxbone_write(0x7001, fb_ctl_reg);
++                      break;
++              default:
++                      return fb_ioctl(inode, file, cmd, arg);         
++      };
++      return 0;
++};
++
++// TODO add our own optimized code here
++static void foxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect){
++      cfb_fillrect(info, rect);
++      fb_update = 1;
++};
++
++
++// TODO add our own optimized code here
++static void foxfb_copyarea(struct fb_info *info, const struct fb_copyarea *area){
++      cfb_copyarea(info, area);
++      fb_update = 1;
++};
++
++// TODO add our own optimized code here
++static void foxfb_imageblit(struct fb_info *info, const struct fb_image *image){
++      cfb_imageblit(info, image);
++      fb_update = 1;
++};
++
++
++/*
++ *  Internal routines
++ */
++
++static u_long get_line_length(int xres_virtual, int bpp)
++{
++      u_long length;
++
++      length = xres_virtual * bpp;
++      length = (length + 31) & ~31;
++      length >>= 3;
++      return (length);
++}
++
++    /*
++     *  Setting the video mode has been split into two parts.
++     *  First part, xxxfb_check_var, must not write anything
++     *  to hardware, it should only verify and adjust var.
++     *  This means it doesn't alter par but it does use hardware
++     *  data from it to check this var. 
++     */
++
++static int foxfb_check_var(struct fb_var_screeninfo *var,
++                       struct fb_info *info)
++{
++      u_long line_length;
++
++      if (var->vmode & FB_VMODE_CONUPDATE) {
++              var->vmode |= FB_VMODE_YWRAP;
++              var->xoffset = info->var.xoffset;
++              var->yoffset = info->var.yoffset;
++      }
++
++      var->xres = 640;
++      var->yres = 400;
++      
++      var->bits_per_pixel = 16;
++      
++      if (var->xres_virtual < var->xoffset + var->xres)
++              var->xres_virtual = var->xoffset + var->xres;
++      if (var->yres_virtual < var->yoffset + var->yres)
++              var->yres_virtual = var->yoffset + var->yres;
++
++      line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
++      if (line_length * var->yres_virtual > videomemorysize)
++              return -ENOMEM;
++
++      var->red.offset = 0;
++      var->red.length = 5;
++      var->green.offset = 5;
++      var->green.length = 6;
++      var->blue.offset = 11;
++      var->blue.length = 5;
++      var->transp.offset = 0;
++      var->transp.length = 0;
++      var->red.msb_right = 0;
++      var->green.msb_right = 0;
++      var->blue.msb_right = 0;
++      var->transp.msb_right = 0;
++
++      return 0;
++}
++
++
++
++/* This routine actually sets the video mode. It's in here where we
++ * the hardware state info->par and fix which can be affected by the 
++ * change in par. For this driver it doesn't do much. 
++ */
++static int foxfb_set_par(struct fb_info *info){
++      info->fix.line_length = get_line_length(info->var.xres_virtual, info->var.bits_per_pixel);
++      return 0;
++}
++
++/*
++ *  Set a single color register. The values supplied are already
++ *  rounded down to the hardware's capabilities (according to the
++ *  entries in the var structure). Return != 0 for invalid regno.
++ */
++
++
++static int foxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info){
++      if (regno >= 256)       /* no. of hw registers */
++              return 1;
++
++      /* grayscale works only partially under directcolor */
++      if (info->var.grayscale) {
++              /* grayscale = 0.30*R + 0.59*G + 0.11*B */
++              red = green = blue =
++                  (red * 77 + green * 151 + blue * 28) >> 8;
++      }
++
++#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
++      switch (info->fix.visual) {
++      case FB_VISUAL_TRUECOLOR:
++      case FB_VISUAL_PSEUDOCOLOR:
++              red = CNVT_TOHW(red, info->var.red.length);
++              green = CNVT_TOHW(green, info->var.green.length);
++              blue = CNVT_TOHW(blue, info->var.blue.length);
++              transp = CNVT_TOHW(transp, info->var.transp.length);
++              break;
++      case FB_VISUAL_DIRECTCOLOR:
++              red = CNVT_TOHW(red, 8);        /* expect 8 bit DAC */
++              green = CNVT_TOHW(green, 8);
++              blue = CNVT_TOHW(blue, 8);
++              /* hey, there is bug in transp handling... */
++              transp = CNVT_TOHW(transp, 8);
++              break;
++      }
++#undef CNVT_TOHW
++      /* Truecolor has hardware independent palette */
++      if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
++              u32 v;
++
++              if (regno >= 16)
++                      return 1;
++
++              v = (red << info->var.red.offset) |
++                  (green << info->var.green.offset) |
++                  (blue << info->var.blue.offset) |
++                  (transp << info->var.transp.offset);
++              switch (info->var.bits_per_pixel) {
++              case 8:
++                      break;
++              case 16:
++                      ((u32 *) (info->pseudo_palette))[regno] = v;
++                      break;
++              case 24:
++              case 32:
++                      ((u32 *) (info->pseudo_palette))[regno] = v;
++                      break;
++              }
++              return 0;
++      }
++      return 0;
++}
++
++
++static int foxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info){
++      if (var->vmode & FB_VMODE_YWRAP) {
++              if (var->yoffset < 0
++                  || var->yoffset >= info->var.yres_virtual
++                  || var->xoffset)
++                      return -EINVAL;
++      } else {
++              if (var->xoffset + var->xres > info->var.xres_virtual ||
++                  var->yoffset + var->yres > info->var.yres_virtual)
++                      return -EINVAL;
++      }
++      info->var.xoffset = var->xoffset;
++      info->var.yoffset = var->yoffset;
++      if (var->vmode & FB_VMODE_YWRAP)
++              info->var.vmode |= FB_VMODE_YWRAP;
++      else
++              info->var.vmode &= ~FB_VMODE_YWRAP;
++      return 0;
++}
++
++
++static int foxfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma){
++        unsigned long page, pos;
++        unsigned long start = vma->vm_start;
++        unsigned long size  = vma->vm_end-vma->vm_start;
++        fb_mmap_enable = 1;
++      printk("mmap : %ld %ld\n", size, (long)info->fix.smem_len);
++      //if (size > info->fix.smem_len){
++        //       return -EINVAL;
++      //}
++      pos = (unsigned long) info->screen_base;
++        while (size > 0) {
++                page = page_to_pfn(vmalloc_to_page((void *)pos));
++              if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
++                      return -EAGAIN;
++              start += PAGE_SIZE;
++              pos += PAGE_SIZE;
++              if (size > PAGE_SIZE)
++                      size -= PAGE_SIZE;
++              else
++                      size = 0;
++        }
++        return 0;
++}
++
++
++// our timer
++struct timer_list foxfb_timer;
++
++// are we currently blitting ?
++static unsigned char we_are_blitting = 0;
++
++// the prototype for the callback
++static void foxfb_timer_callback(unsigned long ptr);
++
++
++static void tasklet_foxfb(unsigned long data);
++DECLARE_TASKLET(tl_foxfb_descr, tasklet_foxfb, 0L);
++static void tasklet_foxfb(unsigned long data){
++      if(fb_update || fb_mmap_enable  ){
++              FOXVHDL_blit(videomemory);
++      } else {
++              DBG(printk("FBWAIT");)
++      };
++      we_are_blitting = 0;
++      fb_update = 0;
++}
++
++
++// setup the fb timer
++static void foxfb_timer_setup(void){
++      init_timer(&foxfb_timer);
++      foxfb_timer.function = foxfb_timer_callback;
++      foxfb_timer.data = 0;
++      foxfb_timer.expires = jiffies + ( HZ / refreshrate);
++      add_timer(&foxfb_timer);        
++};
++
++
++// the timer callback function that detects if the card status has changed
++static void foxfb_timer_callback(unsigned long ptr){
++      if((!we_are_blitting)){
++              we_are_blitting = 1;
++              del_timer(&foxfb_timer);
++              tasklet_schedule(&tl_foxfb_descr);
++              foxfb_timer_setup();
++      };
++};
++
++
++static void foxfb_platform_release(struct device *device){
++      // This is called when the reference count goes to zero.
++}
++
++
++static int __init foxfb_probe(struct platform_device *dev){
++      struct fb_info *info;
++      int retval = -ENOMEM;
++
++      if (!(videomemory = vmalloc(videomemorysize)))
++              return retval;
++              
++      memset(videomemory, 0, videomemorysize);
++
++      info = framebuffer_alloc(sizeof(u32) * 256, &dev->dev);
++      if (!info)
++              goto err;
++
++      info->screen_base = (char*)videomemory;
++      info->fbops = &foxfb_ops;
++      info->fix.smem_len = videomemorysize;
++      retval = fb_find_mode(&info->var, info, NULL,
++                            NULL, 0, NULL, 8);
++
++      if (!retval || (retval == 4))
++              info->var = foxfb_default;
++
++      info->fix = foxfb_fix;
++      info->pseudo_palette = info->par;
++      info->par = NULL;
++      info->flags = FBINFO_FLAG_DEFAULT;
++      //info->cursor.mode &= ~CURSOR_BLINK;
++      retval = fb_alloc_cmap(&info->cmap, 256, 0);
++      if (retval < 0)
++              goto err1;
++
++      retval = register_framebuffer(info);
++      if (retval < 0)
++              goto err2;
++      platform_set_drvdata(dev, info);
++
++      printk(KERN_INFO
++             "fb%d: FOX-VHDL frame buffer device, using %ldK of video memory\n",
++             info->node, videomemorysize >> 10);
++      
++      
++      //FOXVHDL_blit(videomemory);  
++      foxfb_timer_setup();
++      return 0;
++err2:
++      fb_dealloc_cmap(&info->cmap);
++err1:
++      framebuffer_release(info);
++err:
++      vfree(videomemory);
++      return retval;
++}
++
++static int foxfb_remove(struct platform_device *dev)
++{
++      struct fb_info *info = platform_get_drvdata(dev);
++
++      if (info) {
++              unregister_framebuffer(info);
++              vfree(videomemory);
++              framebuffer_release(info);
++      }
++      return 0;
++}
++
++static struct platform_driver foxfb_driver = {
++      .probe  = foxfb_probe,
++      .remove = foxfb_remove,
++      .driver = {
++              .name   = "foxfb",
++      },
++};
++
++static struct platform_device foxfb_device = {
++      .name   = "foxfb",
++      .id     = 0,
++      .dev    = {
++              .release = foxfb_platform_release,
++      }
++};
++
++static int __init foxfb_init(void)
++{
++      int ret = 0;
++      refreshrate = 8;
++      printk(KERN_INFO "fb: Initialising framebuffer\n");
++      
++      FOXVHDL_init();
++
++      ret = platform_driver_register(&foxfb_driver);
++
++      if (!ret) {
++              ret = platform_device_register(&foxfb_device);
++              if (ret)
++                      platform_driver_unregister(&foxfb_driver);
++      }       
++      fb_started = 1;
++      return ret;
++}
++
++static void __exit foxfb_exit(void)
++{
++      platform_device_unregister(&foxfb_device);
++      platform_driver_unregister(&foxfb_driver);
++}
++
++module_exit(foxfb_exit);
++module_init(foxfb_init);
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("K. John '2B|!2B' Crispin");
++MODULE_DESCRIPTION("FOX-VHDL Framebuffer Driver");
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/fox_vhdl_fb/Makefile linux-2.6.19.2/drivers/fox-vhdl/fox_vhdl_fb/Makefile
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/fox_vhdl_fb/Makefile  1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/fox_vhdl_fb/Makefile       2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,5 @@
++# Makefile for fox_vhdl drivers
++# 23.04.2006 <mailto:john@phrozen.org>
++
++# the fox_vhdl_framebuffer driver
++obj-$(CONFIG_FOX_VHDL_FB)          += foxvhdlfb.o
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/Kconfig linux-2.6.19.2/drivers/fox-vhdl/Kconfig
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/Kconfig       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/Kconfig    2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,274 @@
++menu "Acmesystems FPGA"
++
++config FOX_VHDL
++      bool "Support for FOX-VHDL Board"
++      default n
++
++config FOX_FPGA
++      bool "FPGA flash module"
++      depends on FOX_VHDL
++      help
++      Adds the module needed to flash the fpga from the FOX
++
++config FOXBONE
++      bool "Basic FOXBONE support"
++      depends on FOX_VHDL
++      help
++      Include this to get basic FOXBONE support
++
++config VT
++      bool "Virtual terminal (needed for framebuffer)" if EMBEDDED
++      select INPUT
++      default y if !VIOCONS
++      ---help---
++        If you say Y here, you will get support for terminal devices with
++        display and keyboard devices. These are called "virtual" because you
++        can run several virtual terminals (also called virtual consoles) on
++        one physical terminal. This is rather useful, for example one
++        virtual terminal can collect system messages and warnings, another
++        one can be used for a text-mode user session, and a third could run
++        an X session, all in parallel. Switching between virtual terminals
++        is done with certain key combinations, usually Alt-<function key>.
++
++        The setterm command ("man setterm") can be used to change the
++        properties (such as colors or beeping) of a virtual terminal. The
++        man page console_codes(4) ("man console_codes") contains the special
++        character sequences that can be used to change those properties
++        directly. The fonts used on virtual terminals can be changed with
++        the setfont ("man setfont") command and the key bindings are defined
++        with the loadkeys ("man loadkeys") command.
++
++        You need at least one virtual terminal device in order to make use
++        of your keyboard and monitor. Therefore, only people configuring an
++        embedded system would want to say N here in order to save some
++        memory; the only way to log into such a system is then via a serial
++        or network connection.
++
++        If unsure, say Y, or else you won't be able to do much with your new
++        shiny Linux system :-)
++
++
++menu "Framebuffer"    
++depends on VT
++
++config FB
++      bool "Support for frame buffer devices"
++      depends on VT
++      ---help---
++        The frame buffer device provides an abstraction for the graphics
++        hardware. It represents the frame buffer of some video hardware and
++        allows application software to access the graphics hardware through
++        a well-defined interface, so the software doesn't need to know
++        anything about the low-level (hardware register) stuff.
++
++        Frame buffer devices work identically across the different
++        architectures supported by Linux and make the implementation of
++        application programs easier and more portable; at this point, an X
++        server exists which uses the frame buffer device exclusively.
++        On several non-X86 architectures, the frame buffer device is the
++        only way to use the graphics hardware.
++
++        The device is accessed through special device nodes, usually located
++        in the /dev directory, i.e. /dev/fb*.
++
++        You need an utility program called fbset to make full use of frame
++        buffer devices. Please read <file:Documentation/fb/framebuffer.txt>
++        and the Framebuffer-HOWTO at
++        <http://www.tahallah.demon.co.uk/programming/prog.html> for more
++        information.
++
++        Say Y here and to the driver for your graphics board below if you
++        are compiling a kernel for a non-x86 architecture.
++
++        If you are compiling for the x86 architecture, you can say Y if you
++        want to play with it, but it is not essential. Please note that
++        running graphical applications that directly touch the hardware
++        (e.g. an accelerated X server) and that are not frame buffer
++        device-aware may cause unexpected results. If unsure, say N.
++
++config FB_CFB_FILLRECT
++      tristate
++      depends on FB
++      default n
++      ---help---
++        Include the cfb_fillrect function for generic software rectangle
++        filling. This is used by drivers that don't provide their own
++        (accelerated) version.
++
++config FB_CFB_COPYAREA
++      tristate
++      depends on FB
++      default n
++      ---help---
++        Include the cfb_copyarea function for generic software area copying.
++        This is used by drivers that don't provide their own (accelerated)
++        version.
++
++config FB_CFB_IMAGEBLIT
++      tristate
++      depends on FB
++      default n
++      ---help---
++        Include the cfb_imageblit function for generic software image
++        blitting. This is used by drivers that don't provide their own
++        (accelerated) version.
++config DUMMY_CONSOLE
++      bool "Dummy Console"
++      depends on FB
++      #PROM_CONSOLE!=y || VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y 
++      default n
++
++config FRAMEBUFFER_CONSOLE
++      bool "Framebuffer Console support"
++      depends on FB
++      select CRC32
++      help
++        Low-level framebuffer-based console driver.
++config LOGO
++      bool "Bootup logo"
++      depends on FB || SGI_NEWPORT_CONSOLE
++      help
++        Enable and select frame buffer bootup logos.
++
++config LOGO_LINUX_CLUT224
++      bool "Standard 224-color Linux logo"
++      depends on LOGO
++      default y
++config FONTS
++      bool "Select compiled-in fonts"
++      depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
++      help
++        Say Y here if you would like to use fonts other than the default
++        your frame buffer console usually use.
++
++        Note that the answer to this question won't directly affect the
++        kernel: saying N will just cause the configurator to skip all
++        the questions about foreign fonts.
++
++        If unsure, say N (the default choices are safe).
++
++config FONT_8x8
++      bool "VGA 8x8 font" if FONTS
++      depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
++      default y if !SPARC && !FONTS
++      help
++        This is the "high resolution" font for the VGA frame buffer (the one
++        provided by the text console 80x50 (and higher) modes).
++
++        Note that this is a poor quality font. The VGA 8x16 font is quite a
++        lot more readable.
++
++        Given the resolution provided by the frame buffer device, answer N
++        here is safe.
++
++config FONT_8x16
++      bool "VGA 8x16 font" if FONTS
++      depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE=y || STI_CONSOLE || USB_SISUSBVGA_CON 
++      default y if !SPARC && !FONTS
++      help
++        This is the "high resolution" font for the VGA frame buffer (the one
++        provided by the VGA text console 80x25 mode.
++
++        If unsure, say Y.
++
++
++config FOX_VHDL_FB
++        bool "FOX_VHDL Framebuffer"
++      depends on FOXBONE
++      depends on FB
++      select FB_CFB_FILLRECT
++      select FB_CFB_COPYAREA
++      select FB_CFB_IMAGEBLIT                         
++      select VT_CONSOLE
++      select DUMMY_CONSOLE
++      select FRAMEBUFFER_CONSOLE
++      select FONTS
++      select LOGO
++      select LOGO_LINUX_CLUT224
++
++config NANOXKBD
++      bool "nano-X keyboard support"
++      default n
++      depends on FOX_VHDL_FB
++      help 
++      Enable the keyboard driver patches for nano-X
++
++
++
++#if FOX_VHDL_FB
++      #source "drivers/video/console/Kconfig"
++#endif
++
++#if FOX_VHDL_FB 
++#     source "drivers/video/logo/Kconfig"
++#endif
++
++endmenu
++
++
++config FOXBONE_IO
++      bool "FOXBONE I/O pins"
++      depends on FOXBONE
++      help
++      Include this to get access to the I/O pins of the foxbone
++
++config FOXBONE_TIMEBASE
++      bool "FOXBONE Timebase"
++      depends on FOXBONE
++      help
++      Include this to get access to the timebase part of the fpga
++
++config FOXBONE_MMC
++      bool "FOXBONE MMC/SD module"
++      depends on FOXBONE
++      help
++      Include this to be able to access a mmc/sd card connected to J3 of the fox-vhdl board
++
++config FOXBONE_PWM
++      bool "FOXBONE PWM module"
++      depends on FOXBONE
++      help
++      Include this to enable PWM support into the kernel
++
++config FOXBONE_EVENT
++      bool "FOXBONE EVENT counter module"
++      depends on FOXBONE
++      help
++      Include this to enable foxbone event counter support
++
++config FOXBONE_LOOPBACK
++      bool "FOXBONE Loopback module"
++      depends on FOXBONE
++      help
++      Include this to be able to load the loopback module, that you can base your own driver on
++
++config FOXBONE_MULTIPLY
++      bool "FOXBONE Multiplier example"
++      depends on FOXBONE
++      help
++      Include this to use the 64 bit multiplier
++
++menu "FOXBONE interrupt handlers"
++config FOXBONE_SAMPLE_ISR
++      bool "FOXBONE example interrupt handlers"
++      depends on FOXBONE
++      
++config FOXBONE_INT14
++      bool "Int 14 - bit 0 of reg 0x13 set"
++      depends on FOXBONE_SAMPLE_ISR
++
++config FOXBONE_INT31
++      bool "Int 31 - bit 1 of reg 0x13 set"
++      depends on FOXBONE_SAMPLE_ISR
++
++endmenu       
++
++
++config ETRAX_CMDLINE
++      string "Kernel command line" 
++      default "root=/dev/mtdblock3 init=/linuxrc console=ttyS0"
++      help
++      use if no framebuffer is enabled console=ttyS0
++      use if framebuffer is enabled console=tty0
++                                      
++endmenu
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/keyboard/Makefile linux-2.6.19.2/drivers/fox-vhdl/keyboard/Makefile
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/keyboard/Makefile     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/keyboard/Makefile  2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1 @@
++obj-$(CONFIG_NANOXKBD)          += nanoxkbd.o
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/keyboard/nanoxkbd.c linux-2.6.19.2/drivers/fox-vhdl/keyboard/nanoxkbd.c
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/keyboard/nanoxkbd.c   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/keyboard/nanoxkbd.c        2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,173 @@
++/*  
++  nanoxkbd.c
++  Linux Kernel Driver for Nanox Keyboard driver for FOX VHDL Board framebuffer
++  (based on FoxBone protocol interface specifications rel 0.7)    
++  For more info see: http://www.acmesystems.it/?id=120
++  Author: John Crispin
++  Copyright (C) 2006 Phrozen (http://www.phrozen.biz)
++  
++  This 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 example 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.
++    
++  To have a copy of the GNU General Public License write to the Free Software
++  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++*/
++
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/ioport.h>
++#include <linux/version.h>
++#include <linux/init.h>
++#include <asm/uaccess.h>
++#include <asm/io.h>
++#include <linux/vmalloc.h>
++#include <linux/ioport.h>  
++#include <linux/init.h>
++#include <linux/genhd.h>
++
++#define DEV_NAME                      "keyboard"
++#define DEV_MAJOR                     195
++
++
++unsigned char nanoxkbd_is_open = 0;
++
++#define MAX_KEYS 128
++unsigned int keys[MAX_KEYS];
++unsigned char keys_count = 0;
++unsigned char keys_pos = 0;
++
++#define IOCTL_NANOXKBD_GET            0x7878
++
++unsigned char nanoxkbd_add(unsigned int keycode){
++      if(nanoxkbd_is_open){
++              if(keys_count < MAX_KEYS){                      
++                      keys[(keys_pos + keys_count) % MAX_KEYS] = keycode;
++                      keys_count++;
++                      printk("got key %d, %d, %d\n", keycode, keys_pos, keys_count);
++              };
++              return 1;
++      };
++      return 0;
++};
++
++// the app has send us some control data
++static int module_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg){
++      //copy_to_user((char*)arg, (char*)&audio_data, sizeof(AUDIO_DATA));
++      //copy_from_user((char*)&mp3_beep, (char*)arg, sizeof(MP3_BEEP));
++      int retval = 0;
++      switch (cmd) {
++              case IOCTL_NANOXKBD_GET:
++                      if(keys_count > 0){
++                              keys_count--;
++                              copy_to_user((char*)arg, (char*)&keys[keys_pos], sizeof(unsigned int));
++                              keys_pos++;
++                              if(keys_pos >= MAX_KEYS){
++                                      keys_pos = 0;
++                              };
++                              retval = 1;
++                      };
++                      break;
++                              
++              default:
++                      printk("nanoxkbd: unknown ioctl\n");
++                      break;                  
++      }
++
++      return retval;
++};
++
++
++
++static int module_open(struct inode *inode, struct file *file){
++      // Which minor device is the user trying to access ?
++      unsigned int dev_minor = MINOR(inode->i_rdev);
++      
++      // we only supprt minor 0 at the moment
++      if(dev_minor !=  0){
++              printk("nanoxkbd: trying to access unknown minor device -> %d\n", dev_minor);
++              return -ENODEV;
++      }
++      
++      // check if another app is currently using the device
++      if(nanoxkbd_is_open) {
++              printk("nanoxkbd: Device with minor ID %d already in use\n", dev_minor);
++              return -EBUSY;
++      }
++      nanoxkbd_is_open = 1;
++      
++      // more flaming
++      printk("nanoxkbd: Minor %d has been opened\n", dev_minor);
++      return 0;
++};
++
++
++// gets called when an app closes the device
++static int module_close(struct inode * inode, struct file * file){
++      // Which minor device is the user trying to access ?
++      unsigned int dev_minor = MINOR(inode->i_rdev);
++      
++      // remember that the device has been closed
++      nanoxkbd_is_open = 0;
++      
++      
++      // more flaming
++      printk("nanoxkbd: Minor %d has been closed\n", dev_minor);
++      
++      return 0;
++};
++
++// so the kernel knows which functions to access for a given operation
++struct file_operations nanoxkbd_module_fops = {
++        ioctl:         module_ioctl,
++        open:          module_open,
++        release:       module_close
++};
++
++
++// module gets loaded into kernel / char dev is registered
++static int __init mod_init(void){
++      // flame the kprintk
++      printk("nanoxkbd: FOX-VHDL FPGA io module\n");
++      //printk("nanoxkbd: Made by K. John '2B|!2B' Crispin (john@phrozen.org)\n");
++      //printk("nanoxkbd: Starting ...\n");
++      
++      // register the character device
++      if(register_chrdev(DEV_MAJOR, DEV_NAME, &nanoxkbd_module_fops)) {
++              printk( "nanoxkbd: Error whilst opening %s (%d)\n", DEV_NAME, DEV_MAJOR);
++              return( -ENODEV );
++      };
++      
++
++      // remember that the driver has been opened
++      nanoxkbd_is_open = 0;
++      printk("nanoxkbd: Device %s registered for major ID %d\n", DEV_NAME, DEV_MAJOR);
++      return 0;
++}
++
++
++// we are done so shut everything down
++static void __exit mod_exit(void){
++      printk( "nanoxkbd: Cleanup\n" );
++      // tell the kernel that the device is not needed anymore
++      unregister_chrdev(DEV_MAJOR, DEV_NAME);
++      
++}
++
++module_init (mod_init);
++module_exit (mod_exit);
++
++
++
++
++
++
+diff -urN linux-2.6.19.2.orig/drivers/fox-vhdl/Makefile linux-2.6.19.2/drivers/fox-vhdl/Makefile
+--- linux-2.6.19.2.orig/drivers/fox-vhdl/Makefile      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/drivers/fox-vhdl/Makefile   2007-06-17 02:46:15.000000000 +0200
+@@ -0,0 +1,13 @@
++#
++# Makefile for the i2c core.
++#
++obj-$(CONFIG_FOXBONE)         += foxbone/
++obj-$(CONFIG_FOX_VHDL_FB)     += fox_vhdl_fb/
++obj-$(CONFIG_FOX_FPGA)                += fox_fpga_flash/
++obj-$(CONFIG_FOXBONE_PWM)     += fox_pwm/             
++obj-$(CONFIG_FOXBONE_IO)      += fox_io/
++obj-$(CONFIG_FOXBONE_TIMEBASE)        += fox_timebase/
++obj-$(CONFIG_FOXBONE_LOOPBACK)  += fox_loopback/
++obj-$(CONFIG_FOXBONE_EVENT)   += fox_event/
++obj-$(CONFIG_FOXBONE_MULTIPLY)        += fox_multiply/        
++obj-$(CONFIG_NANOXKBD)                += keyboard/
+--- linux-2.6.19.2.orig/arch/cris/Kconfig      2007-06-16 23:58:14.000000000 +0200
++++ linux-2.6.19.2/drivers/fox-vhdl/Kconfig    2007-06-17 02:46:15.000000000 +0200
+@@ -1,244 +1,274 @@
+-#
+-# For a description of the syntax of this configuration file,
+-# see the Configure script.
+-#
++menu "Acmesystems FPGA"
+-mainmenu "Linux/CRIS Kernel Configuration"
+-
+-config MMU
+-      bool
+-      default y
+-
+-config RWSEM_GENERIC_SPINLOCK
+-      bool
+-      default y
+-
+-config RWSEM_XCHGADD_ALGORITHM
+-      bool
+-
+-config GENERIC_IOMAP
+-       bool
+-       default y
+-
+-config GENERIC_FIND_NEXT_BIT
+-      bool
+-      default y
+-
+-config GENERIC_HWEIGHT
+-      bool
++config FOX_VHDL
++      bool "Support for FOX-VHDL Board"
++      default n
++
++config FOX_FPGA
++      bool "FPGA flash module"
++      depends on FOX_VHDL
++      help
++      Adds the module needed to flash the fpga from the FOX
++
++config FOXBONE
++      bool "Basic FOXBONE support"
++      depends on FOX_VHDL
++      help
++      Include this to get basic FOXBONE support
++
++config VT
++      bool "Virtual terminal (needed for framebuffer)" if EMBEDDED
++      select INPUT
++      default y if !VIOCONS
++      ---help---
++        If you say Y here, you will get support for terminal devices with
++        display and keyboard devices. These are called "virtual" because you
++        can run several virtual terminals (also called virtual consoles) on
++        one physical terminal. This is rather useful, for example one
++        virtual terminal can collect system messages and warnings, another
++        one can be used for a text-mode user session, and a third could run
++        an X session, all in parallel. Switching between virtual terminals
++        is done with certain key combinations, usually Alt-<function key>.
++
++        The setterm command ("man setterm") can be used to change the
++        properties (such as colors or beeping) of a virtual terminal. The
++        man page console_codes(4) ("man console_codes") contains the special
++        character sequences that can be used to change those properties
++        directly. The fonts used on virtual terminals can be changed with
++        the setfont ("man setfont") command and the key bindings are defined
++        with the loadkeys ("man loadkeys") command.
++
++        You need at least one virtual terminal device in order to make use
++        of your keyboard and monitor. Therefore, only people configuring an
++        embedded system would want to say N here in order to save some
++        memory; the only way to log into such a system is then via a serial
++        or network connection.
++
++        If unsure, say Y, or else you won't be able to do much with your new
++        shiny Linux system :-)
++
++
++menu "Framebuffer"    
++depends on VT
++
++config FB
++      bool "Support for frame buffer devices"
++      depends on VT
++      ---help---
++        The frame buffer device provides an abstraction for the graphics
++        hardware. It represents the frame buffer of some video hardware and
++        allows application software to access the graphics hardware through
++        a well-defined interface, so the software doesn't need to know
++        anything about the low-level (hardware register) stuff.
++
++        Frame buffer devices work identically across the different
++        architectures supported by Linux and make the implementation of
++        application programs easier and more portable; at this point, an X
++        server exists which uses the frame buffer device exclusively.
++        On several non-X86 architectures, the frame buffer device is the
++        only way to use the graphics hardware.
++
++        The device is accessed through special device nodes, usually located
++        in the /dev directory, i.e. /dev/fb*.
++
++        You need an utility program called fbset to make full use of frame
++        buffer devices. Please read <file:Documentation/fb/framebuffer.txt>
++        and the Framebuffer-HOWTO at
++        <http://www.tahallah.demon.co.uk/programming/prog.html> for more
++        information.
++
++        Say Y here and to the driver for your graphics board below if you
++        are compiling a kernel for a non-x86 architecture.
++
++        If you are compiling for the x86 architecture, you can say Y if you
++        want to play with it, but it is not essential. Please note that
++        running graphical applications that directly touch the hardware
++        (e.g. an accelerated X server) and that are not frame buffer
++        device-aware may cause unexpected results. If unsure, say N.
++
++config FB_CFB_FILLRECT
++      tristate
++      depends on FB
++      default n
++      ---help---
++        Include the cfb_fillrect function for generic software rectangle
++        filling. This is used by drivers that don't provide their own
++        (accelerated) version.
++
++config FB_CFB_COPYAREA
++      tristate
++      depends on FB
++      default n
++      ---help---
++        Include the cfb_copyarea function for generic software area copying.
++        This is used by drivers that don't provide their own (accelerated)
++        version.
++
++config FB_CFB_IMAGEBLIT
++      tristate
++      depends on FB
++      default n
++      ---help---
++        Include the cfb_imageblit function for generic software image
++        blitting. This is used by drivers that don't provide their own
++        (accelerated) version.
++config DUMMY_CONSOLE
++      bool "Dummy Console"
++      depends on FB
++      #PROM_CONSOLE!=y || VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y 
++      default n
++
++config FRAMEBUFFER_CONSOLE
++      bool "Framebuffer Console support"
++      depends on FB
++      select CRC32
++      help
++        Low-level framebuffer-based console driver.
++config LOGO
++      bool "Bootup logo"
++      depends on FB || SGI_NEWPORT_CONSOLE
++      help
++        Enable and select frame buffer bootup logos.
++
++config LOGO_LINUX_CLUT224
++      bool "Standard 224-color Linux logo"
++      depends on LOGO
+       default y
+-
+-config GENERIC_CALIBRATE_DELAY
+-      bool
+-      default y
+-
+-config IRQ_PER_CPU
+-      bool
+-      default y
+-
+-config CRIS
+-      bool
+-      default y
+-
+-source "init/Kconfig"
+-
+-menu "General setup"
+-
+-source "fs/Kconfig.binfmt"
+-
+-config GENERIC_HARDIRQS
+-      bool
+-      default y
+-
+-config SMP
+-       bool "SMP"
+-       help
+-         SMP support. Always Say N.
+-
+-config NR_CPUS
+-       int
+-       depends on SMP
+-       default 2
+-
+-config SCHED_MC
+-      bool "Multi-core scheduler support"
+-      depends on SMP
+-      default y
+-      help
+-        Multi-core scheduler support improves the CPU scheduler's decision
+-        making when dealing with multi-core CPU chips at a cost of slightly
+-        increased overhead in some places. If unsure say N here.
+-
+-config ETRAX_CMDLINE
+-      string "Kernel command line"
+-      default "root=/dev/mtdblock3"
+-      help
+-        Pass additional commands to the kernel.
+-
+-config ETRAX_WATCHDOG
+-      bool "Enable ETRAX watchdog"
+-      help
+-        Enable the built-in watchdog timer support on ETRAX based embedded
+-        network computers.
+-
+-config ETRAX_WATCHDOG_NICE_DOGGY
+-      bool "Disable watchdog during Oops printouts"
+-      depends on ETRAX_WATCHDOG
+-      help
+-        By enabling this you make sure that the watchdog does not bite while
+-        printing oopses. Recommended for development systems but not for
+-        production releases.
+-
+-config ETRAX_FAST_TIMER
+-       bool "Enable ETRAX fast timer API"
+-       help
+-         This options enables the API to a fast timer implementation using
+-       timer1 to get sub jiffie resolution timers (primarily one-shot
+-       timers).
+-       This is needed if CONFIG_ETRAX_SERIAL_FAST_TIMER is enabled.
+-
+-config OOM_REBOOT
+-       bool "Enable reboot at out of memory"
+-
+-source "kernel/Kconfig.preempt"
+-source "kernel/Kconfig.sched"
+-
+-source mm/Kconfig
++config FONTS
++      bool "Select compiled-in fonts"
++      depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
++      help
++        Say Y here if you would like to use fonts other than the default
++        your frame buffer console usually use.
++
++        Note that the answer to this question won't directly affect the
++        kernel: saying N will just cause the configurator to skip all
++        the questions about foreign fonts.
++
++        If unsure, say N (the default choices are safe).
++
++config FONT_8x8
++      bool "VGA 8x8 font" if FONTS
++      depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
++      default y if !SPARC && !FONTS
++      help
++        This is the "high resolution" font for the VGA frame buffer (the one
++        provided by the text console 80x50 (and higher) modes).
++
++        Note that this is a poor quality font. The VGA 8x16 font is quite a
++        lot more readable.
++
++        Given the resolution provided by the frame buffer device, answer N
++        here is safe.
++
++config FONT_8x16
++      bool "VGA 8x16 font" if FONTS
++      depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE=y || STI_CONSOLE || USB_SISUSBVGA_CON 
++      default y if !SPARC && !FONTS
++      help
++        This is the "high resolution" font for the VGA frame buffer (the one
++        provided by the VGA text console 80x25 mode.
++
++        If unsure, say Y.
++
++
++config FOX_VHDL_FB
++        bool "FOX_VHDL Framebuffer"
++      depends on FOXBONE
++      depends on FB
++      select FB_CFB_FILLRECT
++      select FB_CFB_COPYAREA
++      select FB_CFB_IMAGEBLIT                         
++      select VT_CONSOLE
++      select DUMMY_CONSOLE
++      select FRAMEBUFFER_CONSOLE
++      select FONTS
++      select LOGO
++      select LOGO_LINUX_CLUT224
++
++config NANOXKBD
++      bool "nano-X keyboard support"
++      default n
++      depends on FOX_VHDL_FB
++      help 
++      Enable the keyboard driver patches for nano-X
++
++
++
++#if FOX_VHDL_FB
++      #source "drivers/video/console/Kconfig"
++#endif
++
++#if FOX_VHDL_FB 
++#     source "drivers/video/logo/Kconfig"
++#endif
+ endmenu
+-menu "Hardware setup"
+-
+-choice
+-      prompt "Processor type"
+-      default ETRAX100LX
+-config ETRAX100LX
+-      bool "ETRAX-100LX-v1"
++config FOXBONE_IO
++      bool "FOXBONE I/O pins"
++      depends on FOXBONE
+       help
+-        Support version 1 of the ETRAX 100LX.
++      Include this to get access to the I/O pins of the foxbone
+-config ETRAX100LX_V2
+-      bool "ETRAX-100LX-v2"
++config FOXBONE_TIMEBASE
++      bool "FOXBONE Timebase"
++      depends on FOXBONE
+       help
+-        Support version 2 of the ETRAX 100LX.
++      Include this to get access to the timebase part of the fpga
+-config SVINTO_SIM
+-      bool "ETRAX-100LX-for-xsim-simulator"
++config FOXBONE_MMC
++      bool "FOXBONE MMC/SD module"
++      depends on FOXBONE
+       help
+-        Support the xsim ETRAX Simulator.
++      Include this to be able to access a mmc/sd card connected to J3 of the fox-vhdl board
+-config ETRAXFS
+-      bool "ETRAX-FS-V32"
++config FOXBONE_PWM
++      bool "FOXBONE PWM module"
++      depends on FOXBONE
+       help
+-        Support CRIS V32.
++      Include this to enable PWM support into the kernel
+-config ETRAXFS_SIM
+-      bool "ETRAX-FS-V32-Simulator"
++config FOXBONE_EVENT
++      bool "FOXBONE EVENT counter module"
++      depends on FOXBONE
+       help
+-        Support CRIS V32 VCS simualtor.
++      Include this to enable foxbone event counter support
+-endchoice
+-
+-config ETRAX_ARCH_V10
+-       bool
+-       default y if ETRAX100LX || ETRAX100LX_V2
+-       default n if !(ETRAX100LX || ETRAX100LX_V2)
+-
+-config ETRAX_ARCH_V32
+-       bool
+-       default y if ETRAXFS || ETRAXFS_SIM
+-       default n if !(ETRAXFS || ETRAXFS_SIM) 
+-
+-config ETRAX_DRAM_SIZE
+-      int "DRAM size (dec, in MB)"
+-      default "8"
++config FOXBONE_LOOPBACK
++      bool "FOXBONE Loopback module"
++      depends on FOXBONE
+       help
+-        Size of DRAM (decimal in MB) typically 2, 8 or 16.
++      Include this to be able to load the loopback module, that you can base your own driver on
+-config ETRAX_FLASH_BUSWIDTH
+-      int "Buswidth of NOR flash in bytes"
+-      default "2"
++config FOXBONE_MULTIPLY
++      bool "FOXBONE Multiplier example"
++      depends on FOXBONE
+       help
+-        Width in bytes of the NOR Flash bus (1, 2 or 4). Is usually 2.
++      Include this to use the 64 bit multiplier
+-config ETRAX_NANDFLASH_BUSWIDTH
+-      int "Buswidth of NAND flash in bytes"
+-      default "1"
+-      help
+-        Width in bytes of the NAND flash (1 or 2).
++menu "FOXBONE interrupt handlers"
++config FOXBONE_SAMPLE_ISR
++      bool "FOXBONE example interrupt handlers"
++      depends on FOXBONE
++      
++config FOXBONE_INT14
++      bool "Int 14 - bit 0 of reg 0x13 set"
++      depends on FOXBONE_SAMPLE_ISR
+-config ETRAX_FLASH1_SIZE
+-       int "FLASH1 size (dec, in MB. 0 = Unknown)"
+-       default "0"
++config FOXBONE_INT31
++      bool "Int 31 - bit 1 of reg 0x13 set"
++      depends on FOXBONE_SAMPLE_ISR
+-# arch/cris/arch is a symlink to correct arch (arch-v10 or arch-v32)
+-source arch/cris/arch/Kconfig
++endmenu       
+-endmenu
+-
+-source "net/Kconfig"
+-
+-# bring in ETRAX built-in drivers
+-menu "Drivers for built-in interfaces"
+-# arch/cris/arch is a symlink to correct arch (arch-v10 or arch-v32)
+-source arch/cris/arch/drivers/Kconfig
++config ETRAX_CMDLINE
++      string "Kernel command line" 
++      default "root=/dev/mtdblock3 init=/linuxrc console=ttyS0"
++      help
++      use if no framebuffer is enabled console=ttyS0
++      use if framebuffer is enabled console=tty0
++                                      
+ endmenu
+-
+-source "drivers/base/Kconfig"
+-
+-# standard linux drivers
+-source "drivers/mtd/Kconfig"
+-
+-source "drivers/parport/Kconfig"
+-
+-source "drivers/pnp/Kconfig"
+-
+-source "drivers/block/Kconfig"
+-
+-source "drivers/md/Kconfig"
+-
+-source "drivers/ide/Kconfig"
+-
+-source "drivers/scsi/Kconfig"
+-
+-source "drivers/ieee1394/Kconfig"
+-
+-source "drivers/message/i2o/Kconfig"
+-
+-source "drivers/net/Kconfig"
+-
+-source "drivers/isdn/Kconfig"
+-
+-source "drivers/telephony/Kconfig"
+-
+-source "drivers/cdrom/Kconfig"
+-
+-#
+-# input before char - char/joystick depends on it. As does USB.
+-#
+-source "drivers/input/Kconfig"
+-
+-source "drivers/char/Kconfig"
+-
+-#source drivers/misc/Config.in
+-source "drivers/media/Kconfig"
+-
+-source "fs/Kconfig"
+-
+-source "sound/Kconfig"
+-
+-source "drivers/pcmcia/Kconfig"
+-
+-source "drivers/pci/Kconfig"
+-
+-source "drivers/usb/Kconfig"
+-
+-source "arch/cris/Kconfig.debug"
+-
+-source "security/Kconfig"
+-
+-source "crypto/Kconfig"
+-
+-source "lib/Kconfig"
+--- linux-2.6.19.2.orig/arch/cris/Kconfig      2007-06-16 23:58:14.000000000 +0200
++++ linux-2.6.19.2/drivers/fox-vhdl/Kconfig    2007-06-17 02:46:15.000000000 +0200
+@@ -1,244 +1,274 @@
+-#
+-# For a description of the syntax of this configuration file,
+-# see the Configure script.
+-#
++menu "Acmesystems FPGA"
+-mainmenu "Linux/CRIS Kernel Configuration"
+-
+-config MMU
+-      bool
+-      default y
+-
+-config RWSEM_GENERIC_SPINLOCK
+-      bool
+-      default y
+-
+-config RWSEM_XCHGADD_ALGORITHM
+-      bool
+-
+-config GENERIC_IOMAP
+-       bool
+-       default y
+-
+-config GENERIC_FIND_NEXT_BIT
+-      bool
+-      default y
+-
+-config GENERIC_HWEIGHT
+-      bool
++config FOX_VHDL
++      bool "Support for FOX-VHDL Board"
++      default n
++
++config FOX_FPGA
++      bool "FPGA flash module"
++      depends on FOX_VHDL
++      help
++      Adds the module needed to flash the fpga from the FOX
++
++config FOXBONE
++      bool "Basic FOXBONE support"
++      depends on FOX_VHDL
++      help
++      Include this to get basic FOXBONE support
++
++config VT
++      bool "Virtual terminal (needed for framebuffer)" if EMBEDDED
++      select INPUT
++      default y if !VIOCONS
++      ---help---
++        If you say Y here, you will get support for terminal devices with
++        display and keyboard devices. These are called "virtual" because you
++        can run several virtual terminals (also called virtual consoles) on
++        one physical terminal. This is rather useful, for example one
++        virtual terminal can collect system messages and warnings, another
++        one can be used for a text-mode user session, and a third could run
++        an X session, all in parallel. Switching between virtual terminals
++        is done with certain key combinations, usually Alt-<function key>.
++
++        The setterm command ("man setterm") can be used to change the
++        properties (such as colors or beeping) of a virtual terminal. The
++        man page console_codes(4) ("man console_codes") contains the special
++        character sequences that can be used to change those properties
++        directly. The fonts used on virtual terminals can be changed with
++        the setfont ("man setfont") command and the key bindings are defined
++        with the loadkeys ("man loadkeys") command.
++
++        You need at least one virtual terminal device in order to make use
++        of your keyboard and monitor. Therefore, only people configuring an
++        embedded system would want to say N here in order to save some
++        memory; the only way to log into such a system is then via a serial
++        or network connection.
++
++        If unsure, say Y, or else you won't be able to do much with your new
++        shiny Linux system :-)
++
++
++menu "Framebuffer"    
++depends on VT
++
++config FB
++      bool "Support for frame buffer devices"
++      depends on VT
++      ---help---
++        The frame buffer device provides an abstraction for the graphics
++        hardware. It represents the frame buffer of some video hardware and
++        allows application software to access the graphics hardware through
++        a well-defined interface, so the software doesn't need to know
++        anything about the low-level (hardware register) stuff.
++
++        Frame buffer devices work identically across the different
++        architectures supported by Linux and make the implementation of
++        application programs easier and more portable; at this point, an X
++        server exists which uses the frame buffer device exclusively.
++        On several non-X86 architectures, the frame buffer device is the
++        only way to use the graphics hardware.
++
++        The device is accessed through special device nodes, usually located
++        in the /dev directory, i.e. /dev/fb*.
++
++        You need an utility program called fbset to make full use of frame
++        buffer devices. Please read <file:Documentation/fb/framebuffer.txt>
++        and the Framebuffer-HOWTO at
++        <http://www.tahallah.demon.co.uk/programming/prog.html> for more
++        information.
++
++        Say Y here and to the driver for your graphics board below if you
++        are compiling a kernel for a non-x86 architecture.
++
++        If you are compiling for the x86 architecture, you can say Y if you
++        want to play with it, but it is not essential. Please note that
++        running graphical applications that directly touch the hardware
++        (e.g. an accelerated X server) and that are not frame buffer
++        device-aware may cause unexpected results. If unsure, say N.
++
++config FB_CFB_FILLRECT
++      tristate
++      depends on FB
++      default n
++      ---help---
++        Include the cfb_fillrect function for generic software rectangle
++        filling. This is used by drivers that don't provide their own
++        (accelerated) version.
++
++config FB_CFB_COPYAREA
++      tristate
++      depends on FB
++      default n
++      ---help---
++        Include the cfb_copyarea function for generic software area copying.
++        This is used by drivers that don't provide their own (accelerated)
++        version.
++
++config FB_CFB_IMAGEBLIT
++      tristate
++      depends on FB
++      default n
++      ---help---
++        Include the cfb_imageblit function for generic software image
++        blitting. This is used by drivers that don't provide their own
++        (accelerated) version.
++config DUMMY_CONSOLE
++      bool "Dummy Console"
++      depends on FB
++      #PROM_CONSOLE!=y || VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y 
++      default n
++
++config FRAMEBUFFER_CONSOLE
++      bool "Framebuffer Console support"
++      depends on FB
++      select CRC32
++      help
++        Low-level framebuffer-based console driver.
++config LOGO
++      bool "Bootup logo"
++      depends on FB || SGI_NEWPORT_CONSOLE
++      help
++        Enable and select frame buffer bootup logos.
++
++config LOGO_LINUX_CLUT224
++      bool "Standard 224-color Linux logo"
++      depends on LOGO
+       default y
+-
+-config GENERIC_CALIBRATE_DELAY
+-      bool
+-      default y
+-
+-config IRQ_PER_CPU
+-      bool
+-      default y
+-
+-config CRIS
+-      bool
+-      default y
+-
+-source "init/Kconfig"
+-
+-menu "General setup"
+-
+-source "fs/Kconfig.binfmt"
+-
+-config GENERIC_HARDIRQS
+-      bool
+-      default y
+-
+-config SMP
+-       bool "SMP"
+-       help
+-         SMP support. Always Say N.
+-
+-config NR_CPUS
+-       int
+-       depends on SMP
+-       default 2
+-
+-config SCHED_MC
+-      bool "Multi-core scheduler support"
+-      depends on SMP
+-      default y
+-      help
+-        Multi-core scheduler support improves the CPU scheduler's decision
+-        making when dealing with multi-core CPU chips at a cost of slightly
+-        increased overhead in some places. If unsure say N here.
+-
+-config ETRAX_CMDLINE
+-      string "Kernel command line"
+-      default "root=/dev/mtdblock3"
+-      help
+-        Pass additional commands to the kernel.
+-
+-config ETRAX_WATCHDOG
+-      bool "Enable ETRAX watchdog"
+-      help
+-        Enable the built-in watchdog timer support on ETRAX based embedded
+-        network computers.
+-
+-config ETRAX_WATCHDOG_NICE_DOGGY
+-      bool "Disable watchdog during Oops printouts"
+-      depends on ETRAX_WATCHDOG
+-      help
+-        By enabling this you make sure that the watchdog does not bite while
+-        printing oopses. Recommended for development systems but not for
+-        production releases.
+-
+-config ETRAX_FAST_TIMER
+-       bool "Enable ETRAX fast timer API"
+-       help
+-         This options enables the API to a fast timer implementation using
+-       timer1 to get sub jiffie resolution timers (primarily one-shot
+-       timers).
+-       This is needed if CONFIG_ETRAX_SERIAL_FAST_TIMER is enabled.
+-
+-config OOM_REBOOT
+-       bool "Enable reboot at out of memory"
+-
+-source "kernel/Kconfig.preempt"
+-source "kernel/Kconfig.sched"
+-
+-source mm/Kconfig
++config FONTS
++      bool "Select compiled-in fonts"
++      depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
++      help
++        Say Y here if you would like to use fonts other than the default
++        your frame buffer console usually use.
++
++        Note that the answer to this question won't directly affect the
++        kernel: saying N will just cause the configurator to skip all
++        the questions about foreign fonts.
++
++        If unsure, say N (the default choices are safe).
++
++config FONT_8x8
++      bool "VGA 8x8 font" if FONTS
++      depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
++      default y if !SPARC && !FONTS
++      help
++        This is the "high resolution" font for the VGA frame buffer (the one
++        provided by the text console 80x50 (and higher) modes).
++
++        Note that this is a poor quality font. The VGA 8x16 font is quite a
++        lot more readable.
++
++        Given the resolution provided by the frame buffer device, answer N
++        here is safe.
++
++config FONT_8x16
++      bool "VGA 8x16 font" if FONTS
++      depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE=y || STI_CONSOLE || USB_SISUSBVGA_CON 
++      default y if !SPARC && !FONTS
++      help
++        This is the "high resolution" font for the VGA frame buffer (the one
++        provided by the VGA text console 80x25 mode.
++
++        If unsure, say Y.
++
++
++config FOX_VHDL_FB
++        bool "FOX_VHDL Framebuffer"
++      depends on FOXBONE
++      depends on FB
++      select FB_CFB_FILLRECT
++      select FB_CFB_COPYAREA
++      select FB_CFB_IMAGEBLIT                         
++      select VT_CONSOLE
++      select DUMMY_CONSOLE
++      select FRAMEBUFFER_CONSOLE
++      select FONTS
++      select LOGO
++      select LOGO_LINUX_CLUT224
++
++config NANOXKBD
++      bool "nano-X keyboard support"
++      default n
++      depends on FOX_VHDL_FB
++      help 
++      Enable the keyboard driver patches for nano-X
++
++
++
++#if FOX_VHDL_FB
++      #source "drivers/video/console/Kconfig"
++#endif
++
++#if FOX_VHDL_FB 
++#     source "drivers/video/logo/Kconfig"
++#endif
+ endmenu
+-menu "Hardware setup"
+-
+-choice
+-      prompt "Processor type"
+-      default ETRAX100LX
+-config ETRAX100LX
+-      bool "ETRAX-100LX-v1"
++config FOXBONE_IO
++      bool "FOXBONE I/O pins"
++      depends on FOXBONE
+       help
+-        Support version 1 of the ETRAX 100LX.
++      Include this to get access to the I/O pins of the foxbone
+-config ETRAX100LX_V2
+-      bool "ETRAX-100LX-v2"
++config FOXBONE_TIMEBASE
++      bool "FOXBONE Timebase"
++      depends on FOXBONE
+       help
+-        Support version 2 of the ETRAX 100LX.
++      Include this to get access to the timebase part of the fpga
+-config SVINTO_SIM
+-      bool "ETRAX-100LX-for-xsim-simulator"
++config FOXBONE_MMC
++      bool "FOXBONE MMC/SD module"
++      depends on FOXBONE
+       help
+-        Support the xsim ETRAX Simulator.
++      Include this to be able to access a mmc/sd card connected to J3 of the fox-vhdl board
+-config ETRAXFS
+-      bool "ETRAX-FS-V32"
++config FOXBONE_PWM
++      bool "FOXBONE PWM module"
++      depends on FOXBONE
+       help
+-        Support CRIS V32.
++      Include this to enable PWM support into the kernel
+-config ETRAXFS_SIM
+-      bool "ETRAX-FS-V32-Simulator"
++config FOXBONE_EVENT
++      bool "FOXBONE EVENT counter module"
++      depends on FOXBONE
+       help
+-        Support CRIS V32 VCS simualtor.
++      Include this to enable foxbone event counter support
+-endchoice
+-
+-config ETRAX_ARCH_V10
+-       bool
+-       default y if ETRAX100LX || ETRAX100LX_V2
+-       default n if !(ETRAX100LX || ETRAX100LX_V2)
+-
+-config ETRAX_ARCH_V32
+-       bool
+-       default y if ETRAXFS || ETRAXFS_SIM
+-       default n if !(ETRAXFS || ETRAXFS_SIM) 
+-
+-config ETRAX_DRAM_SIZE
+-      int "DRAM size (dec, in MB)"
+-      default "8"
++config FOXBONE_LOOPBACK
++      bool "FOXBONE Loopback module"
++      depends on FOXBONE
+       help
+-        Size of DRAM (decimal in MB) typically 2, 8 or 16.
++      Include this to be able to load the loopback module, that you can base your own driver on
+-config ETRAX_FLASH_BUSWIDTH
+-      int "Buswidth of NOR flash in bytes"
+-      default "2"
++config FOXBONE_MULTIPLY
++      bool "FOXBONE Multiplier example"
++      depends on FOXBONE
+       help
+-        Width in bytes of the NOR Flash bus (1, 2 or 4). Is usually 2.
++      Include this to use the 64 bit multiplier
+-config ETRAX_NANDFLASH_BUSWIDTH
+-      int "Buswidth of NAND flash in bytes"
+-      default "1"
+-      help
+-        Width in bytes of the NAND flash (1 or 2).
++menu "FOXBONE interrupt handlers"
++config FOXBONE_SAMPLE_ISR
++      bool "FOXBONE example interrupt handlers"
++      depends on FOXBONE
++      
++config FOXBONE_INT14
++      bool "Int 14 - bit 0 of reg 0x13 set"
++      depends on FOXBONE_SAMPLE_ISR
+-config ETRAX_FLASH1_SIZE
+-       int "FLASH1 size (dec, in MB. 0 = Unknown)"
+-       default "0"
++config FOXBONE_INT31
++      bool "Int 31 - bit 1 of reg 0x13 set"
++      depends on FOXBONE_SAMPLE_ISR
+-# arch/cris/arch is a symlink to correct arch (arch-v10 or arch-v32)
+-source arch/cris/arch/Kconfig
++endmenu       
+-endmenu
+-
+-source "net/Kconfig"
+-
+-# bring in ETRAX built-in drivers
+-menu "Drivers for built-in interfaces"
+-# arch/cris/arch is a symlink to correct arch (arch-v10 or arch-v32)
+-source arch/cris/arch/drivers/Kconfig
++config ETRAX_CMDLINE
++      string "Kernel command line" 
++      default "root=/dev/mtdblock3 init=/linuxrc console=ttyS0"
++      help
++      use if no framebuffer is enabled console=ttyS0
++      use if framebuffer is enabled console=tty0
++                                      
+ endmenu
+-
+-source "drivers/base/Kconfig"
+-
+-# standard linux drivers
+-source "drivers/mtd/Kconfig"
+-
+-source "drivers/parport/Kconfig"
+-
+-source "drivers/pnp/Kconfig"
+-
+-source "drivers/block/Kconfig"
+-
+-source "drivers/md/Kconfig"
+-
+-source "drivers/ide/Kconfig"
+-
+-source "drivers/scsi/Kconfig"
+-
+-source "drivers/ieee1394/Kconfig"
+-
+-source "drivers/message/i2o/Kconfig"
+-
+-source "drivers/net/Kconfig"
+-
+-source "drivers/isdn/Kconfig"
+-
+-source "drivers/telephony/Kconfig"
+-
+-source "drivers/cdrom/Kconfig"
+-
+-#
+-# input before char - char/joystick depends on it. As does USB.
+-#
+-source "drivers/input/Kconfig"
+-
+-source "drivers/char/Kconfig"
+-
+-#source drivers/misc/Config.in
+-source "drivers/media/Kconfig"
+-
+-source "fs/Kconfig"
+-
+-source "sound/Kconfig"
+-
+-source "drivers/pcmcia/Kconfig"
+-
+-source "drivers/pci/Kconfig"
+-
+-source "drivers/usb/Kconfig"
+-
+-source "arch/cris/Kconfig.debug"
+-
+-source "security/Kconfig"
+-
+-source "crypto/Kconfig"
+-
+-source "lib/Kconfig"
+--- linux-2.6.19.2.orig/arch/cris/Kconfig      2007-06-16 23:58:14.000000000 +0200
++++ linux-2.6.19.2/arch/cris/Kconfig   2007-06-17 02:52:11.000000000 +0200
+@@ -242,3 +242,6 @@
+ source "crypto/Kconfig"
+ source "lib/Kconfig"
++menu "Acmesystems"
++source "drivers/fox-vhdl/Kconfig"
++endmenu
+79a80
+> obj-$(CONFIG_FOX_VHDL) += fox-vhdl/
+diff -urN linux-2.6.19.2.orig/include/linux/foxbone_syscalls.h linux-2.6.19.2/include/linux/foxbone_syscalls.h
+--- linux-2.6.19.2.orig/include/linux/foxbone_syscalls.h       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/include/linux/foxbone_syscalls.h    2007-06-17 03:31:39.000000000 +0200
+@@ -0,0 +1,18 @@
++#ifndef __LINUX_SYSCALL_FOXBONE
++#define __LINUX_SYSCALL_FOXBONE
++#include <linux/autoconf.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <asm/unistd.h>
++
++extern int errno;
++_syscall1(void, foxbonereset, unsigned short int, reg);
++_syscall1(unsigned short int, foxboneread, unsigned short int, reg);
++_syscall2(void, foxbonewrite, unsigned short int, reg, unsigned short int, value);
++_syscall3(void, foxbonebulkread, unsigned short int, reg, unsigned short int *, value, unsigned int, length);
++_syscall3(void, foxbonebulkwrite, unsigned short int, reg, unsigned short int *, value, unsigned int, length);  
++_syscall2(void, foxboneintreg, unsigned long int, interrupt, unsigned char, state);
++_syscall1(unsigned int, foxboneintcheck, unsigned long int, interrupt);
++_syscall2(unsigned int, foxboneintwait, unsigned long int, interrupt, unsigned char, timeout);
++
++#endif
diff --git a/target/linux/etrax-2.6/patches/cris/020-syscalls.patch b/target/linux/etrax-2.6/patches/cris/020-syscalls.patch
new file mode 100644 (file)
index 0000000..f735ce7
--- /dev/null
@@ -0,0 +1,361 @@
+diff -urN linux-2.6.19.2.orig/include/asm-cris/unistd.h linux-2.6.19.2/include/asm/unistd.h
+--- linux-2.6.19.2.orig/include/asm-cris/unistd.h      2007-06-16 23:59:11.000000000 +0200
++++ linux-2.6.19.2/include/asm/unistd.h        2007-06-17 03:43:10.000000000 +0200
+@@ -325,9 +325,52 @@
+ #define __NR_getcpu           318
+ #define __NR_epoll_pwait      319
++#ifdef CONFIG_ETRAX_GPIO 
++      #ifdef CONFIG_FOXBONE
++              #define __NR_gpiosetbits        320
++              #define __NR_gpioclearbits      321
++              #define __NR_gpiosetdir         322
++              #define __NR_gpiotogglebit      323
++              #define __NR_gpiogetbits        324
++              #define __NR_foxboneread        325
++              #define __NR_foxbonewrite       326 
++              #define __NR_foxbonebulkread    327 
++              #define __NR_foxbonebulkwrite   328 
++              #define __NR_foxbonereset       329
++              #define __NR_foxboneintreg      330
++              #define __NR_foxboneintcheck    331
++              #define __NR_foxboneintwait     332
++              #define NR_syscalls 333
++      
++      #else
++              #define __NR_gpiosetbits        320
++              #define __NR_gpioclearbits      321
++              #define __NR_gpiosetdir         322
++              #define __NR_gpiotogglebit      323
++              #define __NR_gpiogetbits        324
++              
++              #define NR_syscalls 325
++      #endif
++#else
++      #ifdef CONFIG_FOXBONE 
++              #define __NR_foxboneread        320
++              #define __NR_foxbonewrite       321 
++              #define __NR_foxbonebulkread    322
++              #define __NR_foxbonebulkwrite   323
++              #define __NR_foxboneintreg      324
++              #define __NR_foxboneintcheck    325
++              #define __NR_foxboneintwait     326
++      
++              #define NR_syscalls 327
++      
++      #else 
++      
++              #define NR_syscalls 320
++      #endif
++#endif
++      
+ #ifdef __KERNEL__
+-#define NR_syscalls 320
+ #include <asm/arch/unistd.h>
+--- linux-2.6.19.2.orig/include/linux/gpio_syscalls.h  1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/include/linux/gpio_syscalls.h       2007-06-17 03:44:49.000000000 +0200
+@@ -0,0 +1,75 @@
++#ifndef __LINUX_SYSCALL_GPIO
++#define __LINUX_SYSCALL_GPIO
++#include <linux/autoconf.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <asm/unistd.h>
++
++// port defines
++#define PORTA         'A'
++#define PORTB         'B'
++#define PORTG         'G'
++
++//direction defines
++#define DIRIN         'I'
++#define DIROUT        'O'
++
++// pin defines for PORTG
++#define PG0   (1<<0)
++#define PG1     (1<<1)
++#define PG2     (1<<2)
++#define PG3     (1<<3)
++#define PG4     (1<<4)
++#define PG5     (1<<5)
++#define PG6     (1<<6)
++#define PG7     (1<<7)
++#define PG8     (1<<8)
++#define PG9     (1<<9)
++#define PG10  (1<<10)
++#define PG11    (1<<11)
++#define PG12    (1<<12)
++#define PG13    (1<<13)
++#define PG14    (1<<14)
++#define PG15    (1<<15)
++#define PG16    (1<<16)
++#define PG17    (1<<17)
++#define PG18    (1<<18)
++#define PG19    (1<<19)
++#define PG20    (1<<20)
++#define PG21    (1<<21)
++#define PG22    (1<<22)
++#define PG23    (1<<23)
++#define PG24    (1<<24)
++
++#define PG8_15        0x00ff00
++#define PG16_23       0xff0000
++
++
++// pin defines for PORTA
++#define PA0   (1<<0)
++#define PA1   (1<<1)
++#define PA2   (1<<2)
++#define PA3   (1<<3)
++#define PA4   (1<<4)
++#define PA5   (1<<5)
++#define PA6   (1<<6)
++#define PA7   (1<<7)
++
++// pin defines for PORTB
++#define PB0   (1<<0)
++#define PB1   (1<<1)
++#define PB2   (1<<2)
++#define PB3   (1<<3)
++#define PB4   (1<<4)
++#define PB5   (1<<5)
++#define PB6   (1<<6)
++#define PB7   (1<<7)
++
++int errno;
++_syscall2(void, gpiosetbits, unsigned char, port, unsigned int, bits);
++_syscall2(void, gpioclearbits, unsigned char, port, unsigned int, bits);
++_syscall3(void, gpiosetdir, unsigned char, port, unsigned char, dir, unsigned int, bits);
++_syscall2(void, gpiotogglebit, unsigned char, port, unsigned int, bits);
++_syscall2(unsigned int, gpiogetbits, unsigned char, port, unsigned int, bits);
++
++#endif
+--- linux-2.6.19.2.orig/arch/cris/arch-v10/kernel/entry.S      2007-06-16 23:58:14.000000000 +0200
++++ linux-2.6.19.2/arch/cris/arch-v10/kernel/entry.S   2007-06-17 03:48:21.000000000 +0200
+@@ -1200,6 +1200,23 @@
+       .long sys_move_pages
+       .long sys_getcpu
+       .long sys_epoll_pwait
++#ifdef CONFIG_ETRAX_GPIO
++      .long sys_gpiosetbits
++      .long sys_gpioclearbits
++      .long sys_gpiosetdir
++      .long sys_gpiotogglebit
++      .long sys_gpiogetbits
++#endif
++#ifdef CONFIG_FOXBONE
++      .long sys_foxboneread
++      .long sys_foxbonewrite
++      .long sys_foxbonebulkread
++      .long sys_foxbonebulkwrite
++      .long sys_foxbonereset
++      .long sys_foxboneintreg
++      .long sys_foxboneintcheck
++      .long sys_foxboneintwait        
++#endif
+               
+         /*
+          * NOTE!! This doesn't have to be exact - we just have
+diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/gpio_syscalls.c linux-2.6.19.2/arch/cris/arch-v10/drivers/gpio_syscalls.c
+--- linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/gpio_syscalls.c     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.2/arch/cris/arch-v10/drivers/gpio_syscalls.c  2007-06-17 04:09:15.000000000 +0200
+@@ -0,0 +1,192 @@
++
++#include <linux/autoconf.h>
++
++#include <linux/module.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/ioport.h>
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/fs.h>
++#include <linux/string.h>
++#include <linux/poll.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++
++#include <asm/uaccess.h>
++#include <linux/gpio_syscalls.h>
++
++#include <asm/etraxgpio.h>
++#include <asm/arch/svinto.h>
++#include <asm/io.h>
++#include <asm/system.h>
++#include <asm/irq.h>
++#include <asm/arch/io_interface_mux.h>
++
++#include <asm/unistd.h>
++
++
++extern int errno;
++
++
++asmlinkage void sys_gpiosetbits(unsigned char port, unsigned int bits){
++      switch(port){
++      case 'G':
++      case 'g':
++              *R_PORT_G_DATA = port_g_data_shadow |= bits;
++              break;
++              
++      case 'A':
++      case 'a':
++              *R_PORT_PA_DATA = port_pa_data_shadow |= bits;
++              break;
++
++      case 'B':
++      case 'b':
++              *R_PORT_PB_DATA = port_pb_data_shadow |= bits;
++              break;
++              
++      };
++};
++
++
++asmlinkage void sys_gpioclearbits(unsigned char port, unsigned int bits){
++      switch(port){
++      case 'G':
++      case 'g':
++              *R_PORT_G_DATA = port_g_data_shadow &= ~bits;
++              break;
++              
++      case 'A':
++      case 'a':
++              *R_PORT_PA_DATA = port_pa_data_shadow &= ~bits;
++              break;
++
++      case 'B':
++      case 'b':
++              *R_PORT_PB_DATA = port_pb_data_shadow &= ~bits;
++              break;
++              
++      };
++};
++
++asmlinkage void sys_gpiosetdir(unsigned char port, unsigned char dir, unsigned int bits){
++      if((dir=='I' )||(dir=='i')){
++              switch(port){
++              case 'G':
++              case 'g':
++                      if(bits & (1<<0)){
++                              genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g0dir);
++                      };
++                      if((bits & 0x0000FF00)==0x0000FF00){
++                              genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g8_15dir);
++                      };                      
++                      if((bits & 0x00FF0000)==0x00FF0000){
++                              genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g16_23dir);
++                      };                      
++                      if(bits & (1<<24)){
++                              genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g24dir);
++                      };                      
++                      *R_GEN_CONFIG = genconfig_shadow;
++                      break;
++              
++              case 'A':
++              case 'a':
++                      *R_PORT_PA_DIR = port_pa_dir_shadow &= ~(bits & 0xff);
++                      break;
++
++              case 'B':
++              case 'b':
++                      *R_PORT_PB_DIR = port_pb_dir_shadow &= ~(bits & 0xff);
++                      break;
++              };
++      } else if((dir=='O' )||(dir=='o')){
++              switch(port){
++              case 'G':
++              case 'g':
++                      if(bits & (1<<0)){
++                              genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g0dir);
++                      };
++                      if((bits & 0x0000FF00)==0x0000FF00){
++                              genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g8_15dir);
++                      };                      
++                      if((bits & 0x00FF0000)==0x00FF0000){
++                              genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g8_15dir);
++                      };                      
++                      if(bits & (1<<24)){
++                              genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g24dir);
++                      };                      
++                      *R_GEN_CONFIG = genconfig_shadow;
++                      break;
++              
++              case 'A':
++              case 'a':
++                      *R_PORT_PA_DIR = port_pa_dir_shadow |= (bits & 0xff);
++                      break;
++
++              case 'B':
++              case 'b':
++                      *R_PORT_PB_DIR = port_pb_dir_shadow |= (bits & 0xff);
++                      break;
++              };
++      };
++};
++
++
++asmlinkage void sys_gpiotogglebit(unsigned char port, unsigned int bits){
++      switch(port){
++      case 'G':
++      case 'g':
++              if(port_g_data_shadow & bits){
++                      *R_PORT_G_DATA = port_g_data_shadow &= ~bits;
++              } else {
++                      *R_PORT_G_DATA = port_g_data_shadow |= bits;
++              };
++              break;
++              
++      case 'A':
++      case 'a':
++              if(*R_PORT_PA_DATA & bits){
++                      *R_PORT_PA_DATA = port_pa_data_shadow &= ~(bits & 0xff);
++              } else {
++                      *R_PORT_PA_DATA = port_pa_data_shadow |= (bits & 0xff); 
++              };
++              break;
++
++      case 'B':
++      case 'b':
++              if(*R_PORT_PB_DATA & bits){
++                      *R_PORT_PB_DATA = port_pb_data_shadow &= ~(bits & 0xff);
++              } else {
++                      *R_PORT_PB_DATA = port_pb_data_shadow |= (bits & 0xff); 
++              };
++              break;
++              
++      };
++};
++
++
++asmlinkage unsigned int sys_gpiogetbits(unsigned char port, unsigned int bits){
++      unsigned int data = 0;
++      switch(port){
++      case 'G':
++      case 'g':
++              data = *R_PORT_G_DATA;
++              break;
++              
++      case 'A':
++      case 'a':
++              data = *R_PORT_PA_DATA;
++              break;
++
++      case 'B':
++      case 'b':
++              data = *R_PORT_PB_DATA;
++              break;
++              
++      };
++      data &= bits;
++      return data;
++};
++
++
+Only in linux-2.6.19.2/arch/cris/arch-v10/drivers/: gpio_syscalls.c
+diff linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/Makefile linux-2.6.19.2/arch/cris/arch-v10/drivers/Makefile
+8a9
+> obj-$(CONFIG_ETRAX_GPIO)            += gpio_syscalls.o
diff --git a/target/linux/etrax-2.6/profiles/100-generic.mk b/target/linux/etrax-2.6/profiles/100-generic.mk
new file mode 100644 (file)
index 0000000..9d0fc72
--- /dev/null
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+define Profile/default
+  NAME:=Normal (default)
+endef
+
+define Profile/default/Description
+       Normal Foxboard setup (no vhdl)
+endef
+$(eval $(call Profile,default))
+
diff --git a/target/linux/etrax-2.6/profiles/101-vhdl-nofb.mk b/target/linux/etrax-2.6/profiles/101-vhdl-nofb.mk
new file mode 100644 (file)
index 0000000..620db42
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+define Profile/vhdl_no_fb
+  NAME:=FOXVHDL no fb
+#  PACKAGES:=kmod-madwifi
+endef
+
+define Profile/vhdl_no_fb/Description
+       Setup the Foxboard for FOXVHDL support with no framebuffer
+endef
+$(eval $(call Profile,vhdl_no_fb))
+