/* Copyright(c) 2002,2003 Device Drivers Limited, All rights reserved. */ /* info@devdrv.com http://www.devdrv.com/ */ #ifndef __KERNEL__ # define __KERNEL__ #endif #ifndef MODULE # define MODULE #endif #include #include #include #include /* printk() */ #include /* everything... */ #include #include #include #include #define BUFSIZ 128 static int debug = 0; typedef unsigned long *ADDR; static unsigned long *sys_pinfunc = (ADDR) 0xB190002C; #define USBA_HT_BIT 15 static unsigned long *usb_ctrl = (ADDR) 0xB800000C; #define USBA_USBPDP_BIT 0 #define USBA_USBPUP_BIT 1 #define USBA_USBPDM_BIT 2 #define USBA_EN0_BIT 6 static unsigned long *usb_status = (ADDR) 0xB8000008; #define USBA_STATUS_BIT 4 /* * usba_read_proc -- */ static int usba_debug_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *data) { int len; len = sprintf(buf, "sys_pinfunc = %08lX\n", *sys_pinfunc); len += sprintf(buf+len, "usb_ctrl = %08lX\n", *usb_ctrl); len += sprintf(buf+len, "usb_status = %08lX\n", *usb_status); *eof = 1; return len; } static int usba_sw_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *data) { int len; unsigned long reg; reg = *sys_pinfunc; len = sprintf(buf, "sys_pinfunc = %s\n", reg & (0x01 << USBA_HT_BIT) ? "Host" : "Device"); reg = *usb_ctrl; len+= sprintf(buf+len, "usbpdp = %s\n", reg & (0x01 << USBA_USBPDP_BIT) ? "Host" : "Device"); len+= sprintf(buf+len, "usbpup = %s\n", reg & (0x01 << USBA_USBPUP_BIT) ? "Device" : "Host"); len+= sprintf(buf+len, "usbpdp = %s\n", reg & (0x01 << USBA_USBPDM_BIT) ? "Host" : "Device"); len+= sprintf(buf+len, "en0 = %s\n", reg & (0x01 << USBA_EN0_BIT) ? "Host" : "Device"); *eof = 1; return len; } static int usba_stat_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *data) { int len; unsigned long reg; reg = *usb_status; len = sprintf(buf, "usb_status = %s\n", reg & (0x01 << USBA_STATUS_BIT) ? "miniB" : "miniA"); *eof = 1; return len; } /* * usba_read_proc -- */ static int usba_write_proc(struct file *file, const char *buf, unsigned long count, void *data) { int length; int usba; unsigned long reg; char buffer[BUFSIZ]; length = count > (BUFSIZ - 1) ? (BUFSIZ - 1) : count; copy_from_user(buffer, buf, length); buffer[length] = '\0'; if (debug) printk("write_usba(), buf = %s, count = %d, length = %d\n", buffer, (int) count, length); usba = simple_strtoul(buffer, NULL, 10); if (usba == 0) { /* Target */ /* reg = *sys_pinfunc; */ *sys_pinfunc &= ~(0x01 << USBA_HT_BIT); reg = *usb_ctrl; reg &= ~(0x01 << USBA_USBPDP_BIT); reg |= (0x01 << USBA_USBPUP_BIT); reg &= ~(0x01 << USBA_USBPDM_BIT); reg &= ~(0x01 << USBA_EN0_BIT); *usb_ctrl = reg; } else { /* Host */ /* reg = *sys_pinfunc; */ *sys_pinfunc |= (0x01 << USBA_HT_BIT); reg = *usb_ctrl; reg |= (0x01 << USBA_USBPDP_BIT); reg &= ~(0x01 << USBA_USBPUP_BIT); reg |= (0x01 << USBA_USBPDM_BIT); reg |= (0x01 << USBA_EN0_BIT); *usb_ctrl = reg; } return length; } static void usba_create_proc() { struct proc_dir_entry *entry; entry = create_proc_entry("net/usbdebug", 0, 0); entry->read_proc = usba_debug_read_proc; entry->write_proc = usba_write_proc; entry = create_proc_entry("net/usbstat", 0, 0); entry->read_proc = usba_stat_read_proc; entry->write_proc = usba_write_proc; entry = create_proc_entry("net/usbsw", 0, 0); entry->read_proc = usba_sw_read_proc; entry->write_proc = usba_write_proc; } static void usba_remove_proc() { remove_proc_entry("net/usbdebug", NULL); remove_proc_entry("net/usbstat", NULL); remove_proc_entry("net/usbsw", NULL); } static int __init usba_init_module(void) { usba_create_proc(); if (debug) printk("<1>Usba, world data\n"); return 0; } static void __exit usba_cleanup_module(void) { if (debug) printk("<1>Usba, world data\n"); usba_remove_proc(); } MODULE_DESCRIPTION("Usba Module for USB Mini A/B test"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Atomu Hidaka "); MODULE_PARM(debug, "i"); MODULE_PARM_DESC(debug, "usba debug level (0-6)"); module_init(usba_init_module); module_exit(usba_cleanup_module);