diff -urN -X ignore orig/linux-2.4.21-pre4/drivers/char/Config.in new/linux-2.4.21-pre4/drivers/char/Config.in --- orig/linux-2.4.21-pre4/drivers/char/Config.in Thu Jul 3 00:57:34 2003 +++ new/linux-2.4.21-pre4/drivers/char/Config.in Wed Feb 11 13:21:25 2004 @@ -359,4 +359,8 @@ if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then tristate ' ITE GPIO' CONFIG_ITE_GPIO fi + +if [ "$CONFIG_HUMBLESOFT_NCARD" = "y" ]; then + tristate ' N-Card IO driver' CONFIG_NCARD_IO +fi endmenu diff -urN -X ignore orig/linux-2.4.21-pre4/drivers/char/Makefile new/linux-2.4.21-pre4/drivers/char/Makefile --- orig/linux-2.4.21-pre4/drivers/char/Makefile Wed Jun 25 07:19:58 2003 +++ new/linux-2.4.21-pre4/drivers/char/Makefile Wed Feb 11 15:00:09 2004 @@ -320,6 +320,8 @@ obj-y += ipmi/ipmi.o endif +obj-$(CONFIG_NCARD_IO) += ncard-io.o + include $(TOPDIR)/Rules.make fastdep: @@ -339,3 +341,4 @@ qtronixmap.c: qtronixmap.map set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@ + diff -urN -X ignore orig/linux-2.4.21-pre4/drivers/char/ncard-io.c new/linux-2.4.21-pre4/drivers/char/ncard-io.c --- orig/linux-2.4.21-pre4/drivers/char/ncard-io.c Thu Jan 1 09:00:00 1970 +++ new/linux-2.4.21-pre4/drivers/char/ncard-io.c Wed Feb 11 15:20:52 2004 @@ -0,0 +1,332 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define IODRV_MAJOR 20 +int iodrv_major = IODRV_MAJOR; + +#define DIPSW_PORT ((volatile unsigned char *)0xaa000000) +#define VDAT_PORT ((volatile unsigned char *)0xaa000002) +#define VCTL_PORT ((volatile unsigned char *)0xaa000004) + +#define EX_PORT ((volatile unsigned char *)0xac000000) + + +#define VCTL_DIR 8 +#define VCTL_RS 4 +#define VCTL_WRZ 2 +#define VCTL_RDZ 1 +#define VR4131_GIUIOSELL (*(volatile unsigned short *)0xaf000140) +#define VR4131_GIUPIODL (*(volatile unsigned short *)0xaf000144) + +static void wait_ms(int ms) +{ + int j = (ms * HZ + 9999)/ 1000; + if(j>0){ + wait_queue_head_t wait; + init_waitqueue_head(&wait); + interruptible_sleep_on_timeout(&wait,j); + } +} + +static int iodrv_default_open(struct inode *inode, struct file *filp) +{ + filp->private_data = NULL; + MOD_INC_USE_COUNT; + return 0; +} + +static int iodrv_default_release(struct inode *inode, struct file *filp) +{ + MOD_DEC_USE_COUNT; + return 0; +} + +/* + * Minor No.0-7 DIPSW + */ + + +static ssize_t iodrv_dipsw_read(struct file *filp, char *buff, size_t count, loff_t *f_pos) +{ + unsigned char data; + char tmp[4]; + int len; + + if(filp->private_data != NULL) + len = 0; + else { + int minor = MINOR(filp->f_dentry->d_inode->i_rdev); + int mask = 1 << (minor % 8); + data = readb(DIPSW_PORT); + sprintf(tmp,"%c\n",data & mask ? '0' : '1'); + len = strlen(tmp); + if(count < len) return -EINVAL; + if(copy_to_user(buff, tmp, len)) return -EFAULT; + *f_pos += len; + filp->private_data = (void *)1; + } + return len; +} + +struct file_operations iodrv_dipsw_fops = { + open: iodrv_default_open, + release: iodrv_default_release, + read: iodrv_dipsw_read, +}; + +/* + * Minor 8-15: LED + */ + +static void led_set(int led, int bOn) +{ + u16 m = (led == 0) ? 0x0100 : 0x2000; + + VR4131_GIUIOSELL |= m; + if(!bOn) + VR4131_GIUPIODL |= m; + else + VR4131_GIUPIODL &= ~m; +} + +static ssize_t iodrv_led_write(struct file *filp, const char *buf,size_t count, + loff_t *f_pos) +{ + int minor = MINOR(filp->f_dentry->d_inode->i_rdev); + int led = minor & 1; + int i; + + for(i=0;i 1000000){ + printk(KERN_WARNING "vfd_write: PBUSY stay hight. timeout.\n"); + break; + } + } + while(d & 0x80); +} + +static void vfd_init(void) +{ + vfd_initialized = 1; +} + + +static ssize_t iodrv_vfd_write(struct file *filp, const char *buf, + size_t count, loff_t *f_pos) +{ + int i; + + if(!vfd_initialized) vfd_init(); + + for(i=0;iprivate_data != NULL) + len = 0; + else { + data = readb(EX_PORT); + sprintf(tmp,"%02x\n", data); + len = strlen(tmp); + if(count < len) return -EINVAL; + if(copy_to_user(buff, tmp, len)) return -EFAULT; + *f_pos += len; + filp->private_data = (void *)1; + } + return len; +} + +struct file_operations iodrv_ex_fops = { + open: iodrv_default_open, + release: iodrv_default_release, + read: iodrv_ex_read, + write: iodrv_ex_write, +}; + +/* + * Minor 255: debug_sw + * + */ +static ssize_t iodrv_debugsw_write(struct file *filp, const char *buf,size_t count, + loff_t *f_pos) +{ + int i; + + for(i=0;iprivate_data != NULL) + len = 0; + else { +#define VR4131_MSYSINT1REG (*(volatile unsigned short *)0xaf00008c) + data = VR4131_MSYSINT1REG; + sprintf(tmp,"MSYSINT1REG=%04x\n", data); + len = strlen(tmp); + if(count < len) return -EINVAL; + if(copy_to_user(buff, tmp, len)) return -EFAULT; + *f_pos += len; + filp->private_data = (void *)1; + } + return len; +} + +struct file_operations iodrv_debugsw_fops = { + open: iodrv_default_open, + release: iodrv_default_release, + read: iodrv_debugsw_read, + write: iodrv_debugsw_write, +}; + + +static int iodrv_open(struct inode *inode, struct file *filp) +{ + int minor = MINOR(inode->i_rdev); + + if(minor < 8) filp->f_op = &iodrv_dipsw_fops; + else if(minor < 15) filp->f_op = &iodrv_led_fops; + else if(minor < 23) return -ENODEV; + else if(minor < 31) filp->f_op = &iodrv_vfd_fops; + else if(minor == 254) filp->f_op = &iodrv_ex_fops; + else if(minor == 255) filp->f_op = &iodrv_debugsw_fops; + else return -ENODEV; + return filp->f_op->open(inode, filp); +} + +struct file_operations iodrv_fops = { + open: iodrv_open, +}; + +static int __init ncardio_init_module(void) +{ + int r = register_chrdev(iodrv_major, "iodrv", &iodrv_fops); + if(r < 0){ + printk(KERN_WARNING "iodrv: can't get mojor %d\n",iodrv_major); + return r; + } + if(iodrv_major == 0) iodrv_major = r; + printk(KERN_INFO "iodrv installed!\n"); + return 0; +} + +static void __exit ncardio_cleanup_module(void) +{ + int r = unregister_chrdev(iodrv_major, "iodrv"); + if(r < 0){ + printk(KERN_ALERT "iodrv: unregister major %d failed\n", iodrv_major); + return; + } + + printk(KERN_INFO "iodrv uninstalled\n"); +} + +module_init(ncardio_init_module); +module_exit(ncardio_cleanup_module); + +MODULE_LICENSE("GPL"); +