mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-11-10 19:02:28 +02:00
41e8f769da
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@7652 3c298f89-4303-0410-b956-a3cf2f4a3e73
4837 lines
138 KiB
Diff
4837 lines
138 KiB
Diff
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
|