summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Schinagl <oliver@schinagl.nl>2011-04-19 11:10:12 (GMT)
committerOliver Schinagl <oliver@schinagl.nl>2011-04-19 11:10:12 (GMT)
commit979d729439057488023d5ba6f095b9256d5d242e (patch)
tree36f3f2c14f96a6388d4004a1b1b49ef297bebad1
parent315a776715d3870391a829724b7f863bd0459b24 (diff)
downloadopenipcam-979d729439057488023d5ba6f095b9256d5d242e.zip
openipcam-979d729439057488023d5ba6f095b9256d5d242e.tar.gz
openipcam-979d729439057488023d5ba6f095b9256d5d242e.tar.bz2
convert to unix file format
-rwxr-xr-xuClinux-2.4.20-uc1/drivers/block/export.c76
-rw-r--r--uClinux-2.4.20-uc1/drivers/block/wbflash/cfi.c558
-rw-r--r--uClinux-2.4.20-uc1/drivers/block/wbflash/cfi.h78
-rw-r--r--uClinux-2.4.20-uc1/drivers/block/wbflash/flash.c2112
-rw-r--r--uClinux-2.4.20-uc1/drivers/block/wbflash/flash_u.c492
-rw-r--r--uClinux-2.4.20-uc1/drivers/block/wbflash/image.c356
-rw-r--r--uClinux-2.4.20-uc1/drivers/char/vdd.c944
-rwxr-xr-xuClinux-2.4.20-uc1/drivers/char/w90n745_i2c.c1200
-rw-r--r--uClinux-2.4.20-uc1/drivers/char/w90n745_i2c.h246
-rwxr-xr-xuClinux-2.4.20-uc1/drivers/char/w90n745_keypad.c506
-rwxr-xr-xuClinux-2.4.20-uc1/drivers/char/w90n745_keypad.h114
-rwxr-xr-xuClinux-2.4.20-uc1/drivers/char/w90n745_usi.c662
-rwxr-xr-xuClinux-2.4.20-uc1/drivers/char/w90n745_usi.h146
-rw-r--r--uClinux-2.4.20-uc1/drivers/sound/w90n745_ac97.c1674
-rw-r--r--uClinux-2.4.20-uc1/drivers/sound/w90n745_ac97.h120
-rw-r--r--uClinux-2.4.20-uc1/drivers/sound/w90n745_audio.h290
-rw-r--r--uClinux-2.4.20-uc1/drivers/sound/w90n745_audio_regs.h398
-rw-r--r--uClinux-2.4.20-uc1/drivers/sound/w90n745_i2s.c1354
-rw-r--r--uClinux-2.4.20-uc1/drivers/sound/w90n745_i2s.h138
-rwxr-xr-xuClinux-2.4.20-uc1/drivers/usb/wbusbd/Makefile26
-rw-r--r--uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_mass.h500
-rw-r--r--uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_vcom.h522
-rw-r--r--uClinux-2.4.20-uc1/include/asm-armnommu/arch-W90N745/flash.h206
-rw-r--r--uClinux-2.4.20-uc1/include/gpio/gpio_interface.h80
24 files changed, 6399 insertions, 6399 deletions
diff --git a/uClinux-2.4.20-uc1/drivers/block/export.c b/uClinux-2.4.20-uc1/drivers/block/export.c
index 97fa9fc..5ec6039 100755
--- a/uClinux-2.4.20-uc1/drivers/block/export.c
+++ b/uClinux-2.4.20-uc1/drivers/block/export.c
@@ -1,38 +1,38 @@
-#include <asm/arch/flash.h>
-#include <linux/slab.h>
-
-#ifndef CONFIG_WBFLASH//CONFIG_W90N745FLASH
-
-asmlinkage int sys_FindImage(UINT32 image_num, tfooter ** image_footer)
-{
- return -ENOSYS;
-}
-asmlinkage int sys_DelImage(UINT32 image_num)
-{
- return -ENOSYS;
-}
-asmlinkage int sys_CorruptCheck(tfooter * image_footer)
-{
- return -ENOSYS;
-}
-asmlinkage int sys_ReadWinbondFlash(unsigned long pos, unsigned long length, char * buffer)
-{
- return -ENOSYS;
-}
-asmlinkage int sys_WriteWinbondFlash(unsigned long pos, unsigned long length, char * buffer)
-{
- return -ENOSYS;
-}
-asmlinkage int sys_WinbondFlashBlockSize(unsigned long pos)
-{
- return -ENOSYS;
-}
-asmlinkage int sys_WinbondFlashTotalSize()
-{
- return -ENOSYS;
-}
-asmlinkage int sys_WinbondFlashBase()
-{
- return -ENOSYS;
-}
-#endif
+#include <asm/arch/flash.h>
+#include <linux/slab.h>
+
+#ifndef CONFIG_WBFLASH//CONFIG_W90N745FLASH
+
+asmlinkage int sys_FindImage(UINT32 image_num, tfooter ** image_footer)
+{
+ return -ENOSYS;
+}
+asmlinkage int sys_DelImage(UINT32 image_num)
+{
+ return -ENOSYS;
+}
+asmlinkage int sys_CorruptCheck(tfooter * image_footer)
+{
+ return -ENOSYS;
+}
+asmlinkage int sys_ReadWinbondFlash(unsigned long pos, unsigned long length, char * buffer)
+{
+ return -ENOSYS;
+}
+asmlinkage int sys_WriteWinbondFlash(unsigned long pos, unsigned long length, char * buffer)
+{
+ return -ENOSYS;
+}
+asmlinkage int sys_WinbondFlashBlockSize(unsigned long pos)
+{
+ return -ENOSYS;
+}
+asmlinkage int sys_WinbondFlashTotalSize()
+{
+ return -ENOSYS;
+}
+asmlinkage int sys_WinbondFlashBase()
+{
+ return -ENOSYS;
+}
+#endif
diff --git a/uClinux-2.4.20-uc1/drivers/block/wbflash/cfi.c b/uClinux-2.4.20-uc1/drivers/block/wbflash/cfi.c
index ba4f0a3..9398461 100644
--- a/uClinux-2.4.20-uc1/drivers/block/wbflash/cfi.c
+++ b/uClinux-2.4.20-uc1/drivers/block/wbflash/cfi.c
@@ -1,279 +1,279 @@
-/******************************************************************************
- *
- * Copyright (c) 2007 Windond Electronics Corp.
- * All rights reserved.
- *
- * $Workfile: cfi.c $
- *
- *
- ******************************************************************************/
-
-//#include <stdio.h>
-//#include <string.h>
-//#include <stdlib.h>
-//#include "wblib.h"
-#include <asm/arch/flash.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-
-#include "cfi.h"
-//#include "platform.h"
-
-//#define FLASH_BASE 0xFF000000
-#define MAX_REGION_NUM 10
-
-static unsigned short cfiCmdSet = 0;
-static unsigned short cfiExtTab = 0;
-static unsigned int cfiDevSize = 0;
-static unsigned short cfiNumEraseBlkRegion = 0;
-
-static struct cfi_erase_block_region_info cfiEraseBlkRegionInfo[MAX_REGION_NUM];
-static int dummyErase(unsigned int address, unsigned int size);
-static int dummyWrite(unsigned int address, unsigned char *data, unsigned int size);
-
-struct cfi_command cfiCmd = {
- write: dummyWrite,
- erase: dummyErase,
-};
-
-
-/* Retrun 0: OK, otherwise: CFI not found */
-static int cfiCheckIdent(void)
-{
- unsigned short i[3];
-
- CFI_READ(FLASH_BASE, 0x10, i[0]);
- CFI_READ(FLASH_BASE, 0x11, i[1]);
- CFI_READ(FLASH_BASE, 0x12, i[2]);
-
- if(i[0] == 'Q' && i[1] == 'R' && i[2] == 'Y')
- return(0);
- else
- return(-1);
-
-}
-
-unsigned int cfiGetFlashSize(void)
-{
- return(cfiDevSize);
-}
-
-unsigned int cfiGetBlockSize(unsigned int address)
-{
- int i, offset = 0;
-
- address = (address | 0x80000000) - (FLASH_BASE | 0x80000000);
- //printk("addr %x %x\n", address, FLASH_BASE);
-
- for(i = 0; i < cfiNumEraseBlkRegion; i++) {
- if(address < (offset += (cfiEraseBlkRegionInfo[i].num * cfiEraseBlkRegionInfo[i].size)))
- return(cfiEraseBlkRegionInfo[i].size);
- }
- //uprintf("get size error\n");
-
- return(0);
-
-}
-
-static void flushDCache(void)
-{
-
- if( *(unsigned int volatile *)(0xFFF02000) & 0x6 ) /* If write buffer or data cache is enabled */
- {
- *(unsigned int volatile *)(0xFFF02004) = 0x86;
- while( *(unsigned int volatile *)(0xFFF02004));
- }
-
-}
-
-
-static int polling16(unsigned int addr, unsigned short data)
-{
- unsigned short rdata;
- int timeout = 0x600000;
-
- rdata = *(unsigned short volatile *)(addr);
- while( rdata != data )
- {
- rdata = *(unsigned short volatile *)(addr);
- if( !(timeout--) )
- {
- rdata = *(unsigned short volatile *)(addr);
- if( rdata != data )
- {
- //printf("timeout\n");
- return -1;
- }
- }
- }
-
- return 0;
-}
-
-static int intelWrite(unsigned int address, unsigned char *data, unsigned int size)
-{
- unsigned int i;
- int status = 0;
-
- address |= 0x80000000;
- for(i = address; i < address + size; i += 2)
- {
- CFI_WRITE(i, 0, 0x40);
- CFI_WRITE(i, 0, *(unsigned short *)data);
- CFI_WRITE(address, 0, 0x70);
- while(!( *(unsigned short *)(address) & 0x80));
- if(*(unsigned short *)(address) & 0x19) {
- status = -1;
- goto exit;
- }
- data+=2;
- }
-
-exit:
- CFI_WRITE(address,0,0xFF);
- flushDCache();
- return(status);
-}
-
-static int dummyWrite(unsigned int address, unsigned char *data, unsigned int size)
-{
- printk("Dummy Write\n");
- return(-1);
-}
-static int amdWrite(unsigned int address, unsigned char *data, unsigned int size)
-{
- int status;
- unsigned int i;
-
- address |= 0x80000000;
- for(i = address; i < address+size; i += 2)
- {
- CFI_WRITE(FLASH_BASE, 0x555, 0xAA);
- CFI_WRITE(FLASH_BASE, 0x2AA, 0x55);
- CFI_WRITE(FLASH_BASE, 0x555, 0xA0);
- CFI_WRITE(i, 0, *(unsigned short *)data);
- status = polling16( i, *(unsigned short *)data);
- if(status < 0) {
- printk("write failed, time out!\n");
- return(status); // time-out
- }
- data+=2;
- }
-
- flushDCache();
- return(0);
-
-}
-
-static int intelErase(unsigned int address, unsigned int size)
-{
- int status = 0;
-
- address|=0x80000000;
-
- CFI_WRITE(address, 0, 0x50); // Clear sttaus register
- CFI_WRITE(address, 0, 0x20);
- CFI_WRITE(address, 0, 0xD0);
-
- CFI_WRITE(address, 0, 0x70);
- while(!( *(unsigned short *)(address) & 0x80));
- if(*(unsigned short *)(address) & 0x39)
- status = -1;
-
- CFI_WRITE(address, 0, 0xFF);
- flushDCache();
- return(status);
-}
-
-static int dummyErase(unsigned int address, unsigned int size)
-{
- printk("Dummy Erase\n");
- return(-1);
-}
-static int amdErase(unsigned int address, unsigned int size)
-{
- int status;
-
- //printk("erase addr: %x\n", address);
-
- if((address & (size - 1)) != 0x0)
- return -1;// not in the start of a block
- address |= 0x80000000;
- //printf("erase addr: %08x\n", address);
- CFI_WRITE(FLASH_BASE, 0x555, 0xAA);
- CFI_WRITE(FLASH_BASE, 0x2AA, 0x55);
- CFI_WRITE(FLASH_BASE, 0x555, 0x80);
- CFI_WRITE(FLASH_BASE, 0x555, 0xAA);
- CFI_WRITE(FLASH_BASE, 0x2AA, 0x55);
- CFI_WRITE(address, 0, 0x30);
- status = polling16(address, 0xFFFF);
- CFI_WRITE(FLASH_BASE, 0, 0xFF);
- flushDCache();
- if(status < 0)
- printk("erase failed, time out!\n");
- return(status);
-
-}
-
-int cfiGetFlashInfo(void)
-{
-
- unsigned int i;
-
- // goes into query mode
- DESELECT_QUERY_MODE(FLASH_BASE);
- SELECT_QUERY_MODE(FLASH_BASE);
-
- if(cfiCheckIdent() != 0) {
- printk("No CFI information found\n");
- goto exit;
- }
-
- CFI_READ(FLASH_BASE, 0x13, cfiCmdSet);
- CFI_READ(FLASH_BASE, 0x15, cfiExtTab);
- CFI_READ(FLASH_BASE, 0x27, cfiDevSize);
- cfiDevSize = 1 << cfiDevSize;
-
- CFI_READ(FLASH_BASE, 0x2C, cfiNumEraseBlkRegion);
- //cfiEraseBlkRegionInfo = (struct cfi_erase_block_region_info *)malloc(sizeof(struct cfi_erase_block_region_info) * cfiNumEraseBlkRegion);
-
- if(cfiNumEraseBlkRegion > MAX_REGION_NUM) {
- //sysprintf("Out of memory\n");
- goto exit;
- }
-
- for(i = 0; i < cfiNumEraseBlkRegion * 4; i += 4) {
- unsigned short s1, s2;
- CFI_READ(FLASH_BASE, 0x2D + i, s1);
- CFI_READ(FLASH_BASE, 0x2E + i, s2);
-
- cfiEraseBlkRegionInfo[i/4].num = s1 + (s2 << 8) + 1;
- //printk("num %d ", (cfiEraseBlkRegionInfo + i/4)->num);
-
- CFI_READ(FLASH_BASE, 0x2F + i, s1);
- CFI_READ(FLASH_BASE, 0x30 + i, s2);
-
- cfiEraseBlkRegionInfo[i/4].size = (s1 + (s2 << 8)) * 256;
- //printk("size %x \n", (cfiEraseBlkRegionInfo + i/4)->size);
-
- }
-
- DESELECT_QUERY_MODE(FLASH_BASE);
- if(cfiCmdSet == AMD_CMD_SET) {
- cfiCmd.write = amdWrite;
- cfiCmd.erase = amdErase;
-
- }else if(cfiCmdSet == INTEL_CMD_SET) {
- cfiCmd.write = intelWrite;
- cfiCmd.erase = intelErase;
-
- } else {
- printk("CFI command set %04x not support!\n", cfiCmdSet);
- return(-1);
- }
- printk("CFI command set %04x will be used\n", cfiCmdSet);
-
-exit:
- return(0);
-
-}
+/******************************************************************************
+ *
+ * Copyright (c) 2007 Windond Electronics Corp.
+ * All rights reserved.
+ *
+ * $Workfile: cfi.c $
+ *
+ *
+ ******************************************************************************/
+
+//#include <stdio.h>
+//#include <string.h>
+//#include <stdlib.h>
+//#include "wblib.h"
+#include <asm/arch/flash.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+
+#include "cfi.h"
+//#include "platform.h"
+
+//#define FLASH_BASE 0xFF000000
+#define MAX_REGION_NUM 10
+
+static unsigned short cfiCmdSet = 0;
+static unsigned short cfiExtTab = 0;
+static unsigned int cfiDevSize = 0;
+static unsigned short cfiNumEraseBlkRegion = 0;
+
+static struct cfi_erase_block_region_info cfiEraseBlkRegionInfo[MAX_REGION_NUM];
+static int dummyErase(unsigned int address, unsigned int size);
+static int dummyWrite(unsigned int address, unsigned char *data, unsigned int size);
+
+struct cfi_command cfiCmd = {
+ write: dummyWrite,
+ erase: dummyErase,
+};
+
+
+/* Retrun 0: OK, otherwise: CFI not found */
+static int cfiCheckIdent(void)
+{
+ unsigned short i[3];
+
+ CFI_READ(FLASH_BASE, 0x10, i[0]);
+ CFI_READ(FLASH_BASE, 0x11, i[1]);
+ CFI_READ(FLASH_BASE, 0x12, i[2]);
+
+ if(i[0] == 'Q' && i[1] == 'R' && i[2] == 'Y')
+ return(0);
+ else
+ return(-1);
+
+}
+
+unsigned int cfiGetFlashSize(void)
+{
+ return(cfiDevSize);
+}
+
+unsigned int cfiGetBlockSize(unsigned int address)
+{
+ int i, offset = 0;
+
+ address = (address | 0x80000000) - (FLASH_BASE | 0x80000000);
+ //printk("addr %x %x\n", address, FLASH_BASE);
+
+ for(i = 0; i < cfiNumEraseBlkRegion; i++) {
+ if(address < (offset += (cfiEraseBlkRegionInfo[i].num * cfiEraseBlkRegionInfo[i].size)))
+ return(cfiEraseBlkRegionInfo[i].size);
+ }
+ //uprintf("get size error\n");
+
+ return(0);
+
+}
+
+static void flushDCache(void)
+{
+
+ if( *(unsigned int volatile *)(0xFFF02000) & 0x6 ) /* If write buffer or data cache is enabled */
+ {
+ *(unsigned int volatile *)(0xFFF02004) = 0x86;
+ while( *(unsigned int volatile *)(0xFFF02004));
+ }
+
+}
+
+
+static int polling16(unsigned int addr, unsigned short data)
+{
+ unsigned short rdata;
+ int timeout = 0x600000;
+
+ rdata = *(unsigned short volatile *)(addr);
+ while( rdata != data )
+ {
+ rdata = *(unsigned short volatile *)(addr);
+ if( !(timeout--) )
+ {
+ rdata = *(unsigned short volatile *)(addr);
+ if( rdata != data )
+ {
+ //printf("timeout\n");
+ return -1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int intelWrite(unsigned int address, unsigned char *data, unsigned int size)
+{
+ unsigned int i;
+ int status = 0;
+
+ address |= 0x80000000;
+ for(i = address; i < address + size; i += 2)
+ {
+ CFI_WRITE(i, 0, 0x40);
+ CFI_WRITE(i, 0, *(unsigned short *)data);
+ CFI_WRITE(address, 0, 0x70);
+ while(!( *(unsigned short *)(address) & 0x80));
+ if(*(unsigned short *)(address) & 0x19) {
+ status = -1;
+ goto exit;
+ }
+ data+=2;
+ }
+
+exit:
+ CFI_WRITE(address,0,0xFF);
+ flushDCache();
+ return(status);
+}
+
+static int dummyWrite(unsigned int address, unsigned char *data, unsigned int size)
+{
+ printk("Dummy Write\n");
+ return(-1);
+}
+static int amdWrite(unsigned int address, unsigned char *data, unsigned int size)
+{
+ int status;
+ unsigned int i;
+
+ address |= 0x80000000;
+ for(i = address; i < address+size; i += 2)
+ {
+ CFI_WRITE(FLASH_BASE, 0x555, 0xAA);
+ CFI_WRITE(FLASH_BASE, 0x2AA, 0x55);
+ CFI_WRITE(FLASH_BASE, 0x555, 0xA0);
+ CFI_WRITE(i, 0, *(unsigned short *)data);
+ status = polling16( i, *(unsigned short *)data);
+ if(status < 0) {
+ printk("write failed, time out!\n");
+ return(status); // time-out
+ }
+ data+=2;
+ }
+
+ flushDCache();
+ return(0);
+
+}
+
+static int intelErase(unsigned int address, unsigned int size)
+{
+ int status = 0;
+
+ address|=0x80000000;
+
+ CFI_WRITE(address, 0, 0x50); // Clear sttaus register
+ CFI_WRITE(address, 0, 0x20);
+ CFI_WRITE(address, 0, 0xD0);
+
+ CFI_WRITE(address, 0, 0x70);
+ while(!( *(unsigned short *)(address) & 0x80));
+ if(*(unsigned short *)(address) & 0x39)
+ status = -1;
+
+ CFI_WRITE(address, 0, 0xFF);
+ flushDCache();
+ return(status);
+}
+
+static int dummyErase(unsigned int address, unsigned int size)
+{
+ printk("Dummy Erase\n");
+ return(-1);
+}
+static int amdErase(unsigned int address, unsigned int size)
+{
+ int status;
+
+ //printk("erase addr: %x\n", address);
+
+ if((address & (size - 1)) != 0x0)
+ return -1;// not in the start of a block
+ address |= 0x80000000;
+ //printf("erase addr: %08x\n", address);
+ CFI_WRITE(FLASH_BASE, 0x555, 0xAA);
+ CFI_WRITE(FLASH_BASE, 0x2AA, 0x55);
+ CFI_WRITE(FLASH_BASE, 0x555, 0x80);
+ CFI_WRITE(FLASH_BASE, 0x555, 0xAA);
+ CFI_WRITE(FLASH_BASE, 0x2AA, 0x55);
+ CFI_WRITE(address, 0, 0x30);
+ status = polling16(address, 0xFFFF);
+ CFI_WRITE(FLASH_BASE, 0, 0xFF);
+ flushDCache();
+ if(status < 0)
+ printk("erase failed, time out!\n");
+ return(status);
+
+}
+
+int cfiGetFlashInfo(void)
+{
+
+ unsigned int i;
+
+ // goes into query mode
+ DESELECT_QUERY_MODE(FLASH_BASE);
+ SELECT_QUERY_MODE(FLASH_BASE);
+
+ if(cfiCheckIdent() != 0) {
+ printk("No CFI information found\n");
+ goto exit;
+ }
+
+ CFI_READ(FLASH_BASE, 0x13, cfiCmdSet);
+ CFI_READ(FLASH_BASE, 0x15, cfiExtTab);
+ CFI_READ(FLASH_BASE, 0x27, cfiDevSize);
+ cfiDevSize = 1 << cfiDevSize;
+
+ CFI_READ(FLASH_BASE, 0x2C, cfiNumEraseBlkRegion);
+ //cfiEraseBlkRegionInfo = (struct cfi_erase_block_region_info *)malloc(sizeof(struct cfi_erase_block_region_info) * cfiNumEraseBlkRegion);
+
+ if(cfiNumEraseBlkRegion > MAX_REGION_NUM) {
+ //sysprintf("Out of memory\n");
+ goto exit;
+ }
+
+ for(i = 0; i < cfiNumEraseBlkRegion * 4; i += 4) {
+ unsigned short s1, s2;
+ CFI_READ(FLASH_BASE, 0x2D + i, s1);
+ CFI_READ(FLASH_BASE, 0x2E + i, s2);
+
+ cfiEraseBlkRegionInfo[i/4].num = s1 + (s2 << 8) + 1;
+ //printk("num %d ", (cfiEraseBlkRegionInfo + i/4)->num);
+
+ CFI_READ(FLASH_BASE, 0x2F + i, s1);
+ CFI_READ(FLASH_BASE, 0x30 + i, s2);
+
+ cfiEraseBlkRegionInfo[i/4].size = (s1 + (s2 << 8)) * 256;
+ //printk("size %x \n", (cfiEraseBlkRegionInfo + i/4)->size);
+
+ }
+
+ DESELECT_QUERY_MODE(FLASH_BASE);
+ if(cfiCmdSet == AMD_CMD_SET) {
+ cfiCmd.write = amdWrite;
+ cfiCmd.erase = amdErase;
+
+ }else if(cfiCmdSet == INTEL_CMD_SET) {
+ cfiCmd.write = intelWrite;
+ cfiCmd.erase = intelErase;
+
+ } else {
+ printk("CFI command set %04x not support!\n", cfiCmdSet);
+ return(-1);
+ }
+ printk("CFI command set %04x will be used\n", cfiCmdSet);
+
+exit:
+ return(0);
+
+}
diff --git a/uClinux-2.4.20-uc1/drivers/block/wbflash/cfi.h b/uClinux-2.4.20-uc1/drivers/block/wbflash/cfi.h
index 19f2a65..88c0514 100644
--- a/uClinux-2.4.20-uc1/drivers/block/wbflash/cfi.h
+++ b/uClinux-2.4.20-uc1/drivers/block/wbflash/cfi.h
@@ -1,39 +1,39 @@
-/******************************************************************************
- *
- * Copyright (c) 2007 Windond Electronics Corp.
- * All rights reserved.
- *
- * $Workfile: cfi.h $
- *
- *
- ******************************************************************************/
-#ifndef __CFI_H__
-#define __CFI_H__
-
-#define SELECT_QUERY_MODE(_base_) do{*(unsigned short volatile *)(((_base_) & 0xFFF00000) + (0x55 << 1)) = 0x98;}while(0)
-#define DESELECT_QUERY_MODE(_base_) do{*(unsigned short volatile *)((_base_) & 0xFFF00000) = 0xF0;\
- *(unsigned short volatile *)((_base_) & 0xFFF00000) = 0xFF;}while(0)
-
-#define CFI_READ(_base_, _offset_, _var_) do{_var_ = *(unsigned short volatile *)(((_base_) & 0xFFF00000) + ((_offset_) << 1));}while(0)
-#define CFI_WRITE(_base_, _offset_, _var_) do{*(unsigned short volatile *)(((_base_) /*& 0xFFF00000*/) + ((_offset_) << 1)) = (_var_);}while(0)
-
-#define AMD_CMD_SET 0x0002
-#define INTEL_CMD_SET 0x0003
-
-struct cfi_erase_block_region_info {
- unsigned int size;
- unsigned int num;
-};
-
-
-struct cfi_command{
- int (*write) (unsigned int address, unsigned char *data, unsigned int size);
- int (*erase) (unsigned int address, unsigned int size);
-};
-
-extern unsigned int cfiGetBlockSize(unsigned int address);
-extern unsigned int cfiGetFlashSize(void);
-extern int cfiGetFlashInfo(void);
-extern struct cfi_command cfiCmd;
-
-#endif // #ifdef __CFI_H__
+/******************************************************************************
+ *
+ * Copyright (c) 2007 Windond Electronics Corp.
+ * All rights reserved.
+ *
+ * $Workfile: cfi.h $
+ *
+ *
+ ******************************************************************************/
+#ifndef __CFI_H__
+#define __CFI_H__
+
+#define SELECT_QUERY_MODE(_base_) do{*(unsigned short volatile *)(((_base_) & 0xFFF00000) + (0x55 << 1)) = 0x98;}while(0)
+#define DESELECT_QUERY_MODE(_base_) do{*(unsigned short volatile *)((_base_) & 0xFFF00000) = 0xF0;\
+ *(unsigned short volatile *)((_base_) & 0xFFF00000) = 0xFF;}while(0)
+
+#define CFI_READ(_base_, _offset_, _var_) do{_var_ = *(unsigned short volatile *)(((_base_) & 0xFFF00000) + ((_offset_) << 1));}while(0)
+#define CFI_WRITE(_base_, _offset_, _var_) do{*(unsigned short volatile *)(((_base_) /*& 0xFFF00000*/) + ((_offset_) << 1)) = (_var_);}while(0)
+
+#define AMD_CMD_SET 0x0002
+#define INTEL_CMD_SET 0x0003
+
+struct cfi_erase_block_region_info {
+ unsigned int size;
+ unsigned int num;
+};
+
+
+struct cfi_command{
+ int (*write) (unsigned int address, unsigned char *data, unsigned int size);
+ int (*erase) (unsigned int address, unsigned int size);
+};
+
+extern unsigned int cfiGetBlockSize(unsigned int address);
+extern unsigned int cfiGetFlashSize(void);
+extern int cfiGetFlashInfo(void);
+extern struct cfi_command cfiCmd;
+
+#endif // #ifdef __CFI_H__
diff --git a/uClinux-2.4.20-uc1/drivers/block/wbflash/flash.c b/uClinux-2.4.20-uc1/drivers/block/wbflash/flash.c
index d13d4a8..e4eaf2f 100644
--- a/uClinux-2.4.20-uc1/drivers/block/wbflash/flash.c
+++ b/uClinux-2.4.20-uc1/drivers/block/wbflash/flash.c
@@ -1,1056 +1,1056 @@
-/******************************************************************************
- *
- * Copyright (c) 2003 Windond Electronics Corp.
- * All rights reserved.
- *
- * $Workfile: flash.c $
- *
- * $Author: andy $
- ******************************************************************************/
-/*
- * $History: flash.c $
- *
- * ***************** Version 10 *****************
- * User: Wschang0 Date: 04/01/07 Time: 11:34a
- * Updated in $/W90N740/FIRMWARE/WBLv1_1/Src
- * Increase the timeout count in polling16 function to avoid early timeout
- * in W29LV800BT
- *
- * ***************** Version 9 *****************
- * User: Wschang0 Date: 03/12/25 Time: 4:06p
- * Updated in $/W90N740/FIRMWARE/WBLv1_1/Src
- * Add W29LV800BT, W29LV160DT, W29LV320DT
- * Remove the FLASH_NUM
- *
- * ***************** Version 8 *****************
- * User: Wschang0 Date: 03/12/03 Time: 5:16p
- * Updated in $/W90N740/FIRMWARE/WBLv1_1/Src
- * Add MX29LV160BT/TT
- * Fixed MX28F160C3BT/TT.
- * The MX28F160C3 sectors are default to be locked, thus it needs unlock
- * it before write/erase it.
- *
- * ***************** Version 7 *****************
- * User: Wschang0 Date: 03/11/05 Time: 11:03a
- * Updated in $/W90N740/FIRMWARE/WBLv1_1/Src
- * Add MX28F160C3T & MX28F160C3B
- *
- * ***************** Version 6 *****************
- * User: Wschang0 Date: 03/09/26 Time: 2:30p
- * Updated in $/W90N740/FIRMWARE/WBLv1_1/Src
- * Correct the flash name of SST39VF160 in the flash[] table
- *
- * ***************** Version 5 *****************
- * User: Wschang0 Date: 03/08/27 Time: 1:41p
- * Updated in $/W90N740/FIRMWARE/WBLv1_1/Src
- * Add FlushDCache to Write/Erase functions to avoid data cache
- * incohereance after Write/Erase flash.
- *
- * ***************** Version 4 *****************
- * User: Wschang0 Date: 03/08/27 Time: 11:28a
- * Updated in $/W90N740/FIRMWARE/WBLv1_1/Src
- * Add SST 39VF160 flash type
- *
- * ***************** Version 3 *****************
- * User: Wschang0 Date: 03/08/20 Time: 1:39p
- * Updated in $/W90N740/FIRMWARE/WBLv1_1/Src
- *
- * ***************** Version 2 *****************
- * User: Wschang0 Date: 03/08/20 Time: 11:53a
- * Updated in $/W90N740/FIRMWARE/WBLv1_1/Src
- * Add VSS header
- */
-#include <asm/arch/flash.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-// Update Note:
-// 8/19, 2003: Add Flash Tyep W28J800BT, W28J320TT, Fix the PID of W28J320BT
-// 8/07, 2003: W39L010 was protected when the erase address not in offset 0
-// 7/24, 2003: Remove the redundant code. Time-out check, for reliability
-
-UINT32 _flash_size = 0;
-
-#define DELAY_1US 20
-
-#define TIMEOUT 8000000UL
-static int normal_polling(unsigned int addr, unsigned short mask)
-{
- unsigned short rdata;
- unsigned int cnt;
-
- rdata=inph(addr)&mask;
- cnt=0;
- while( rdata != mask )
- {
- rdata=inph(addr)&mask;
- if( cnt++ > TIMEOUT ) return -1; // time-out
- }
-
- return 0;
-}
-
-static int polling16(unsigned int addr, unsigned short data)
-{
- unsigned short rdata;
- int timeout=0x600000;
-
- rdata=inph(addr);
- while( rdata != data )
- {
- rdata=inph(addr);
- if( (rdata&0x20) || !(timeout--) )
- {
- rdata=inph(addr);
- if( rdata != data )
- {
- //printf("polling time-out: %x\n",rdata);
- return -1; //polling time-out
- }
- }
- }
-
- return 0;
-}
-
-
-static INT CheckDataWidth(INT w)
-{
- INT extio_flag=0;
- // check if the platform (the Flash ROM is not in 0x7F000000)
- if( (ROMCON&0xFF000000)==0xFC000000 )extio_flag=1;
-
- switch(w)
- {
- case 8:
- if(extio_flag)
- {
- if( (EXT3CON&0x3)== 0x1 )return 1;
- else return 0;
- }
- else
- {
- if( (ROMCON&0xC)== 0x0 )return 1;
- else return 0;
- }
- case 16:
- if(extio_flag)
- {
- if( (EXT3CON&0x3)== 0x2 )return 1;
- else return 0;
- }
- else
- {
- if( (ROMCON&0xC)== 0x4 )return 1;
- else return 0;
- }
- case 32:
- if(extio_flag)
- {
- if( (EXT3CON&0x3)== 0x3 )return 1;
- else return 0;
- }
- else
- {
- if( (ROMCON&0xC)== 0x8 )return 1;
- else return 0;
- }
- default:
- return 0;
- }
-
-}
-
-
-void FlashDelay(UINT32 delay)
-{
- volatile UINT32 i;
- for(i=0;i<delay*DELAY_1US;i++);
-}
-
-static __inline void FlushDCache()
-{
- /* Flush Entire DCache */
- if( CAHCNF_R & 0x6 ) /* If write buffer or data cache is enabled */
- {
- CAHCON_R=0x86;
- while( CAHCON_R );
- }
-
-}
-
-
-
-INT BlockLock_W28J800TT(UINT32 address, UINT32 op)
-{
- address|=0x80000000;
-
- if( op==BLOCK_LOCK )
- {
- outph(address,0x70);
- while( !(inph(address)&0x80) );
- outph(address,0x60);
- outph(address,0x01);
- while( !(inph(address)&0x80) );
- outph(address,0xFFFF);
- }
- else if( op==BLOCK_UNLOCK )
- {
- outph(address,0x70);
- while( !(inph(address)&0x80) );
- outph(address,0x60);
- outph(address,0xD0);
- while( !(inph(address)&0x80) );
- outph(address,0xFFFF);
- }
- return 0;
-}
-
-INT BlockSize_W28J800TT(UINT32 address)
-{
- address-=FLASH_BASE;
- address&=0x7FFFFFFF;
- if( address >= 0xF0000 )
- {
- if( address < _flash_size )
- return 0x2000;
- else
- return 0;
- }
- else
- return 0x10000;
-}
-
-INT BlockSize_W28J800BT(UINT32 address)
-{
- address-=FLASH_BASE;
- address&=0x7FFFFFFF;
- if( address < 0x10000 )
- return 0x2000;
- else
- {
- if( address < _flash_size )
- return 0x10000;
- else
- return 0;
- }
-}
-
-
-INT BlockErase_W28J800TT(UINT32 address,UINT32 size)
-{
- int status;
- if( (address&(size-1))!=0x0 )return -1;// not in the start of a block
-
- BlockLock_W28J800TT(address,BLOCK_UNLOCK); // The intel flash sector is default to be locked
-
- address|=0x80000000;
- outph(address,0x70);
- status=normal_polling( address, 0x80 );
- if( status < 0 )return -1; // polling time-out
- outph(address,0x20);
- outph(address,0xD0);
- status=normal_polling( address, 0x80 );
- if( status < 0 )return -1; // polling time-out
- outph(address,0xFFFF);
- FlushDCache();
-
- return 0;
-}
-
-INT BlockWrite_W28J800TT(UINT32 address, UCHAR * data, UINT32 size)
-{
- UINT32 i;
- int status;
- address|=0x80000000;
- BlockLock_W28J800TT(address,BLOCK_UNLOCK); // The MX28F160C3 sector is default to be locked
- for(i=address;i<address+size;i+=2)
- {
- outph(i,0x40);
- outph(i,*((UINT16 *)data));
- //while( !(inph(i)&0x80) );
- status=normal_polling( i, 0x80 );
- if( status < 0 )return -1; // polling time-out
- data+=2;
- }
- outph(address,0xFFFF);
- FlushDCache();
-
- return 0;
-}
-
-INT ReadPID_Winbond(UINT32 address, UCHAR *pid0, UCHAR *pid1)
-{
- if( !CheckDataWidth(16) )return -1;
-
- address|=0x80000000;
- outph(address,0x70);
- FlashDelay(50000); // delay 50ms
- outph(address,0x90);
- *pid0=inph(address);
- *pid1=inph(address+1);
- outph(address,0xFFFF);
-
- return 0;
-}
-
-INT ReadPID_W28J800TT(UINT32 address, UCHAR *pid0, UCHAR *pid1)
-{
- int status;
- status=ReadPID_Winbond(address,pid0,pid1);
- if( status < 0 )return -1; // not x16 flash
- _flash_size=0x100000;
- return 0;
-}
-
-INT ReadPID_W28J800BT(UINT32 address, UCHAR *pid0, UCHAR *pid1)
-{
- int status;
- status=ReadPID_Winbond(address,pid0,pid1);
- if( status < 0 )return -1; // not x16 flash
- _flash_size=0x100000;
- return 0;
-}
-
-INT ReadPID_W28J160TT(UINT32 address, UCHAR *pid0, UCHAR *pid1)
-{
- int status;
- status=ReadPID_Winbond(address,pid0,pid1);
- if( status < 0 )return -1; // not x16 flash
- _flash_size=0x200000;
- return 0;
-}
-
-INT ReadPID_W28J320TT(UINT32 address, UCHAR *pid0, UCHAR *pid1)
-{
- int status;
- status=ReadPID_Winbond(address,pid0,pid1);
- if( status < 0 )return -1; // not x16 flash
- _flash_size=0x400000;
- return 0;
-}
-
-
-
-
-INT BlockSize_W28J320TT(UINT32 address)
-{
- address-=FLASH_BASE;
- address&=0x7FFFFFFF;
- if( address >= 0x3F0000 )
- {
- if( address < _flash_size )
- return 0x2000;
- else
- return 0;
- }
- else
- return 0x10000;
-}
-
-
-INT BlockSize_W28J320BT(UINT32 address)
-{
- address-=FLASH_BASE;
- address&=0x7FFFFFFF;
- if( address < 0x10000 )
- return 0x2000;
- else
- {
- if( address < _flash_size )
- return 0x10000;
- else
- return 0;
- }
-}
-
-
-
-INT BlockSize_W28J160BT(UINT32 address)
-{
- address-=FLASH_BASE;
- address&=0x7FFFFFFF;
- if( address < 0x10000 )
- return 0x2000;
- else
- {
- if( address < _flash_size )
- return 0x10000;
- else
- return 0;
- }
-}
-
-INT BlockSize_W28J160TT(UINT32 address)
-{
- address-=FLASH_BASE;
- address&=0x7FFFFFFF;
- if( address >= 0x1F0000 )
- {
- if( address < 0x200000 )
- return 0x2000;
- else
- return 0;
- }
- else
- return 0x10000;
-}
-
-
-INT BlockLock_W39L010(UINT32 address, UINT32 op)
-{
- return -1;
-}
-
-INT BlockSize_W39L010(UINT32 address)
-{
- address-=FLASH_BASE;
- address&=0x7FFFFFFF;
- if( address < _flash_size )
- return 0x20000;
- else
- return 0;
-}
-
-INT BlockErase_W39L010(UINT32 address,UINT32 size)
-{
- UINT32 addr1,addr2;
-
- if( (address&(0x20000-1))!=0x0 )return -1;// not in the start of flash
-
- address|=0x80000000;
- addr1=(address&0xFFF00000)+(0x5555);
- addr2=(address&0xFFF00000)+(0x2AAA);
-
- outpb(addr1,0xAA);
- outpb(addr2,0x55);
- outpb(addr1,0x80);
- outpb(addr1,0xAA);
- outpb(addr2,0x55);
- outpb(addr1,0x10);
- while( (inpb(address)&0x80)!=0x80 );
-
- FlushDCache();
-
- return 0;
-}
-
-INT BlockWrite_W39L010(UINT32 address, UCHAR * data, UINT32 size)
-{
- UINT32 i;
- UINT32 addr1, addr2;
-
- address|=0x80000000;
- addr1=(address&0xFFF00000)+(0x5555);
- addr2=(address&0xFFF00000)+(0x2AAA);
- for(i=address;i<address+size;i++)
- {
- outpb(addr1,0xAA);
- outpb(addr2,0x55);
- outpb(addr1,0xA0);
- outpb(i,*data);
- while( !((inpb(i)&0x80)==(*data&0x80)) );
- data++;
- }
- FlushDCache();
-
- return 0;
-}
-
-INT ReadPID_W39L010(UINT32 address, UCHAR *pid0, UCHAR *pid1)
-{
- UINT32 addr1, addr2;
-
- if( !CheckDataWidth(8) )return -1;
-
-
-
- address|=0x80000000;
- addr1=(address&0xFFF00000)+(0x5555);
- addr2=(address&0xFFF00000)+(0x2AAA);
-
- outpb(addr1,0xAA);
- outpb(addr2,0x55);
- outpb(addr1,0x80);
- outpb(addr1,0xAA);
- outpb(addr2,0x55);
- outpb(addr1,0x60);
- *pid0=inpb(address);
- *pid1=inpb(address+1);
- outpb(addr1,0xAA);
- outpb(addr2,0x55);
- outpb(addr1,0xF0);
- outpb(address,0xFF);
-
- _flash_size=0x20000;
-
- return 0;
-}
-
-
-
-INT BlockLock_W29EE011(UINT32 address, UINT32 op)
-{
- return -1;
-}
-
-
-INT BlockSize_W29EE011(UINT32 address)
-{
- address-=FLASH_BASE;
- address&=0x7FFFFFFF;
- if( address < _flash_size )
- return 0x80;
- else
- return 0;
-}
-
-INT BlockErase_W29EE011(UINT32 address,UINT32 size)
-{
- UINT32 addr1,addr2;
- static INT flag=0;
-
- if( flag )return 0;
-
- flag=1;
-
- address|=0x80000000;
- addr1=(address&0xFFF00000)+(0x5555);
- addr2=(address&0xFFF00000)+(0x2AAA);
-
- outpb(addr1,0xAA);
- outpb(addr2,0x55);
- outpb(addr1,0x80);
- outpb(addr1,0xAA);
- outpb(addr2,0x55);
- outpb(addr1,0x10);
- FlashDelay(50000); // delay 50ms
-
- FlushDCache();
-
- return 0;
-}
-
-INT BlockWrite_W29EE011(UINT32 address, UCHAR * data, UINT32 size)
-{
- UINT32 i;
- UINT32 addr1, addr2;
-
- address|=0x80000000;
- addr1=(address&0xFFF00000)+(0x5555);
- addr2=(address&0xFFF00000)+(0x2AAA);
- outpb(addr1,0xAA);
- outpb(addr2,0x55);
- outpb(addr1,0xA0);
- for(i=0;i<size;i++)
- outpb(address+i,*(data+i));
- while( inpb(address+i-1)!=*(data+i-1) );
- FlushDCache();
-
- return 0;
-}
-
-INT ReadPID_W29EE011(UINT32 address, UCHAR *pid0, UCHAR *pid1)
-{
- UINT32 addr1, addr2;
-
- if( !CheckDataWidth(8) )return -1;
-
-
- address|=0x80000000;
- addr1=(address&0xFFF00000)+(0x5555);
- addr2=(address&0xFFF00000)+(0x2AAA);
-
- outpb(addr1,0xAA);
- outpb(addr2,0x55);
- outpb(addr1,0x80);
- outpb(addr1,0xAA);
- outpb(addr2,0x55);
- outpb(addr1,0x60);
- FlashDelay(10);//delay 10 us
- *pid0=inpb(address);
- *pid1=inpb(address+1);
- outpb(addr1,0xAA);
- outpb(addr2,0x55);
- outpb(addr1,0xF0);
- FlashDelay(10);//delay 10 us
- outpb(address,0xFF);
-
- _flash_size=0x20000;
-
- return 0;
-}
-
-
-
-INT BlockLock_AM29LV800BB(UINT32 address, UINT32 op)
-{
- return -1;
-}
-
-
-INT BlockSize_AM29LV800BB(UINT32 address)
-{
- address-=FLASH_BASE;
- address&=0x7FFFFFFF;
- if( address < 0x4000 )
- return 0x4000;
- else if( address < 0x6000 )
- return 0x2000;
- else if( address < 0x8000 )
- return 0x2000;
- else if( address < 0x10000 )
- return 0x8000;
- else
- {
- if( address < _flash_size )
- return 0x10000;
- else
- return 0;
- }
-}
-
-INT BlockSize_AM29LV800BT(UINT32 address)
-{
- address-=FLASH_BASE;
- address&=0x7FFFFFFF;
- if( address < 0x0F0000 )
- return 0x10000;
- else if( address < 0xF8000 )
- return 0x8000;
- else if( address < 0xFA000 )
- return 0x2000;
- else if( address < 0xFC000 )
- return 0x2000;
- else
- {
- if( address < _flash_size )
- return 0x4000;
- else
- return 0;
- }
-}
-INT BlockErase_AM29LV800BB(UINT32 address,UINT32 size)
-{
- UINT32 addr1,addr2;
- INT status;
-
- if( (address&(size-1))!=0x0 )return -1;// not in the start of a block
-
- address|=0x80000000;
- addr1=(address&0xFFF00000)+(0x5555<<1);
- addr2=(address&0xFFF00000)+(0x2AAA<<1);
-
- outph(addr1,0xAA);
- outph(addr2,0x55);
- outph(addr1,0x80);
- outph(addr1,0xAA);
- outph(addr2,0x55);
- outph(address,0x30);
- //while( (inph(address))!=0xFFFF );
- status=polling16(address, 0xFFFF);
-
- FlushDCache();
-
- return status;
-}
-
-INT BlockWrite_AM29LV800BB(UINT32 address, UCHAR * data, UINT32 size)
-{
- UINT32 i;
- UINT32 addr1, addr2;
- INT status;
-
- address|=0x80000000;
- addr1=(address&0xFFF00000)+(0x5555<<1);
- addr2=(address&0xFFF00000)+(0x2AAA<<1);
-
- for(i=address;i<address+size;i+=2)
- {
- outph(addr1,0xAA);
- outph(addr2,0x55);
- outph(addr1,0xA0);
- outph(i,*((UINT16*)data));
- status=polling16( i, (*(UINT16 *)data));
- if( status < 0 )return status; // time-out
- data+=2;
- }
-
- outph(address,0xFFFF);
- FlushDCache();
-
- return status;
-}
-
-
-INT ReadPID_AM29LV(UINT32 address, UCHAR *pid0, UCHAR *pid1)
-{
- UINT32 addr1, addr2;
-
- if( !CheckDataWidth(16) )return -1;
-
-
- address|=0x80000000;
- addr1=(address&0xFFF00000)+(0x5555<<1);
- addr2=(address&0xFFF00000)+(0x2AAA<<1);
-
- outph(addr1,0xAA);
- outph(addr2,0x55);
- outph(addr1,0x90);
- *pid0=(char)inph(address);
- *pid1=(char)inph((address+2));
- outph(address,0xFFFF);
-
- return 0;
-}
-
-
-INT ReadPID_AM29LV800BB(UINT32 address, UCHAR *pid0, UCHAR *pid1)
-{
-
- ReadPID_AM29LV(address, pid0, pid1);
- _flash_size=0x100000;
-
- return 0;
-}
-
-INT ReadPID_AM29LV160DB(UINT32 address, UCHAR *pid0, UCHAR *pid1)
-{
-
- ReadPID_AM29LV(address, pid0, pid1);
- _flash_size=0x200000;
-
- return 0;
-}
-
-INT ReadPID_AM29LV320DB(UINT32 address, UCHAR *pid0, UCHAR *pid1)
-{
-
- ReadPID_AM29LV(address, pid0, pid1);
- _flash_size=0x400000;
-
- return 0;
-}
-
-
-
-INT BlockSize_AM29LV160DB(UINT32 address)
-{
- address-=FLASH_BASE;
- address&=0x7FFFFFFF;
- if( address < 0x4000 )
- return 0x4000;
- else if( address < 0x6000 )
- return 0x2000;
- else if( address < 0x8000 )
- return 0x2000;
- else if( address < 0x10000 )
- return 0x8000;
- else
- {
- if( address < _flash_size )
- return 0x10000;
- else
- return 0;
- }
-}
-
-INT BlockSize_AM29LV160DT(UINT32 address)
-{
- address-=FLASH_BASE;
- address&=0x7FFFFFFF;
- if( address < 0x1F0000 )
- return 0x10000;
- else if( address < 0x1F8000 )
- return 0x8000;
- else if( address < 0x1FA000 )
- return 0x2000;
- else if( address < 0x1FC000 )
- return 0x2000;
- else
- {
- if( address < _flash_size )
- return 0x4000;
- else
- return 0;
- }
-}
-INT BlockSize_AM29LV320DB(UINT32 address)
-{
- address-=FLASH_BASE;
- address&=0x7FFFFFFF;
- if( address < 0x10000 )
- return 0x2000;
- else
- {
- if( address < _flash_size )
- return 0x10000;
- else
- return 0;
- }
-}
-
-INT BlockSize_AM29LV320DT(UINT32 address)
-{
- address-=FLASH_BASE;
- address&=0x7FFFFFFF;
- if( address < 0x3F0000 )
- return 0x10000;
- else
- {
- if( address < _flash_size )
- return 0x2000;
- else
- return 0;
- }
-}
-
-INT BlockLock_E28F640(UINT32 address, UINT32 op)
-{
-
- address|=0x80000000;
-
- if( op==BLOCK_LOCK )
- {
- outph(address,0x60);
- outph(address,0x01);
- while( !(inph(address)&0x80) );
- outph(address,0xFFFF);
- }
- else if( op==BLOCK_UNLOCK )
- {
- outph(address,0x60);
- outph(address,0xD0);
- while( !(inph(address)&0x80) );
- outph(address,0xFFFF);
- }
-
- return 0;
-}
-
-INT BlockSize_E28F640(UINT32 address)
-{
- address-=FLASH_BASE;
- address&=0x7FFFFFFF;
- if( address < _flash_size )
- return 0x10000;
- else
- return 0;
-}
-
-INT BlockErase_E28F640(UINT32 address,UINT32 size)
-{
- UINT32 i,j,tmp;
- CHAR * buffer;
-
- address|=0x80000000;
- buffer = kmalloc(128*1024,GFP_KERNEL);
- if(!buffer)
- return 1;
- // backup the data
- j=0xFFFF;
- if( (address & FLASH_BLOCK_SIZE) )
- {
-
- for(i=0;i<FLASH_BLOCK_SIZE/2;i++)
- {
- tmp=*((volatile unsigned short *)(address-FLASH_BLOCK_SIZE)+i);
- *((volatile unsigned short *)buffer+i)=tmp;
- j&=tmp;
- }
- }
- else
- {
- for(i=0;i<FLASH_BLOCK_SIZE/2;i++)
- {
- tmp=*((volatile unsigned short *)(address+FLASH_BLOCK_SIZE)+i);
- *((volatile unsigned short *)buffer+i)=tmp;
- j&=tmp;
- }
- }
-
-
- outph(address,0x20);
- outph(address,0xD0);
- while( !(inph(address)&0x80) );
- outph(address,0xFFFF);
-
-
- // write back the data
- if( (j&0xFFFF)!=0xFFFF )
- {
- if( (address & FLASH_BLOCK_SIZE) )
- BlockWrite_E28F640(address-FLASH_BLOCK_SIZE, (UCHAR *)buffer, FLASH_BLOCK_SIZE);
- else
- BlockWrite_E28F640(address+FLASH_BLOCK_SIZE, (UCHAR *)buffer, FLASH_BLOCK_SIZE);
- }
- FlushDCache();
- kfree(buffer);
- return 0;
-}
-
-INT BlockWrite_E28F640(UINT32 address, UCHAR * data, UINT32 size)
-{
- UINT32 i;
-#if 0
- UINT32 pdata,j;
-
- address|=0x80000000;
-
- do{
- outph(address, 0xE8);
- }while( !(inph(address)&0x80) );
-
- i=size;
- while(i)
- {
- if( i < 32 )
- {
- outph(address, i);
- for(j=0;j<i/2;j++)
- outph(address+j, *((unsigned short *)pdata+j));
- pdata+=i;
- i=0;
- }
- else
- {
- outph(address, 32);
- for(j=0;j<16;j++)
- outph(address+j, *((unsigned short *)pdata+j));
- pdata+=32;
- i-=32;
- }
- outph(address, 0xD0);
- while( !(inph(address)&0x80) );
- }
-
-#else
- address|=0x80000000;
-
- for(i=address;i<address+size;i+=2)
- {
- outph(i,0x40);
- outph(i,*((UINT16 *)data));
- while( !(inph(i)&0x80) );
- data+=2;
- }
-
- outph(address,0xFFFF);
-#endif
-
- FlushDCache();
- return 0;
-}
-
-INT ReadPID_E28F640(UINT32 address, UCHAR *pid0, UCHAR *pid1)
-{
- if( !CheckDataWidth(16) )return -1;
-
- outph(address,0x90);
- *pid0=inph(address);
- *pid1=inph(address+1);
- outph(address,0xFFFF);
-
- _flash_size=0x800000;
-
- return 0;
-}
-
-
-INT BlockSize_SST39VF160(UINT32 address)
-{
- address-=FLASH_BASE;
- address&=0x7FFFFFFF;
- if( address < _flash_size )
- return 0x10000;
- else
- return 0;
-
-}
-
-
-INT ReadPID_SST39VF160(UINT32 address, UCHAR *pid0, UCHAR *pid1)
-{
-
- ReadPID_AM29LV(address, pid0, pid1);
- outph(address, 0x00F0 ); /* Exit Software ID mode */
- _flash_size=0x200000;
-
- return 0;
-}
-
-INT BlockErase_SST39VF160(UINT32 address,UINT32 size)
-{
- UINT32 addr1,addr2;
- INT status;
-
- if( (address&(size-1))!=0x0 )return -1;// not in the start of a block
-
- address|=0x80000000;
- addr1=(address&0xFFF00000)+(0x5555<<1);
- addr2=(address&0xFFF00000)+(0x2AAA<<1);
-
- outph(addr1,0xAA);
- outph(addr2,0x55);
- outph(addr1,0x80);
- outph(addr1,0xAA);
- outph(addr2,0x55);
- outph(address,0x50);
- status=polling16(address, 0xFFFF);
-
- FlushDCache();
-
- return status;
-}
-
-INT BlockErase_MX28F160C3B(UINT32 address,UINT32 size)
-{
- int status;
- if( (address&(size-1))!=0x0 )return -1;// not in the start of a block
-
- BlockLock_W28J800TT(address,BLOCK_UNLOCK); // The MX28F160C3 sector is default to be locked
-
- address|=0x80000000;
- outph(address,0x70);
- status=normal_polling( address, 0x80 );
- if( status < 0 )return -1; // polling time-out
- outph(address,0x20);
- outph(address,0xD0);
- status=normal_polling( address, 0x80 );
- if( status < 0 )return -1; // polling time-out
- outph(address,0xFFFF);
- FlushDCache();
-
- return 0;
-}
-
-INT BlockWrite_MX28F160C3B(UINT32 address, UCHAR * data, UINT32 size)
-{
- UINT32 i;
- int status;
-
- BlockLock_W28J800TT(address,BLOCK_UNLOCK); // The MX28F160C3 sector is default to be locked
-
- address|=0x80000000;
- for(i=address;i<address+size;i+=2)
- {
- outph(i,0x40);
- outph(i,*((UINT16 *)data));
- //while( !(inph(i)&0x80) );
- status=normal_polling( i, 0x80 );
- if( status < 0 )return -1; // polling time-out
- data+=2;
- }
- outph(address,0xFFFF);
- FlushDCache();
-
- return 0;
-}
-
-UINT32 FlashSize()
-{
- return _flash_size;
-}
-
-
-
-
+/******************************************************************************
+ *
+ * Copyright (c) 2003 Windond Electronics Corp.
+ * All rights reserved.
+ *
+ * $Workfile: flash.c $
+ *
+ * $Author: andy $
+ ******************************************************************************/
+/*
+ * $History: flash.c $
+ *
+ * ***************** Version 10 *****************
+ * User: Wschang0 Date: 04/01/07 Time: 11:34a
+ * Updated in $/W90N740/FIRMWARE/WBLv1_1/Src
+ * Increase the timeout count in polling16 function to avoid early timeout
+ * in W29LV800BT
+ *
+ * ***************** Version 9 *****************
+ * User: Wschang0 Date: 03/12/25 Time: 4:06p
+ * Updated in $/W90N740/FIRMWARE/WBLv1_1/Src
+ * Add W29LV800BT, W29LV160DT, W29LV320DT
+ * Remove the FLASH_NUM
+ *
+ * ***************** Version 8 *****************
+ * User: Wschang0 Date: 03/12/03 Time: 5:16p
+ * Updated in $/W90N740/FIRMWARE/WBLv1_1/Src
+ * Add MX29LV160BT/TT
+ * Fixed MX28F160C3BT/TT.
+ * The MX28F160C3 sectors are default to be locked, thus it needs unlock
+ * it before write/erase it.
+ *
+ * ***************** Version 7 *****************
+ * User: Wschang0 Date: 03/11/05 Time: 11:03a
+ * Updated in $/W90N740/FIRMWARE/WBLv1_1/Src
+ * Add MX28F160C3T & MX28F160C3B
+ *
+ * ***************** Version 6 *****************
+ * User: Wschang0 Date: 03/09/26 Time: 2:30p
+ * Updated in $/W90N740/FIRMWARE/WBLv1_1/Src
+ * Correct the flash name of SST39VF160 in the flash[] table
+ *
+ * ***************** Version 5 *****************
+ * User: Wschang0 Date: 03/08/27 Time: 1:41p
+ * Updated in $/W90N740/FIRMWARE/WBLv1_1/Src
+ * Add FlushDCache to Write/Erase functions to avoid data cache
+ * incohereance after Write/Erase flash.
+ *
+ * ***************** Version 4 *****************
+ * User: Wschang0 Date: 03/08/27 Time: 11:28a
+ * Updated in $/W90N740/FIRMWARE/WBLv1_1/Src
+ * Add SST 39VF160 flash type
+ *
+ * ***************** Version 3 *****************
+ * User: Wschang0 Date: 03/08/20 Time: 1:39p
+ * Updated in $/W90N740/FIRMWARE/WBLv1_1/Src
+ *
+ * ***************** Version 2 *****************
+ * User: Wschang0 Date: 03/08/20 Time: 11:53a
+ * Updated in $/W90N740/FIRMWARE/WBLv1_1/Src
+ * Add VSS header
+ */
+#include <asm/arch/flash.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+// Update Note:
+// 8/19, 2003: Add Flash Tyep W28J800BT, W28J320TT, Fix the PID of W28J320BT
+// 8/07, 2003: W39L010 was protected when the erase address not in offset 0
+// 7/24, 2003: Remove the redundant code. Time-out check, for reliability
+
+UINT32 _flash_size = 0;
+
+#define DELAY_1US 20
+
+#define TIMEOUT 8000000UL
+static int normal_polling(unsigned int addr, unsigned short mask)
+{
+ unsigned short rdata;
+ unsigned int cnt;
+
+ rdata=inph(addr)&mask;
+ cnt=0;
+ while( rdata != mask )
+ {
+ rdata=inph(addr)&mask;
+ if( cnt++ > TIMEOUT ) return -1; // time-out
+ }
+
+ return 0;
+}
+
+static int polling16(unsigned int addr, unsigned short data)
+{
+ unsigned short rdata;
+ int timeout=0x600000;
+
+ rdata=inph(addr);
+ while( rdata != data )
+ {
+ rdata=inph(addr);
+ if( (rdata&0x20) || !(timeout--) )
+ {
+ rdata=inph(addr);
+ if( rdata != data )
+ {
+ //printf("polling time-out: %x\n",rdata);
+ return -1; //polling time-out
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+static INT CheckDataWidth(INT w)
+{
+ INT extio_flag=0;
+ // check if the platform (the Flash ROM is not in 0x7F000000)
+ if( (ROMCON&0xFF000000)==0xFC000000 )extio_flag=1;
+
+ switch(w)
+ {
+ case 8:
+ if(extio_flag)
+ {
+ if( (EXT3CON&0x3)== 0x1 )return 1;
+ else return 0;
+ }
+ else
+ {
+ if( (ROMCON&0xC)== 0x0 )return 1;
+ else return 0;
+ }
+ case 16:
+ if(extio_flag)
+ {
+ if( (EXT3CON&0x3)== 0x2 )return 1;
+ else return 0;
+ }
+ else
+ {
+ if( (ROMCON&0xC)== 0x4 )return 1;
+ else return 0;
+ }
+ case 32:
+ if(extio_flag)
+ {
+ if( (EXT3CON&0x3)== 0x3 )return 1;
+ else return 0;
+ }
+ else
+ {
+ if( (ROMCON&0xC)== 0x8 )return 1;
+ else return 0;
+ }
+ default:
+ return 0;
+ }
+
+}
+
+
+void FlashDelay(UINT32 delay)
+{
+ volatile UINT32 i;
+ for(i=0;i<delay*DELAY_1US;i++);
+}
+
+static __inline void FlushDCache()
+{
+ /* Flush Entire DCache */
+ if( CAHCNF_R & 0x6 ) /* If write buffer or data cache is enabled */
+ {
+ CAHCON_R=0x86;
+ while( CAHCON_R );
+ }
+
+}
+
+
+
+INT BlockLock_W28J800TT(UINT32 address, UINT32 op)
+{
+ address|=0x80000000;
+
+ if( op==BLOCK_LOCK )
+ {
+ outph(address,0x70);
+ while( !(inph(address)&0x80) );
+ outph(address,0x60);
+ outph(address,0x01);
+ while( !(inph(address)&0x80) );
+ outph(address,0xFFFF);
+ }
+ else if( op==BLOCK_UNLOCK )
+ {
+ outph(address,0x70);
+ while( !(inph(address)&0x80) );
+ outph(address,0x60);
+ outph(address,0xD0);
+ while( !(inph(address)&0x80) );
+ outph(address,0xFFFF);
+ }
+ return 0;
+}
+
+INT BlockSize_W28J800TT(UINT32 address)
+{
+ address-=FLASH_BASE;
+ address&=0x7FFFFFFF;
+ if( address >= 0xF0000 )
+ {
+ if( address < _flash_size )
+ return 0x2000;
+ else
+ return 0;
+ }
+ else
+ return 0x10000;
+}
+
+INT BlockSize_W28J800BT(UINT32 address)
+{
+ address-=FLASH_BASE;
+ address&=0x7FFFFFFF;
+ if( address < 0x10000 )
+ return 0x2000;
+ else
+ {
+ if( address < _flash_size )
+ return 0x10000;
+ else
+ return 0;
+ }
+}
+
+
+INT BlockErase_W28J800TT(UINT32 address,UINT32 size)
+{
+ int status;
+ if( (address&(size-1))!=0x0 )return -1;// not in the start of a block
+
+ BlockLock_W28J800TT(address,BLOCK_UNLOCK); // The intel flash sector is default to be locked
+
+ address|=0x80000000;
+ outph(address,0x70);
+ status=normal_polling( address, 0x80 );
+ if( status < 0 )return -1; // polling time-out
+ outph(address,0x20);
+ outph(address,0xD0);
+ status=normal_polling( address, 0x80 );
+ if( status < 0 )return -1; // polling time-out
+ outph(address,0xFFFF);
+ FlushDCache();
+
+ return 0;
+}
+
+INT BlockWrite_W28J800TT(UINT32 address, UCHAR * data, UINT32 size)
+{
+ UINT32 i;
+ int status;
+ address|=0x80000000;
+ BlockLock_W28J800TT(address,BLOCK_UNLOCK); // The MX28F160C3 sector is default to be locked
+ for(i=address;i<address+size;i+=2)
+ {
+ outph(i,0x40);
+ outph(i,*((UINT16 *)data));
+ //while( !(inph(i)&0x80) );
+ status=normal_polling( i, 0x80 );
+ if( status < 0 )return -1; // polling time-out
+ data+=2;
+ }
+ outph(address,0xFFFF);
+ FlushDCache();
+
+ return 0;
+}
+
+INT ReadPID_Winbond(UINT32 address, UCHAR *pid0, UCHAR *pid1)
+{
+ if( !CheckDataWidth(16) )return -1;
+
+ address|=0x80000000;
+ outph(address,0x70);
+ FlashDelay(50000); // delay 50ms
+ outph(address,0x90);
+ *pid0=inph(address);
+ *pid1=inph(address+1);
+ outph(address,0xFFFF);
+
+ return 0;
+}
+
+INT ReadPID_W28J800TT(UINT32 address, UCHAR *pid0, UCHAR *pid1)
+{
+ int status;
+ status=ReadPID_Winbond(address,pid0,pid1);
+ if( status < 0 )return -1; // not x16 flash
+ _flash_size=0x100000;
+ return 0;
+}
+
+INT ReadPID_W28J800BT(UINT32 address, UCHAR *pid0, UCHAR *pid1)
+{
+ int status;
+ status=ReadPID_Winbond(address,pid0,pid1);
+ if( status < 0 )return -1; // not x16 flash
+ _flash_size=0x100000;
+ return 0;
+}
+
+INT ReadPID_W28J160TT(UINT32 address, UCHAR *pid0, UCHAR *pid1)
+{
+ int status;
+ status=ReadPID_Winbond(address,pid0,pid1);
+ if( status < 0 )return -1; // not x16 flash
+ _flash_size=0x200000;
+ return 0;
+}
+
+INT ReadPID_W28J320TT(UINT32 address, UCHAR *pid0, UCHAR *pid1)
+{
+ int status;
+ status=ReadPID_Winbond(address,pid0,pid1);
+ if( status < 0 )return -1; // not x16 flash
+ _flash_size=0x400000;
+ return 0;
+}
+
+
+
+
+INT BlockSize_W28J320TT(UINT32 address)
+{
+ address-=FLASH_BASE;
+ address&=0x7FFFFFFF;
+ if( address >= 0x3F0000 )
+ {
+ if( address < _flash_size )
+ return 0x2000;
+ else
+ return 0;
+ }
+ else
+ return 0x10000;
+}
+
+
+INT BlockSize_W28J320BT(UINT32 address)
+{
+ address-=FLASH_BASE;
+ address&=0x7FFFFFFF;
+ if( address < 0x10000 )
+ return 0x2000;
+ else
+ {
+ if( address < _flash_size )
+ return 0x10000;
+ else
+ return 0;
+ }
+}
+
+
+
+INT BlockSize_W28J160BT(UINT32 address)
+{
+ address-=FLASH_BASE;
+ address&=0x7FFFFFFF;
+ if( address < 0x10000 )
+ return 0x2000;
+ else
+ {
+ if( address < _flash_size )
+ return 0x10000;
+ else
+ return 0;
+ }
+}
+
+INT BlockSize_W28J160TT(UINT32 address)
+{
+ address-=FLASH_BASE;
+ address&=0x7FFFFFFF;
+ if( address >= 0x1F0000 )
+ {
+ if( address < 0x200000 )
+ return 0x2000;
+ else
+ return 0;
+ }
+ else
+ return 0x10000;
+}
+
+
+INT BlockLock_W39L010(UINT32 address, UINT32 op)
+{
+ return -1;
+}
+
+INT BlockSize_W39L010(UINT32 address)
+{
+ address-=FLASH_BASE;
+ address&=0x7FFFFFFF;
+ if( address < _flash_size )
+ return 0x20000;
+ else
+ return 0;
+}
+
+INT BlockErase_W39L010(UINT32 address,UINT32 size)
+{
+ UINT32 addr1,addr2;
+
+ if( (address&(0x20000-1))!=0x0 )return -1;// not in the start of flash
+
+ address|=0x80000000;
+ addr1=(address&0xFFF00000)+(0x5555);
+ addr2=(address&0xFFF00000)+(0x2AAA);
+
+ outpb(addr1,0xAA);
+ outpb(addr2,0x55);
+ outpb(addr1,0x80);
+ outpb(addr1,0xAA);
+ outpb(addr2,0x55);
+ outpb(addr1,0x10);
+ while( (inpb(address)&0x80)!=0x80 );
+
+ FlushDCache();
+
+ return 0;
+}
+
+INT BlockWrite_W39L010(UINT32 address, UCHAR * data, UINT32 size)
+{
+ UINT32 i;
+ UINT32 addr1, addr2;
+
+ address|=0x80000000;
+ addr1=(address&0xFFF00000)+(0x5555);
+ addr2=(address&0xFFF00000)+(0x2AAA);
+ for(i=address;i<address+size;i++)
+ {
+ outpb(addr1,0xAA);
+ outpb(addr2,0x55);
+ outpb(addr1,0xA0);
+ outpb(i,*data);
+ while( !((inpb(i)&0x80)==(*data&0x80)) );
+ data++;
+ }
+ FlushDCache();
+
+ return 0;
+}
+
+INT ReadPID_W39L010(UINT32 address, UCHAR *pid0, UCHAR *pid1)
+{
+ UINT32 addr1, addr2;
+
+ if( !CheckDataWidth(8) )return -1;
+
+
+
+ address|=0x80000000;
+ addr1=(address&0xFFF00000)+(0x5555);
+ addr2=(address&0xFFF00000)+(0x2AAA);
+
+ outpb(addr1,0xAA);
+ outpb(addr2,0x55);
+ outpb(addr1,0x80);
+ outpb(addr1,0xAA);
+ outpb(addr2,0x55);
+ outpb(addr1,0x60);
+ *pid0=inpb(address);
+ *pid1=inpb(address+1);
+ outpb(addr1,0xAA);
+ outpb(addr2,0x55);
+ outpb(addr1,0xF0);
+ outpb(address,0xFF);
+
+ _flash_size=0x20000;
+
+ return 0;
+}
+
+
+
+INT BlockLock_W29EE011(UINT32 address, UINT32 op)
+{
+ return -1;
+}
+
+
+INT BlockSize_W29EE011(UINT32 address)
+{
+ address-=FLASH_BASE;
+ address&=0x7FFFFFFF;
+ if( address < _flash_size )
+ return 0x80;
+ else
+ return 0;
+}
+
+INT BlockErase_W29EE011(UINT32 address,UINT32 size)
+{
+ UINT32 addr1,addr2;
+ static INT flag=0;
+
+ if( flag )return 0;
+
+ flag=1;
+
+ address|=0x80000000;
+ addr1=(address&0xFFF00000)+(0x5555);
+ addr2=(address&0xFFF00000)+(0x2AAA);
+
+ outpb(addr1,0xAA);
+ outpb(addr2,0x55);
+ outpb(addr1,0x80);
+ outpb(addr1,0xAA);
+ outpb(addr2,0x55);
+ outpb(addr1,0x10);
+ FlashDelay(50000); // delay 50ms
+
+ FlushDCache();
+
+ return 0;
+}
+
+INT BlockWrite_W29EE011(UINT32 address, UCHAR * data, UINT32 size)
+{
+ UINT32 i;
+ UINT32 addr1, addr2;
+
+ address|=0x80000000;
+ addr1=(address&0xFFF00000)+(0x5555);
+ addr2=(address&0xFFF00000)+(0x2AAA);
+ outpb(addr1,0xAA);
+ outpb(addr2,0x55);
+ outpb(addr1,0xA0);
+ for(i=0;i<size;i++)
+ outpb(address+i,*(data+i));
+ while( inpb(address+i-1)!=*(data+i-1) );
+ FlushDCache();
+
+ return 0;
+}
+
+INT ReadPID_W29EE011(UINT32 address, UCHAR *pid0, UCHAR *pid1)
+{
+ UINT32 addr1, addr2;
+
+ if( !CheckDataWidth(8) )return -1;
+
+
+ address|=0x80000000;
+ addr1=(address&0xFFF00000)+(0x5555);
+ addr2=(address&0xFFF00000)+(0x2AAA);
+
+ outpb(addr1,0xAA);
+ outpb(addr2,0x55);
+ outpb(addr1,0x80);
+ outpb(addr1,0xAA);
+ outpb(addr2,0x55);
+ outpb(addr1,0x60);
+ FlashDelay(10);//delay 10 us
+ *pid0=inpb(address);
+ *pid1=inpb(address+1);
+ outpb(addr1,0xAA);
+ outpb(addr2,0x55);
+ outpb(addr1,0xF0);
+ FlashDelay(10);//delay 10 us
+ outpb(address,0xFF);
+
+ _flash_size=0x20000;
+
+ return 0;
+}
+
+
+
+INT BlockLock_AM29LV800BB(UINT32 address, UINT32 op)
+{
+ return -1;
+}
+
+
+INT BlockSize_AM29LV800BB(UINT32 address)
+{
+ address-=FLASH_BASE;
+ address&=0x7FFFFFFF;
+ if( address < 0x4000 )
+ return 0x4000;
+ else if( address < 0x6000 )
+ return 0x2000;
+ else if( address < 0x8000 )
+ return 0x2000;
+ else if( address < 0x10000 )
+ return 0x8000;
+ else
+ {
+ if( address < _flash_size )
+ return 0x10000;
+ else
+ return 0;
+ }
+}
+
+INT BlockSize_AM29LV800BT(UINT32 address)
+{
+ address-=FLASH_BASE;
+ address&=0x7FFFFFFF;
+ if( address < 0x0F0000 )
+ return 0x10000;
+ else if( address < 0xF8000 )
+ return 0x8000;
+ else if( address < 0xFA000 )
+ return 0x2000;
+ else if( address < 0xFC000 )
+ return 0x2000;
+ else
+ {
+ if( address < _flash_size )
+ return 0x4000;
+ else
+ return 0;
+ }
+}
+INT BlockErase_AM29LV800BB(UINT32 address,UINT32 size)
+{
+ UINT32 addr1,addr2;
+ INT status;
+
+ if( (address&(size-1))!=0x0 )return -1;// not in the start of a block
+
+ address|=0x80000000;
+ addr1=(address&0xFFF00000)+(0x5555<<1);
+ addr2=(address&0xFFF00000)+(0x2AAA<<1);
+
+ outph(addr1,0xAA);
+ outph(addr2,0x55);
+ outph(addr1,0x80);
+ outph(addr1,0xAA);
+ outph(addr2,0x55);
+ outph(address,0x30);
+ //while( (inph(address))!=0xFFFF );
+ status=polling16(address, 0xFFFF);
+
+ FlushDCache();
+
+ return status;
+}
+
+INT BlockWrite_AM29LV800BB(UINT32 address, UCHAR * data, UINT32 size)
+{
+ UINT32 i;
+ UINT32 addr1, addr2;
+ INT status;
+
+ address|=0x80000000;
+ addr1=(address&0xFFF00000)+(0x5555<<1);
+ addr2=(address&0xFFF00000)+(0x2AAA<<1);
+
+ for(i=address;i<address+size;i+=2)
+ {
+ outph(addr1,0xAA);
+ outph(addr2,0x55);
+ outph(addr1,0xA0);
+ outph(i,*((UINT16*)data));
+ status=polling16( i, (*(UINT16 *)data));
+ if( status < 0 )return status; // time-out
+ data+=2;
+ }
+
+ outph(address,0xFFFF);
+ FlushDCache();
+
+ return status;
+}
+
+
+INT ReadPID_AM29LV(UINT32 address, UCHAR *pid0, UCHAR *pid1)
+{
+ UINT32 addr1, addr2;
+
+ if( !CheckDataWidth(16) )return -1;
+
+
+ address|=0x80000000;
+ addr1=(address&0xFFF00000)+(0x5555<<1);
+ addr2=(address&0xFFF00000)+(0x2AAA<<1);
+
+ outph(addr1,0xAA);
+ outph(addr2,0x55);
+ outph(addr1,0x90);
+ *pid0=(char)inph(address);
+ *pid1=(char)inph((address+2));
+ outph(address,0xFFFF);
+
+ return 0;
+}
+
+
+INT ReadPID_AM29LV800BB(UINT32 address, UCHAR *pid0, UCHAR *pid1)
+{
+
+ ReadPID_AM29LV(address, pid0, pid1);
+ _flash_size=0x100000;
+
+ return 0;
+}
+
+INT ReadPID_AM29LV160DB(UINT32 address, UCHAR *pid0, UCHAR *pid1)
+{
+
+ ReadPID_AM29LV(address, pid0, pid1);
+ _flash_size=0x200000;
+
+ return 0;
+}
+
+INT ReadPID_AM29LV320DB(UINT32 address, UCHAR *pid0, UCHAR *pid1)
+{
+
+ ReadPID_AM29LV(address, pid0, pid1);
+ _flash_size=0x400000;
+
+ return 0;
+}
+
+
+
+INT BlockSize_AM29LV160DB(UINT32 address)
+{
+ address-=FLASH_BASE;
+ address&=0x7FFFFFFF;
+ if( address < 0x4000 )
+ return 0x4000;
+ else if( address < 0x6000 )
+ return 0x2000;
+ else if( address < 0x8000 )
+ return 0x2000;
+ else if( address < 0x10000 )
+ return 0x8000;
+ else
+ {
+ if( address < _flash_size )
+ return 0x10000;
+ else
+ return 0;
+ }
+}
+
+INT BlockSize_AM29LV160DT(UINT32 address)
+{
+ address-=FLASH_BASE;
+ address&=0x7FFFFFFF;
+ if( address < 0x1F0000 )
+ return 0x10000;
+ else if( address < 0x1F8000 )
+ return 0x8000;
+ else if( address < 0x1FA000 )
+ return 0x2000;
+ else if( address < 0x1FC000 )
+ return 0x2000;
+ else
+ {
+ if( address < _flash_size )
+ return 0x4000;
+ else
+ return 0;
+ }
+}
+INT BlockSize_AM29LV320DB(UINT32 address)
+{
+ address-=FLASH_BASE;
+ address&=0x7FFFFFFF;
+ if( address < 0x10000 )
+ return 0x2000;
+ else
+ {
+ if( address < _flash_size )
+ return 0x10000;
+ else
+ return 0;
+ }
+}
+
+INT BlockSize_AM29LV320DT(UINT32 address)
+{
+ address-=FLASH_BASE;
+ address&=0x7FFFFFFF;
+ if( address < 0x3F0000 )
+ return 0x10000;
+ else
+ {
+ if( address < _flash_size )
+ return 0x2000;
+ else
+ return 0;
+ }
+}
+
+INT BlockLock_E28F640(UINT32 address, UINT32 op)
+{
+
+ address|=0x80000000;
+
+ if( op==BLOCK_LOCK )
+ {
+ outph(address,0x60);
+ outph(address,0x01);
+ while( !(inph(address)&0x80) );
+ outph(address,0xFFFF);
+ }
+ else if( op==BLOCK_UNLOCK )
+ {
+ outph(address,0x60);
+ outph(address,0xD0);
+ while( !(inph(address)&0x80) );
+ outph(address,0xFFFF);
+ }
+
+ return 0;
+}
+
+INT BlockSize_E28F640(UINT32 address)
+{
+ address-=FLASH_BASE;
+ address&=0x7FFFFFFF;
+ if( address < _flash_size )
+ return 0x10000;
+ else
+ return 0;
+}
+
+INT BlockErase_E28F640(UINT32 address,UINT32 size)
+{
+ UINT32 i,j,tmp;
+ CHAR * buffer;
+
+ address|=0x80000000;
+ buffer = kmalloc(128*1024,GFP_KERNEL);
+ if(!buffer)
+ return 1;
+ // backup the data
+ j=0xFFFF;
+ if( (address & FLASH_BLOCK_SIZE) )
+ {
+
+ for(i=0;i<FLASH_BLOCK_SIZE/2;i++)
+ {
+ tmp=*((volatile unsigned short *)(address-FLASH_BLOCK_SIZE)+i);
+ *((volatile unsigned short *)buffer+i)=tmp;
+ j&=tmp;
+ }
+ }
+ else
+ {
+ for(i=0;i<FLASH_BLOCK_SIZE/2;i++)
+ {
+ tmp=*((volatile unsigned short *)(address+FLASH_BLOCK_SIZE)+i);
+ *((volatile unsigned short *)buffer+i)=tmp;
+ j&=tmp;
+ }
+ }
+
+
+ outph(address,0x20);
+ outph(address,0xD0);
+ while( !(inph(address)&0x80) );
+ outph(address,0xFFFF);
+
+
+ // write back the data
+ if( (j&0xFFFF)!=0xFFFF )
+ {
+ if( (address & FLASH_BLOCK_SIZE) )
+ BlockWrite_E28F640(address-FLASH_BLOCK_SIZE, (UCHAR *)buffer, FLASH_BLOCK_SIZE);
+ else
+ BlockWrite_E28F640(address+FLASH_BLOCK_SIZE, (UCHAR *)buffer, FLASH_BLOCK_SIZE);
+ }
+ FlushDCache();
+ kfree(buffer);
+ return 0;
+}
+
+INT BlockWrite_E28F640(UINT32 address, UCHAR * data, UINT32 size)
+{
+ UINT32 i;
+#if 0
+ UINT32 pdata,j;
+
+ address|=0x80000000;
+
+ do{
+ outph(address, 0xE8);
+ }while( !(inph(address)&0x80) );
+
+ i=size;
+ while(i)
+ {
+ if( i < 32 )
+ {
+ outph(address, i);
+ for(j=0;j<i/2;j++)
+ outph(address+j, *((unsigned short *)pdata+j));
+ pdata+=i;
+ i=0;
+ }
+ else
+ {
+ outph(address, 32);
+ for(j=0;j<16;j++)
+ outph(address+j, *((unsigned short *)pdata+j));
+ pdata+=32;
+ i-=32;
+ }
+ outph(address, 0xD0);
+ while( !(inph(address)&0x80) );
+ }
+
+#else
+ address|=0x80000000;
+
+ for(i=address;i<address+size;i+=2)
+ {
+ outph(i,0x40);
+ outph(i,*((UINT16 *)data));
+ while( !(inph(i)&0x80) );
+ data+=2;
+ }
+
+ outph(address,0xFFFF);
+#endif
+
+ FlushDCache();
+ return 0;
+}
+
+INT ReadPID_E28F640(UINT32 address, UCHAR *pid0, UCHAR *pid1)
+{
+ if( !CheckDataWidth(16) )return -1;
+
+ outph(address,0x90);
+ *pid0=inph(address);
+ *pid1=inph(address+1);
+ outph(address,0xFFFF);
+
+ _flash_size=0x800000;
+
+ return 0;
+}
+
+
+INT BlockSize_SST39VF160(UINT32 address)
+{
+ address-=FLASH_BASE;
+ address&=0x7FFFFFFF;
+ if( address < _flash_size )
+ return 0x10000;
+ else
+ return 0;
+
+}
+
+
+INT ReadPID_SST39VF160(UINT32 address, UCHAR *pid0, UCHAR *pid1)
+{
+
+ ReadPID_AM29LV(address, pid0, pid1);
+ outph(address, 0x00F0 ); /* Exit Software ID mode */
+ _flash_size=0x200000;
+
+ return 0;
+}
+
+INT BlockErase_SST39VF160(UINT32 address,UINT32 size)
+{
+ UINT32 addr1,addr2;
+ INT status;
+
+ if( (address&(size-1))!=0x0 )return -1;// not in the start of a block
+
+ address|=0x80000000;
+ addr1=(address&0xFFF00000)+(0x5555<<1);
+ addr2=(address&0xFFF00000)+(0x2AAA<<1);
+
+ outph(addr1,0xAA);
+ outph(addr2,0x55);
+ outph(addr1,0x80);
+ outph(addr1,0xAA);
+ outph(addr2,0x55);
+ outph(address,0x50);
+ status=polling16(address, 0xFFFF);
+
+ FlushDCache();
+
+ return status;
+}
+
+INT BlockErase_MX28F160C3B(UINT32 address,UINT32 size)
+{
+ int status;
+ if( (address&(size-1))!=0x0 )return -1;// not in the start of a block
+
+ BlockLock_W28J800TT(address,BLOCK_UNLOCK); // The MX28F160C3 sector is default to be locked
+
+ address|=0x80000000;
+ outph(address,0x70);
+ status=normal_polling( address, 0x80 );
+ if( status < 0 )return -1; // polling time-out
+ outph(address,0x20);
+ outph(address,0xD0);
+ status=normal_polling( address, 0x80 );
+ if( status < 0 )return -1; // polling time-out
+ outph(address,0xFFFF);
+ FlushDCache();
+
+ return 0;
+}
+
+INT BlockWrite_MX28F160C3B(UINT32 address, UCHAR * data, UINT32 size)
+{
+ UINT32 i;
+ int status;
+
+ BlockLock_W28J800TT(address,BLOCK_UNLOCK); // The MX28F160C3 sector is default to be locked
+
+ address|=0x80000000;
+ for(i=address;i<address+size;i+=2)
+ {
+ outph(i,0x40);
+ outph(i,*((UINT16 *)data));
+ //while( !(inph(i)&0x80) );
+ status=normal_polling( i, 0x80 );
+ if( status < 0 )return -1; // polling time-out
+ data+=2;
+ }
+ outph(address,0xFFFF);
+ FlushDCache();
+
+ return 0;
+}
+
+UINT32 FlashSize()
+{
+ return _flash_size;
+}
+
+
+
+
diff --git a/uClinux-2.4.20-uc1/drivers/block/wbflash/flash_u.c b/uClinux-2.4.20-uc1/drivers/block/wbflash/flash_u.c
index 55e6f52..51cb3fd 100644
--- a/uClinux-2.4.20-uc1/drivers/block/wbflash/flash_u.c
+++ b/uClinux-2.4.20-uc1/drivers/block/wbflash/flash_u.c
@@ -1,246 +1,246 @@
-#include <asm/semaphore.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/config.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <asm/fcntl.h>
-#include <asm/unistd.h>
-#include <asm/uaccess.h>
-#include <asm/arch/flash.h>
-#include <asm/arch/bib.h>
-
-#include <linux/init.h>
-#include "cfi.h"
-
-static int Init_WinbondFlash(void);
-
-#define BL_PHY 0
-#define BL_IC_PLUS 1
-#define BL_MARVELL6052 2
-
-tbl_info info;
-DECLARE_MUTEX(spare_lock);
-
-#define _DEBUG
-#undef _DEBUG
-
-#define MALLOC(x) kmalloc((x), GFP_KERNEL)
-#define FREE kfree
-#define MEMCPY memcpy //or use "copy_to_user"
-
-//yyang1 030605 ???
-int __init Init_WinbondFlash(void)
-{
-
- if (cfiGetFlashInfo() == -1) {
- printk("No supported flash detected!\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-asmlinkage int sys_ReadWinbondFlash(unsigned long pos, unsigned long length, char * buffer)
-{
- // if(!pCurFlash)
- // return -EINVAL;
- if(cfiGetFlashSize() <= 0)
- return(-EINVAL);
-
-#ifdef _DEBUG
- printk("\nWinbondFlash Read: pos = %x, length = %d, buffer = 0x%x.\n", pos, length, buffer);
-#endif
- if(length%2)
- length++;
- down(&spare_lock);
- if(copy_to_user(buffer, (void*)(FLASH_BASE | pos), length))
- {
- up(&spare_lock);
- return -EFAULT;
- }
- up(&spare_lock);
- return length;
-}
-
-static int _FlashWrite(char *pcBuf, int iBufLen, int iOffset);
-asmlinkage int sys_WriteWinbondFlash(unsigned long pos, unsigned long length, char * buffer)
-{
- // if(!pCurFlash)
- // return -EINVAL;;
-
- if(cfiGetFlashSize() <= 0)
- return(-EINVAL);
-
-#ifdef _DEBUG
- printk("\nWinbondFlash Write: pos = %x, length = %d, buffer = 0x%x.\n", pos, length, buffer);
-#endif
-
- return _FlashWrite(buffer, length, pos);
-}
-
-asmlinkage int sys_WinbondFlashBlockSize(unsigned long pos)
-{
- if(cfiGetFlashSize() == 0)
- return -EINVAL;;
-
-#ifdef _DEBUG
- printk("\nWinbondFlash BlockSize: pos = %d.\n", pos);
-#endif
-
- pos |= FLASH_BASE;
- return cfiGetBlockSize(pos);
-}
-asmlinkage int sys_WinbondFlashTotalSize(void)
-{
- printk("sys_WinbondFlashTotalSize\n");
- return cfiGetFlashSize();
-}
-asmlinkage int sys_WinbondFlashBase(void)
-{
- return FLASH_BASE;
-}
-
-static int _FlashWrite(char *pcBuf, int iBufLen, int iOffset)
-{
- // unsigned long flags;
- UINT32 blockSize,src,dest;
- INT i;
-
- if (cfiGetFlashSize() == 0) return -EINVAL;
-
-#ifdef _DEBUG
- printk("\nWinbondFlash _FlashWrite: pos = %x, length = %d, buffer = 0x%x.\n", iOffset, iBufLen, pcBuf);
-#endif
-
- //i = iBufLen;
- i=(iBufLen%2)?(iBufLen+1):iBufLen;
-
- src = (UINT32)pcBuf;
- dest = (iOffset%2)?(iOffset+1):iOffset | FLASH_BASE;
-
- //CSR_WRITE(WTCR, (CSR_READ(WTCR)&0xF7)|0x01);//clyu reset watch dog
-
- while (i>0)
- {
- volatile UINT32 buf;
- volatile UINT32 addr;
- UINT32 count;
- int len;
- blockSize = cfiGetBlockSize(dest);
- if(blockSize<=0)
- return 0;
-
-#ifdef _DEBUG
-//#if 1
- printk("\n_FlashWrite:dest:%x,cur blockSize:%x\n",dest,blockSize);
-#endif
- addr=dest&~(blockSize-1);
- for(len=0;len<i&&(len+dest-addr)<blockSize;len+=2)
- if(inph((dest+len))!=0xFFFF)
- {
-#ifdef _DEBUG
- printk("01 inph(%x):%x\n",dest+len,inph(dest+len));
-#endif
- if((dest&(blockSize-1))||(dest+i-addr)<=blockSize)
- {
- buf=(UINT32)MALLOC(blockSize);
- if(buf != 0)
- {
-#ifdef _DEBUG
- printk("\n_FlashWrite:dest:%x,addr:%x,buf:%x\n",dest,addr,buf);
-#endif
- //memset((UCHAR *)buf,0xFF,blockSize);
- MEMCPY((UCHAR *)buf,(UCHAR *)addr,blockSize);
-
- //MEMCPY((UCHAR *)buf,(UCHAR *)addr,dest-addr);
- if(i<blockSize-(dest-addr))
- count=i;
- else
- count=blockSize-(dest-addr);
-
-#ifdef _DEBUG
- printk("\n_FlashWrite:i:%d,count:%d,dest:%x,addr:%x,len:%d\n",i,count,dest,addr,len);
-#endif
-
- MEMCPY((void *)(buf+(dest-addr)),(void *)src,count);
-
- down(&spare_lock);
- //save_flags(flags); cli();//prevent closing watch dog interrupt
-#ifdef _DEBUG
- printk("%s:%d BlockErase,%x\n",__FILE__,__LINE__,inph(dest+len));
-#endif
- cfiCmd.erase(addr, blockSize);
-#ifdef _DEBUG
- printk("02 inph(%x):%x\n",dest+len,inph(dest+len));
- printk("%s:%d BlockWrite\n",__FILE__,__LINE__);
-#endif
- cfiCmd.write(addr, (UCHAR *)buf, blockSize);
-#ifdef _DEBUG
- printk("03 inph(%x):%x\n",dest+len,inph(dest+len));
-#endif
- //restore_flags(flags);
- up(&spare_lock);
-
- FREE((void *)buf);
- blockSize = count;
- }
- else
- {
- return (iBufLen - i);
- }
- }
- else
- {
- down(&spare_lock);
- //save_flags(flags); cli();
-#ifdef _DEBUG
- printk("\nb_FlashWrite:i:%d,count:%d,dest:%x,addr:%x,%x\n",i,count,dest,addr,inph(dest+len));
-#endif
- cfiCmd.erase(dest, blockSize);
- cfiCmd.write(dest, (UCHAR *)src, blockSize);
-
- //restore_flags(flags);
- up(&spare_lock);
- }
- break;
- }
- if((len>=i)||((len+dest-addr)>=cfiGetBlockSize(dest)))
- {
- if((dest&(blockSize-1))||(dest+i-addr)<=blockSize)
- {
-#ifdef _DEBUG
-printk("Write direct\n");
-#endif
- if(i<blockSize-(dest-addr))
- count=i;
- else
- count=blockSize-(dest-addr);
- down(&spare_lock);
- //save_flags(flags); cli();
- cfiCmd.write(dest, (UCHAR *)src, count);
- //restore_flags(flags);
- up(&spare_lock);
- blockSize=count;
- }
- else
- {
-#ifdef _DEBUG
-printk("Write direct one block\n");
-#endif
- down(&spare_lock);
- //save_flags(flags); cli();
- cfiCmd.write(dest, (UCHAR *)src, blockSize);
- //restore_flags(flags);
- up(&spare_lock);
- }
- }
- src+=blockSize;
- dest+=blockSize;
- i-=blockSize;
- }
-
- return (iBufLen);
-}
-
-module_init(Init_WinbondFlash);
+#include <asm/semaphore.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/major.h>
+#include <linux/slab.h>
+#include <asm/fcntl.h>
+#include <asm/unistd.h>
+#include <asm/uaccess.h>
+#include <asm/arch/flash.h>
+#include <asm/arch/bib.h>
+
+#include <linux/init.h>
+#include "cfi.h"
+
+static int Init_WinbondFlash(void);
+
+#define BL_PHY 0
+#define BL_IC_PLUS 1
+#define BL_MARVELL6052 2
+
+tbl_info info;
+DECLARE_MUTEX(spare_lock);
+
+#define _DEBUG
+#undef _DEBUG
+
+#define MALLOC(x) kmalloc((x), GFP_KERNEL)
+#define FREE kfree
+#define MEMCPY memcpy //or use "copy_to_user"
+
+//yyang1 030605 ???
+int __init Init_WinbondFlash(void)
+{
+
+ if (cfiGetFlashInfo() == -1) {
+ printk("No supported flash detected!\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+asmlinkage int sys_ReadWinbondFlash(unsigned long pos, unsigned long length, char * buffer)
+{
+ // if(!pCurFlash)
+ // return -EINVAL;
+ if(cfiGetFlashSize() <= 0)
+ return(-EINVAL);
+
+#ifdef _DEBUG
+ printk("\nWinbondFlash Read: pos = %x, length = %d, buffer = 0x%x.\n", pos, length, buffer);
+#endif
+ if(length%2)
+ length++;
+ down(&spare_lock);
+ if(copy_to_user(buffer, (void*)(FLASH_BASE | pos), length))
+ {
+ up(&spare_lock);
+ return -EFAULT;
+ }
+ up(&spare_lock);
+ return length;
+}
+
+static int _FlashWrite(char *pcBuf, int iBufLen, int iOffset);
+asmlinkage int sys_WriteWinbondFlash(unsigned long pos, unsigned long length, char * buffer)
+{
+ // if(!pCurFlash)
+ // return -EINVAL;;
+
+ if(cfiGetFlashSize() <= 0)
+ return(-EINVAL);
+
+#ifdef _DEBUG
+ printk("\nWinbondFlash Write: pos = %x, length = %d, buffer = 0x%x.\n", pos, length, buffer);
+#endif
+
+ return _FlashWrite(buffer, length, pos);
+}
+
+asmlinkage int sys_WinbondFlashBlockSize(unsigned long pos)
+{
+ if(cfiGetFlashSize() == 0)
+ return -EINVAL;;
+
+#ifdef _DEBUG
+ printk("\nWinbondFlash BlockSize: pos = %d.\n", pos);
+#endif
+
+ pos |= FLASH_BASE;
+ return cfiGetBlockSize(pos);
+}
+asmlinkage int sys_WinbondFlashTotalSize(void)
+{
+ printk("sys_WinbondFlashTotalSize\n");
+ return cfiGetFlashSize();
+}
+asmlinkage int sys_WinbondFlashBase(void)
+{
+ return FLASH_BASE;
+}
+
+static int _FlashWrite(char *pcBuf, int iBufLen, int iOffset)
+{
+ // unsigned long flags;
+ UINT32 blockSize,src,dest;
+ INT i;
+
+ if (cfiGetFlashSize() == 0) return -EINVAL;
+
+#ifdef _DEBUG
+ printk("\nWinbondFlash _FlashWrite: pos = %x, length = %d, buffer = 0x%x.\n", iOffset, iBufLen, pcBuf);
+#endif
+
+ //i = iBufLen;
+ i=(iBufLen%2)?(iBufLen+1):iBufLen;
+
+ src = (UINT32)pcBuf;
+ dest = (iOffset%2)?(iOffset+1):iOffset | FLASH_BASE;
+
+ //CSR_WRITE(WTCR, (CSR_READ(WTCR)&0xF7)|0x01);//clyu reset watch dog
+
+ while (i>0)
+ {
+ volatile UINT32 buf;
+ volatile UINT32 addr;
+ UINT32 count;
+ int len;
+ blockSize = cfiGetBlockSize(dest);
+ if(blockSize<=0)
+ return 0;
+
+#ifdef _DEBUG
+//#if 1
+ printk("\n_FlashWrite:dest:%x,cur blockSize:%x\n",dest,blockSize);
+#endif
+ addr=dest&~(blockSize-1);
+ for(len=0;len<i&&(len+dest-addr)<blockSize;len+=2)
+ if(inph((dest+len))!=0xFFFF)
+ {
+#ifdef _DEBUG
+ printk("01 inph(%x):%x\n",dest+len,inph(dest+len));
+#endif
+ if((dest&(blockSize-1))||(dest+i-addr)<=blockSize)
+ {
+ buf=(UINT32)MALLOC(blockSize);
+ if(buf != 0)
+ {
+#ifdef _DEBUG
+ printk("\n_FlashWrite:dest:%x,addr:%x,buf:%x\n",dest,addr,buf);
+#endif
+ //memset((UCHAR *)buf,0xFF,blockSize);
+ MEMCPY((UCHAR *)buf,(UCHAR *)addr,blockSize);
+
+ //MEMCPY((UCHAR *)buf,(UCHAR *)addr,dest-addr);
+ if(i<blockSize-(dest-addr))
+ count=i;
+ else
+ count=blockSize-(dest-addr);
+
+#ifdef _DEBUG
+ printk("\n_FlashWrite:i:%d,count:%d,dest:%x,addr:%x,len:%d\n",i,count,dest,addr,len);
+#endif
+
+ MEMCPY((void *)(buf+(dest-addr)),(void *)src,count);
+
+ down(&spare_lock);
+ //save_flags(flags); cli();//prevent closing watch dog interrupt
+#ifdef _DEBUG
+ printk("%s:%d BlockErase,%x\n",__FILE__,__LINE__,inph(dest+len));
+#endif
+ cfiCmd.erase(addr, blockSize);
+#ifdef _DEBUG
+ printk("02 inph(%x):%x\n",dest+len,inph(dest+len));
+ printk("%s:%d BlockWrite\n",__FILE__,__LINE__);
+#endif
+ cfiCmd.write(addr, (UCHAR *)buf, blockSize);
+#ifdef _DEBUG
+ printk("03 inph(%x):%x\n",dest+len,inph(dest+len));
+#endif
+ //restore_flags(flags);
+ up(&spare_lock);
+
+ FREE((void *)buf);
+ blockSize = count;
+ }
+ else
+ {
+ return (iBufLen - i);
+ }
+ }
+ else
+ {
+ down(&spare_lock);
+ //save_flags(flags); cli();
+#ifdef _DEBUG
+ printk("\nb_FlashWrite:i:%d,count:%d,dest:%x,addr:%x,%x\n",i,count,dest,addr,inph(dest+len));
+#endif
+ cfiCmd.erase(dest, blockSize);
+ cfiCmd.write(dest, (UCHAR *)src, blockSize);
+
+ //restore_flags(flags);
+ up(&spare_lock);
+ }
+ break;
+ }
+ if((len>=i)||((len+dest-addr)>=cfiGetBlockSize(dest)))
+ {
+ if((dest&(blockSize-1))||(dest+i-addr)<=blockSize)
+ {
+#ifdef _DEBUG
+printk("Write direct\n");
+#endif
+ if(i<blockSize-(dest-addr))
+ count=i;
+ else
+ count=blockSize-(dest-addr);
+ down(&spare_lock);
+ //save_flags(flags); cli();
+ cfiCmd.write(dest, (UCHAR *)src, count);
+ //restore_flags(flags);
+ up(&spare_lock);
+ blockSize=count;
+ }
+ else
+ {
+#ifdef _DEBUG
+printk("Write direct one block\n");
+#endif
+ down(&spare_lock);
+ //save_flags(flags); cli();
+ cfiCmd.write(dest, (UCHAR *)src, blockSize);
+ //restore_flags(flags);
+ up(&spare_lock);
+ }
+ }
+ src+=blockSize;
+ dest+=blockSize;
+ i-=blockSize;
+ }
+
+ return (iBufLen);
+}
+
+module_init(Init_WinbondFlash);
diff --git a/uClinux-2.4.20-uc1/drivers/block/wbflash/image.c b/uClinux-2.4.20-uc1/drivers/block/wbflash/image.c
index ea79b7d..800fc2f 100644
--- a/uClinux-2.4.20-uc1/drivers/block/wbflash/image.c
+++ b/uClinux-2.4.20-uc1/drivers/block/wbflash/image.c
@@ -1,178 +1,178 @@
-#include <asm/arch/flash.h>
-#include <asm/semaphore.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/config.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <asm/fcntl.h>
-#include <asm/unistd.h>
-#include <asm/uaccess.h>
-#include "cfi.h"
-
-extern struct semaphore spare_lock;
-
-
-
-int FindFooter(tfooter *** image_footer)
-{
- static tfooter * image_footers[MAX_FOOTER_NUM];
- unsigned int footer_num=0;
- //int flash_type;
- unsigned int blocksize,addr,i;
- tfooter * footer;
- unsigned int * p;
- unsigned long long sum;
-
- *image_footer=image_footers;
-
- if(cfiGetFlashSize() == 0 )
- return -1;
-
- addr=FLASH_BASE+BOOTER_BLOCK_LENGTH; // the 64kb of flash was preservied to boot loader
- blocksize=cfiGetBlockSize(addr);
- while( blocksize!= 0 )
- {
- addr+=blocksize;
- footer=(tfooter *)(addr-sizeof(tfooter));
- if(footer->signature==SIGNATURE_WORD)
- {
- p=(unsigned int *)footer;
- sum=0;
- for(i=0;i<sizeof(tfooter)/4-1;i++)// Not include the checksum
- {
- sum+=*(p+i);
- }
- sum = ~((sum&(-1LU))+(sum>>32));
- if( (unsigned int)sum == footer->checksum )
- image_footers[footer_num++]=footer;
- }
-
- blocksize=cfiGetBlockSize(addr);
- }
-
- return footer_num;
-}
-
-/*1 success 0 failure*/
-asmlinkage int sys_FindImage(unsigned int image_num, tfooter ** image_footer)
-{
- int footer_num;
- tfooter ** footer;
- int i;
-
-
- footer_num=FindFooter(&footer);
- if(footer_num<=0)
- {
- return 0;
- }
-
- for(i=0;i<footer_num;i++)
- {
- if( footer[i]->num == image_num )
- {
- *image_footer=footer[i];
- return 1;
- }
- }
-
-
- return 0;
-}
-
-
-
-/*0 success*/
-asmlinkage int sys_DelImage(unsigned int image_num)
-{
- unsigned int flash_type;
- tfooter * footer;
- unsigned int addr;
- unsigned int blocksize;
- unsigned int end;
- unsigned long flags;
-
- if( sys_FindImage( image_num, &footer) )
- {
- if(cfiGetFlashSize() == 0) {
- printk("delete failed\n");
- return -EINVAL;
- }
- addr=footer->base;
- blocksize = cfiGetBlockSize(addr);
- end=footer->base+footer->length;
-
- end+=sizeof(tfooter);
-
- //printk("end at:%x", end);
-
- if((end & (blocksize-1)) == 0 )
- end -= blocksize;
- else
- end = end&(~(blocksize-1));
-
- //printk("end at:%x", end);
-
-
- {
- down(&spare_lock);
- save_flags(flags); cli();
-
- cfiGetBlockSize(end);
- cfiCmd.erase(end,blocksize);
- restore_flags(flags);
- up(&spare_lock);
- }
-
- return 0;
- }
- printk("delete image failed\n");
- return -EINVAL;
-}
-
-/*0 success 1 Corrupt*/
-asmlinkage int sys_CorruptCheck(tfooter * image_footer)
-{
- int footer_num;
- tfooter ** footer;
- int i;
- unsigned int a0,a1,b0,b1;
-
- if( image_footer->base < (FLASH_BASE+BOOTER_BLOCK_LENGTH) )return 1;
- if( image_footer->base+image_footer->length > (FLASH_BASE+cfiGetFlashSize()) )return 1;
- footer_num=FindFooter(&footer);
-
- if(footer_num<=0)
- return 0;
- for(i=0;i<footer_num;i++)
- {
- if( image_footer->num == footer[i]->num ) {
- printk("iamge exists");
- return 1;
- }
- }
-
-
- b0=image_footer->base;
- if( FLASH_BLOCK_SIZE-(image_footer->length%FLASH_BLOCK_SIZE) < sizeof(tfooter) )
- b1=image_footer->base+image_footer->length+FLASH_BLOCK_SIZE;
- else
- b1=image_footer->base+image_footer->length;
- for(i=0;i<footer_num;i++)
- {
- a0=footer[i]->base;
- if( (FLASH_BLOCK_SIZE-(footer[i]->length%FLASH_BLOCK_SIZE) < sizeof(tfooter)) || !(footer[i]->length&(FLASH_BLOCK_SIZE-1)) )
- a1=footer[i]->base+footer[i]->length+FLASH_BLOCK_SIZE;
- else
- a1=footer[i]->base+footer[i]->length;
- if( (b0 >= a0) && (b0 < a1) )return 1;
- if( (b1 >= a0) && (b1 < a1) )return 1;
- if( (a0 > b0) && (a1 < b1) )return 1;
- }
-
- return 0;
-}
-
-
-
+#include <asm/arch/flash.h>
+#include <asm/semaphore.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/major.h>
+#include <linux/slab.h>
+#include <asm/fcntl.h>
+#include <asm/unistd.h>
+#include <asm/uaccess.h>
+#include "cfi.h"
+
+extern struct semaphore spare_lock;
+
+
+
+int FindFooter(tfooter *** image_footer)
+{
+ static tfooter * image_footers[MAX_FOOTER_NUM];
+ unsigned int footer_num=0;
+ //int flash_type;
+ unsigned int blocksize,addr,i;
+ tfooter * footer;
+ unsigned int * p;
+ unsigned long long sum;
+
+ *image_footer=image_footers;
+
+ if(cfiGetFlashSize() == 0 )
+ return -1;
+
+ addr=FLASH_BASE+BOOTER_BLOCK_LENGTH; // the 64kb of flash was preservied to boot loader
+ blocksize=cfiGetBlockSize(addr);
+ while( blocksize!= 0 )
+ {
+ addr+=blocksize;
+ footer=(tfooter *)(addr-sizeof(tfooter));
+ if(footer->signature==SIGNATURE_WORD)
+ {
+ p=(unsigned int *)footer;
+ sum=0;
+ for(i=0;i<sizeof(tfooter)/4-1;i++)// Not include the checksum
+ {
+ sum+=*(p+i);
+ }
+ sum = ~((sum&(-1LU))+(sum>>32));
+ if( (unsigned int)sum == footer->checksum )
+ image_footers[footer_num++]=footer;
+ }
+
+ blocksize=cfiGetBlockSize(addr);
+ }
+
+ return footer_num;
+}
+
+/*1 success 0 failure*/
+asmlinkage int sys_FindImage(unsigned int image_num, tfooter ** image_footer)
+{
+ int footer_num;
+ tfooter ** footer;
+ int i;
+
+
+ footer_num=FindFooter(&footer);
+ if(footer_num<=0)
+ {
+ return 0;
+ }
+
+ for(i=0;i<footer_num;i++)
+ {
+ if( footer[i]->num == image_num )
+ {
+ *image_footer=footer[i];
+ return 1;
+ }
+ }
+
+
+ return 0;
+}
+
+
+
+/*0 success*/
+asmlinkage int sys_DelImage(unsigned int image_num)
+{
+ unsigned int flash_type;
+ tfooter * footer;
+ unsigned int addr;
+ unsigned int blocksize;
+ unsigned int end;
+ unsigned long flags;
+
+ if( sys_FindImage( image_num, &footer) )
+ {
+ if(cfiGetFlashSize() == 0) {
+ printk("delete failed\n");
+ return -EINVAL;
+ }
+ addr=footer->base;
+ blocksize = cfiGetBlockSize(addr);
+ end=footer->base+footer->length;
+
+ end+=sizeof(tfooter);
+
+ //printk("end at:%x", end);
+
+ if((end & (blocksize-1)) == 0 )
+ end -= blocksize;
+ else
+ end = end&(~(blocksize-1));
+
+ //printk("end at:%x", end);
+
+
+ {
+ down(&spare_lock);
+ save_flags(flags); cli();
+
+ cfiGetBlockSize(end);
+ cfiCmd.erase(end,blocksize);
+ restore_flags(flags);
+ up(&spare_lock);
+ }
+
+ return 0;
+ }
+ printk("delete image failed\n");
+ return -EINVAL;
+}
+
+/*0 success 1 Corrupt*/
+asmlinkage int sys_CorruptCheck(tfooter * image_footer)
+{
+ int footer_num;
+ tfooter ** footer;
+ int i;
+ unsigned int a0,a1,b0,b1;
+
+ if( image_footer->base < (FLASH_BASE+BOOTER_BLOCK_LENGTH) )return 1;
+ if( image_footer->base+image_footer->length > (FLASH_BASE+cfiGetFlashSize()) )return 1;
+ footer_num=FindFooter(&footer);
+
+ if(footer_num<=0)
+ return 0;
+ for(i=0;i<footer_num;i++)
+ {
+ if( image_footer->num == footer[i]->num ) {
+ printk("iamge exists");
+ return 1;
+ }
+ }
+
+
+ b0=image_footer->base;
+ if( FLASH_BLOCK_SIZE-(image_footer->length%FLASH_BLOCK_SIZE) < sizeof(tfooter) )
+ b1=image_footer->base+image_footer->length+FLASH_BLOCK_SIZE;
+ else
+ b1=image_footer->base+image_footer->length;
+ for(i=0;i<footer_num;i++)
+ {
+ a0=footer[i]->base;
+ if( (FLASH_BLOCK_SIZE-(footer[i]->length%FLASH_BLOCK_SIZE) < sizeof(tfooter)) || !(footer[i]->length&(FLASH_BLOCK_SIZE-1)) )
+ a1=footer[i]->base+footer[i]->length+FLASH_BLOCK_SIZE;
+ else
+ a1=footer[i]->base+footer[i]->length;
+ if( (b0 >= a0) && (b0 < a1) )return 1;
+ if( (b1 >= a0) && (b1 < a1) )return 1;
+ if( (a0 > b0) && (a1 < b1) )return 1;
+ }
+
+ return 0;
+}
+
+
+
diff --git a/uClinux-2.4.20-uc1/drivers/char/vdd.c b/uClinux-2.4.20-uc1/drivers/char/vdd.c
index ff6c6d9..3661ebe 100644
--- a/uClinux-2.4.20-uc1/drivers/char/vdd.c
+++ b/uClinux-2.4.20-uc1/drivers/char/vdd.c
@@ -1,472 +1,472 @@
-/*
- * linux/drivers/char/vdd.c
- *
- * Winbond uclinux virtual debug device.
- * yyang1|pc32 030528
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <asm/page.h>
-#include <linux/errno.h>
-
-#ifndef _DEBUG
-#define _DEBUG
-#endif
-#undef _DEBUG
-
-#ifndef EOF
-#define EOF (-1)
-#endif
-
-typedef unsigned char BYTE;
-typedef unsigned int BOOL;
-#define TRUE 1
-#define FALSE 0
-
-#define MALLOC(x) kmalloc((x), GFP_KERNEL)
-#define FREE kfree
-#define MEMCPY memcpy //or use "copy_to_user"
-
-#define DEBUGBUF_SIZE (1024 * 2)
-
-
-#define VDD_CLEAR 0x5901 //clear current queue
-#define MAX_VDD_DEV 2
-#define VDD_MAJOR 99
-
-typedef struct Queue
-{
- void * queue;
- size_t MaxSize;
- size_t begin;
- size_t end;
- size_t usage;
-} Queue_t;
-
-#ifdef CONFIG_DEVFS_FS
-#include <linux/devfs_fs_kernel.h>
-static devfs_handle_t devfs_vdd_handle[MAX_VDD_DEV];
-static DECLARE_MUTEX(vdd_table_mutex);
-#endif
-
-static Queue_t debug_queue = {NULL, DEBUGBUF_SIZE + 1, 0, 0, 0};
-
-static int vdd_open(struct inode *inode, struct file *filep);
-static int vdd_release(struct inode *inode, struct file *filep);
-static ssize_t vdd_read(struct file *filp, char * buf, size_t count, loff_t *f_pos);
-static ssize_t vdd_write(struct file *filp, const char * buf, size_t count, loff_t *f_pos);
-static loff_t vdd_llseek (struct file *, loff_t, int);
-static int vdd_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, unsigned long arg);
-
-
-static struct file_operations vdd_ops =
-{
- open: vdd_open,
- read: vdd_read,
- write: vdd_write,
- llseek: vdd_llseek,
- release: vdd_release,
- ioctl: vdd_ioctl,
-};
-
-//----------------------------queue funcs----------------------------------//
-#define _Capacity() (debug_queue.MaxSize - 1)
-
-#define _IsEmpty() (debug_queue.begin == debug_queue.end)
-#define _IsFull() (((debug_queue.end + 1) % debug_queue.MaxSize == debug_queue.begin) ? TRUE : FALSE)
-#define _Free() (_Capacity() - _Size())
-
-#define _Begin() (debug_queue.begin)
-#define _End() (debug_queue.end)
-#define _nIterator(x) ((_Begin() + (x)) % debug_queue.MaxSize)
-
-#define _First() (((BYTE *)debug_queue.queue)[(debug_queue.begin + 1) % debug_queue.MaxSize])
-#define _Last() (((BYTE *)debug_queue.queue)[debug_queue.end])
-
-#define _Usage() (debug_queue.usage)
-
-static size_t _Size()
-{
- long diff_ = (long)debug_queue.end - (long)debug_queue.begin;
- return (diff_ >= 0) ? diff_ : (debug_queue.MaxSize + diff_);
-}
-
-static size_t _Distance(size_t begin, size_t end)
-{
- long diff_ = (long)end - (long)begin;
- return (diff_ >= 0) ? diff_ : (debug_queue.MaxSize + diff_);
-}
-
-static BYTE _nElement(size_t index) // index = 0 --> *(begin + 1)
-{
-// ASSERT((index >= 0) && (index < _Size()));
- return ((BYTE *)debug_queue.queue)[_nIterator(index + 1)];
-}
-
-static void _Delete()
-{
- if (_IsEmpty())
- return;
-
- debug_queue.begin = (debug_queue.begin + 1) % debug_queue.MaxSize;
-}
-
-static void _Add(BYTE x)
-{
- if (_IsFull())
- _Delete();
-
- debug_queue.end = (debug_queue.end + 1) % debug_queue.MaxSize;
- ((BYTE *)debug_queue.queue)[debug_queue.end] = x;
-}
-
-//random and memcpy to optimize..
-static size_t N_copy(void *buf, size_t begin, size_t end)
-{
- void * src_, *dst_ = buf;
- size_t copy_num = 0;
-
-// ASSERT(buf && (begin < debug_queue.MaxSize) && (end < debug_queue.MaxSize));
-
- if(end == begin)
- return 0;
-
- if(end < begin)
- {
- size_t split_diff = _Capacity() - begin;
- if(split_diff)
- {
- (BYTE *)src_ = (BYTE *)debug_queue.queue + (begin + 1) % _Capacity();
- MEMCPY(dst_, src_, split_diff);
- copy_num += split_diff;
- (BYTE *)dst_ += copy_num;
- }
-
- src_ = debug_queue.queue;
- MEMCPY(dst_, src_, end + 1);
- copy_num += end + 1;
- }
- else // greater than
- {
- copy_num = end - begin;
- (BYTE *)src_ = (BYTE *)debug_queue.queue + begin + 1;
- MEMCPY(dst_, src_, copy_num);
- }
-
- return copy_num;
-}
-
-static void N_Delete(size_t n)
-{
- if (_Size() < n)
- {
- debug_queue.begin = debug_queue.end;
- return;
- }
-
- debug_queue.begin = (debug_queue.begin + n) % debug_queue.MaxSize;
-}
-
-static void N_Add(const void *buf, size_t count)
-{
- size_t freed_;
- size_t valid_ = (count > _Capacity()) ? _Capacity() : count;
- void * src_, *dst_;
- src_ = (BYTE *)buf + count - valid_;
- dst_ = (BYTE *)debug_queue.queue + (debug_queue.end + 1) % debug_queue.MaxSize;
-
-#ifdef _DEBUG
- printk("***N_Add(buf = 0x%x, count = %d).\n", buf, count);
-#endif
-
- freed_ = _Free();
- if (freed_ < valid_)
- {
-#ifdef _DEBUG
- printk("Free: %d, valid %d.\n", _Free(), valid_);
-#endif
-
- N_Delete(valid_ - freed_);
- }
-
- if(debug_queue.end >= debug_queue.begin)
- {
- size_t split_diff = _Capacity() - debug_queue.end;
- if(valid_ > split_diff)
- {
- MEMCPY(dst_, src_, split_diff);
-
- debug_queue.end = _Capacity();
-
- (BYTE *)src_ += split_diff;
- valid_ -= split_diff;
- dst_ = debug_queue.queue;
- }
- }
-
- MEMCPY(dst_, src_, valid_);
- debug_queue.end = ((BYTE *)dst_ - (BYTE *)debug_queue.queue) + valid_ - 1;
-}
-
-//----------------------------driver funcs----------------------------------//
-static int vdd_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, unsigned long arg)
-{
-
-
-#ifdef _DEBUG
- printk("***vdd_ioctl: cmd = 0x%x, arg = 0x%x\n", cmd, arg);
-#endif
-
- switch(cmd)
- {
- case VDD_CLEAR:
- {
- debug_queue.begin = debug_queue.end = 0;
-
-#ifdef _DEBUG
- printk("***vdd_ioctl[VDD_CLEAR], now queue size = %d.\n", _Size());
-#endif
-
- break;
- }
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static loff_t vdd_llseek (struct file *filp, loff_t off, int whence)
-{
- long newpos;
-
-#ifdef _DEBUG
- printk("*** 1 vdd_llseek off = %llu, whence = %d.\n", off, whence);
-#endif
-
- switch(whence)
- {
- case 0: //begin
- newpos = off;
- break;
-
- case 1: //current
- newpos = filp->f_pos + off;
- break;
-
- case 2: //end
- newpos = _Size() + off;
- break;
-
- default:
- return -EINVAL;
- }
-
- if(newpos < 0)
- return -EINVAL;
-
- filp->f_pos = newpos;
-
-#ifdef _DEBUG
- printk("*** 2 vdd_llseek newpos = %d, f_pos = %llu, whence = %d.\n", newpos, filp->f_pos, whence);
-#endif
-
- return newpos;
-}
-
-static ssize_t vdd_read(struct file *filep, char * buf, size_t count, loff_t *f_pos)
-{
- size_t read_num = 0;
- size_t begin_, end_;
-
- if(!debug_queue.queue || !count)
- return 0;
-
-#ifdef _DEBUG
- printk("***before debug_read count = %d, buf = 0x%x, f_pos = 0x%x.\n", count, buf, filep->f_pos);
-#endif
-
-#if 0
-
- begin_ = (count >= _Size()) ? _Begin() : (_nIterator(_Size() - count));
- read_num = N_copy(buf, begin_, _End());
-
-#else
-
- if(filep->f_pos >= _Size())
- {
- //filep->f_pos = 0; //if end, then lseek to begin...
- read_num = 0;
- }
- else
- {
- begin_ = _nIterator(filep->f_pos);
- end_ = (count >= _Distance(begin_, _End())) ? _End() : (_nIterator(_Distance(_Begin(), begin_) + count));
-
- _Usage()++;
- read_num = N_copy(buf, begin_, end_);
- _Usage()--;
-
-#ifdef _DEBUG
- printk("***debug_reading begin_ = %d, end_ = %d, read_num = %d.\n", begin_, end_, read_num);
-#endif
- filep->f_pos += read_num;
- }
-
-#endif
-
-#ifdef _DEBUG
- printk("***after debug_read count = %d, buf = 0x%x, f_pos = 0x%x.\n", count, buf, filep->f_pos);
-#endif
-
- return read_num;
-}
-
-static ssize_t vdd_write(struct file *filep, const char * buf, size_t count, loff_t *f_pos)
-{
- if(!debug_queue.queue)
- return 0;
-
- _Usage()++;
- N_Add(buf, count);
- _Usage()--;
-
-#ifdef _DEBUG
- printk("***debug_write count = %d, buf = 0x%x, f_pos = 0x%x.\n", count, buf, filep->f_pos);
-#endif
-
- return count;
-}
-
-
-
-
-static int vdd_open(struct inode *inode, struct file *filep)
-{
- unsigned int dev = MINOR(inode->i_rdev);
-
- if(dev >= MAX_VDD_DEV)
- return -EFAULT;
-
- //030529?
- if(_Usage())
- return -EFAULT;
-
- filep->f_op = &vdd_ops;
- filep->f_pos = 0;
-
- MOD_INC_USE_COUNT;
-
-#ifdef _DEBUG
- printk("open VDD[vdd%d] succeed!\n", dev);
-#endif
-
- return 0;
-}
-
-static int vdd_release(struct inode *inode, struct file *filep)
-{
- MOD_DEC_USE_COUNT;
-
-#ifdef _DEBUG
- printk("close VDD succeed!\n");
-#endif
- return 0;
-}
-#ifdef CONFIG_DEVFS_FS
-static void register_vdd_usr(void)
-{
- int i;
-
- down(&vdd_table_mutex);
-
- MOD_INC_USE_COUNT;
-
- for (i=0; i< MAX_VDD_DEV; i++)
- {
- char name[8];
- sprintf(name, "vdd%d", i);
-
- devfs_vdd_handle[i] = devfs_register(NULL, name,
- DEVFS_FL_DEFAULT, VDD_MAJOR, i,
- S_IFCHR | S_IRUGO | S_IWUGO,
- &vdd_ops, NULL);
-
- }
-
- up(&vdd_table_mutex);
-}
-
-static void unregister_vdd_usr(void)
-{
- int i;
-
- down(&vdd_table_mutex);
-
- MOD_DEC_USE_COUNT;
-
- for (i=0; i< MAX_VDD_DEV; i++)
- devfs_unregister(devfs_vdd_handle[i]);
-
- up(&vdd_table_mutex);
-}
-#endif
-//----------------------------module funcs----------------------------------//
-int vdd_init(void)
-{
- int result;
-
-#ifdef _DEBUG
- char *cptr = "Winbond Virtual Debug Device[c, 2k, round queue]!\n";
- printk("****vdd initing...");
-#endif
-#ifdef CONFIG_DEVFS_FS
- result = devfs_register_chrdev(VDD_MAJOR, "vdd", &vdd_ops);
- if(result < 0)
- {
- printk("VDD: can't register vdd.\n");
- return result;
- }
-
- register_vdd_usr();
-#else
- result = register_chrdev(VDD_MAJOR, "vdd", &vdd_ops);
- if(result < 0)
- {
- printk("VDD: can't register vdd.\n");
- return result;
- }
-#endif
- if(!debug_queue.queue)
- debug_queue.queue = MALLOC(debug_queue.MaxSize);
-
-#ifdef _DEBUG
- N_Add(cptr, strlen(cptr));
-#endif
- return 0;
-}
-
-void vdd_cleanup(void)
-{
- if(debug_queue.queue)
- {
- FREE(debug_queue.queue);
- debug_queue.queue = NULL;
- }
-#ifdef CONFIG_DEVFS_FS
- unregister_vdd_usr();
- devfs_unregister_chrdev(VDD_MAJOR, "vdd");
-#else
- unregister_chrdev(VDD_MAJOR, "vdd");
-#endif
-}
-
-module_init(vdd_init);
-module_exit(vdd_cleanup);
+/*
+ * linux/drivers/char/vdd.c
+ *
+ * Winbond uclinux virtual debug device.
+ * yyang1|pc32 030528
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <linux/errno.h>
+
+#ifndef _DEBUG
+#define _DEBUG
+#endif
+#undef _DEBUG
+
+#ifndef EOF
+#define EOF (-1)
+#endif
+
+typedef unsigned char BYTE;
+typedef unsigned int BOOL;
+#define TRUE 1
+#define FALSE 0
+
+#define MALLOC(x) kmalloc((x), GFP_KERNEL)
+#define FREE kfree
+#define MEMCPY memcpy //or use "copy_to_user"
+
+#define DEBUGBUF_SIZE (1024 * 2)
+
+
+#define VDD_CLEAR 0x5901 //clear current queue
+#define MAX_VDD_DEV 2
+#define VDD_MAJOR 99
+
+typedef struct Queue
+{
+ void * queue;
+ size_t MaxSize;
+ size_t begin;
+ size_t end;
+ size_t usage;
+} Queue_t;
+
+#ifdef CONFIG_DEVFS_FS
+#include <linux/devfs_fs_kernel.h>
+static devfs_handle_t devfs_vdd_handle[MAX_VDD_DEV];
+static DECLARE_MUTEX(vdd_table_mutex);
+#endif
+
+static Queue_t debug_queue = {NULL, DEBUGBUF_SIZE + 1, 0, 0, 0};
+
+static int vdd_open(struct inode *inode, struct file *filep);
+static int vdd_release(struct inode *inode, struct file *filep);
+static ssize_t vdd_read(struct file *filp, char * buf, size_t count, loff_t *f_pos);
+static ssize_t vdd_write(struct file *filp, const char * buf, size_t count, loff_t *f_pos);
+static loff_t vdd_llseek (struct file *, loff_t, int);
+static int vdd_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, unsigned long arg);
+
+
+static struct file_operations vdd_ops =
+{
+ open: vdd_open,
+ read: vdd_read,
+ write: vdd_write,
+ llseek: vdd_llseek,
+ release: vdd_release,
+ ioctl: vdd_ioctl,
+};
+
+//----------------------------queue funcs----------------------------------//
+#define _Capacity() (debug_queue.MaxSize - 1)
+
+#define _IsEmpty() (debug_queue.begin == debug_queue.end)
+#define _IsFull() (((debug_queue.end + 1) % debug_queue.MaxSize == debug_queue.begin) ? TRUE : FALSE)
+#define _Free() (_Capacity() - _Size())
+
+#define _Begin() (debug_queue.begin)
+#define _End() (debug_queue.end)
+#define _nIterator(x) ((_Begin() + (x)) % debug_queue.MaxSize)
+
+#define _First() (((BYTE *)debug_queue.queue)[(debug_queue.begin + 1) % debug_queue.MaxSize])
+#define _Last() (((BYTE *)debug_queue.queue)[debug_queue.end])
+
+#define _Usage() (debug_queue.usage)
+
+static size_t _Size()
+{
+ long diff_ = (long)debug_queue.end - (long)debug_queue.begin;
+ return (diff_ >= 0) ? diff_ : (debug_queue.MaxSize + diff_);
+}
+
+static size_t _Distance(size_t begin, size_t end)
+{
+ long diff_ = (long)end - (long)begin;
+ return (diff_ >= 0) ? diff_ : (debug_queue.MaxSize + diff_);
+}
+
+static BYTE _nElement(size_t index) // index = 0 --> *(begin + 1)
+{
+// ASSERT((index >= 0) && (index < _Size()));
+ return ((BYTE *)debug_queue.queue)[_nIterator(index + 1)];
+}
+
+static void _Delete()
+{
+ if (_IsEmpty())
+ return;
+
+ debug_queue.begin = (debug_queue.begin + 1) % debug_queue.MaxSize;
+}
+
+static void _Add(BYTE x)
+{
+ if (_IsFull())
+ _Delete();
+
+ debug_queue.end = (debug_queue.end + 1) % debug_queue.MaxSize;
+ ((BYTE *)debug_queue.queue)[debug_queue.end] = x;
+}
+
+//random and memcpy to optimize..
+static size_t N_copy(void *buf, size_t begin, size_t end)
+{
+ void * src_, *dst_ = buf;
+ size_t copy_num = 0;
+
+// ASSERT(buf && (begin < debug_queue.MaxSize) && (end < debug_queue.MaxSize));
+
+ if(end == begin)
+ return 0;
+
+ if(end < begin)
+ {
+ size_t split_diff = _Capacity() - begin;
+ if(split_diff)
+ {
+ (BYTE *)src_ = (BYTE *)debug_queue.queue + (begin + 1) % _Capacity();
+ MEMCPY(dst_, src_, split_diff);
+ copy_num += split_diff;
+ (BYTE *)dst_ += copy_num;
+ }
+
+ src_ = debug_queue.queue;
+ MEMCPY(dst_, src_, end + 1);
+ copy_num += end + 1;
+ }
+ else // greater than
+ {
+ copy_num = end - begin;
+ (BYTE *)src_ = (BYTE *)debug_queue.queue + begin + 1;
+ MEMCPY(dst_, src_, copy_num);
+ }
+
+ return copy_num;
+}
+
+static void N_Delete(size_t n)
+{
+ if (_Size() < n)
+ {
+ debug_queue.begin = debug_queue.end;
+ return;
+ }
+
+ debug_queue.begin = (debug_queue.begin + n) % debug_queue.MaxSize;
+}
+
+static void N_Add(const void *buf, size_t count)
+{
+ size_t freed_;
+ size_t valid_ = (count > _Capacity()) ? _Capacity() : count;
+ void * src_, *dst_;
+ src_ = (BYTE *)buf + count - valid_;
+ dst_ = (BYTE *)debug_queue.queue + (debug_queue.end + 1) % debug_queue.MaxSize;
+
+#ifdef _DEBUG
+ printk("***N_Add(buf = 0x%x, count = %d).\n", buf, count);
+#endif
+
+ freed_ = _Free();
+ if (freed_ < valid_)
+ {
+#ifdef _DEBUG
+ printk("Free: %d, valid %d.\n", _Free(), valid_);
+#endif
+
+ N_Delete(valid_ - freed_);
+ }
+
+ if(debug_queue.end >= debug_queue.begin)
+ {
+ size_t split_diff = _Capacity() - debug_queue.end;
+ if(valid_ > split_diff)
+ {
+ MEMCPY(dst_, src_, split_diff);
+
+ debug_queue.end = _Capacity();
+
+ (BYTE *)src_ += split_diff;
+ valid_ -= split_diff;
+ dst_ = debug_queue.queue;
+ }
+ }
+
+ MEMCPY(dst_, src_, valid_);
+ debug_queue.end = ((BYTE *)dst_ - (BYTE *)debug_queue.queue) + valid_ - 1;
+}
+
+//----------------------------driver funcs----------------------------------//
+static int vdd_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, unsigned long arg)
+{
+
+
+#ifdef _DEBUG
+ printk("***vdd_ioctl: cmd = 0x%x, arg = 0x%x\n", cmd, arg);
+#endif
+
+ switch(cmd)
+ {
+ case VDD_CLEAR:
+ {
+ debug_queue.begin = debug_queue.end = 0;
+
+#ifdef _DEBUG
+ printk("***vdd_ioctl[VDD_CLEAR], now queue size = %d.\n", _Size());
+#endif
+
+ break;
+ }
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static loff_t vdd_llseek (struct file *filp, loff_t off, int whence)
+{
+ long newpos;
+
+#ifdef _DEBUG
+ printk("*** 1 vdd_llseek off = %llu, whence = %d.\n", off, whence);
+#endif
+
+ switch(whence)
+ {
+ case 0: //begin
+ newpos = off;
+ break;
+
+ case 1: //current
+ newpos = filp->f_pos + off;
+ break;
+
+ case 2: //end
+ newpos = _Size() + off;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ if(newpos < 0)
+ return -EINVAL;
+
+ filp->f_pos = newpos;
+
+#ifdef _DEBUG
+ printk("*** 2 vdd_llseek newpos = %d, f_pos = %llu, whence = %d.\n", newpos, filp->f_pos, whence);
+#endif
+
+ return newpos;
+}
+
+static ssize_t vdd_read(struct file *filep, char * buf, size_t count, loff_t *f_pos)
+{
+ size_t read_num = 0;
+ size_t begin_, end_;
+
+ if(!debug_queue.queue || !count)
+ return 0;
+
+#ifdef _DEBUG
+ printk("***before debug_read count = %d, buf = 0x%x, f_pos = 0x%x.\n", count, buf, filep->f_pos);
+#endif
+
+#if 0
+
+ begin_ = (count >= _Size()) ? _Begin() : (_nIterator(_Size() - count));
+ read_num = N_copy(buf, begin_, _End());
+
+#else
+
+ if(filep->f_pos >= _Size())
+ {
+ //filep->f_pos = 0; //if end, then lseek to begin...
+ read_num = 0;
+ }
+ else
+ {
+ begin_ = _nIterator(filep->f_pos);
+ end_ = (count >= _Distance(begin_, _End())) ? _End() : (_nIterator(_Distance(_Begin(), begin_) + count));
+
+ _Usage()++;
+ read_num = N_copy(buf, begin_, end_);
+ _Usage()--;
+
+#ifdef _DEBUG
+ printk("***debug_reading begin_ = %d, end_ = %d, read_num = %d.\n", begin_, end_, read_num);
+#endif
+ filep->f_pos += read_num;
+ }
+
+#endif
+
+#ifdef _DEBUG
+ printk("***after debug_read count = %d, buf = 0x%x, f_pos = 0x%x.\n", count, buf, filep->f_pos);
+#endif
+
+ return read_num;
+}
+
+static ssize_t vdd_write(struct file *filep, const char * buf, size_t count, loff_t *f_pos)
+{
+ if(!debug_queue.queue)
+ return 0;
+
+ _Usage()++;
+ N_Add(buf, count);
+ _Usage()--;
+
+#ifdef _DEBUG
+ printk("***debug_write count = %d, buf = 0x%x, f_pos = 0x%x.\n", count, buf, filep->f_pos);
+#endif
+
+ return count;
+}
+
+
+
+
+static int vdd_open(struct inode *inode, struct file *filep)
+{
+ unsigned int dev = MINOR(inode->i_rdev);
+
+ if(dev >= MAX_VDD_DEV)
+ return -EFAULT;
+
+ //030529?
+ if(_Usage())
+ return -EFAULT;
+
+ filep->f_op = &vdd_ops;
+ filep->f_pos = 0;
+
+ MOD_INC_USE_COUNT;
+
+#ifdef _DEBUG
+ printk("open VDD[vdd%d] succeed!\n", dev);
+#endif
+
+ return 0;
+}
+
+static int vdd_release(struct inode *inode, struct file *filep)
+{
+ MOD_DEC_USE_COUNT;
+
+#ifdef _DEBUG
+ printk("close VDD succeed!\n");
+#endif
+ return 0;
+}
+#ifdef CONFIG_DEVFS_FS
+static void register_vdd_usr(void)
+{
+ int i;
+
+ down(&vdd_table_mutex);
+
+ MOD_INC_USE_COUNT;
+
+ for (i=0; i< MAX_VDD_DEV; i++)
+ {
+ char name[8];
+ sprintf(name, "vdd%d", i);
+
+ devfs_vdd_handle[i] = devfs_register(NULL, name,
+ DEVFS_FL_DEFAULT, VDD_MAJOR, i,
+ S_IFCHR | S_IRUGO | S_IWUGO,
+ &vdd_ops, NULL);
+
+ }
+
+ up(&vdd_table_mutex);
+}
+
+static void unregister_vdd_usr(void)
+{
+ int i;
+
+ down(&vdd_table_mutex);
+
+ MOD_DEC_USE_COUNT;
+
+ for (i=0; i< MAX_VDD_DEV; i++)
+ devfs_unregister(devfs_vdd_handle[i]);
+
+ up(&vdd_table_mutex);
+}
+#endif
+//----------------------------module funcs----------------------------------//
+int vdd_init(void)
+{
+ int result;
+
+#ifdef _DEBUG
+ char *cptr = "Winbond Virtual Debug Device[c, 2k, round queue]!\n";
+ printk("****vdd initing...");
+#endif
+#ifdef CONFIG_DEVFS_FS
+ result = devfs_register_chrdev(VDD_MAJOR, "vdd", &vdd_ops);
+ if(result < 0)
+ {
+ printk("VDD: can't register vdd.\n");
+ return result;
+ }
+
+ register_vdd_usr();
+#else
+ result = register_chrdev(VDD_MAJOR, "vdd", &vdd_ops);
+ if(result < 0)
+ {
+ printk("VDD: can't register vdd.\n");
+ return result;
+ }
+#endif
+ if(!debug_queue.queue)
+ debug_queue.queue = MALLOC(debug_queue.MaxSize);
+
+#ifdef _DEBUG
+ N_Add(cptr, strlen(cptr));
+#endif
+ return 0;
+}
+
+void vdd_cleanup(void)
+{
+ if(debug_queue.queue)
+ {
+ FREE(debug_queue.queue);
+ debug_queue.queue = NULL;
+ }
+#ifdef CONFIG_DEVFS_FS
+ unregister_vdd_usr();
+ devfs_unregister_chrdev(VDD_MAJOR, "vdd");
+#else
+ unregister_chrdev(VDD_MAJOR, "vdd");
+#endif
+}
+
+module_init(vdd_init);
+module_exit(vdd_cleanup);
diff --git a/uClinux-2.4.20-uc1/drivers/char/w90n745_i2c.c b/uClinux-2.4.20-uc1/drivers/char/w90n745_i2c.c
index 7b9cd9b..fd0f815 100755
--- a/uClinux-2.4.20-uc1/drivers/char/w90n745_i2c.c
+++ b/uClinux-2.4.20-uc1/drivers/char/w90n745_i2c.c
@@ -1,600 +1,600 @@
-/****************************************************************************
- *
- * Copyright (c) 2004 - 2006 Winbond Electronics Corp. All rights reserved.
- *
- ****************************************************************************/
-
-/****************************************************************************
- *
- * FILENAME
- * w90n745_i2c.c
- *
- * VERSION
- * 1.0
- *
- * DESCRIPTION
- * Winbond W90N710 I2C Driver
- *
- * DATA STRUCTURES
- * None
- *
- * FUNCTIONS
- * None
- *
- * HISTORY
- * 2005/05/20 Ver 1.0 Created by PC34 QFu
- *
- * REMARK
- * None
- *************************************************************************/
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/semaphore.h>
-
-#include "w90n745_i2c.h"
-
-
-//#define I2C_DEBUG
-//#define I2C_DEBUG_PRINT_LINE
-//#define I2C_DEBUG_ENABLE_ENTER_LEAVE
-//#define I2C_DEBUG_ENABLE_MSG
-//#define I2C_DEBUG_ENABLE_MSG2
-
-#ifdef I2C_DEBUG
-#define PDEBUG(fmt, arg...) printk(fmt, ##arg)
-#else
-#define PDEBUG(fmt, arg...)
-#endif
-
-#ifdef I2C_DEBUG_PRINT_LINE
-#define PRN_LINE() PDEBUG("[%-20s] : %d\n", __FUNCTION__, __LINE__)
-#else
-#define PRN_LINE()
-#endif
-
-#ifdef I2C_DEBUG_ENABLE_ENTER_LEAVE
-#define ENTER() PDEBUG("[%-20s] : Enter...\n", __FUNCTION__)
-#define LEAVE() PDEBUG("[%-20s] : Leave...\n", __FUNCTION__)
-#else
-#define ENTER()
-#define LEAVE()
-#endif
-
-#ifdef I2C_DEBUG_ENABLE_MSG
-#define MSG(msg) PDEBUG("[%-20s] : %s", __FUNCTION__, msg)
-#else
-#define MSG(msg)
-#endif
-
-#ifdef I2C_DEBUG_ENABLE_MSG2
-#define MSG2(fmt, arg...) PDEBUG("[%-20s] : "fmt, __FUNCTION__, ##arg)
-#define PRNBUF(buf, count) {int i;MSG2("CID Data: ");for(i=0;i<count;i++)\
- PDEBUG("%02x ", buf[i]);PDEBUG("\n");}
-#else
-#define MSG2(fmt, arg...)
-#define PRNBUF(buf, count)
-#endif
-
-
-
-#define i2c_outl(dev, dword, addr) outl(dword, base[dev->no] + addr)
-#define i2c_inl(dev, addr) inl(base[dev->no] + addr)
-
-
-static const int base[I2C_NUMBER] = {I2C0_IO_BASE, I2C1_IO_BASE};
-static const int irq[I2C_NUMBER] = {I2C0_IRQ, I2C1_IRQ};
-static int bNackValid;
-
-static void i2c_Disable(i2c_dev *dev) /* Disable i2c core and interrupt */
-{
-
- i2c_outl(dev, 0x00, CSR);
-}
-
-static void i2c_Enable(i2c_dev *dev) /* Enable i2c core and interrupt */
-{
- i2c_outl(dev, 0x03, CSR);
-}
-
-static int i2c_SetSpeed(i2c_dev *dev, int sp)
-{
- unsigned int d;
-
- if( sp != 100 && sp != 400)
- return -1;
-
- d = I2C_INPUT_CLOCK/(sp * 5) -1;
-
- i2c_outl(dev, d & 0xffff, DIVIDER);
-
- MSG2("Set Speed = %d\n", sp);
-
- return 0;
-}
-
-static int i2c_IsBusFree(i2c_dev *dev)
-{
- if( (i2c_inl(dev, SWR) & 0x18) == 0x18 && //SDR and SCR keep high
- (i2c_inl(dev, CSR) & 0x0400) == 0 ){ //I2C_BUSY is false
- //MSG("Bus Free\n");
-
- return 1;
- }
- else{
- //MSG("Bus Busy\n");
-
- return 0;
- }
-
-}
-
-static int i2c_Command(i2c_dev *dev, int cmd)
-{
-
-#if 0
- printk("CMD : ");
-
- if(cmd & I2C_CMD_START){
- printk("START ");
- }
-
- if (cmd & I2C_CMD_STOP){
- printk("STOP ");
-
- }
-
- if(cmd & I2C_CMD_NACK){
- printk("NACK ");
- }
-
- if(cmd & I2C_CMD_WRITE){
- printk("WRITE : [%02x]", i2c_inl(dev, TXR) & 0xff);
- }
-
- if(cmd & I2C_CMD_READ){
- printk("READ : [%02x]", i2c_inl(dev, RXR) & 0xff);
- }
-
- printk("\n");
-
-#endif
-
- if(cmd & I2C_CMD_WRITE)
- bNackValid = 1;
- else
- bNackValid = 0;
-
- i2c_outl(dev, cmd, CMDR);
-
- return 0;
-
-}
-
-
-static int i2c_CalculateAddress(i2c_dev *dev, int mode)
-{
- int i;
- unsigned int addr;
- unsigned int subaddr;
-
- subaddr = dev->subaddr;
- addr = dev->addr;
-
- addr = ((addr << 1) & 0xfe) | I2C_WRITE;
-
- dev->buffer[0] = addr & 0xff;
-
- for(i = dev->subaddr_len; i > 0; i--){
- dev->buffer[i] = subaddr & 0xff;
- subaddr >>= 8;
- }
-
- if(mode == I2C_STATE_READ){
- i = dev->subaddr_len + 1;
- dev->buffer[i] = (addr & 0xfe) | I2C_READ;
- }
-
-#ifdef I2C_DEBUG
- if(mode == I2C_STATE_WRITE){
- MSG2("Begin Write to Device [%02x] Address [%02x]\n",
- dev->addr, dev->subaddr);
- MSG("Buffer : \n");
- for(i = 0; i < dev->subaddr_len +1; i++)
- PDEBUG("%02x ", dev->buffer[i]);
- PDEBUG("\n");
- }
- else{
- MSG2("Begin Read from Device [%02x] Address [%02x]\n",
- dev->addr, dev->subaddr);
- MSG("Buffer : \n");
- for(i = 0; i < dev->subaddr_len +2; i++)
- PDEBUG("%02x ", dev->buffer[i]);
- PDEBUG("\n");
- }
-#endif
-
- return 0;
-}
-
-/* init i2c_dev after open */
-static int i2c_ResetI2C(i2c_dev *dev)
-{
- u32 reg;
-
- // configure i2c pin
- reg = inl(REG_GPIO_CFG5);
- reg &= 0x3ff00fff;
- reg |= 0x00055000;
- outl(reg, REG_GPIO_CFG5);
-
- dev->addr = -1;
- dev->last_error = 0;
- dev->subaddr = 0;
- dev->subaddr_len = 0;
-
- init_waitqueue_head(&dev->wq);
-
- return i2c_SetSpeed(dev, 100);
-
-}
-
-void i2c_interrupt(int irq, void *data, struct pt_regs *reg)
-{
- i2c_dev *dev = (i2c_dev *)data;
- int csr, val;
-
- csr = i2c_inl(dev, CSR);
-
- //MSG2("INT : CSR : [%02x] dev->pos = [%02x]\n", csr, dev->pos);
-
- csr |= 0x04;
-
- i2c_outl(dev, csr, CSR);
-
- if(dev->state == I2C_STATE_NOP)
- return;
-
- MSG2("bNackValid = %d\n", bNackValid);
-
- if((csr & 0x800) && bNackValid){ /* NACK only valid in WRITE */
- MSG("NACK Error\n");
- dev->last_error = I2C_ERR_NACK;
- i2c_Command(dev, I2C_CMD_STOP);
- goto wake_up_quit;
- }
- else if(csr & 0x200){ /* Arbitration lost */
- MSG("Arbitration lost\n");
- dev->last_error = I2C_ERR_LOSTARBITRATION;
- i2c_Command(dev, I2C_CMD_STOP);
- goto wake_up_quit;
- }
- else if(!(csr & 0x100)){ /* transmit complete */
- if(dev->pos < dev->subaddr_len + 1){ /* send address state */
- MSG("Send Address\n");
- val = dev->buffer[dev->pos++] & 0xff;
- i2c_outl(dev, val, TXR);
- i2c_Command(dev, I2C_CMD_WRITE);
- }
- else if(dev->state == I2C_STATE_READ){
-
- /* sub address send over , begin restart a read command */
-
- if(dev->pos == dev->subaddr_len + 1){
-
- MSG("Restart Reading...\n");
-
- val = dev->buffer[dev->pos++];
- i2c_outl(dev, val, TXR);
- i2c_Command(dev, I2C_CMD_START | I2C_CMD_WRITE);
- }
- else{
-
- dev->buffer[dev->pos++] = i2c_inl(dev, RXR) & 0xff;
-
- MSG2("Read Pos : [%02x] Data : [%02x]\n",
- dev->pos, dev->buffer[dev->pos-1]);
-
- if( dev->pos < dev->len){
- MSG("Read Next\n");
- if(dev->pos == dev->len -1 ) /* last character */
- i2c_Command(dev, I2C_CMD_READ |
- I2C_CMD_STOP |
- I2C_CMD_NACK);
- else
- i2c_Command(dev, I2C_CMD_READ);
- }
- else{
- MSG("Read Over \n");
- goto wake_up_quit;
- }
- }
- }
- else if(dev->state == I2C_STATE_WRITE){ /* write data */
-
- if( dev->pos < dev->len){
- MSG2("Write Pos : [%02x] Data : [%02x]\n",
- dev->pos, dev->buffer[dev->pos]);
-
- val = dev->buffer[dev->pos];
-
- i2c_outl(dev, val, TXR);
-
- if(dev->pos == dev->len -1 ) /* last character */
- i2c_Command(dev, I2C_CMD_WRITE| I2C_CMD_STOP);
- else
- i2c_Command(dev, I2C_CMD_WRITE);
-
- dev->pos ++;
- }
- else{
- MSG("Write Over\n");
- goto wake_up_quit;
- }
- }
- //else if(dev->state == I2C_STATE_PROBE){
- // MSG2("Probe Address : [%02x]\n", dev->addr);
- // goto wake_up_quit;
- //}
-
- }
-
- return;
-
-wake_up_quit:
-
- MSG("Wake up \n");
-
- dev->state = I2C_STATE_NOP;
- wake_up_interruptible(&dev->wq);
-
- return;
-}
-
-static int i2c_open(struct inode *inode, struct file *filp)
-{
- i2c_dev *dev;
-
- unsigned int num = MINOR(inode->i_rdev);
-
- if( num >= I2C_NUMBER) {
- printk("I2C : no dev\n");
- return -ENODEV;
- }
- dev = (i2c_dev *)kmalloc(sizeof(i2c_dev), GFP_KERNEL);
- if(dev == NULL) {
- printk("no mem\n");
- return -ENOMEM;
- }
- dev->no = num;
-
- if(request_irq(irq[num], i2c_interrupt, SA_INTERRUPT, "i2c", dev) < 0){
- printk("I2C : Request Irq error\n");
- kfree(dev);
- return -EIO;
- }
-
- if(i2c_ResetI2C(dev)){
- free_irq(irq[num], dev);
- kfree(dev);
- printk("eio\n");
- return -EIO;
- }
-
-
- MOD_INC_USE_COUNT;
-
- filp->private_data = dev;
-
- return 0;
-}
-
-static int i2c_release(struct inode *inode, struct file *flip)
-{
- i2c_dev *dev = flip->private_data;
-
- MSG2("Free IRQ %d\n", irq[dev->no]);
-
- free_irq(irq[dev->no], dev);
- kfree(dev);
- MOD_DEC_USE_COUNT;
-
- return 0;
-}
-
-static int i2c_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
-{
- i2c_dev *dev = (i2c_dev *)filp->private_data;
-
- if(count == 0)
- return 0;
-
- if(!i2c_IsBusFree(dev))
- return -EBUSY;
-
- if(count > I2C_MAX_BUF_LEN - 10)
- count = I2C_MAX_BUF_LEN - 10;
-
- dev->state = I2C_STATE_READ;
- dev->pos = 1;
- dev->len = dev->subaddr_len + 1 + count + 2;/* plus 1 unused char */
- dev->last_error = 0;
-
- i2c_CalculateAddress(dev, I2C_STATE_READ);
-
- i2c_Enable(dev);
-
- i2c_outl(dev, dev->buffer[0] & 0xff, TXR);
-
- i2c_Command(dev, I2C_CMD_START | I2C_CMD_WRITE);
-
- wait_event_interruptible(dev->wq, dev->state == I2C_STATE_NOP);
-
- i2c_Disable(dev);
-
- if(dev->last_error)
- return -EIO;
-
- if(copy_to_user(buf, dev->buffer + dev->subaddr_len + 3, count))
- return -EFAULT;
-
- dev->subaddr += count;
-
- return count;
-}
-
-static int i2c_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
-{
- i2c_dev *dev = (i2c_dev *)filp->private_data;
-
-
- if(count == 0)
- return 0;
-
- if(!i2c_IsBusFree(dev))
- return -EBUSY;
-
-
- if(count > I2C_MAX_BUF_LEN - 10)
- count = I2C_MAX_BUF_LEN - 10;
-
- if(copy_from_user(dev->buffer + dev->subaddr_len + 1 , buf, count))
- return -EFAULT;
-
-
- dev->state = I2C_STATE_WRITE;
- dev->pos = 1;
- dev->len = dev->subaddr_len + 1 + count;
- dev->last_error = 0;
-
- i2c_CalculateAddress(dev, I2C_STATE_WRITE);
-
- i2c_Enable(dev);
-
- i2c_outl(dev, dev->buffer[0] & 0xff, TXR);
-
- i2c_Command(dev, I2C_CMD_START | I2C_CMD_WRITE);
-
- wait_event_interruptible(dev->wq, dev->state == I2C_STATE_NOP);
-
- i2c_Disable(dev);
-
- if(dev->last_error)
- return -EIO;
-
- dev->subaddr += count;
-
- return count;
-}
-
-static int i2c_ioctl(struct inode *inode, struct file *flip, unsigned int cmd, unsigned long arg)
-{
- int err = 0, tmp, retval = 0;
- struct sub_address sub_addr;
- i2c_dev *dev =(i2c_dev *)flip->private_data;
-
- if(_IOC_TYPE(cmd) != I2C_IOC_MAGIC) return -ENOTTY;
- if(_IOC_NR(cmd) > I2C_IOC_MAXNR) return -ENOTTY;
-
- if(_IOC_DIR(cmd) & _IOC_READ)
- err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
- else if(_IOC_DIR(cmd) & _IOC_WRITE)
- err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
-
- if(err)
- return -EFAULT;
-
- switch(cmd){
- case I2C_IOC_SET_DEV_ADDRESS:
- dev->addr = arg;
- MSG2("Address : %02x\n", arg&0xff);
- break;
-
- case I2C_IOC_SET_SPEED:
- if(i2c_SetSpeed(dev, arg))
- retval = -EPERM;
-
- break;
-
- case I2C_IOC_GET_LAST_ERROR:
- if(put_user(dev->last_error, (int *)arg)){
- retval = -EFAULT;
- break;
- }
-
- break;
-
- case I2C_IOC_SET_SUB_ADDRESS:
- if(copy_from_user(&sub_addr, (void *)arg, sizeof(sub_addr))){
- retval = -EFAULT;
- break;
- }
-
- if(sub_addr.sub_addr_len > 4){
- retval = -EPERM;
- break;
- }
-
- MSG2("Sub Address = %02x, length = %d\n",
- sub_addr.sub_addr, sub_addr.sub_addr_len);
-
- dev->subaddr = sub_addr.sub_addr;
- dev->subaddr_len = sub_addr.sub_addr_len;
-
- break;
-
- default:
- retval = -ENOTTY;
- break;
- }
-
- return retval;
-
-}
-
-
-struct file_operations i2c_fops =
-{
- owner: THIS_MODULE,
- open: i2c_open,
- release: i2c_release,
- ioctl: i2c_ioctl,
- read: i2c_read,
- write: i2c_write,
-};
-
-static void i2c_module_exit(void)
-{
- unregister_chrdev(I2C_MAJOR, "i2c");
-}
-
-static int __init i2c_module_init(void)
-{
- int i, retval;
-
- retval = register_chrdev(I2C_MAJOR, "i2c", &i2c_fops);
- if(retval < 0)
- goto failed;
-
- printk("I2C Bus Driver has been installed successfully.\n");
-
- return 0;
-
-failed:
-
- i2c_module_exit();
-
- printk("Init I2C Bus Driver failed!\n");
-
- return retval;
-}
-
-module_init(i2c_module_init);
-module_exit(i2c_module_exit);
-
+/****************************************************************************
+ *
+ * Copyright (c) 2004 - 2006 Winbond Electronics Corp. All rights reserved.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FILENAME
+ * w90n745_i2c.c
+ *
+ * VERSION
+ * 1.0
+ *
+ * DESCRIPTION
+ * Winbond W90N710 I2C Driver
+ *
+ * DATA STRUCTURES
+ * None
+ *
+ * FUNCTIONS
+ * None
+ *
+ * HISTORY
+ * 2005/05/20 Ver 1.0 Created by PC34 QFu
+ *
+ * REMARK
+ * None
+ *************************************************************************/
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/semaphore.h>
+
+#include "w90n745_i2c.h"
+
+
+//#define I2C_DEBUG
+//#define I2C_DEBUG_PRINT_LINE
+//#define I2C_DEBUG_ENABLE_ENTER_LEAVE
+//#define I2C_DEBUG_ENABLE_MSG
+//#define I2C_DEBUG_ENABLE_MSG2
+
+#ifdef I2C_DEBUG
+#define PDEBUG(fmt, arg...) printk(fmt, ##arg)
+#else
+#define PDEBUG(fmt, arg...)
+#endif
+
+#ifdef I2C_DEBUG_PRINT_LINE
+#define PRN_LINE() PDEBUG("[%-20s] : %d\n", __FUNCTION__, __LINE__)
+#else
+#define PRN_LINE()
+#endif
+
+#ifdef I2C_DEBUG_ENABLE_ENTER_LEAVE
+#define ENTER() PDEBUG("[%-20s] : Enter...\n", __FUNCTION__)
+#define LEAVE() PDEBUG("[%-20s] : Leave...\n", __FUNCTION__)
+#else
+#define ENTER()
+#define LEAVE()
+#endif
+
+#ifdef I2C_DEBUG_ENABLE_MSG
+#define MSG(msg) PDEBUG("[%-20s] : %s", __FUNCTION__, msg)
+#else
+#define MSG(msg)
+#endif
+
+#ifdef I2C_DEBUG_ENABLE_MSG2
+#define MSG2(fmt, arg...) PDEBUG("[%-20s] : "fmt, __FUNCTION__, ##arg)
+#define PRNBUF(buf, count) {int i;MSG2("CID Data: ");for(i=0;i<count;i++)\
+ PDEBUG("%02x ", buf[i]);PDEBUG("\n");}
+#else
+#define MSG2(fmt, arg...)
+#define PRNBUF(buf, count)
+#endif
+
+
+
+#define i2c_outl(dev, dword, addr) outl(dword, base[dev->no] + addr)
+#define i2c_inl(dev, addr) inl(base[dev->no] + addr)
+
+
+static const int base[I2C_NUMBER] = {I2C0_IO_BASE, I2C1_IO_BASE};
+static const int irq[I2C_NUMBER] = {I2C0_IRQ, I2C1_IRQ};
+static int bNackValid;
+
+static void i2c_Disable(i2c_dev *dev) /* Disable i2c core and interrupt */
+{
+
+ i2c_outl(dev, 0x00, CSR);
+}
+
+static void i2c_Enable(i2c_dev *dev) /* Enable i2c core and interrupt */
+{
+ i2c_outl(dev, 0x03, CSR);
+}
+
+static int i2c_SetSpeed(i2c_dev *dev, int sp)
+{
+ unsigned int d;
+
+ if( sp != 100 && sp != 400)
+ return -1;
+
+ d = I2C_INPUT_CLOCK/(sp * 5) -1;
+
+ i2c_outl(dev, d & 0xffff, DIVIDER);
+
+ MSG2("Set Speed = %d\n", sp);
+
+ return 0;
+}
+
+static int i2c_IsBusFree(i2c_dev *dev)
+{
+ if( (i2c_inl(dev, SWR) & 0x18) == 0x18 && //SDR and SCR keep high
+ (i2c_inl(dev, CSR) & 0x0400) == 0 ){ //I2C_BUSY is false
+ //MSG("Bus Free\n");
+
+ return 1;
+ }
+ else{
+ //MSG("Bus Busy\n");
+
+ return 0;
+ }
+
+}
+
+static int i2c_Command(i2c_dev *dev, int cmd)
+{
+
+#if 0
+ printk("CMD : ");
+
+ if(cmd & I2C_CMD_START){
+ printk("START ");
+ }
+
+ if (cmd & I2C_CMD_STOP){
+ printk("STOP ");
+
+ }
+
+ if(cmd & I2C_CMD_NACK){
+ printk("NACK ");
+ }
+
+ if(cmd & I2C_CMD_WRITE){
+ printk("WRITE : [%02x]", i2c_inl(dev, TXR) & 0xff);
+ }
+
+ if(cmd & I2C_CMD_READ){
+ printk("READ : [%02x]", i2c_inl(dev, RXR) & 0xff);
+ }
+
+ printk("\n");
+
+#endif
+
+ if(cmd & I2C_CMD_WRITE)
+ bNackValid = 1;
+ else
+ bNackValid = 0;
+
+ i2c_outl(dev, cmd, CMDR);
+
+ return 0;
+
+}
+
+
+static int i2c_CalculateAddress(i2c_dev *dev, int mode)
+{
+ int i;
+ unsigned int addr;
+ unsigned int subaddr;
+
+ subaddr = dev->subaddr;
+ addr = dev->addr;
+
+ addr = ((addr << 1) & 0xfe) | I2C_WRITE;
+
+ dev->buffer[0] = addr & 0xff;
+
+ for(i = dev->subaddr_len; i > 0; i--){
+ dev->buffer[i] = subaddr & 0xff;
+ subaddr >>= 8;
+ }
+
+ if(mode == I2C_STATE_READ){
+ i = dev->subaddr_len + 1;
+ dev->buffer[i] = (addr & 0xfe) | I2C_READ;
+ }
+
+#ifdef I2C_DEBUG
+ if(mode == I2C_STATE_WRITE){
+ MSG2("Begin Write to Device [%02x] Address [%02x]\n",
+ dev->addr, dev->subaddr);
+ MSG("Buffer : \n");
+ for(i = 0; i < dev->subaddr_len +1; i++)
+ PDEBUG("%02x ", dev->buffer[i]);
+ PDEBUG("\n");
+ }
+ else{
+ MSG2("Begin Read from Device [%02x] Address [%02x]\n",
+ dev->addr, dev->subaddr);
+ MSG("Buffer : \n");
+ for(i = 0; i < dev->subaddr_len +2; i++)
+ PDEBUG("%02x ", dev->buffer[i]);
+ PDEBUG("\n");
+ }
+#endif
+
+ return 0;
+}
+
+/* init i2c_dev after open */
+static int i2c_ResetI2C(i2c_dev *dev)
+{
+ u32 reg;
+
+ // configure i2c pin
+ reg = inl(REG_GPIO_CFG5);
+ reg &= 0x3ff00fff;
+ reg |= 0x00055000;
+ outl(reg, REG_GPIO_CFG5);
+
+ dev->addr = -1;
+ dev->last_error = 0;
+ dev->subaddr = 0;
+ dev->subaddr_len = 0;
+
+ init_waitqueue_head(&dev->wq);
+
+ return i2c_SetSpeed(dev, 100);
+
+}
+
+void i2c_interrupt(int irq, void *data, struct pt_regs *reg)
+{
+ i2c_dev *dev = (i2c_dev *)data;
+ int csr, val;
+
+ csr = i2c_inl(dev, CSR);
+
+ //MSG2("INT : CSR : [%02x] dev->pos = [%02x]\n", csr, dev->pos);
+
+ csr |= 0x04;
+
+ i2c_outl(dev, csr, CSR);
+
+ if(dev->state == I2C_STATE_NOP)
+ return;
+
+ MSG2("bNackValid = %d\n", bNackValid);
+
+ if((csr & 0x800) && bNackValid){ /* NACK only valid in WRITE */
+ MSG("NACK Error\n");
+ dev->last_error = I2C_ERR_NACK;
+ i2c_Command(dev, I2C_CMD_STOP);
+ goto wake_up_quit;
+ }
+ else if(csr & 0x200){ /* Arbitration lost */
+ MSG("Arbitration lost\n");
+ dev->last_error = I2C_ERR_LOSTARBITRATION;
+ i2c_Command(dev, I2C_CMD_STOP);
+ goto wake_up_quit;
+ }
+ else if(!(csr & 0x100)){ /* transmit complete */
+ if(dev->pos < dev->subaddr_len + 1){ /* send address state */
+ MSG("Send Address\n");
+ val = dev->buffer[dev->pos++] & 0xff;
+ i2c_outl(dev, val, TXR);
+ i2c_Command(dev, I2C_CMD_WRITE);
+ }
+ else if(dev->state == I2C_STATE_READ){
+
+ /* sub address send over , begin restart a read command */
+
+ if(dev->pos == dev->subaddr_len + 1){
+
+ MSG("Restart Reading...\n");
+
+ val = dev->buffer[dev->pos++];
+ i2c_outl(dev, val, TXR);
+ i2c_Command(dev, I2C_CMD_START | I2C_CMD_WRITE);
+ }
+ else{
+
+ dev->buffer[dev->pos++] = i2c_inl(dev, RXR) & 0xff;
+
+ MSG2("Read Pos : [%02x] Data : [%02x]\n",
+ dev->pos, dev->buffer[dev->pos-1]);
+
+ if( dev->pos < dev->len){
+ MSG("Read Next\n");
+ if(dev->pos == dev->len -1 ) /* last character */
+ i2c_Command(dev, I2C_CMD_READ |
+ I2C_CMD_STOP |
+ I2C_CMD_NACK);
+ else
+ i2c_Command(dev, I2C_CMD_READ);
+ }
+ else{
+ MSG("Read Over \n");
+ goto wake_up_quit;
+ }
+ }
+ }
+ else if(dev->state == I2C_STATE_WRITE){ /* write data */
+
+ if( dev->pos < dev->len){
+ MSG2("Write Pos : [%02x] Data : [%02x]\n",
+ dev->pos, dev->buffer[dev->pos]);
+
+ val = dev->buffer[dev->pos];
+
+ i2c_outl(dev, val, TXR);
+
+ if(dev->pos == dev->len -1 ) /* last character */
+ i2c_Command(dev, I2C_CMD_WRITE| I2C_CMD_STOP);
+ else
+ i2c_Command(dev, I2C_CMD_WRITE);
+
+ dev->pos ++;
+ }
+ else{
+ MSG("Write Over\n");
+ goto wake_up_quit;
+ }
+ }
+ //else if(dev->state == I2C_STATE_PROBE){
+ // MSG2("Probe Address : [%02x]\n", dev->addr);
+ // goto wake_up_quit;
+ //}
+
+ }
+
+ return;
+
+wake_up_quit:
+
+ MSG("Wake up \n");
+
+ dev->state = I2C_STATE_NOP;
+ wake_up_interruptible(&dev->wq);
+
+ return;
+}
+
+static int i2c_open(struct inode *inode, struct file *filp)
+{
+ i2c_dev *dev;
+
+ unsigned int num = MINOR(inode->i_rdev);
+
+ if( num >= I2C_NUMBER) {
+ printk("I2C : no dev\n");
+ return -ENODEV;
+ }
+ dev = (i2c_dev *)kmalloc(sizeof(i2c_dev), GFP_KERNEL);
+ if(dev == NULL) {
+ printk("no mem\n");
+ return -ENOMEM;
+ }
+ dev->no = num;
+
+ if(request_irq(irq[num], i2c_interrupt, SA_INTERRUPT, "i2c", dev) < 0){
+ printk("I2C : Request Irq error\n");
+ kfree(dev);
+ return -EIO;
+ }
+
+ if(i2c_ResetI2C(dev)){
+ free_irq(irq[num], dev);
+ kfree(dev);
+ printk("eio\n");
+ return -EIO;
+ }
+
+
+ MOD_INC_USE_COUNT;
+
+ filp->private_data = dev;
+
+ return 0;
+}
+
+static int i2c_release(struct inode *inode, struct file *flip)
+{
+ i2c_dev *dev = flip->private_data;
+
+ MSG2("Free IRQ %d\n", irq[dev->no]);
+
+ free_irq(irq[dev->no], dev);
+ kfree(dev);
+ MOD_DEC_USE_COUNT;
+
+ return 0;
+}
+
+static int i2c_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
+{
+ i2c_dev *dev = (i2c_dev *)filp->private_data;
+
+ if(count == 0)
+ return 0;
+
+ if(!i2c_IsBusFree(dev))
+ return -EBUSY;
+
+ if(count > I2C_MAX_BUF_LEN - 10)
+ count = I2C_MAX_BUF_LEN - 10;
+
+ dev->state = I2C_STATE_READ;
+ dev->pos = 1;
+ dev->len = dev->subaddr_len + 1 + count + 2;/* plus 1 unused char */
+ dev->last_error = 0;
+
+ i2c_CalculateAddress(dev, I2C_STATE_READ);
+
+ i2c_Enable(dev);
+
+ i2c_outl(dev, dev->buffer[0] & 0xff, TXR);
+
+ i2c_Command(dev, I2C_CMD_START | I2C_CMD_WRITE);
+
+ wait_event_interruptible(dev->wq, dev->state == I2C_STATE_NOP);
+
+ i2c_Disable(dev);
+
+ if(dev->last_error)
+ return -EIO;
+
+ if(copy_to_user(buf, dev->buffer + dev->subaddr_len + 3, count))
+ return -EFAULT;
+
+ dev->subaddr += count;
+
+ return count;
+}
+
+static int i2c_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
+{
+ i2c_dev *dev = (i2c_dev *)filp->private_data;
+
+
+ if(count == 0)
+ return 0;
+
+ if(!i2c_IsBusFree(dev))
+ return -EBUSY;
+
+
+ if(count > I2C_MAX_BUF_LEN - 10)
+ count = I2C_MAX_BUF_LEN - 10;
+
+ if(copy_from_user(dev->buffer + dev->subaddr_len + 1 , buf, count))
+ return -EFAULT;
+
+
+ dev->state = I2C_STATE_WRITE;
+ dev->pos = 1;
+ dev->len = dev->subaddr_len + 1 + count;
+ dev->last_error = 0;
+
+ i2c_CalculateAddress(dev, I2C_STATE_WRITE);
+
+ i2c_Enable(dev);
+
+ i2c_outl(dev, dev->buffer[0] & 0xff, TXR);
+
+ i2c_Command(dev, I2C_CMD_START | I2C_CMD_WRITE);
+
+ wait_event_interruptible(dev->wq, dev->state == I2C_STATE_NOP);
+
+ i2c_Disable(dev);
+
+ if(dev->last_error)
+ return -EIO;
+
+ dev->subaddr += count;
+
+ return count;
+}
+
+static int i2c_ioctl(struct inode *inode, struct file *flip, unsigned int cmd, unsigned long arg)
+{
+ int err = 0, tmp, retval = 0;
+ struct sub_address sub_addr;
+ i2c_dev *dev =(i2c_dev *)flip->private_data;
+
+ if(_IOC_TYPE(cmd) != I2C_IOC_MAGIC) return -ENOTTY;
+ if(_IOC_NR(cmd) > I2C_IOC_MAXNR) return -ENOTTY;
+
+ if(_IOC_DIR(cmd) & _IOC_READ)
+ err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
+ else if(_IOC_DIR(cmd) & _IOC_WRITE)
+ err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
+
+ if(err)
+ return -EFAULT;
+
+ switch(cmd){
+ case I2C_IOC_SET_DEV_ADDRESS:
+ dev->addr = arg;
+ MSG2("Address : %02x\n", arg&0xff);
+ break;
+
+ case I2C_IOC_SET_SPEED:
+ if(i2c_SetSpeed(dev, arg))
+ retval = -EPERM;
+
+ break;
+
+ case I2C_IOC_GET_LAST_ERROR:
+ if(put_user(dev->last_error, (int *)arg)){
+ retval = -EFAULT;
+ break;
+ }
+
+ break;
+
+ case I2C_IOC_SET_SUB_ADDRESS:
+ if(copy_from_user(&sub_addr, (void *)arg, sizeof(sub_addr))){
+ retval = -EFAULT;
+ break;
+ }
+
+ if(sub_addr.sub_addr_len > 4){
+ retval = -EPERM;
+ break;
+ }
+
+ MSG2("Sub Address = %02x, length = %d\n",
+ sub_addr.sub_addr, sub_addr.sub_addr_len);
+
+ dev->subaddr = sub_addr.sub_addr;
+ dev->subaddr_len = sub_addr.sub_addr_len;
+
+ break;
+
+ default:
+ retval = -ENOTTY;
+ break;
+ }
+
+ return retval;
+
+}
+
+
+struct file_operations i2c_fops =
+{
+ owner: THIS_MODULE,
+ open: i2c_open,
+ release: i2c_release,
+ ioctl: i2c_ioctl,
+ read: i2c_read,
+ write: i2c_write,
+};
+
+static void i2c_module_exit(void)
+{
+ unregister_chrdev(I2C_MAJOR, "i2c");
+}
+
+static int __init i2c_module_init(void)
+{
+ int i, retval;
+
+ retval = register_chrdev(I2C_MAJOR, "i2c", &i2c_fops);
+ if(retval < 0)
+ goto failed;
+
+ printk("I2C Bus Driver has been installed successfully.\n");
+
+ return 0;
+
+failed:
+
+ i2c_module_exit();
+
+ printk("Init I2C Bus Driver failed!\n");
+
+ return retval;
+}
+
+module_init(i2c_module_init);
+module_exit(i2c_module_exit);
+
diff --git a/uClinux-2.4.20-uc1/drivers/char/w90n745_i2c.h b/uClinux-2.4.20-uc1/drivers/char/w90n745_i2c.h
index b1ab388..5ff85a8 100644
--- a/uClinux-2.4.20-uc1/drivers/char/w90n745_i2c.h
+++ b/uClinux-2.4.20-uc1/drivers/char/w90n745_i2c.h
@@ -1,123 +1,123 @@
-/****************************************************************************
- *
- * Copyright (c) 2004 - 2006 Winbond Electronics Corp. All rights reserved.
- *
- ****************************************************************************/
-
-/****************************************************************************
- *
- * FILENAME
- * w90n745_i2c.h
- *
- * VERSION
- * 1.0
- *
- * DESCRIPTION
- * Winbond W90N745 I2C Driver header
- *
- * DATA STRUCTURES
- * None
- *
- * FUNCTIONS
- * None
- *
- * HISTORY
- * 2005/05/20 Ver 1.0 Created by PC34 QFu
- *
- * REMARK
- * None
- *************************************************************************/
-#ifndef _W90N745_I2C_H_
-#define _W90N745_I2C_H_
-
-#include <linux/types.h>
-#include <linux/ioctl.h>
-
-#include <asm/arch/irqs.h>
-
-#ifdef __KERNEL__
-
-#define I2C_NUMBER 2
-
-#define I2C_FIFO_LEN 4
-#define I2C_MAX_BUF_LEN 450
-
-#define I2C0_IRQ INT_I2C0
-#define I2C1_IRQ INT_I2C1
-
-#define I2C_MAJOR 89
-#define I2C0_IO_BASE 0xfff86000
-#define I2C1_IO_BASE 0xfff86100
-#define I2C_IOMEM_SIZE 0x18
-
-#define REG_GPIO_CFG5 0xFFF83050
-#define I2C_INPUT_CLOCK 80000 /* 80 000 KHz */
-
-/* register map */
-#define CSR 0x00
-#define DIVIDER 0x04
-#define CMDR 0x08
-#define SWR 0x0c /* not available in W90n710 */
-#define RXR 0x10
-#define TXR 0x14
-
-/* bit map in CMDR */
-#define I2C_CMD_START 0x10
-#define I2C_CMD_STOP 0x08
-#define I2C_CMD_READ 0x04
-#define I2C_CMD_WRITE 0x02
-#define I2C_CMD_NACK 0x01
-
-/* for transfer use */
-#define I2C_WRITE 0x00
-#define I2C_READ 0x01
-
-
-#define I2C_STATE_NOP 0x00
-#define I2C_STATE_READ 0x01
-#define I2C_STATE_WRITE 0x02
-#define I2C_STATE_PROBE 0x03
-
-typedef struct _i2c_dev{
- int no; /* i2c bus number */
- volatile int state;
- int last_error;
- int addr;
-
- unsigned subaddr;
- int subaddr_len;
-
- unsigned char buffer[I2C_MAX_BUF_LEN];
- volatile unsigned int pos, len;
-
- wait_queue_head_t wq;
-
-}i2c_dev;
-
-#endif
-
-struct sub_address{
- char sub_addr_len;
- unsigned int sub_addr;
-};
-
-/* error code */
-#define I2C_ERR_ID (0x00)
-
-#define I2C_ERR_NOERROR (0x00)
-#define I2C_ERR_LOSTARBITRATION (0x01 | I2C_ERR_ID)
-#define I2C_ERR_BUSBUSY (0x02 | I2C_ERR_ID)
-#define I2C_ERR_NACK (0x03 | I2C_ERR_ID) /* data transfer error */
-#define I2C_ERR_SLAVENACK (0x04 | I2C_ERR_ID) /* slave not respond after address */
-
-/* define ioctl command */
-#define I2C_IOC_MAGIC 'i'
-
-#define I2C_IOC_MAXNR 3
-
-#define I2C_IOC_SET_DEV_ADDRESS _IOW(I2C_IOC_MAGIC, 0, int)
-#define I2C_IOC_SET_SUB_ADDRESS _IOW(I2C_IOC_MAGIC, 1, int)
-#define I2C_IOC_SET_SPEED _IOW(I2C_IOC_MAGIC, 2, int)
-#define I2C_IOC_GET_LAST_ERROR _IOR(I2C_IOC_MAGIC, 3, int)
-#endif
-
+/****************************************************************************
+ *
+ * Copyright (c) 2004 - 2006 Winbond Electronics Corp. All rights reserved.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FILENAME
+ * w90n745_i2c.h
+ *
+ * VERSION
+ * 1.0
+ *
+ * DESCRIPTION
+ * Winbond W90N745 I2C Driver header
+ *
+ * DATA STRUCTURES
+ * None
+ *
+ * FUNCTIONS
+ * None
+ *
+ * HISTORY
+ * 2005/05/20 Ver 1.0 Created by PC34 QFu
+ *
+ * REMARK
+ * None
+ *************************************************************************/
+#ifndef _W90N745_I2C_H_
+#define _W90N745_I2C_H_
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#include <asm/arch/irqs.h>
+
+#ifdef __KERNEL__
+
+#define I2C_NUMBER 2
+
+#define I2C_FIFO_LEN 4
+#define I2C_MAX_BUF_LEN 450
+
+#define I2C0_IRQ INT_I2C0
+#define I2C1_IRQ INT_I2C1
+
+#define I2C_MAJOR 89
+#define I2C0_IO_BASE 0xfff86000
+#define I2C1_IO_BASE 0xfff86100
+#define I2C_IOMEM_SIZE 0x18
+
+#define REG_GPIO_CFG5 0xFFF83050
+#define I2C_INPUT_CLOCK 80000 /* 80 000 KHz */
+
+/* register map */
+#define CSR 0x00
+#define DIVIDER 0x04
+#define CMDR 0x08
+#define SWR 0x0c /* not available in W90n710 */
+#define RXR 0x10
+#define TXR 0x14
+
+/* bit map in CMDR */
+#define I2C_CMD_START 0x10
+#define I2C_CMD_STOP 0x08
+#define I2C_CMD_READ 0x04
+#define I2C_CMD_WRITE 0x02
+#define I2C_CMD_NACK 0x01
+
+/* for transfer use */
+#define I2C_WRITE 0x00
+#define I2C_READ 0x01
+
+
+#define I2C_STATE_NOP 0x00
+#define I2C_STATE_READ 0x01
+#define I2C_STATE_WRITE 0x02
+#define I2C_STATE_PROBE 0x03
+
+typedef struct _i2c_dev{
+ int no; /* i2c bus number */
+ volatile int state;
+ int last_error;
+ int addr;
+
+ unsigned subaddr;
+ int subaddr_len;
+
+ unsigned char buffer[I2C_MAX_BUF_LEN];
+ volatile unsigned int pos, len;
+
+ wait_queue_head_t wq;
+
+}i2c_dev;
+
+#endif
+
+struct sub_address{
+ char sub_addr_len;
+ unsigned int sub_addr;
+};
+
+/* error code */
+#define I2C_ERR_ID (0x00)
+
+#define I2C_ERR_NOERROR (0x00)
+#define I2C_ERR_LOSTARBITRATION (0x01 | I2C_ERR_ID)
+#define I2C_ERR_BUSBUSY (0x02 | I2C_ERR_ID)
+#define I2C_ERR_NACK (0x03 | I2C_ERR_ID) /* data transfer error */
+#define I2C_ERR_SLAVENACK (0x04 | I2C_ERR_ID) /* slave not respond after address */
+
+/* define ioctl command */
+#define I2C_IOC_MAGIC 'i'
+
+#define I2C_IOC_MAXNR 3
+
+#define I2C_IOC_SET_DEV_ADDRESS _IOW(I2C_IOC_MAGIC, 0, int)
+#define I2C_IOC_SET_SUB_ADDRESS _IOW(I2C_IOC_MAGIC, 1, int)
+#define I2C_IOC_SET_SPEED _IOW(I2C_IOC_MAGIC, 2, int)
+#define I2C_IOC_GET_LAST_ERROR _IOR(I2C_IOC_MAGIC, 3, int)
+#endif
+
diff --git a/uClinux-2.4.20-uc1/drivers/char/w90n745_keypad.c b/uClinux-2.4.20-uc1/drivers/char/w90n745_keypad.c
index d350a47..9f65862 100755
--- a/uClinux-2.4.20-uc1/drivers/char/w90n745_keypad.c
+++ b/uClinux-2.4.20-uc1/drivers/char/w90n745_keypad.c
@@ -1,253 +1,253 @@
-/****************************************************************************
- * *
- * Copyright (c) 2004 - 2006 Winbond Electronics Corp. All rights reserved. *
- * *
- ****************************************************************************/
-
-/****************************************************************************
- *
- * FILENAME
- * w90n745_keypad.c
- *
- * VERSION
- * 1.0
- *
- * DESCRIPTION
- * The Winbond 64-keyboard driver
- *
- * DATA STRUCTURES
- * None
- *
- * FUNCTIONS
- * None
- *
- * HISTORY
- * 2005/09/09 Ver 1.0 Created by PC34 YHan
- *
- * REMARK
- * None
- *************************************************************************/
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <asm/errno.h>
-#include <asm/delay.h>
-//#include <asm/fcntl.h>
-#include <asm/arch/irqs.h>
-#include <linux/mm.h>
-#include <linux/poll.h>
-#include <linux/module.h>
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include "w90n745_keypad.h"
-
-#define MAJOR_NUM 192
-
-static int volatile kpd_get=0;
-static int volatile kpd_block=1;
-unsigned char DEV_NAME[10] = "Keypad";
-
-typedef struct _keymap
-{
- short row;
- short col;
-}keymap;
-
-keymap key __attribute__ ((aligned (4)));
-
-static DECLARE_WAIT_QUEUE_HEAD(read_wait_a);
-
-static void read_task_block()
-{
- DECLARE_WAITQUEUE(wait, current);
- add_wait_queue(&read_wait_a, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
-
- schedule();
-
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&read_wait_a, &wait);
-
- return ;
-}
-
-static void read_task_wake_up(void)
-{
- wake_up_interruptible(&read_wait_a);
-
- return ;
-}
-
-void keypad745_irq(int irq, void *dev_id, struct pt_regs *regs)
-{
-
- volatile unsigned int status;
- kpd_get=1;
-
- key.row = 0;
- key.col = 0;
-
- status = readl(KPISTATUS);
- #ifdef KPI_DEBUG
- printk("KPI ISR KPISTATUS=0x%08x\n",status);
- #endif
- if(status&0x00210000)
- {
- key.row = (status&0x00000078)>>3;
- key.col = (status&0x00000007);
- }
-
- if(kpd_block)
- read_task_wake_up();
-
- return;
-
-}
-
-int keypad745_open(struct inode* i,struct file* f)
-{
- int result;
- int irq;
- int old_cfg;
- kpd_block=1;
-
- if(f->f_flags & 0x800) //0x800:04000
- kpd_block=0;
-
-
- irq = INT_KEYPAD;
-
- MOD_INC_USE_COUNT;
-
- result = request_irq(irq,keypad745_irq,0,DEV_NAME,NULL);
- if(result!=0)
- printk("register the keypad_irq failed!\n");
-
- old_cfg=readl(GPIO_CFG);
- old_cfg=old_cfg&GPIO_CFG_MASK;
- old_cfg=old_cfg|GPIO_CFG_VALUE;
- writel(old_cfg,GPIO_CFG);
-
- #ifdef KPI_DEBUG
- printk("KPI OPEN:\nKPICONF=0x%08x\nGPIO_CFG=0x%08x\n",readl(KPICONF),readl(GPIO_CFG));
- #endif
-
- return 0;
-}
-
-int keypad745_close(struct inode* i,struct file* f)
-{
- MOD_DEC_USE_COUNT;
- free_irq(INT_KEYPAD,NULL);
-
- return 0;
-}
-
-
-ssize_t keypad745_read(struct file *filp, char *buff, size_t read_mode, loff_t *offp)
-{
- kpd_block = read_mode ;
-
- if(kpd_block)
- {
- read_task_block();
- }
-
- if(kpd_get)
- {
- kpd_get=0;
- copy_to_user(buff,(char*)&key,sizeof(keymap));
- key.row = 0;
- key.col = 0;
- return 1;
- }
- else
- return -1;
-}
-
-static int keypad745_ioctl(struct inode *inode, struct file *flip,
- unsigned int cmd, unsigned long arg)
-{
- int err = 0;
-
- if(_IOC_TYPE(cmd) != KEYPAD_MAGIC) return -ENOTTY;
- if(_IOC_NR(cmd) > KEYPAD_MAXNR) return -ENOTTY;
-
- if(_IOC_DIR(cmd) & _IOC_READ)
- err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
- else if(_IOC_DIR(cmd) & _IOC_WRITE)
- err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
-
- if(err)
- return -EFAULT;
-
- switch (cmd)
- {
- case KPD_BLOCK:
- kpd_block=1;
- flip->f_flags &= ~0x800;
- break;
- case KPD_NONBLOCK:
- kpd_block=0;
- flip->f_flags |= ~0x800;
-
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-struct file_operations keypad745_fops =
-{
- owner: THIS_MODULE,
- open: keypad745_open,
- read: keypad745_read,
- ioctl:keypad745_ioctl,
- release: keypad745_close,
-};
-
-static int __init keypad_745_reg(void)
-{
- int result;
- int old_cfg;
- result = register_chrdev(MAJOR_NUM,DEV_NAME,&keypad745_fops);
- if(result<0)
- {
- printk("initial the device error!\n");
- return (result);
- }
-
- old_cfg=readl(GPIO_CFG);
- old_cfg=old_cfg&GPIO_CFG_MASK;
- old_cfg=old_cfg|GPIO_CFG_VALUE;
- writel(old_cfg,GPIO_CFG);
-
- writel(0,KPICONF);
- writel(0,KPI3KCONF);
- writel(0,KPISTATUS);
-#ifdef __WB_EVB__
- old_cfg=readl(GPIO_DIR);
- old_cfg |= 0x3FF0000;
- writel(old_cfg,GPIO_DIR);
-#endif
- writel(KPICONF_VALUE,KPICONF);
-
- init_waitqueue_head(&read_wait_a);
-
- printk("W90N745 Keypad initialized successful\n");
-
- return (result);
-
-}
-
-static void keypad_745_exit(void)
-{
- unregister_chrdev(MAJOR_NUM,DEV_NAME);
-
- return;
-}
-
-module_init(keypad_745_reg);
-module_exit(keypad_745_exit);
+/****************************************************************************
+ * *
+ * Copyright (c) 2004 - 2006 Winbond Electronics Corp. All rights reserved. *
+ * *
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FILENAME
+ * w90n745_keypad.c
+ *
+ * VERSION
+ * 1.0
+ *
+ * DESCRIPTION
+ * The Winbond 64-keyboard driver
+ *
+ * DATA STRUCTURES
+ * None
+ *
+ * FUNCTIONS
+ * None
+ *
+ * HISTORY
+ * 2005/09/09 Ver 1.0 Created by PC34 YHan
+ *
+ * REMARK
+ * None
+ *************************************************************************/
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <asm/errno.h>
+#include <asm/delay.h>
+//#include <asm/fcntl.h>
+#include <asm/arch/irqs.h>
+#include <linux/mm.h>
+#include <linux/poll.h>
+#include <linux/module.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include "w90n745_keypad.h"
+
+#define MAJOR_NUM 192
+
+static int volatile kpd_get=0;
+static int volatile kpd_block=1;
+unsigned char DEV_NAME[10] = "Keypad";
+
+typedef struct _keymap
+{
+ short row;
+ short col;
+}keymap;
+
+keymap key __attribute__ ((aligned (4)));
+
+static DECLARE_WAIT_QUEUE_HEAD(read_wait_a);
+
+static void read_task_block()
+{
+ DECLARE_WAITQUEUE(wait, current);
+ add_wait_queue(&read_wait_a, &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ schedule();
+
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&read_wait_a, &wait);
+
+ return ;
+}
+
+static void read_task_wake_up(void)
+{
+ wake_up_interruptible(&read_wait_a);
+
+ return ;
+}
+
+void keypad745_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+
+ volatile unsigned int status;
+ kpd_get=1;
+
+ key.row = 0;
+ key.col = 0;
+
+ status = readl(KPISTATUS);
+ #ifdef KPI_DEBUG
+ printk("KPI ISR KPISTATUS=0x%08x\n",status);
+ #endif
+ if(status&0x00210000)
+ {
+ key.row = (status&0x00000078)>>3;
+ key.col = (status&0x00000007);
+ }
+
+ if(kpd_block)
+ read_task_wake_up();
+
+ return;
+
+}
+
+int keypad745_open(struct inode* i,struct file* f)
+{
+ int result;
+ int irq;
+ int old_cfg;
+ kpd_block=1;
+
+ if(f->f_flags & 0x800) //0x800:04000
+ kpd_block=0;
+
+
+ irq = INT_KEYPAD;
+
+ MOD_INC_USE_COUNT;
+
+ result = request_irq(irq,keypad745_irq,0,DEV_NAME,NULL);
+ if(result!=0)
+ printk("register the keypad_irq failed!\n");
+
+ old_cfg=readl(GPIO_CFG);
+ old_cfg=old_cfg&GPIO_CFG_MASK;
+ old_cfg=old_cfg|GPIO_CFG_VALUE;
+ writel(old_cfg,GPIO_CFG);
+
+ #ifdef KPI_DEBUG
+ printk("KPI OPEN:\nKPICONF=0x%08x\nGPIO_CFG=0x%08x\n",readl(KPICONF),readl(GPIO_CFG));
+ #endif
+
+ return 0;
+}
+
+int keypad745_close(struct inode* i,struct file* f)
+{
+ MOD_DEC_USE_COUNT;
+ free_irq(INT_KEYPAD,NULL);
+
+ return 0;
+}
+
+
+ssize_t keypad745_read(struct file *filp, char *buff, size_t read_mode, loff_t *offp)
+{
+ kpd_block = read_mode ;
+
+ if(kpd_block)
+ {
+ read_task_block();
+ }
+
+ if(kpd_get)
+ {
+ kpd_get=0;
+ copy_to_user(buff,(char*)&key,sizeof(keymap));
+ key.row = 0;
+ key.col = 0;
+ return 1;
+ }
+ else
+ return -1;
+}
+
+static int keypad745_ioctl(struct inode *inode, struct file *flip,
+ unsigned int cmd, unsigned long arg)
+{
+ int err = 0;
+
+ if(_IOC_TYPE(cmd) != KEYPAD_MAGIC) return -ENOTTY;
+ if(_IOC_NR(cmd) > KEYPAD_MAXNR) return -ENOTTY;
+
+ if(_IOC_DIR(cmd) & _IOC_READ)
+ err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
+ else if(_IOC_DIR(cmd) & _IOC_WRITE)
+ err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
+
+ if(err)
+ return -EFAULT;
+
+ switch (cmd)
+ {
+ case KPD_BLOCK:
+ kpd_block=1;
+ flip->f_flags &= ~0x800;
+ break;
+ case KPD_NONBLOCK:
+ kpd_block=0;
+ flip->f_flags |= ~0x800;
+
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+struct file_operations keypad745_fops =
+{
+ owner: THIS_MODULE,
+ open: keypad745_open,
+ read: keypad745_read,
+ ioctl:keypad745_ioctl,
+ release: keypad745_close,
+};
+
+static int __init keypad_745_reg(void)
+{
+ int result;
+ int old_cfg;
+ result = register_chrdev(MAJOR_NUM,DEV_NAME,&keypad745_fops);
+ if(result<0)
+ {
+ printk("initial the device error!\n");
+ return (result);
+ }
+
+ old_cfg=readl(GPIO_CFG);
+ old_cfg=old_cfg&GPIO_CFG_MASK;
+ old_cfg=old_cfg|GPIO_CFG_VALUE;
+ writel(old_cfg,GPIO_CFG);
+
+ writel(0,KPICONF);
+ writel(0,KPI3KCONF);
+ writel(0,KPISTATUS);
+#ifdef __WB_EVB__
+ old_cfg=readl(GPIO_DIR);
+ old_cfg |= 0x3FF0000;
+ writel(old_cfg,GPIO_DIR);
+#endif
+ writel(KPICONF_VALUE,KPICONF);
+
+ init_waitqueue_head(&read_wait_a);
+
+ printk("W90N745 Keypad initialized successful\n");
+
+ return (result);
+
+}
+
+static void keypad_745_exit(void)
+{
+ unregister_chrdev(MAJOR_NUM,DEV_NAME);
+
+ return;
+}
+
+module_init(keypad_745_reg);
+module_exit(keypad_745_exit);
diff --git a/uClinux-2.4.20-uc1/drivers/char/w90n745_keypad.h b/uClinux-2.4.20-uc1/drivers/char/w90n745_keypad.h
index 4395461..a3965fa 100755
--- a/uClinux-2.4.20-uc1/drivers/char/w90n745_keypad.h
+++ b/uClinux-2.4.20-uc1/drivers/char/w90n745_keypad.h
@@ -1,57 +1,57 @@
-/****************************************************************************
- *
- * Copyright (c) 2004 - 2006 Winbond Electronics Corp. All rights reserved.
- *
- ****************************************************************************/
-
-/****************************************************************************
- *
- * FILENAME
- * w90n745_keypad.h
- *
- * VERSION
- * 1.0
- *
- * DESCRIPTION
- * The winbond 64-keyboard driver header file
- *
- * DATA STRUCTURES
- * None
- *
- * FUNCTIONS
- * None
- *
- * HISTORY
- * 2005/09/09 Ver 1.0 Created by PC34 YHan
- *
- * REMARK
- * None
- *************************************************************************/
-
-#ifndef W90N745__KEYPAD_H
-#define W90N745__KEYPAD_H
-
-//#define KPI_DEBUG
-
-#define KPICONF 0xFFF88000
-#define KPI3KCONF 0xFFF88004
-#define KPILPCONF 0xFFF88008
-#define KPISTATUS 0xFFF8800C
-
-#ifdef __WB_EVB__
-#define GPIO_CFG 0xFFF83020
-#define GPIO_DIR 0xFFF83024
-#define GPIO_CFG_MASK 0xFFF00000
-#define GPIO_CFG_VALUE 0x000AAAAA
-#define KPICONF_VALUE 0x000405FA
-#endif
-
-
-
-#define KEYPAD_MAGIC 'k'
-#define KEYPAD_MAXNR 2
-
-#define KPD_BLOCK _IOW('k', 1, unsigned int)
-#define KPD_NONBLOCK _IOW('k', 2, unsigned int)
-
-#endif
+/****************************************************************************
+ *
+ * Copyright (c) 2004 - 2006 Winbond Electronics Corp. All rights reserved.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FILENAME
+ * w90n745_keypad.h
+ *
+ * VERSION
+ * 1.0
+ *
+ * DESCRIPTION
+ * The winbond 64-keyboard driver header file
+ *
+ * DATA STRUCTURES
+ * None
+ *
+ * FUNCTIONS
+ * None
+ *
+ * HISTORY
+ * 2005/09/09 Ver 1.0 Created by PC34 YHan
+ *
+ * REMARK
+ * None
+ *************************************************************************/
+
+#ifndef W90N745__KEYPAD_H
+#define W90N745__KEYPAD_H
+
+//#define KPI_DEBUG
+
+#define KPICONF 0xFFF88000
+#define KPI3KCONF 0xFFF88004
+#define KPILPCONF 0xFFF88008
+#define KPISTATUS 0xFFF8800C
+
+#ifdef __WB_EVB__
+#define GPIO_CFG 0xFFF83020
+#define GPIO_DIR 0xFFF83024
+#define GPIO_CFG_MASK 0xFFF00000
+#define GPIO_CFG_VALUE 0x000AAAAA
+#define KPICONF_VALUE 0x000405FA
+#endif
+
+
+
+#define KEYPAD_MAGIC 'k'
+#define KEYPAD_MAXNR 2
+
+#define KPD_BLOCK _IOW('k', 1, unsigned int)
+#define KPD_NONBLOCK _IOW('k', 2, unsigned int)
+
+#endif
diff --git a/uClinux-2.4.20-uc1/drivers/char/w90n745_usi.c b/uClinux-2.4.20-uc1/drivers/char/w90n745_usi.c
index a8765c4..68e7082 100755
--- a/uClinux-2.4.20-uc1/drivers/char/w90n745_usi.c
+++ b/uClinux-2.4.20-uc1/drivers/char/w90n745_usi.c
@@ -1,331 +1,331 @@
-/****************************************************************************
- *
- * Copyright (c) 2004 - 2006 Winbond Electronics Corp. All rights reserved.
- *
- ****************************************************************************/
-
-/****************************************************************************
- *
- * FILENAME
- * w90n745_usi.c
- *
- * VERSION
- * 1.0
- *
- * DESCRIPTION
- * USI driver supported for W90n710.
- *
- * FUNCTIONS
- * all functions, if they has return value, return 0 if they success, others failed.
- *
- * HISTORY
- * 2006/01/10 Created by QFu
- *
- * REMARK
- * None
- *************************************************************************/
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/time.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-
-#include <asm/arch/hardware.h>
-#include <asm/arch/irqs.h>
-
-#include <asm/uaccess.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/string.h>
-#include <asm/atomic.h>
-
-#include "w90n745_usi.h"
-
-//#define USI_DEBUG
-//#define USI_DEBUG_ENABLE_ENTER_LEAVE
-//#define USI_DEBUG_ENABLE_MSG
-//#define USI_DEBUG_ENABLE_MSG2
-
-#ifdef USI_DEBUG
-#define PDEBUG(fmt, arg...) printk(fmt, ##arg)
-#else
-#define PDEBUG(fmt, arg...)
-#endif
-
-#ifdef USI_DEBUG_ENABLE_ENTER_LEAVE
-#define ENTER() PDEBUG("[%-20s] : Enter...\n", __FUNCTION__)
-#define LEAVE() PDEBUG("[%-20s] : Leave...\n", __FUNCTION__)
-#else
-#define ENTER()
-#define LEAVE()
-#endif
-
-#ifdef USI_DEBUG_ENABLE_MSG
-#define MSG(msg) PDEBUG("[%-20s] : %s\n", __FUNCTION__, msg)
-#else
-#define MSG(msg)
-#endif
-
-#ifdef USI_DEBUG_ENABLE_MSG2
-#define MSG2(fmt, arg...) PDEBUG("[%-20s] : "fmt, __FUNCTION__, ##arg)
-#define PRNBUF(buf, count) {int i;MSG2("Data: ");for(i=0;i<count;i++)\
- PDEBUG("%02x ", buf[i]);PDEBUG("\n");}
-#else
-#define MSG2(fmt, arg...)
-#define PRNBUF(buf, count)
-#endif
-
-#define usi_inl(addr) (*((volatile u32 *)(addr)))
-#define usi_outl(val, addr) (*((volatile u32 *)(addr))=(val))
-
-
-static atomic_t usi_available = ATOMIC_INIT(1);
-static struct usi_parameter global_parameter;
-static wait_queue_head_t wq;
-static volatile int trans_finish, slave_select;
-
-void usi_deselect_slave(void)
-{
- usi_outl(usi_inl(USI_SSR)&0xc, USI_SSR);
- slave_select = 0;
-}
-
-void usi_select_slave(int x)
-{
- usi_outl((global_parameter.active_level << 2)|(1 << x), USI_SSR);
- slave_select = 1;
-}
-
-static void usi_interrupt(int irq, void * dev_id, struct pt_regs *regs)
-{
- u32 reg;
-
- ENTER();
-
- reg = usi_inl(USI_CNTRL);
-
- if (!(reg & 0x10000)) /* it not me ? */
- return;
-
- reg |= 0x10000;
- usi_outl(reg, USI_CNTRL); /* clear interrupt flag */
-
- trans_finish = 1;
-
- wake_up_interruptible(&wq);
-
- LEAVE();
-}
-
-static int usi_transit(struct usi_data *data_ptr)
-{
- u32 reg,mask;
-
- ENTER();
-
- if (slave_select == 0)
- return -ENODEV;
-
- mask = (1 << data_ptr->bit_len) - 1;
-
- MSG2("bit_len : %d, mask : %x\n", data_ptr->bit_len, mask);
-
- usi_outl(data_ptr->write_data & mask , USI_TX0); /* write data to hardware buffer */
-
- MSG2("-> %x\n", data_ptr->write_data & mask);
-
- reg = (global_parameter.sleep << 12) |
- (global_parameter.lsb << 10) |
- (data_ptr->bit_len << 3) |
- (global_parameter.tx_neg << 2) |
- (global_parameter.rx_neg << 1) | 0x20001;
-
- trans_finish = 0;
- usi_outl(reg, USI_CNTRL); /* start */
- wait_event_interruptible(wq, trans_finish != 0);
-
- data_ptr->read_data = usi_inl(USI_RX0) & mask;
-
- MSG2("<- %x\n", data_ptr->read_data & mask);
-
- LEAVE();
-
- return 0;
-
-}
-
-static int usi_ioctl(struct inode *inode, struct file *flip, unsigned int cmd, unsigned long arg)
-{
- int err = 0;
- struct usi_parameter tmp_parameter;
- struct usi_data tmp_data;
-
- ENTER();
-
- if(_IOC_TYPE(cmd) != USI_IOC_MAGIC) return -ENOTTY;
- if(_IOC_NR(cmd) > USI_IOC_MAXNR) return -ENOTTY;
-
- if(_IOC_DIR(cmd) & _IOC_READ)
- err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
- else if(_IOC_DIR(cmd) & _IOC_WRITE)
- err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
-
- if(err)
- return -EFAULT;
-
- switch(cmd) {
- case USI_IOC_GETPARAMETER:
- if (copy_to_user((void *)arg, &global_parameter,
- sizeof(struct usi_parameter)))
- return -EFAULT;
- break;
- case USI_IOC_SETPARAMETER:
- if (copy_from_user(&tmp_parameter, (void *)arg,
- sizeof(struct usi_parameter)))
- return -EFAULT;
- memcpy(&global_parameter, &tmp_parameter,
- sizeof(struct usi_parameter));
-
- usi_outl(global_parameter.divider, USI_DIVIDER); /* update clock */
-
- break;
-
- case USI_IOC_SELECTSLAVE:
- if (arg < -1 && arg > 1)
- return -EPERM;
- if (arg == -1)
- usi_deselect_slave();
- else
- usi_select_slave(arg);
- break;
-
- case USI_IOC_TRANSIT:
- if (copy_from_user(&tmp_data, (void *)arg, sizeof(tmp_data)))
- return -EFAULT;
- err = usi_transit(&tmp_data);
- if (err)
- return err;
- if (copy_to_user((void *)arg, &tmp_data, sizeof(tmp_data)))
- return -EFAULT;
- break;
-
- default:
- return -ENOTTY;
-
- }
-
- LEAVE();
-
- return 0;
-}
-
-
-static int usi_open(struct inode *inode, struct file *filp)
-{
- u32 reg;
- int retval = -EBUSY;
-
- ENTER();
-
- if (! atomic_dec_and_test (&usi_available))
- goto failed;
-
- global_parameter.active_level = 0;
- global_parameter.lsb = 0;
- global_parameter.rx_neg = 0;
- global_parameter.tx_neg = 1;
- global_parameter.divider = 0x1;
- global_parameter.sleep = 0;
- slave_select = 0;
-
- reg = usi_inl(0xFFF83050) & 0xfff00fff;
- reg |= 0xaa000;
- usi_outl(reg, 0xFFF83050);
-
- reg = usi_inl(USI_CNTRL);
- reg |= 0x20000;
- usi_outl(reg, USI_CNTRL);
-
- MSG2("GPIO 5 : %x\n", usi_inl(0xFFF83050));
-
- usi_outl(global_parameter.divider, USI_DIVIDER); /* set clock */
-
- if ((retval = request_irq(INT_SPI, usi_interrupt, SA_INTERRUPT, "usi", NULL)) < 0) {
- printk("usi : request irq error\n");
- goto failed;
- }
-
- LEAVE();
-
- return 0; /* success */
-
-failed:
-
- atomic_inc(&usi_available); /* release the device */
-
- return retval;
-}
-
-static int usi_release(struct inode *inode, struct file *flip)
-{
- u32 reg;
-
- ENTER();
-
- reg = usi_inl(USI_CNTRL);
- reg &= 0xffff;
- usi_outl(reg, USI_CNTRL);
-
- free_irq(INT_SPI, NULL);
- usi_deselect_slave();
- atomic_inc(&usi_available); /* release the device */
-
- LEAVE();
-
- return 0;
-}
-
-
-struct file_operations usi_fops =
-{
- owner: THIS_MODULE,
- open: usi_open,
- release: usi_release,
- ioctl: usi_ioctl,
-};
-
-static int __init usi_init(void)
-{
- u32 reg;
- int result;
-
- init_waitqueue_head(&wq);
-
- /* every things ok, now, we can register char device safely */
-
- result = register_chrdev(USI_MAJOR, "usi", &usi_fops);
- if( result < 0){
- unregister_chrdev(USI_MAJOR, "usi");
- printk("usi : can't get major %d\n", USI_MAJOR);
- goto failed;
- }
-
- printk("USI driver has been installed successfully!\n");
-
-failed:
-
- return result;
-
-}
-
-static void __exit usi_exit(void)
-{
- unregister_chrdev(USI_MAJOR, "usi");
-}
-
-module_init(usi_init);
-module_exit(usi_exit);
-
+/****************************************************************************
+ *
+ * Copyright (c) 2004 - 2006 Winbond Electronics Corp. All rights reserved.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FILENAME
+ * w90n745_usi.c
+ *
+ * VERSION
+ * 1.0
+ *
+ * DESCRIPTION
+ * USI driver supported for W90n710.
+ *
+ * FUNCTIONS
+ * all functions, if they has return value, return 0 if they success, others failed.
+ *
+ * HISTORY
+ * 2006/01/10 Created by QFu
+ *
+ * REMARK
+ * None
+ *************************************************************************/
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/time.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/irqs.h>
+
+#include <asm/uaccess.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/string.h>
+#include <asm/atomic.h>
+
+#include "w90n745_usi.h"
+
+//#define USI_DEBUG
+//#define USI_DEBUG_ENABLE_ENTER_LEAVE
+//#define USI_DEBUG_ENABLE_MSG
+//#define USI_DEBUG_ENABLE_MSG2
+
+#ifdef USI_DEBUG
+#define PDEBUG(fmt, arg...) printk(fmt, ##arg)
+#else
+#define PDEBUG(fmt, arg...)
+#endif
+
+#ifdef USI_DEBUG_ENABLE_ENTER_LEAVE
+#define ENTER() PDEBUG("[%-20s] : Enter...\n", __FUNCTION__)
+#define LEAVE() PDEBUG("[%-20s] : Leave...\n", __FUNCTION__)
+#else
+#define ENTER()
+#define LEAVE()
+#endif
+
+#ifdef USI_DEBUG_ENABLE_MSG
+#define MSG(msg) PDEBUG("[%-20s] : %s\n", __FUNCTION__, msg)
+#else
+#define MSG(msg)
+#endif
+
+#ifdef USI_DEBUG_ENABLE_MSG2
+#define MSG2(fmt, arg...) PDEBUG("[%-20s] : "fmt, __FUNCTION__, ##arg)
+#define PRNBUF(buf, count) {int i;MSG2("Data: ");for(i=0;i<count;i++)\
+ PDEBUG("%02x ", buf[i]);PDEBUG("\n");}
+#else
+#define MSG2(fmt, arg...)
+#define PRNBUF(buf, count)
+#endif
+
+#define usi_inl(addr) (*((volatile u32 *)(addr)))
+#define usi_outl(val, addr) (*((volatile u32 *)(addr))=(val))
+
+
+static atomic_t usi_available = ATOMIC_INIT(1);
+static struct usi_parameter global_parameter;
+static wait_queue_head_t wq;
+static volatile int trans_finish, slave_select;
+
+void usi_deselect_slave(void)
+{
+ usi_outl(usi_inl(USI_SSR)&0xc, USI_SSR);
+ slave_select = 0;
+}
+
+void usi_select_slave(int x)
+{
+ usi_outl((global_parameter.active_level << 2)|(1 << x), USI_SSR);
+ slave_select = 1;
+}
+
+static void usi_interrupt(int irq, void * dev_id, struct pt_regs *regs)
+{
+ u32 reg;
+
+ ENTER();
+
+ reg = usi_inl(USI_CNTRL);
+
+ if (!(reg & 0x10000)) /* it not me ? */
+ return;
+
+ reg |= 0x10000;
+ usi_outl(reg, USI_CNTRL); /* clear interrupt flag */
+
+ trans_finish = 1;
+
+ wake_up_interruptible(&wq);
+
+ LEAVE();
+}
+
+static int usi_transit(struct usi_data *data_ptr)
+{
+ u32 reg,mask;
+
+ ENTER();
+
+ if (slave_select == 0)
+ return -ENODEV;
+
+ mask = (1 << data_ptr->bit_len) - 1;
+
+ MSG2("bit_len : %d, mask : %x\n", data_ptr->bit_len, mask);
+
+ usi_outl(data_ptr->write_data & mask , USI_TX0); /* write data to hardware buffer */
+
+ MSG2("-> %x\n", data_ptr->write_data & mask);
+
+ reg = (global_parameter.sleep << 12) |
+ (global_parameter.lsb << 10) |
+ (data_ptr->bit_len << 3) |
+ (global_parameter.tx_neg << 2) |
+ (global_parameter.rx_neg << 1) | 0x20001;
+
+ trans_finish = 0;
+ usi_outl(reg, USI_CNTRL); /* start */
+ wait_event_interruptible(wq, trans_finish != 0);
+
+ data_ptr->read_data = usi_inl(USI_RX0) & mask;
+
+ MSG2("<- %x\n", data_ptr->read_data & mask);
+
+ LEAVE();
+
+ return 0;
+
+}
+
+static int usi_ioctl(struct inode *inode, struct file *flip, unsigned int cmd, unsigned long arg)
+{
+ int err = 0;
+ struct usi_parameter tmp_parameter;
+ struct usi_data tmp_data;
+
+ ENTER();
+
+ if(_IOC_TYPE(cmd) != USI_IOC_MAGIC) return -ENOTTY;
+ if(_IOC_NR(cmd) > USI_IOC_MAXNR) return -ENOTTY;
+
+ if(_IOC_DIR(cmd) & _IOC_READ)
+ err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
+ else if(_IOC_DIR(cmd) & _IOC_WRITE)
+ err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
+
+ if(err)
+ return -EFAULT;
+
+ switch(cmd) {
+ case USI_IOC_GETPARAMETER:
+ if (copy_to_user((void *)arg, &global_parameter,
+ sizeof(struct usi_parameter)))
+ return -EFAULT;
+ break;
+ case USI_IOC_SETPARAMETER:
+ if (copy_from_user(&tmp_parameter, (void *)arg,
+ sizeof(struct usi_parameter)))
+ return -EFAULT;
+ memcpy(&global_parameter, &tmp_parameter,
+ sizeof(struct usi_parameter));
+
+ usi_outl(global_parameter.divider, USI_DIVIDER); /* update clock */
+
+ break;
+
+ case USI_IOC_SELECTSLAVE:
+ if (arg < -1 && arg > 1)
+ return -EPERM;
+ if (arg == -1)
+ usi_deselect_slave();
+ else
+ usi_select_slave(arg);
+ break;
+
+ case USI_IOC_TRANSIT:
+ if (copy_from_user(&tmp_data, (void *)arg, sizeof(tmp_data)))
+ return -EFAULT;
+ err = usi_transit(&tmp_data);
+ if (err)
+ return err;
+ if (copy_to_user((void *)arg, &tmp_data, sizeof(tmp_data)))
+ return -EFAULT;
+ break;
+
+ default:
+ return -ENOTTY;
+
+ }
+
+ LEAVE();
+
+ return 0;
+}
+
+
+static int usi_open(struct inode *inode, struct file *filp)
+{
+ u32 reg;
+ int retval = -EBUSY;
+
+ ENTER();
+
+ if (! atomic_dec_and_test (&usi_available))
+ goto failed;
+
+ global_parameter.active_level = 0;
+ global_parameter.lsb = 0;
+ global_parameter.rx_neg = 0;
+ global_parameter.tx_neg = 1;
+ global_parameter.divider = 0x1;
+ global_parameter.sleep = 0;
+ slave_select = 0;
+
+ reg = usi_inl(0xFFF83050) & 0xfff00fff;
+ reg |= 0xaa000;
+ usi_outl(reg, 0xFFF83050);
+
+ reg = usi_inl(USI_CNTRL);
+ reg |= 0x20000;
+ usi_outl(reg, USI_CNTRL);
+
+ MSG2("GPIO 5 : %x\n", usi_inl(0xFFF83050));
+
+ usi_outl(global_parameter.divider, USI_DIVIDER); /* set clock */
+
+ if ((retval = request_irq(INT_SPI, usi_interrupt, SA_INTERRUPT, "usi", NULL)) < 0) {
+ printk("usi : request irq error\n");
+ goto failed;
+ }
+
+ LEAVE();
+
+ return 0; /* success */
+
+failed:
+
+ atomic_inc(&usi_available); /* release the device */
+
+ return retval;
+}
+
+static int usi_release(struct inode *inode, struct file *flip)
+{
+ u32 reg;
+
+ ENTER();
+
+ reg = usi_inl(USI_CNTRL);
+ reg &= 0xffff;
+ usi_outl(reg, USI_CNTRL);
+
+ free_irq(INT_SPI, NULL);
+ usi_deselect_slave();
+ atomic_inc(&usi_available); /* release the device */
+
+ LEAVE();
+
+ return 0;
+}
+
+
+struct file_operations usi_fops =
+{
+ owner: THIS_MODULE,
+ open: usi_open,
+ release: usi_release,
+ ioctl: usi_ioctl,
+};
+
+static int __init usi_init(void)
+{
+ u32 reg;
+ int result;
+
+ init_waitqueue_head(&wq);
+
+ /* every things ok, now, we can register char device safely */
+
+ result = register_chrdev(USI_MAJOR, "usi", &usi_fops);
+ if( result < 0){
+ unregister_chrdev(USI_MAJOR, "usi");
+ printk("usi : can't get major %d\n", USI_MAJOR);
+ goto failed;
+ }
+
+ printk("USI driver has been installed successfully!\n");
+
+failed:
+
+ return result;
+
+}
+
+static void __exit usi_exit(void)
+{
+ unregister_chrdev(USI_MAJOR, "usi");
+}
+
+module_init(usi_init);
+module_exit(usi_exit);
+
diff --git a/uClinux-2.4.20-uc1/drivers/char/w90n745_usi.h b/uClinux-2.4.20-uc1/drivers/char/w90n745_usi.h
index 14c8867..345ac6a 100755
--- a/uClinux-2.4.20-uc1/drivers/char/w90n745_usi.h
+++ b/uClinux-2.4.20-uc1/drivers/char/w90n745_usi.h
@@ -1,73 +1,73 @@
-/****************************************************************************
- *
- * Copyright (c) 2004 - 2006 Winbond Electronics Corp. All rights reserved.
- *
- ****************************************************************************/
-
-/****************************************************************************
- *
- * FILENAME
- * w90n745_usi.h
- *
- * VERSION
- * 1.0
- *
- * DESCRIPTION
- * USI driver supported for W90n710.
- *
- * FUNCTIONS
- * all functions, if they has return value, return 0 if they success, others failed.
- *
- * HISTORY
- * 2006/01/10 Created by QFu
- *
- * REMARK
- * None
- *************************************************************************/
-#ifndef _W90N745_USI_H_
-#define _W90N745_USI_H_
-
-#include <linux/types.h>
-#include <linux/ioctl.h>
-
-#define USI_BASE 0xfff86200
-#define USI_SIZE 0x30
-
-#define USI_CNTRL (USI_BASE | 0x00)
-#define USI_DIVIDER (USI_BASE | 0x04)
-#define USI_SSR (USI_BASE | 0x08)
-
-#define USI_RX0 (USI_BASE | 0x10)
-#define USI_RX1 (USI_BASE | 0x14)
-#define USI_RX2 (USI_BASE | 0x18)
-#define USI_RX3 (USI_BASE | 0x1c)
-
-#define USI_TX0 (USI_BASE | 0x10)
-#define USI_TX1 (USI_BASE | 0x14)
-#define USI_TX2 (USI_BASE | 0x18)
-#define USI_TX3 (USI_BASE | 0x1c)
-
-struct usi_parameter{
- unsigned int active_level:1;
- unsigned int lsb:1, tx_neg:1, rx_neg:1, divider:16;
- unsigned int sleep:4;
-};
-
-struct usi_data{
- unsigned int write_data;
- unsigned int read_data;
- unsigned int bit_len;
-};
-
-#define USI_MAJOR 231
-
-#define USI_IOC_MAGIC 'u'
-#define USI_IOC_MAXNR 3
-
-#define USI_IOC_GETPARAMETER _IOR(USI_IOC_MAGIC, 0, struct usi_parameter *)
-#define USI_IOC_SETPARAMETER _IOW(USI_IOC_MAGIC, 1, struct usi_parameter *)
-#define USI_IOC_SELECTSLAVE _IOW(USI_IOC_MAGIC, 2, int)
-#define USI_IOC_TRANSIT _IOW(USI_IOC_MAGIC, 3, struct usi_data *)
-
-#endif /* _W90N745_USI_H_ */
-
+/****************************************************************************
+ *
+ * Copyright (c) 2004 - 2006 Winbond Electronics Corp. All rights reserved.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FILENAME
+ * w90n745_usi.h
+ *
+ * VERSION
+ * 1.0
+ *
+ * DESCRIPTION
+ * USI driver supported for W90n710.
+ *
+ * FUNCTIONS
+ * all functions, if they has return value, return 0 if they success, others failed.
+ *
+ * HISTORY
+ * 2006/01/10 Created by QFu
+ *
+ * REMARK
+ * None
+ *************************************************************************/
+#ifndef _W90N745_USI_H_
+#define _W90N745_USI_H_
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define USI_BASE 0xfff86200
+#define USI_SIZE 0x30
+
+#define USI_CNTRL (USI_BASE | 0x00)
+#define USI_DIVIDER (USI_BASE | 0x04)
+#define USI_SSR (USI_BASE | 0x08)
+
+#define USI_RX0 (USI_BASE | 0x10)
+#define USI_RX1 (USI_BASE | 0x14)
+#define USI_RX2 (USI_BASE | 0x18)
+#define USI_RX3 (USI_BASE | 0x1c)
+
+#define USI_TX0 (USI_BASE | 0x10)
+#define USI_TX1 (USI_BASE | 0x14)
+#define USI_TX2 (USI_BASE | 0x18)
+#define USI_TX3 (USI_BASE | 0x1c)
+
+struct usi_parameter{
+ unsigned int active_level:1;
+ unsigned int lsb:1, tx_neg:1, rx_neg:1, divider:16;
+ unsigned int sleep:4;
+};
+
+struct usi_data{
+ unsigned int write_data;
+ unsigned int read_data;
+ unsigned int bit_len;
+};
+
+#define USI_MAJOR 231
+
+#define USI_IOC_MAGIC 'u'
+#define USI_IOC_MAXNR 3
+
+#define USI_IOC_GETPARAMETER _IOR(USI_IOC_MAGIC, 0, struct usi_parameter *)
+#define USI_IOC_SETPARAMETER _IOW(USI_IOC_MAGIC, 1, struct usi_parameter *)
+#define USI_IOC_SELECTSLAVE _IOW(USI_IOC_MAGIC, 2, int)
+#define USI_IOC_TRANSIT _IOW(USI_IOC_MAGIC, 3, struct usi_data *)
+
+#endif /* _W90N745_USI_H_ */
+
diff --git a/uClinux-2.4.20-uc1/drivers/sound/w90n745_ac97.c b/uClinux-2.4.20-uc1/drivers/sound/w90n745_ac97.c
index fb58349..297c90e 100644
--- a/uClinux-2.4.20-uc1/drivers/sound/w90n745_ac97.c
+++ b/uClinux-2.4.20-uc1/drivers/sound/w90n745_ac97.c
@@ -1,837 +1,837 @@
-/****************************************************************************
- *
- * Copyright (c) 2004 - 2007 Winbond Electronics Corp. All rights reserved.
- *
- *
- * FILENAME
- * w90n745_AC97.c
- *
- * VERSION
- * 1.2
- *
- * DESCRIPTION
- * AC97 interface for W83972D codec
- *
- * DATA STRUCTURES
- * None
- *
- * FUNCTIONS
- * ...
- *
- * HISTORY
- * 2004.06.01 Created by Yung-Chang Huang
- * 2004.09.02 Ver 1.0 Modify for w90n745 coding standard
- * 2005.11.24 Ver 1.1 Modified for uCLinux Sound Driver by PC34 QFu
- * 2006.01.17 Ver 1.2 Modified for w90n745 Version B
- *
- * REMARK
- * None
- *
- **************************************************************************/
-#include <linux/soundcard.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include "w90n745_audio_regs.h"
-#include "w90n745_audio.h"
-#include "w90n745_ac97.h"
-
-//#define AC97_DEBUG
-//#define AC97_DEBUG_ENTER_LEAVE
-//#define AC97_DEBUG_MSG
-//#define AC97_DEBUG_MSG2
-
-#ifdef AC97_DEBUG
-#define DBG(fmt, arg...) printk(fmt, ##arg)
-#else
-#define DBG(fmt, arg...)
-#endif
-
-#ifdef AC97_DEBUG_ENTER_LEAVE
-#define ENTER() DBG("[%-10s] : Enter\n", __FUNCTION__)
-#define LEAVE() DBG("[%-10s] : Leave\n", __FUNCTION__)
-#else
-#define ENTER()
-#define LEAVE()
-#endif
-
-#ifdef AC97_DEBUG_MSG
-#define MSG(fmt) DBG("[%-10s] : "fmt, __FUNCTION__)
-#else
-#define MSG(fmt)
-#endif
-
-#ifdef AC97_DEBUG_MSG2
-#define MSG2(fmt, arg...) DBG("[%-10s] : "fmt, __FUNCTION__, ##arg)
-#else
-#define MSG2(fmt, arg...)
-#endif
-
-#define AUDIO_WRITE(addr, val) writel(val, addr)
-#define AUDIO_READ(addr) readl(addr)
-
-static AUDIO_T _tAC97;
-
-static int _bAC97Active = 0;
-static volatile int _bPlayDmaToggle, _bRecDmaToggle;
-
-static void ac97StopPlay(void);
-
-struct semaphore ac97_sem;
-
-static unsigned int ac97_read_register(INT nIdx)
-{
- volatile INT nWait;
- unsigned int i;
-
- down(&ac97_sem);
-
- /* set the R_WB bit and write register index */
- AUDIO_WRITE(REG_ACTL_ACOS1, 0x80 | nIdx);
-
- /* set the valid frame bit and valid slots */
- AUDIO_WRITE(REG_ACTL_ACOS0, AUDIO_READ(REG_ACTL_ACOS0) |0x11);
-
- udelay(100);
-
- /* polling the AC_R_FINISH */
- for (nWait = 0; nWait < 0x10000; nWait++)
- {
- if (AUDIO_READ(REG_ACTL_ACCON) & AC_R_FINISH)
- break;
- }
- if (nWait == 0x10000)
- MSG("ac97_read_register time out!\n");
-
- AUDIO_WRITE(REG_ACTL_ACOS0, AUDIO_READ(REG_ACTL_ACOS0) & ~1);
-
- if (AUDIO_READ(REG_ACTL_ACIS1) >> 2 != nIdx)
- { MSG2("ac97_read_register - R_INDEX of REG_ACTL_ACIS1 not match!, 0x%x\n", AUDIO_READ(REG_ACTL_ACIS1)); }
-
- udelay(100);
- i = AUDIO_READ(REG_ACTL_ACIS2) & 0xFFFF;
-
- up(&ac97_sem);
- return (i);
-}
-
-
-static int ac97_write_register(INT nIdx, UINT16 sValue)
-{
- volatile INT nWait;
-
- down(&ac97_sem);
-
- /* clear the R_WB bit and write register index */
- AUDIO_WRITE(REG_ACTL_ACOS1, nIdx);
-
- /* write register value */
- AUDIO_WRITE(REG_ACTL_ACOS2, (UINT32)sValue);
-
- /* set the valid frame bit and valid slots */
- AUDIO_WRITE(REG_ACTL_ACOS0, AUDIO_READ(REG_ACTL_ACOS0) | 0x13);
-
- udelay(100);
-
- /* polling the AC_W_FINISH */
- for (nWait = 0; nWait < 0x10000; nWait++)
- {
- if (!(AUDIO_READ(REG_ACTL_ACCON) & AC_W_FINISH))
- break;
- }
-
- AUDIO_WRITE(REG_ACTL_ACOS0, AUDIO_READ(REG_ACTL_ACOS0) & ~3);
-
- up(&ac97_sem);
-
-
- // paraniod?
- //if (ac97_read_register(nIdx) != sValue)
- // MSG2("ac97_write_register, nIdx=0x%x, mismatch, 0x%x must be 0x%x\n", nIdx, ac97_read_register(nIdx), sValue);
-
- return 0;
-}
-
-#if 0
-static void ac97_read_all_registers()
-{
- MSG("AC97_RESET = 0x%04x\n", ac97_read_register(AC97_RESET));
- MSG("AC97_MASTER_VOLUME = 0x%04x\n", ac97_read_register(AC97_MASTER_VOLUME));
- MSG("AC97_AUX_OUT_VOLUME = 0x%04x\n", ac97_read_register(AC97_AUX_OUT_VOLUME));
- MSG("AC97_MONO_VOLUME = 0x%04x\n", ac97_read_register(AC97_MONO_VOLUME));
- MSG("AC97_MASTER_TONE = 0x%04x\n", ac97_read_register(AC97_MASTER_TONE));
- MSG("AC97_PC_BEEP_VOLUME = 0x%04x\n", ac97_read_register(AC97_PC_BEEP_VOLUME));
- MSG("AC97_PHONE_VOLUME = 0x%04x\n", ac97_read_register(AC97_PHONE_VOLUME));
- MSG("AC97_MIC_VOLUME = 0x%04x\n", ac97_read_register(AC97_MIC_VOLUME));
- MSG("AC97_LINE_IN_VOLUME = 0x%04x\n", ac97_read_register(AC97_LINE_IN_VOLUME));
- MSG("AC97_CD_VOLUME = 0x%04x\n", ac97_read_register(AC97_CD_VOLUME));
- MSG("AC97_VIDEO_VOLUME = 0x%04x\n", ac97_read_register(AC97_VIDEO_VOLUME));
- MSG("AC97_AUX_IN_VOLUME = 0x%04x\n", ac97_read_register(AC97_AUX_IN_VOLUME));
- MSG("AC97_PCM_OUT_VOLUME = 0x%04x\n", ac97_read_register(AC97_PCM_OUT_VOLUME));
- MSG("AC97_RECORD_SELECT = 0x%04x\n", ac97_read_register(AC97_RECORD_SELECT));
- MSG("AC97_RECORD_GAIN = 0x%04x\n", ac97_read_register(AC97_RECORD_GAIN));
- MSG("AC97_RECORD_GAIN_MIC = 0x%04x\n", ac97_read_register(AC97_RECORD_GAIN_MIC));
- MSG("AC97_GENERAL_PURPOSE = 0x%04x\n", ac97_read_register(AC97_GENERAL_PURPOSE));
- MSG("AC97_3D_CONTROL = 0x%04x\n", ac97_read_register(AC97_3D_CONTROL));
- MSG("AC97_AUDIO_INT_PAGING = 0x%04x\n", ac97_read_register(AC97_AUDIO_INT_PAGING));
- MSG("AC97_POWERDOWN_CTRL = 0x%04x\n", ac97_read_register(AC97_POWERDOWN_CTRL));
- MSG("AC97_FRONT_DAC_RATE = 0x%04x\n", ac97_read_register(AC97_FRONT_DAC_RATE));
-}
-#endif
-
-static void ac97_play_isr(void)
-{
- int bPlayLastBlock;
-
- ENTER();
-
- if(!(AUDIO_READ(REG_ACTL_CON) & T_DMA_IRQ))
- return;
-
- AUDIO_WRITE(REG_ACTL_CON, AUDIO_READ(REG_ACTL_CON) | T_DMA_IRQ);
-
- if (_bPlayDmaToggle == 0)
- {
- if (AUDIO_READ(REG_ACTL_PSR) & P_DMA_MIDDLE_IRQ)
- AUDIO_WRITE(REG_ACTL_PSR, P_DMA_MIDDLE_IRQ);
- else
- MSG("ac97_play_isr - miss middle!\n");
-
- _bPlayDmaToggle = 1;
-
- bPlayLastBlock = _tAC97.fnPlayCallBack(_tAC97.uPlayBufferAddr,
- _tAC97.uPlayBufferLength/2);
- }
- else
- {
- if (AUDIO_READ(REG_ACTL_PSR) & P_DMA_END_IRQ)
- AUDIO_WRITE(REG_ACTL_PSR, P_DMA_END_IRQ);
- else
- MSG("ac97_play_isr - miss end!\n");
-
- _bPlayDmaToggle = 0;
-
- bPlayLastBlock = _tAC97.fnPlayCallBack(_tAC97.uPlayBufferAddr+ _tAC97.uPlayBufferLength/ 2,
- _tAC97.uPlayBufferLength/2);
- }
-
-
- /* here, we will check whether the next buffer is ready. If not, stop play. */
- if (bPlayLastBlock)
- AUDIO_WRITE(REG_ACTL_PSR, P_DMA_MIDDLE_IRQ | P_DMA_END_IRQ);
-
-
- LEAVE();
-
-}
-
-
-static void ac97_rec_isr(void)
-{
- int bPlayLastBlock;
-
- ENTER();
-
- if(!(AUDIO_READ(REG_ACTL_CON) & R_DMA_IRQ))
- return;
-
- AUDIO_WRITE(REG_ACTL_CON, AUDIO_READ(REG_ACTL_CON) | R_DMA_IRQ);
-
- if (_bRecDmaToggle == 0)
- {
- if (AUDIO_READ(REG_ACTL_RSR) & R_DMA_MIDDLE_IRQ)
- AUDIO_WRITE(REG_ACTL_RSR, R_DMA_MIDDLE_IRQ);
- else
- MSG("ac97_rec_isr - miss middle!\n");
-
- _bRecDmaToggle = 1;
- bPlayLastBlock = _tAC97.fnRecCallBack(_tAC97.uRecordBufferAddr,
- _tAC97.uRecordBufferLength/2);
- }
- else
- {
- if (AUDIO_READ(REG_ACTL_RSR) & R_DMA_END_IRQ)
- AUDIO_WRITE(REG_ACTL_RSR, R_DMA_END_IRQ);
- else
- MSG("ac97_rec_isr - miss end!\n");
-
- _bRecDmaToggle = 0;
- bPlayLastBlock = _tAC97.fnRecCallBack(_tAC97.uRecordBufferAddr + _tAC97.uRecordBufferLength / 2,
- _tAC97.uRecordBufferLength /2);
- }
-
- if (bPlayLastBlock)
- AUDIO_WRITE(REG_ACTL_RSR, R_DMA_MIDDLE_IRQ | R_DMA_END_IRQ);
-
- LEAVE();
-}
-
-static int ac97_reset(void)
-{
- ENTER();
-
- AUDIO_WRITE(REG_CLKSEL, AUDIO_READ(REG_CLKSEL) | 0x10000);
-
- AUDIO_WRITE(0xFFF83000,0x155);//GPIO_CFG0 PT0CFG0~4
- AUDIO_WRITE(0xFFF83004,0xd);//GPIO4,1:In GPIO0,2,3:Out
-
- //AUDIO_WRITE(REG_GPIOA_OE, (AUDIO_READ(REG_GPIOA_OE) & 0xFFFFC0FF) | 0x2700);
-
- /* disable pull-high/low */
- //AUDIO_WRITE(REG_GPIOA_PE, 0x3F00);
-
- udelay(1000);
-
- _tAC97.sPlayVolume = 0x0000;
- _tAC97.sRecVolume = 0x0000;
-
- /* enable audio controller and AC-link interface */
- AUDIO_WRITE(REG_ACTL_CON, IIS_AC_PIN_SEL | AUDIO_EN | ACLINK_EN | PFIFO_EN | RFIFO_EN | T_DMA_IRQ | R_DMA_IRQ | DMA_EN);
- udelay(1000);
-
- /* reset Audio Controller */
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | ACTL_RESET_BIT);
- udelay(1000);
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~ACTL_RESET_BIT);
- udelay(1000);
-
- /* reset AC-link interface */
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | AC_RESET);
- udelay(1000);
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~AC_RESET);
- udelay(1000);
-
-
- /* cold reset AC 97 */
- AUDIO_WRITE(REG_ACTL_ACCON, AUDIO_READ(REG_ACTL_ACCON) | AC_C_RES);
- udelay(1000);
- AUDIO_WRITE(REG_ACTL_ACCON, AUDIO_READ(REG_ACTL_ACCON) & ~AC_C_RES);
- udelay(1000);
-
-
- if (!(AUDIO_READ(REG_ACTL_ACIS0) & 0x10))
- {
- MSG("Error - AC97 codec ready was not set, cold reset failed!\n");
- return ERR_AC97_CODEC_RESET;
- }
-
- udelay(100);
- //ac97_read_all_registers();
-
- /* set volumes */
-
- ac97_write_register(AC97_MASTER_VOLUME, _tAC97.sPlayVolume);
-
- ac97_write_register(AC97_MONO_VOLUME, 0x000f);
- //ac97_write_register(AC97_MASTER_TONE, 0x0303);
- ac97_write_register(AC97_MIC_VOLUME, 0x8000);
- //ac97_write_register(AC97_LINE_IN_VOLUME, 0x0707);
- //ac97_write_register(AC97_AUX_IN_VOLUME, 0x0707);
- ac97_write_register(AC97_PCM_OUT_VOLUME, _tAC97.sPlayVolume);
-
- ac97_write_register(AC97_RECORD_SELECT, 0); /* record select MIC in */
- ac97_write_register(AC97_RECORD_GAIN, 0x0404);
- ac97_write_register(AC97_RECORD_GAIN_MIC, 0x0004);
- ac97_write_register(AC97_GENERAL_PURPOSE, 0);
-
- LEAVE();
-
- return 0;
-}
-
-static VOID ac97SetPlaySampleRate(INT nSamplingRate)
-{
- ENTER();
-
- /* set play sampling rate */
- if (nSamplingRate != 48000)
- {
- /* enable VRA and set sampling frequency */
- ac97_write_register(AC97_EXT_AUDIO_CTRL, ac97_read_register(AC97_EXT_AUDIO_CTRL)|0x1);
- ac97_write_register(AC97_FRONT_DAC_RATE, nSamplingRate);
- }
-
- _tAC97.nPlaySamplingRate = nSamplingRate;
-
- LEAVE();
-}
-
-static VOID ac97SetRecordSampleRate(INT nSamplingRate)
-{
- ENTER();
-
- /* set record sampling rate */
- if (nSamplingRate != 48000)
- {
- /* enable VRA and set sampling frequency */
- ac97_write_register(AC97_EXT_AUDIO_CTRL, ac97_read_register(AC97_EXT_AUDIO_CTRL)|0x1);
- ac97_write_register(AC97_LR_ADC_RATE, nSamplingRate);
- }
-
- _tAC97.nRecSamplingRate = nSamplingRate;
-
- LEAVE();
-}
-
-static VOID ac97SetPlayCallBackFunction(AU_CB_FUN_T fnCallBack)
-{
- ENTER();
-
- _tAC97.fnPlayCallBack = fnCallBack;
-
- LEAVE();
-}
-
-static VOID ac97SetRecordCallBackFunction(AU_CB_FUN_T fnCallBack)
-{
- ENTER();
-
- _tAC97.fnRecCallBack = fnCallBack;
-
- LEAVE();
-}
-
-
-
-/*************************************************************************/
-/* */
-/* FUNCTION */
-/* ac97SetPlayVolume */
-/* */
-/* DESCRIPTION */
-/* Set AC97 left and right channel play volume. */
-/* */
-/* INPUTS */
-/* ucLeftVol play volume of left channel */
-/* ucRightVol play volume of left channel */
-/* 0: mute */
-/* 1: minimal volume */
-/* 31: maxmum volume */
-/* */
-/* OUTPUTS */
-/* None */
-/* */
-/* RETURN */
-/* 0 Success */
-/* Otherwise error */
-/* */
-/*************************************************************************/
-static int ac97SetPlayVolume(UINT32 ucLeftVol, UINT32 ucRightVol)
-{
- int nLData, nRData;
-
- ENTER();
-
- //MSG2("Set AC97 volume to : %d-%d\n", ucLeftVol, ucRightVol);
-
- if (ucLeftVol == 0)
- nLData = 0x80;
- else
- nLData = 31 - (ucLeftVol & 0x1f);
-
- if (ucRightVol == 0)
- nRData = 0x80;
- else
- nRData = 31 - (ucRightVol & 0x1f);
-
- _tAC97.sPlayVolume = (nLData << 8) | nRData;
- ac97_write_register(AC97_PCM_OUT_VOLUME, (nLData << 8) | nRData);
- //ac97_write_register(AC97_PCM_OUT_VOLUME, 0x101);
-
- if (ucLeftVol == 0)
- nLData = 0x80;
- else
- nLData = 62 - ucLeftVol*2;
-
- if (ucRightVol == 0)
- nRData = 0x80;
- else
- nRData = 62 - ucRightVol*2;
-
- ac97_write_register(AC97_AUX_OUT_VOLUME, (nLData << 8) | nRData);
- ac97_write_register(AC97_MASTER_VOLUME, (nLData << 8) | nRData);
-
- MSG2("AC97_MASTER_VOLUME = 0x%04x\r\n", ac97_read_register(AC97_MASTER_VOLUME));
- MSG2("AC97_AUX_OUT_VOLUME = 0x%04x\r\n", ac97_read_register(AC97_AUX_OUT_VOLUME));
- MSG2("AC97_PCM_OUT_VOLUME = 0x%04x\r\n", ac97_read_register(AC97_PCM_OUT_VOLUME));
-#if 0
- down(&ac97_sem);
- if (_bAC97Active & AC97_PLAY_ACTIVE)
- AUDIO_WRITE(REG_ACTL_ACOS0, 0x1f);
- else
- AUDIO_WRITE(REG_ACTL_ACOS0, 0);
- up(&ac97_sem);
-#endif
- LEAVE();
-
- return 0;
-}
-
-
-/*************************************************************************/
-/* */
-/* FUNCTION */
-/* ac97SetRecordVolume */
-/* */
-/* DESCRIPTION */
-/* Set AC97 left and right channel record volume. */
-/* */
-/* INPUTS */
-/* ucLeftVol record volume of left channel */
-/* ucRightVol record volume of left channel */
-/* 0: mute */
-/* 1: minimal volume */
-/* 31: maxmum volume */
-/* */
-/* OUTPUTS */
-/* None */
-/* */
-/* RETURN */
-/* 0 Success */
-/* Otherwise error */
-/* */
-/*************************************************************************/
-static int ac97SetRecordVolume(UINT32 ucLeftVol, UINT32 ucRightVol)
-{
- //INT nStatus;
-
- ENTER();
-
- if (ucLeftVol == 0)
- ucLeftVol = 0x80;
- else
- ucLeftVol = 32 - (ucLeftVol & 0x1f);
-
- if (ucRightVol == 0)
- ucRightVol = 0x80;
- else
- ucRightVol = 32 - (ucRightVol & 0x1f);
-
- _tAC97.sRecVolume = (ucLeftVol << 8) | ucRightVol;
-
- ac97_write_register(AC97_MIC_VOLUME, ucRightVol );
-
- //ac97_read_all_registers();
- LEAVE();
-
- return 0;
-}
-
-
-/*************************************************************************/
-/* */
-/* FUNCTION */
-/* ac97StartPlay */
-/* */
-/* DESCRIPTION */
-/* Start AC97 playback. */
-/* */
-/* INPUTS */
-/* fnCallBack client program provided callback function. The audio */
-/* driver will call back to get next block of PCM data */
-/* nSamplingRate the playback sampling rate. Supported sampling */
-/* rate are 48000, 44100, 32000, 24000, 22050, 16000, */
-/* 11025, and 8000 Hz */
-/* nChannels number of playback nChannels */
-/* 1: single channel, otherwise: double nChannels */
-/* */
-/* OUTPUTS */
-/* None */
-/* */
-/* RETURN */
-/* 0 Success */
-/* Otherwise error */
-/* */
-/*************************************************************************/
-static int ac97StartPlay(AU_CB_FUN_T fnCallBack, INT nSamplingRate, INT nChannels)
-{
- INT nStatus;
-
- ENTER();
-
- if (_bAC97Active & AC97_PLAY_ACTIVE)
- return ERR_AC97_PLAY_ACTIVE; /* AC97 was playing */
-
-
- if (_bAC97Active == 0)
- {
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) &~PLAY_LEFT_CHNNEL &~PLAY_RIGHT_CHNNEL);
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | PLAY_RIGHT_CHNNEL);
- if (nChannels != 1)
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | PLAY_LEFT_CHNNEL);
-
- nStatus = ac97_reset();
- if (nStatus < 0)
- return nStatus;
- }
-
- /* disable by Qfu , for the installation of irq has been done in wb_audio.c
- the only thing to do is to enable irq by this routine */
- Enable_Int(AU_PLAY_INT_NUM);
-
- /* set play sampling rate */
- ac97SetPlaySampleRate(nSamplingRate);
- ac97SetPlayCallBackFunction(fnCallBack);
-
- /* set DMA play destination base address */
- AUDIO_WRITE(REG_ACTL_PDSTB, _tAC97.uPlayBufferAddr);
-
- /* set DMA play buffer length */
- AUDIO_WRITE(REG_ACTL_PDST_LENGTH, _tAC97.uPlayBufferLength);
-
- /* start playing */
- MSG("AC97 start playing...\n");
- _bPlayDmaToggle = 0;
- down(&ac97_sem);
- AUDIO_WRITE(REG_ACTL_ACOS0, AUDIO_READ(REG_ACTL_ACOS0) | 0x1C);
- up(&ac97_sem);
- AUDIO_WRITE(REG_ACTL_PSR, 0x3);
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | AC_PLAY);
- _bAC97Active |= AC97_PLAY_ACTIVE;
-
- LEAVE();
-
- return 0;
-}
-
-
-/*************************************************************************/
-/* */
-/* FUNCTION */
-/* ac97StopPlay */
-/* */
-/* DESCRIPTION */
-/* Stop AC97 playback immdediately. */
-/* */
-/* INPUTS */
-/* None */
-/* */
-/* OUTPUTS */
-/* None */
-/* */
-/* RETURN */
-/* 0 Success */
-/* Otherwise error */
-/* */
-/*************************************************************************/
-static void ac97StopPlay(void)
-{
- ENTER();
-
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~(PLAY_RIGHT_CHNNEL | PLAY_LEFT_CHNNEL));
-
- if (!(_bAC97Active & AC97_PLAY_ACTIVE))
- return;
-
-
- //ac97_read_all_registers ();
-
- /* stop playing */
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~AC_PLAY);
-
- down(&ac97_sem);
- AUDIO_WRITE(REG_ACTL_ACOS0, AUDIO_READ(REG_ACTL_ACOS0) & ~0xC);
- up(&ac97_sem);
-
-
- _bAC97Active &= ~AC97_PLAY_ACTIVE;
- /* disable audio play interrupt */
- if (!_bAC97Active)
- Disable_Int(AU_PLAY_INT_NUM);
-
-
- LEAVE();
-
- return;
-}
-
-
-/*************************************************************************/
-/* */
-/* FUNCTION */
-/* ac97StartRecord */
-/* */
-/* DESCRIPTION */
-/* Start AC97 record. */
-/* */
-/* INPUTS */
-/* fnCallBack client program provided callback function. The audio */
-/* driver will call back to deliver the newly recorded */
-/* block of PCM data */
-/* nSamplingRate the record sampling rate. Supported sampling */
-/* rate are 48000, 44100, 32000, 24000, 22050, 16000, */
-/* 11025, and 8000 Hz */
-/* nChannels number of record nChannels */
-/* 1: single channel, otherwise: double nChannels */
-/* */
-/* OUTPUTS */
-/* None */
-/* */
-/* RETURN */
-/* 0 Success */
-/* Otherwise error */
-/* */
-/*************************************************************************/
-static int ac97StartRecord(AU_CB_FUN_T fnCallBack, INT nSamplingRate, INT nChannels)
-{
- INT nStatus;
- unsigned int i;
-
- ENTER();
-
- if (_bAC97Active & AC97_REC_ACTIVE)
- return ERR_AC97_REC_ACTIVE; /* AC97 was recording */
-
- if (_bAC97Active == 0)
- {
-
- nStatus = ac97_reset();
- if (nStatus < 0)
- return nStatus;
- }
-
-
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) &~RECORD_RIGHT_CHNNEL &~RECORD_LEFT_CHNNEL);
-
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | RECORD_RIGHT_CHNNEL);
- if (nChannels != 1) {
-
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | RECORD_LEFT_CHNNEL);
- }
-
-
-
-
- /* enable AC97 record interrupt */
- Enable_Int(AU_REC_INT_NUM);
-
-
-
- /* set record sampling rate */
- ac97SetRecordSampleRate(nSamplingRate);
- ac97SetRecordCallBackFunction(fnCallBack);
-
-
- /* set DMA record destination base address */
- AUDIO_WRITE(REG_ACTL_RDSTB, _tAC97.uRecordBufferAddr);
-
- /* set DMA record buffer length */
- AUDIO_WRITE(REG_ACTL_RDST_LENGTH, _tAC97.uRecordBufferLength);
-
- /* start recording */
- MSG("AC97 start recording...\n");
- _bRecDmaToggle = 0;
- AUDIO_WRITE(REG_ACTL_RSR, 0x3);
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | AC_RECORD);
- _bAC97Active |= AC97_REC_ACTIVE;
-
- LEAVE();
-
- return 0;
-}
-
-
-/*************************************************************************/
-/* */
-/* FUNCTION */
-/* ac97StopRecord */
-/* */
-/* DESCRIPTION */
-/* Stop AC97 record immediately. */
-/* */
-/* INPUTS */
-/* None */
-/* */
-/* OUTPUTS */
-/* None */
-/* */
-/* RETURN */
-/* 0 Success */
-/* Otherwise error */
-/* */
-/*************************************************************************/
-static void ac97StopRecord(void)
-{
- ENTER();
-
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~(RECORD_RIGHT_CHNNEL | RECORD_LEFT_CHNNEL));
-
- if (!(_bAC97Active & AC97_REC_ACTIVE))
- return;
-
- //ac97_read_all_registers ();
- /* stop recording */
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~AC_RECORD);
-
- _bAC97Active &= ~AC97_REC_ACTIVE;
- /* disable audio record interrupt */
- if (!_bAC97Active)
- Disable_Int(AU_PLAY_INT_NUM);
-
-
- LEAVE();
-
- return;
-}
-
-static void ac97SetPlayBuffer(UINT32 uDMABufferAddr, UINT32 uDMABufferLength)
-{
- ENTER();
-
- _tAC97.uPlayBufferAddr = uDMABufferAddr;
- _tAC97.uPlayBufferLength = uDMABufferLength;
-
- LEAVE();
-}
-
-static void ac97SetRecordBuffer(UINT32 uDMABufferAddr, UINT32 uDMABufferLength)
-{
- ENTER();
-
- _tAC97.uRecordBufferAddr = uDMABufferAddr;
- _tAC97.uRecordBufferLength = uDMABufferLength;
-
- LEAVE();
-}
-
-
-static INT ac97Init(VOID)
-{
- int nStatus = 0;
-
- ENTER();
-
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) &~PLAY_LEFT_CHNNEL &~PLAY_RIGHT_CHNNEL);
-
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) &~RECORD_LEFT_CHNNEL &~RECORD_RIGHT_CHNNEL);
-
- nStatus = ac97_reset();
- if (nStatus < 0)
- return nStatus;
-
- LEAVE();
-
- return 0;
-}
-
-static INT ac97GetCapacity(VOID)
-{
- return DSP_CAP_DUPLEX; /* support full duplex */
-}
-
-WB_AUDIO_CODEC_T wb_ac97_codec = {
- dev: AU_DEV_AC97,
- get_capacity: ac97GetCapacity,
- set_play_buffer: ac97SetPlayBuffer,
- set_record_buffer: ac97SetRecordBuffer,
- reset: ac97Init,
- start_play: ac97StartPlay,
- stop_play: ac97StopPlay,
- start_record: ac97StartRecord,
- stop_record: ac97StopRecord,
- set_play_volume: ac97SetPlayVolume,
- set_record_volume: ac97SetRecordVolume,
- play_interrupt: ac97_play_isr,
- record_interrupt: ac97_rec_isr,
-};
+/****************************************************************************
+ *
+ * Copyright (c) 2004 - 2007 Winbond Electronics Corp. All rights reserved.
+ *
+ *
+ * FILENAME
+ * w90n745_AC97.c
+ *
+ * VERSION
+ * 1.2
+ *
+ * DESCRIPTION
+ * AC97 interface for W83972D codec
+ *
+ * DATA STRUCTURES
+ * None
+ *
+ * FUNCTIONS
+ * ...
+ *
+ * HISTORY
+ * 2004.06.01 Created by Yung-Chang Huang
+ * 2004.09.02 Ver 1.0 Modify for w90n745 coding standard
+ * 2005.11.24 Ver 1.1 Modified for uCLinux Sound Driver by PC34 QFu
+ * 2006.01.17 Ver 1.2 Modified for w90n745 Version B
+ *
+ * REMARK
+ * None
+ *
+ **************************************************************************/
+#include <linux/soundcard.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include "w90n745_audio_regs.h"
+#include "w90n745_audio.h"
+#include "w90n745_ac97.h"
+
+//#define AC97_DEBUG
+//#define AC97_DEBUG_ENTER_LEAVE
+//#define AC97_DEBUG_MSG
+//#define AC97_DEBUG_MSG2
+
+#ifdef AC97_DEBUG
+#define DBG(fmt, arg...) printk(fmt, ##arg)
+#else
+#define DBG(fmt, arg...)
+#endif
+
+#ifdef AC97_DEBUG_ENTER_LEAVE
+#define ENTER() DBG("[%-10s] : Enter\n", __FUNCTION__)
+#define LEAVE() DBG("[%-10s] : Leave\n", __FUNCTION__)
+#else
+#define ENTER()
+#define LEAVE()
+#endif
+
+#ifdef AC97_DEBUG_MSG
+#define MSG(fmt) DBG("[%-10s] : "fmt, __FUNCTION__)
+#else
+#define MSG(fmt)
+#endif
+
+#ifdef AC97_DEBUG_MSG2
+#define MSG2(fmt, arg...) DBG("[%-10s] : "fmt, __FUNCTION__, ##arg)
+#else
+#define MSG2(fmt, arg...)
+#endif
+
+#define AUDIO_WRITE(addr, val) writel(val, addr)
+#define AUDIO_READ(addr) readl(addr)
+
+static AUDIO_T _tAC97;
+
+static int _bAC97Active = 0;
+static volatile int _bPlayDmaToggle, _bRecDmaToggle;
+
+static void ac97StopPlay(void);
+
+struct semaphore ac97_sem;
+
+static unsigned int ac97_read_register(INT nIdx)
+{
+ volatile INT nWait;
+ unsigned int i;
+
+ down(&ac97_sem);
+
+ /* set the R_WB bit and write register index */
+ AUDIO_WRITE(REG_ACTL_ACOS1, 0x80 | nIdx);
+
+ /* set the valid frame bit and valid slots */
+ AUDIO_WRITE(REG_ACTL_ACOS0, AUDIO_READ(REG_ACTL_ACOS0) |0x11);
+
+ udelay(100);
+
+ /* polling the AC_R_FINISH */
+ for (nWait = 0; nWait < 0x10000; nWait++)
+ {
+ if (AUDIO_READ(REG_ACTL_ACCON) & AC_R_FINISH)
+ break;
+ }
+ if (nWait == 0x10000)
+ MSG("ac97_read_register time out!\n");
+
+ AUDIO_WRITE(REG_ACTL_ACOS0, AUDIO_READ(REG_ACTL_ACOS0) & ~1);
+
+ if (AUDIO_READ(REG_ACTL_ACIS1) >> 2 != nIdx)
+ { MSG2("ac97_read_register - R_INDEX of REG_ACTL_ACIS1 not match!, 0x%x\n", AUDIO_READ(REG_ACTL_ACIS1)); }
+
+ udelay(100);
+ i = AUDIO_READ(REG_ACTL_ACIS2) & 0xFFFF;
+
+ up(&ac97_sem);
+ return (i);
+}
+
+
+static int ac97_write_register(INT nIdx, UINT16 sValue)
+{
+ volatile INT nWait;
+
+ down(&ac97_sem);
+
+ /* clear the R_WB bit and write register index */
+ AUDIO_WRITE(REG_ACTL_ACOS1, nIdx);
+
+ /* write register value */
+ AUDIO_WRITE(REG_ACTL_ACOS2, (UINT32)sValue);
+
+ /* set the valid frame bit and valid slots */
+ AUDIO_WRITE(REG_ACTL_ACOS0, AUDIO_READ(REG_ACTL_ACOS0) | 0x13);
+
+ udelay(100);
+
+ /* polling the AC_W_FINISH */
+ for (nWait = 0; nWait < 0x10000; nWait++)
+ {
+ if (!(AUDIO_READ(REG_ACTL_ACCON) & AC_W_FINISH))
+ break;
+ }
+
+ AUDIO_WRITE(REG_ACTL_ACOS0, AUDIO_READ(REG_ACTL_ACOS0) & ~3);
+
+ up(&ac97_sem);
+
+
+ // paraniod?
+ //if (ac97_read_register(nIdx) != sValue)
+ // MSG2("ac97_write_register, nIdx=0x%x, mismatch, 0x%x must be 0x%x\n", nIdx, ac97_read_register(nIdx), sValue);
+
+ return 0;
+}
+
+#if 0
+static void ac97_read_all_registers()
+{
+ MSG("AC97_RESET = 0x%04x\n", ac97_read_register(AC97_RESET));
+ MSG("AC97_MASTER_VOLUME = 0x%04x\n", ac97_read_register(AC97_MASTER_VOLUME));
+ MSG("AC97_AUX_OUT_VOLUME = 0x%04x\n", ac97_read_register(AC97_AUX_OUT_VOLUME));
+ MSG("AC97_MONO_VOLUME = 0x%04x\n", ac97_read_register(AC97_MONO_VOLUME));
+ MSG("AC97_MASTER_TONE = 0x%04x\n", ac97_read_register(AC97_MASTER_TONE));
+ MSG("AC97_PC_BEEP_VOLUME = 0x%04x\n", ac97_read_register(AC97_PC_BEEP_VOLUME));
+ MSG("AC97_PHONE_VOLUME = 0x%04x\n", ac97_read_register(AC97_PHONE_VOLUME));
+ MSG("AC97_MIC_VOLUME = 0x%04x\n", ac97_read_register(AC97_MIC_VOLUME));
+ MSG("AC97_LINE_IN_VOLUME = 0x%04x\n", ac97_read_register(AC97_LINE_IN_VOLUME));
+ MSG("AC97_CD_VOLUME = 0x%04x\n", ac97_read_register(AC97_CD_VOLUME));
+ MSG("AC97_VIDEO_VOLUME = 0x%04x\n", ac97_read_register(AC97_VIDEO_VOLUME));
+ MSG("AC97_AUX_IN_VOLUME = 0x%04x\n", ac97_read_register(AC97_AUX_IN_VOLUME));
+ MSG("AC97_PCM_OUT_VOLUME = 0x%04x\n", ac97_read_register(AC97_PCM_OUT_VOLUME));
+ MSG("AC97_RECORD_SELECT = 0x%04x\n", ac97_read_register(AC97_RECORD_SELECT));
+ MSG("AC97_RECORD_GAIN = 0x%04x\n", ac97_read_register(AC97_RECORD_GAIN));
+ MSG("AC97_RECORD_GAIN_MIC = 0x%04x\n", ac97_read_register(AC97_RECORD_GAIN_MIC));
+ MSG("AC97_GENERAL_PURPOSE = 0x%04x\n", ac97_read_register(AC97_GENERAL_PURPOSE));
+ MSG("AC97_3D_CONTROL = 0x%04x\n", ac97_read_register(AC97_3D_CONTROL));
+ MSG("AC97_AUDIO_INT_PAGING = 0x%04x\n", ac97_read_register(AC97_AUDIO_INT_PAGING));
+ MSG("AC97_POWERDOWN_CTRL = 0x%04x\n", ac97_read_register(AC97_POWERDOWN_CTRL));
+ MSG("AC97_FRONT_DAC_RATE = 0x%04x\n", ac97_read_register(AC97_FRONT_DAC_RATE));
+}
+#endif
+
+static void ac97_play_isr(void)
+{
+ int bPlayLastBlock;
+
+ ENTER();
+
+ if(!(AUDIO_READ(REG_ACTL_CON) & T_DMA_IRQ))
+ return;
+
+ AUDIO_WRITE(REG_ACTL_CON, AUDIO_READ(REG_ACTL_CON) | T_DMA_IRQ);
+
+ if (_bPlayDmaToggle == 0)
+ {
+ if (AUDIO_READ(REG_ACTL_PSR) & P_DMA_MIDDLE_IRQ)
+ AUDIO_WRITE(REG_ACTL_PSR, P_DMA_MIDDLE_IRQ);
+ else
+ MSG("ac97_play_isr - miss middle!\n");
+
+ _bPlayDmaToggle = 1;
+
+ bPlayLastBlock = _tAC97.fnPlayCallBack(_tAC97.uPlayBufferAddr,
+ _tAC97.uPlayBufferLength/2);
+ }
+ else
+ {
+ if (AUDIO_READ(REG_ACTL_PSR) & P_DMA_END_IRQ)
+ AUDIO_WRITE(REG_ACTL_PSR, P_DMA_END_IRQ);
+ else
+ MSG("ac97_play_isr - miss end!\n");
+
+ _bPlayDmaToggle = 0;
+
+ bPlayLastBlock = _tAC97.fnPlayCallBack(_tAC97.uPlayBufferAddr+ _tAC97.uPlayBufferLength/ 2,
+ _tAC97.uPlayBufferLength/2);
+ }
+
+
+ /* here, we will check whether the next buffer is ready. If not, stop play. */
+ if (bPlayLastBlock)
+ AUDIO_WRITE(REG_ACTL_PSR, P_DMA_MIDDLE_IRQ | P_DMA_END_IRQ);
+
+
+ LEAVE();
+
+}
+
+
+static void ac97_rec_isr(void)
+{
+ int bPlayLastBlock;
+
+ ENTER();
+
+ if(!(AUDIO_READ(REG_ACTL_CON) & R_DMA_IRQ))
+ return;
+
+ AUDIO_WRITE(REG_ACTL_CON, AUDIO_READ(REG_ACTL_CON) | R_DMA_IRQ);
+
+ if (_bRecDmaToggle == 0)
+ {
+ if (AUDIO_READ(REG_ACTL_RSR) & R_DMA_MIDDLE_IRQ)
+ AUDIO_WRITE(REG_ACTL_RSR, R_DMA_MIDDLE_IRQ);
+ else
+ MSG("ac97_rec_isr - miss middle!\n");
+
+ _bRecDmaToggle = 1;
+ bPlayLastBlock = _tAC97.fnRecCallBack(_tAC97.uRecordBufferAddr,
+ _tAC97.uRecordBufferLength/2);
+ }
+ else
+ {
+ if (AUDIO_READ(REG_ACTL_RSR) & R_DMA_END_IRQ)
+ AUDIO_WRITE(REG_ACTL_RSR, R_DMA_END_IRQ);
+ else
+ MSG("ac97_rec_isr - miss end!\n");
+
+ _bRecDmaToggle = 0;
+ bPlayLastBlock = _tAC97.fnRecCallBack(_tAC97.uRecordBufferAddr + _tAC97.uRecordBufferLength / 2,
+ _tAC97.uRecordBufferLength /2);
+ }
+
+ if (bPlayLastBlock)
+ AUDIO_WRITE(REG_ACTL_RSR, R_DMA_MIDDLE_IRQ | R_DMA_END_IRQ);
+
+ LEAVE();
+}
+
+static int ac97_reset(void)
+{
+ ENTER();
+
+ AUDIO_WRITE(REG_CLKSEL, AUDIO_READ(REG_CLKSEL) | 0x10000);
+
+ AUDIO_WRITE(0xFFF83000,0x155);//GPIO_CFG0 PT0CFG0~4
+ AUDIO_WRITE(0xFFF83004,0xd);//GPIO4,1:In GPIO0,2,3:Out
+
+ //AUDIO_WRITE(REG_GPIOA_OE, (AUDIO_READ(REG_GPIOA_OE) & 0xFFFFC0FF) | 0x2700);
+
+ /* disable pull-high/low */
+ //AUDIO_WRITE(REG_GPIOA_PE, 0x3F00);
+
+ udelay(1000);
+
+ _tAC97.sPlayVolume = 0x0000;
+ _tAC97.sRecVolume = 0x0000;
+
+ /* enable audio controller and AC-link interface */
+ AUDIO_WRITE(REG_ACTL_CON, IIS_AC_PIN_SEL | AUDIO_EN | ACLINK_EN | PFIFO_EN | RFIFO_EN | T_DMA_IRQ | R_DMA_IRQ | DMA_EN);
+ udelay(1000);
+
+ /* reset Audio Controller */
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | ACTL_RESET_BIT);
+ udelay(1000);
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~ACTL_RESET_BIT);
+ udelay(1000);
+
+ /* reset AC-link interface */
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | AC_RESET);
+ udelay(1000);
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~AC_RESET);
+ udelay(1000);
+
+
+ /* cold reset AC 97 */
+ AUDIO_WRITE(REG_ACTL_ACCON, AUDIO_READ(REG_ACTL_ACCON) | AC_C_RES);
+ udelay(1000);
+ AUDIO_WRITE(REG_ACTL_ACCON, AUDIO_READ(REG_ACTL_ACCON) & ~AC_C_RES);
+ udelay(1000);
+
+
+ if (!(AUDIO_READ(REG_ACTL_ACIS0) & 0x10))
+ {
+ MSG("Error - AC97 codec ready was not set, cold reset failed!\n");
+ return ERR_AC97_CODEC_RESET;
+ }
+
+ udelay(100);
+ //ac97_read_all_registers();
+
+ /* set volumes */
+
+ ac97_write_register(AC97_MASTER_VOLUME, _tAC97.sPlayVolume);
+
+ ac97_write_register(AC97_MONO_VOLUME, 0x000f);
+ //ac97_write_register(AC97_MASTER_TONE, 0x0303);
+ ac97_write_register(AC97_MIC_VOLUME, 0x8000);
+ //ac97_write_register(AC97_LINE_IN_VOLUME, 0x0707);
+ //ac97_write_register(AC97_AUX_IN_VOLUME, 0x0707);
+ ac97_write_register(AC97_PCM_OUT_VOLUME, _tAC97.sPlayVolume);
+
+ ac97_write_register(AC97_RECORD_SELECT, 0); /* record select MIC in */
+ ac97_write_register(AC97_RECORD_GAIN, 0x0404);
+ ac97_write_register(AC97_RECORD_GAIN_MIC, 0x0004);
+ ac97_write_register(AC97_GENERAL_PURPOSE, 0);
+
+ LEAVE();
+
+ return 0;
+}
+
+static VOID ac97SetPlaySampleRate(INT nSamplingRate)
+{
+ ENTER();
+
+ /* set play sampling rate */
+ if (nSamplingRate != 48000)
+ {
+ /* enable VRA and set sampling frequency */
+ ac97_write_register(AC97_EXT_AUDIO_CTRL, ac97_read_register(AC97_EXT_AUDIO_CTRL)|0x1);
+ ac97_write_register(AC97_FRONT_DAC_RATE, nSamplingRate);
+ }
+
+ _tAC97.nPlaySamplingRate = nSamplingRate;
+
+ LEAVE();
+}
+
+static VOID ac97SetRecordSampleRate(INT nSamplingRate)
+{
+ ENTER();
+
+ /* set record sampling rate */
+ if (nSamplingRate != 48000)
+ {
+ /* enable VRA and set sampling frequency */
+ ac97_write_register(AC97_EXT_AUDIO_CTRL, ac97_read_register(AC97_EXT_AUDIO_CTRL)|0x1);
+ ac97_write_register(AC97_LR_ADC_RATE, nSamplingRate);
+ }
+
+ _tAC97.nRecSamplingRate = nSamplingRate;
+
+ LEAVE();
+}
+
+static VOID ac97SetPlayCallBackFunction(AU_CB_FUN_T fnCallBack)
+{
+ ENTER();
+
+ _tAC97.fnPlayCallBack = fnCallBack;
+
+ LEAVE();
+}
+
+static VOID ac97SetRecordCallBackFunction(AU_CB_FUN_T fnCallBack)
+{
+ ENTER();
+
+ _tAC97.fnRecCallBack = fnCallBack;
+
+ LEAVE();
+}
+
+
+
+/*************************************************************************/
+/* */
+/* FUNCTION */
+/* ac97SetPlayVolume */
+/* */
+/* DESCRIPTION */
+/* Set AC97 left and right channel play volume. */
+/* */
+/* INPUTS */
+/* ucLeftVol play volume of left channel */
+/* ucRightVol play volume of left channel */
+/* 0: mute */
+/* 1: minimal volume */
+/* 31: maxmum volume */
+/* */
+/* OUTPUTS */
+/* None */
+/* */
+/* RETURN */
+/* 0 Success */
+/* Otherwise error */
+/* */
+/*************************************************************************/
+static int ac97SetPlayVolume(UINT32 ucLeftVol, UINT32 ucRightVol)
+{
+ int nLData, nRData;
+
+ ENTER();
+
+ //MSG2("Set AC97 volume to : %d-%d\n", ucLeftVol, ucRightVol);
+
+ if (ucLeftVol == 0)
+ nLData = 0x80;
+ else
+ nLData = 31 - (ucLeftVol & 0x1f);
+
+ if (ucRightVol == 0)
+ nRData = 0x80;
+ else
+ nRData = 31 - (ucRightVol & 0x1f);
+
+ _tAC97.sPlayVolume = (nLData << 8) | nRData;
+ ac97_write_register(AC97_PCM_OUT_VOLUME, (nLData << 8) | nRData);
+ //ac97_write_register(AC97_PCM_OUT_VOLUME, 0x101);
+
+ if (ucLeftVol == 0)
+ nLData = 0x80;
+ else
+ nLData = 62 - ucLeftVol*2;
+
+ if (ucRightVol == 0)
+ nRData = 0x80;
+ else
+ nRData = 62 - ucRightVol*2;
+
+ ac97_write_register(AC97_AUX_OUT_VOLUME, (nLData << 8) | nRData);
+ ac97_write_register(AC97_MASTER_VOLUME, (nLData << 8) | nRData);
+
+ MSG2("AC97_MASTER_VOLUME = 0x%04x\r\n", ac97_read_register(AC97_MASTER_VOLUME));
+ MSG2("AC97_AUX_OUT_VOLUME = 0x%04x\r\n", ac97_read_register(AC97_AUX_OUT_VOLUME));
+ MSG2("AC97_PCM_OUT_VOLUME = 0x%04x\r\n", ac97_read_register(AC97_PCM_OUT_VOLUME));
+#if 0
+ down(&ac97_sem);
+ if (_bAC97Active & AC97_PLAY_ACTIVE)
+ AUDIO_WRITE(REG_ACTL_ACOS0, 0x1f);
+ else
+ AUDIO_WRITE(REG_ACTL_ACOS0, 0);
+ up(&ac97_sem);
+#endif
+ LEAVE();
+
+ return 0;
+}
+
+
+/*************************************************************************/
+/* */
+/* FUNCTION */
+/* ac97SetRecordVolume */
+/* */
+/* DESCRIPTION */
+/* Set AC97 left and right channel record volume. */
+/* */
+/* INPUTS */
+/* ucLeftVol record volume of left channel */
+/* ucRightVol record volume of left channel */
+/* 0: mute */
+/* 1: minimal volume */
+/* 31: maxmum volume */
+/* */
+/* OUTPUTS */
+/* None */
+/* */
+/* RETURN */
+/* 0 Success */
+/* Otherwise error */
+/* */
+/*************************************************************************/
+static int ac97SetRecordVolume(UINT32 ucLeftVol, UINT32 ucRightVol)
+{
+ //INT nStatus;
+
+ ENTER();
+
+ if (ucLeftVol == 0)
+ ucLeftVol = 0x80;
+ else
+ ucLeftVol = 32 - (ucLeftVol & 0x1f);
+
+ if (ucRightVol == 0)
+ ucRightVol = 0x80;
+ else
+ ucRightVol = 32 - (ucRightVol & 0x1f);
+
+ _tAC97.sRecVolume = (ucLeftVol << 8) | ucRightVol;
+
+ ac97_write_register(AC97_MIC_VOLUME, ucRightVol );
+
+ //ac97_read_all_registers();
+ LEAVE();
+
+ return 0;
+}
+
+
+/*************************************************************************/
+/* */
+/* FUNCTION */
+/* ac97StartPlay */
+/* */
+/* DESCRIPTION */
+/* Start AC97 playback. */
+/* */
+/* INPUTS */
+/* fnCallBack client program provided callback function. The audio */
+/* driver will call back to get next block of PCM data */
+/* nSamplingRate the playback sampling rate. Supported sampling */
+/* rate are 48000, 44100, 32000, 24000, 22050, 16000, */
+/* 11025, and 8000 Hz */
+/* nChannels number of playback nChannels */
+/* 1: single channel, otherwise: double nChannels */
+/* */
+/* OUTPUTS */
+/* None */
+/* */
+/* RETURN */
+/* 0 Success */
+/* Otherwise error */
+/* */
+/*************************************************************************/
+static int ac97StartPlay(AU_CB_FUN_T fnCallBack, INT nSamplingRate, INT nChannels)
+{
+ INT nStatus;
+
+ ENTER();
+
+ if (_bAC97Active & AC97_PLAY_ACTIVE)
+ return ERR_AC97_PLAY_ACTIVE; /* AC97 was playing */
+
+
+ if (_bAC97Active == 0)
+ {
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) &~PLAY_LEFT_CHNNEL &~PLAY_RIGHT_CHNNEL);
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | PLAY_RIGHT_CHNNEL);
+ if (nChannels != 1)
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | PLAY_LEFT_CHNNEL);
+
+ nStatus = ac97_reset();
+ if (nStatus < 0)
+ return nStatus;
+ }
+
+ /* disable by Qfu , for the installation of irq has been done in wb_audio.c
+ the only thing to do is to enable irq by this routine */
+ Enable_Int(AU_PLAY_INT_NUM);
+
+ /* set play sampling rate */
+ ac97SetPlaySampleRate(nSamplingRate);
+ ac97SetPlayCallBackFunction(fnCallBack);
+
+ /* set DMA play destination base address */
+ AUDIO_WRITE(REG_ACTL_PDSTB, _tAC97.uPlayBufferAddr);
+
+ /* set DMA play buffer length */
+ AUDIO_WRITE(REG_ACTL_PDST_LENGTH, _tAC97.uPlayBufferLength);
+
+ /* start playing */
+ MSG("AC97 start playing...\n");
+ _bPlayDmaToggle = 0;
+ down(&ac97_sem);
+ AUDIO_WRITE(REG_ACTL_ACOS0, AUDIO_READ(REG_ACTL_ACOS0) | 0x1C);
+ up(&ac97_sem);
+ AUDIO_WRITE(REG_ACTL_PSR, 0x3);
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | AC_PLAY);
+ _bAC97Active |= AC97_PLAY_ACTIVE;
+
+ LEAVE();
+
+ return 0;
+}
+
+
+/*************************************************************************/
+/* */
+/* FUNCTION */
+/* ac97StopPlay */
+/* */
+/* DESCRIPTION */
+/* Stop AC97 playback immdediately. */
+/* */
+/* INPUTS */
+/* None */
+/* */
+/* OUTPUTS */
+/* None */
+/* */
+/* RETURN */
+/* 0 Success */
+/* Otherwise error */
+/* */
+/*************************************************************************/
+static void ac97StopPlay(void)
+{
+ ENTER();
+
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~(PLAY_RIGHT_CHNNEL | PLAY_LEFT_CHNNEL));
+
+ if (!(_bAC97Active & AC97_PLAY_ACTIVE))
+ return;
+
+
+ //ac97_read_all_registers ();
+
+ /* stop playing */
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~AC_PLAY);
+
+ down(&ac97_sem);
+ AUDIO_WRITE(REG_ACTL_ACOS0, AUDIO_READ(REG_ACTL_ACOS0) & ~0xC);
+ up(&ac97_sem);
+
+
+ _bAC97Active &= ~AC97_PLAY_ACTIVE;
+ /* disable audio play interrupt */
+ if (!_bAC97Active)
+ Disable_Int(AU_PLAY_INT_NUM);
+
+
+ LEAVE();
+
+ return;
+}
+
+
+/*************************************************************************/
+/* */
+/* FUNCTION */
+/* ac97StartRecord */
+/* */
+/* DESCRIPTION */
+/* Start AC97 record. */
+/* */
+/* INPUTS */
+/* fnCallBack client program provided callback function. The audio */
+/* driver will call back to deliver the newly recorded */
+/* block of PCM data */
+/* nSamplingRate the record sampling rate. Supported sampling */
+/* rate are 48000, 44100, 32000, 24000, 22050, 16000, */
+/* 11025, and 8000 Hz */
+/* nChannels number of record nChannels */
+/* 1: single channel, otherwise: double nChannels */
+/* */
+/* OUTPUTS */
+/* None */
+/* */
+/* RETURN */
+/* 0 Success */
+/* Otherwise error */
+/* */
+/*************************************************************************/
+static int ac97StartRecord(AU_CB_FUN_T fnCallBack, INT nSamplingRate, INT nChannels)
+{
+ INT nStatus;
+ unsigned int i;
+
+ ENTER();
+
+ if (_bAC97Active & AC97_REC_ACTIVE)
+ return ERR_AC97_REC_ACTIVE; /* AC97 was recording */
+
+ if (_bAC97Active == 0)
+ {
+
+ nStatus = ac97_reset();
+ if (nStatus < 0)
+ return nStatus;
+ }
+
+
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) &~RECORD_RIGHT_CHNNEL &~RECORD_LEFT_CHNNEL);
+
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | RECORD_RIGHT_CHNNEL);
+ if (nChannels != 1) {
+
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | RECORD_LEFT_CHNNEL);
+ }
+
+
+
+
+ /* enable AC97 record interrupt */
+ Enable_Int(AU_REC_INT_NUM);
+
+
+
+ /* set record sampling rate */
+ ac97SetRecordSampleRate(nSamplingRate);
+ ac97SetRecordCallBackFunction(fnCallBack);
+
+
+ /* set DMA record destination base address */
+ AUDIO_WRITE(REG_ACTL_RDSTB, _tAC97.uRecordBufferAddr);
+
+ /* set DMA record buffer length */
+ AUDIO_WRITE(REG_ACTL_RDST_LENGTH, _tAC97.uRecordBufferLength);
+
+ /* start recording */
+ MSG("AC97 start recording...\n");
+ _bRecDmaToggle = 0;
+ AUDIO_WRITE(REG_ACTL_RSR, 0x3);
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | AC_RECORD);
+ _bAC97Active |= AC97_REC_ACTIVE;
+
+ LEAVE();
+
+ return 0;
+}
+
+
+/*************************************************************************/
+/* */
+/* FUNCTION */
+/* ac97StopRecord */
+/* */
+/* DESCRIPTION */
+/* Stop AC97 record immediately. */
+/* */
+/* INPUTS */
+/* None */
+/* */
+/* OUTPUTS */
+/* None */
+/* */
+/* RETURN */
+/* 0 Success */
+/* Otherwise error */
+/* */
+/*************************************************************************/
+static void ac97StopRecord(void)
+{
+ ENTER();
+
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~(RECORD_RIGHT_CHNNEL | RECORD_LEFT_CHNNEL));
+
+ if (!(_bAC97Active & AC97_REC_ACTIVE))
+ return;
+
+ //ac97_read_all_registers ();
+ /* stop recording */
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~AC_RECORD);
+
+ _bAC97Active &= ~AC97_REC_ACTIVE;
+ /* disable audio record interrupt */
+ if (!_bAC97Active)
+ Disable_Int(AU_PLAY_INT_NUM);
+
+
+ LEAVE();
+
+ return;
+}
+
+static void ac97SetPlayBuffer(UINT32 uDMABufferAddr, UINT32 uDMABufferLength)
+{
+ ENTER();
+
+ _tAC97.uPlayBufferAddr = uDMABufferAddr;
+ _tAC97.uPlayBufferLength = uDMABufferLength;
+
+ LEAVE();
+}
+
+static void ac97SetRecordBuffer(UINT32 uDMABufferAddr, UINT32 uDMABufferLength)
+{
+ ENTER();
+
+ _tAC97.uRecordBufferAddr = uDMABufferAddr;
+ _tAC97.uRecordBufferLength = uDMABufferLength;
+
+ LEAVE();
+}
+
+
+static INT ac97Init(VOID)
+{
+ int nStatus = 0;
+
+ ENTER();
+
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) &~PLAY_LEFT_CHNNEL &~PLAY_RIGHT_CHNNEL);
+
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) &~RECORD_LEFT_CHNNEL &~RECORD_RIGHT_CHNNEL);
+
+ nStatus = ac97_reset();
+ if (nStatus < 0)
+ return nStatus;
+
+ LEAVE();
+
+ return 0;
+}
+
+static INT ac97GetCapacity(VOID)
+{
+ return DSP_CAP_DUPLEX; /* support full duplex */
+}
+
+WB_AUDIO_CODEC_T wb_ac97_codec = {
+ dev: AU_DEV_AC97,
+ get_capacity: ac97GetCapacity,
+ set_play_buffer: ac97SetPlayBuffer,
+ set_record_buffer: ac97SetRecordBuffer,
+ reset: ac97Init,
+ start_play: ac97StartPlay,
+ stop_play: ac97StopPlay,
+ start_record: ac97StartRecord,
+ stop_record: ac97StopRecord,
+ set_play_volume: ac97SetPlayVolume,
+ set_record_volume: ac97SetRecordVolume,
+ play_interrupt: ac97_play_isr,
+ record_interrupt: ac97_rec_isr,
+};
diff --git a/uClinux-2.4.20-uc1/drivers/sound/w90n745_ac97.h b/uClinux-2.4.20-uc1/drivers/sound/w90n745_ac97.h
index 96c4dc4..8919160 100644
--- a/uClinux-2.4.20-uc1/drivers/sound/w90n745_ac97.h
+++ b/uClinux-2.4.20-uc1/drivers/sound/w90n745_ac97.h
@@ -1,60 +1,60 @@
-/**************************************************************************************************
- *
- * Copyright (c) 2004 - 2007 Winbond Electronics Corp. All rights reserved.
- *
- * FILENAME
- * w90n745_AC97.h
- *
- * VERSION
- * 1.0
- *
- * DESCRIPTION
- * This file contains the register map of AC97 audio codec
- *
- * HISTORY
- * 02/09/2004 Ver 1.0 Created by PC30 YCHuang
- *
- * REMARK
- * None
- *
- *************************************************************************************************/
-#ifndef _W90N745_AC97_H_
-#define _W90N745_AC97_H_
-
-#define AC97_RESET 0x00
-#define AC97_MASTER_VOLUME 0x02
-#define AC97_AUX_OUT_VOLUME 0x04
-#define AC97_MONO_VOLUME 0x06
-#define AC97_MASTER_TONE 0x08
-#define AC97_PC_BEEP_VOLUME 0x0A
-#define AC97_PHONE_VOLUME 0x0C
-#define AC97_MIC_VOLUME 0x0E
-#define AC97_LINE_IN_VOLUME 0x10
-#define AC97_CD_VOLUME 0x12
-#define AC97_VIDEO_VOLUME 0x14
-#define AC97_AUX_IN_VOLUME 0x16
-#define AC97_PCM_OUT_VOLUME 0x18
-#define AC97_RECORD_SELECT 0x1A
-#define AC97_RECORD_GAIN 0x1C
-#define AC97_RECORD_GAIN_MIC 0x1E
-#define AC97_GENERAL_PURPOSE 0x20
-#define AC97_3D_CONTROL 0x22
-#define AC97_AUDIO_INT_PAGING 0x24
-#define AC97_POWERDOWN_CTRL 0x26
-#define AC97_EXT_AUDIO_ID 0x28
-#define AC97_EXT_AUDIO_CTRL 0x2A
-#define AC97_FRONT_DAC_RATE 0x2C
-#define AC97_LR_ADC_RATE 0x32
-#define AC97_MIC_ADC_RATE 0x34
-
-/* bit definition of ATCL_CON register */
-#define AUDCLK_EN 0x8000
-#define PFIFO_EN 0x4000
-#define RFIFO_EN 0x2000
-
-#define AC97_ACTIVE 0x1
-#define AC97_PLAY_ACTIVE 0x2
-#define AC97_REC_ACTIVE 0x4
-
-
-#endif /* _W90N745_AC97_H_ */
+/**************************************************************************************************
+ *
+ * Copyright (c) 2004 - 2007 Winbond Electronics Corp. All rights reserved.
+ *
+ * FILENAME
+ * w90n745_AC97.h
+ *
+ * VERSION
+ * 1.0
+ *
+ * DESCRIPTION
+ * This file contains the register map of AC97 audio codec
+ *
+ * HISTORY
+ * 02/09/2004 Ver 1.0 Created by PC30 YCHuang
+ *
+ * REMARK
+ * None
+ *
+ *************************************************************************************************/
+#ifndef _W90N745_AC97_H_
+#define _W90N745_AC97_H_
+
+#define AC97_RESET 0x00
+#define AC97_MASTER_VOLUME 0x02
+#define AC97_AUX_OUT_VOLUME 0x04
+#define AC97_MONO_VOLUME 0x06
+#define AC97_MASTER_TONE 0x08
+#define AC97_PC_BEEP_VOLUME 0x0A
+#define AC97_PHONE_VOLUME 0x0C
+#define AC97_MIC_VOLUME 0x0E
+#define AC97_LINE_IN_VOLUME 0x10
+#define AC97_CD_VOLUME 0x12
+#define AC97_VIDEO_VOLUME 0x14
+#define AC97_AUX_IN_VOLUME 0x16
+#define AC97_PCM_OUT_VOLUME 0x18
+#define AC97_RECORD_SELECT 0x1A
+#define AC97_RECORD_GAIN 0x1C
+#define AC97_RECORD_GAIN_MIC 0x1E
+#define AC97_GENERAL_PURPOSE 0x20
+#define AC97_3D_CONTROL 0x22
+#define AC97_AUDIO_INT_PAGING 0x24
+#define AC97_POWERDOWN_CTRL 0x26
+#define AC97_EXT_AUDIO_ID 0x28
+#define AC97_EXT_AUDIO_CTRL 0x2A
+#define AC97_FRONT_DAC_RATE 0x2C
+#define AC97_LR_ADC_RATE 0x32
+#define AC97_MIC_ADC_RATE 0x34
+
+/* bit definition of ATCL_CON register */
+#define AUDCLK_EN 0x8000
+#define PFIFO_EN 0x4000
+#define RFIFO_EN 0x2000
+
+#define AC97_ACTIVE 0x1
+#define AC97_PLAY_ACTIVE 0x2
+#define AC97_REC_ACTIVE 0x4
+
+
+#endif /* _W90N745_AC97_H_ */
diff --git a/uClinux-2.4.20-uc1/drivers/sound/w90n745_audio.h b/uClinux-2.4.20-uc1/drivers/sound/w90n745_audio.h
index 421f3d4..665143e 100644
--- a/uClinux-2.4.20-uc1/drivers/sound/w90n745_audio.h
+++ b/uClinux-2.4.20-uc1/drivers/sound/w90n745_audio.h
@@ -1,145 +1,145 @@
-/**************************************************************************************************
- *
- * Copyright (c) 2004 - 2007 Winbond Electronics Corp. All rights reserved.
- *
- * FILENAME
- * W90N745_AUDIO.H
- *
- * VERSION
- * 1.1
- *
- * DESCRIPTION
- * This file contains the main structure of w90n745 audio module
- *
- * HISTORY
- * 02/09/2004 Ver 1.0 Created by PC30 YCHuang
- * 11/25/2005 Ver 1.1 Modified by PC34 QFu
- *
- * REMARK
- * None
- *
- *************************************************************************************************/
-
-#ifndef _W90N745_AUDIO_H_
-#define _W90N745_AUDIO_H_
-
-#include <asm/arch/cdefs.h>
-#include <asm/semaphore.h>
-
-typedef int (*AU_CB_FUN_T)(UINT32, UINT32);
-
-typedef enum au_dev_e
-{
- AU_DEV_AC97,
- AU_DEV_IIS
-} AU_DEV_E;
-
-typedef struct wb_audio_codec_t{
- AU_DEV_E dev; /* codec type */
- INT (*get_capacity)(VOID);
- VOID (*set_play_buffer)(UINT32, UINT32);
- VOID (*set_record_buffer)(UINT32, UINT32);
-
- INT (*set_play_volume)(UINT32 nLeft, UINT32 nRight);
- INT (*set_record_volume)(UINT32 nLeft, UINT32 nRight);
-
- INT (*reset)(VOID);
-
- INT (*start_play)(AU_CB_FUN_T fnCallBack, INT nSamplingRate, INT nChannels);
- VOID (*stop_play)(VOID);
-
- INT (*start_record)(AU_CB_FUN_T fnCallBack, INT nSamplingRate, INT nChannels);
- VOID (*stop_record)(VOID);
-
- VOID (*play_interrupt)(VOID); /* nonzero play stopped */
- VOID (*record_interrupt)(VOID);
-}WB_AUDIO_CODEC_T;
-
-typedef struct audio_t
-{
- AU_CB_FUN_T fnPlayCallBack;
- AU_CB_FUN_T fnRecCallBack;
- INT nPlaySamplingRate;
- INT nRecSamplingRate;
- short sPlayVolume;
- short sRecVolume;
- UINT32 uPlayBufferAddr;
- UINT32 uPlayBufferLength;
- UINT32 uRecordBufferAddr;
- UINT32 uRecordBufferLength;
-}AUDIO_T;
-
-typedef struct wb_audio_t{
- int state;
- int open_flags;
- int dsp_dev, dsp_openflag;
- int mixer_dev, mixer_openflag;
- unsigned int play_buf_addr, record_buf_addr;
- unsigned int play_buf_length, record_buf_length;
- int nSamplingRate;
- int nChannels;
- int nPlayVolumeLeft, nPlayVolumeRight, nRecordVolumeLeft, nRecordVolumeRight;
-
- struct{
- int ptr;
- }play_half_buf[2], record_half_buf[2];
-
- WB_AUDIO_CODEC_T *codec;
- struct semaphore dsp_read_sem, dsp_write_sem, mixer_sem;
- struct fasync_struct *fasync_ptr;
- wait_queue_head_t write_wait_queue, read_wait_queue;
-}WB_AUDIO_T;
-
-
-
-#define AU_SAMPLE_RATE_48000 48000
-#define AU_SAMPLE_RATE_44100 44100
-#define AU_SAMPLE_RATE_32000 32000
-#define AU_SAMPLE_RATE_24000 24000
-#define AU_SAMPLE_RATE_22050 22050
-#define AU_SAMPLE_RATE_16000 16000
-#define AU_SAMPLE_RATE_11025 11025
-#define AU_SAMPLE_RATE_8000 8000
-
-#define AU_CH_MONO 1
-#define AU_CH_STEREO 2
-
-/* state code */
-#define AU_STATE_NOP 0
-#define AU_STATE_PLAYING 1
-#define AU_STATE_RECORDING 2
-
-/* capacity */
-#define AU_CAP_DUPLEX 1
-
-/* Error Code */
-#define ERR_AU_GENERAL_ERROR -1
-#define ERR_AU_NO_MEMORY -5 /* memory allocate failure */
-#define ERR_AU_ILL_BUFF_SIZE -10 /* illegal callback buffer size */
-#define ERR_AC97_CODEC_RESET -20 /* AC97 codec reset failed */
-#define ERR_AC97_PLAY_ACTIVE -22 /* AC97 playback has been activated */
-#define ERR_AC97_REC_ACTIVE -23 /* AC97 record has been activated */
-#define ERR_AC97_NO_DEVICE -24 /* have no AC97 codec on board */
-#define ERR_MA3_PLAY_ACTIVE -50 /* MA3 playback has been activated */
-#define ERR_MA3_NO_DEVICE -51 /* have no MA3 chip on board */
-#define ERR_MA5_PLAY_ACTIVE -80 /* MA5 playback has been activated */
-#define ERR_MA5_NO_DEVICE -81 /* have no MA5 chip on board */
-#define ERR_MA5I_NO_DEVICE -90 /* have no MA5i chip on board */
-#define ERR_DAC_PLAY_ACTIVE -110 /* DAC playback has been activated */
-#define ERR_DAC_NO_DEVICE -111 /* DAC is not available */
-#define ERR_ADC_REC_ACTIVE -120 /* ADC record has been activated */
-#define ERR_ADC_NO_DEVICE -121 /* ADC is not available */
-#define ERR_IIS_PLAY_ACTIVE -140 /* IIS playback has been activated */
-#define ERR_IIS_REC_ACTIVE -141 /* IIS record has been activated */
-#define ERR_IIS_NO_DEVICE -142 /* has no IIS codec on board */
-#define ERR_WM8753_NO_DEVICE -150 /* has no wm8753 codec on board */
-#define ERR_W5691_PLAY_ACTIVE -160 /* W5691 playback has been activated */
-#define ERR_W5691_NO_DEVICE -161 /* Have no W5691 chip on board */
-
-#define ERR_NO_DEVICE -201 /* audio device not available */
-
-extern WB_AUDIO_CODEC_T wb_ac97_codec;
-extern WB_AUDIO_CODEC_T wb_i2s_codec;
-
-#endif /* _W90N745_AUDIO_H_ */
-
+/**************************************************************************************************
+ *
+ * Copyright (c) 2004 - 2007 Winbond Electronics Corp. All rights reserved.
+ *
+ * FILENAME
+ * W90N745_AUDIO.H
+ *
+ * VERSION
+ * 1.1
+ *
+ * DESCRIPTION
+ * This file contains the main structure of w90n745 audio module
+ *
+ * HISTORY
+ * 02/09/2004 Ver 1.0 Created by PC30 YCHuang
+ * 11/25/2005 Ver 1.1 Modified by PC34 QFu
+ *
+ * REMARK
+ * None
+ *
+ *************************************************************************************************/
+
+#ifndef _W90N745_AUDIO_H_
+#define _W90N745_AUDIO_H_
+
+#include <asm/arch/cdefs.h>
+#include <asm/semaphore.h>
+
+typedef int (*AU_CB_FUN_T)(UINT32, UINT32);
+
+typedef enum au_dev_e
+{
+ AU_DEV_AC97,
+ AU_DEV_IIS
+} AU_DEV_E;
+
+typedef struct wb_audio_codec_t{
+ AU_DEV_E dev; /* codec type */
+ INT (*get_capacity)(VOID);
+ VOID (*set_play_buffer)(UINT32, UINT32);
+ VOID (*set_record_buffer)(UINT32, UINT32);
+
+ INT (*set_play_volume)(UINT32 nLeft, UINT32 nRight);
+ INT (*set_record_volume)(UINT32 nLeft, UINT32 nRight);
+
+ INT (*reset)(VOID);
+
+ INT (*start_play)(AU_CB_FUN_T fnCallBack, INT nSamplingRate, INT nChannels);
+ VOID (*stop_play)(VOID);
+
+ INT (*start_record)(AU_CB_FUN_T fnCallBack, INT nSamplingRate, INT nChannels);
+ VOID (*stop_record)(VOID);
+
+ VOID (*play_interrupt)(VOID); /* nonzero play stopped */
+ VOID (*record_interrupt)(VOID);
+}WB_AUDIO_CODEC_T;
+
+typedef struct audio_t
+{
+ AU_CB_FUN_T fnPlayCallBack;
+ AU_CB_FUN_T fnRecCallBack;
+ INT nPlaySamplingRate;
+ INT nRecSamplingRate;
+ short sPlayVolume;
+ short sRecVolume;
+ UINT32 uPlayBufferAddr;
+ UINT32 uPlayBufferLength;
+ UINT32 uRecordBufferAddr;
+ UINT32 uRecordBufferLength;
+}AUDIO_T;
+
+typedef struct wb_audio_t{
+ int state;
+ int open_flags;
+ int dsp_dev, dsp_openflag;
+ int mixer_dev, mixer_openflag;
+ unsigned int play_buf_addr, record_buf_addr;
+ unsigned int play_buf_length, record_buf_length;
+ int nSamplingRate;
+ int nChannels;
+ int nPlayVolumeLeft, nPlayVolumeRight, nRecordVolumeLeft, nRecordVolumeRight;
+
+ struct{
+ int ptr;
+ }play_half_buf[2], record_half_buf[2];
+
+ WB_AUDIO_CODEC_T *codec;
+ struct semaphore dsp_read_sem, dsp_write_sem, mixer_sem;
+ struct fasync_struct *fasync_ptr;
+ wait_queue_head_t write_wait_queue, read_wait_queue;
+}WB_AUDIO_T;
+
+
+
+#define AU_SAMPLE_RATE_48000 48000
+#define AU_SAMPLE_RATE_44100 44100
+#define AU_SAMPLE_RATE_32000 32000
+#define AU_SAMPLE_RATE_24000 24000
+#define AU_SAMPLE_RATE_22050 22050
+#define AU_SAMPLE_RATE_16000 16000
+#define AU_SAMPLE_RATE_11025 11025
+#define AU_SAMPLE_RATE_8000 8000
+
+#define AU_CH_MONO 1
+#define AU_CH_STEREO 2
+
+/* state code */
+#define AU_STATE_NOP 0
+#define AU_STATE_PLAYING 1
+#define AU_STATE_RECORDING 2
+
+/* capacity */
+#define AU_CAP_DUPLEX 1
+
+/* Error Code */
+#define ERR_AU_GENERAL_ERROR -1
+#define ERR_AU_NO_MEMORY -5 /* memory allocate failure */
+#define ERR_AU_ILL_BUFF_SIZE -10 /* illegal callback buffer size */
+#define ERR_AC97_CODEC_RESET -20 /* AC97 codec reset failed */
+#define ERR_AC97_PLAY_ACTIVE -22 /* AC97 playback has been activated */
+#define ERR_AC97_REC_ACTIVE -23 /* AC97 record has been activated */
+#define ERR_AC97_NO_DEVICE -24 /* have no AC97 codec on board */
+#define ERR_MA3_PLAY_ACTIVE -50 /* MA3 playback has been activated */
+#define ERR_MA3_NO_DEVICE -51 /* have no MA3 chip on board */
+#define ERR_MA5_PLAY_ACTIVE -80 /* MA5 playback has been activated */
+#define ERR_MA5_NO_DEVICE -81 /* have no MA5 chip on board */
+#define ERR_MA5I_NO_DEVICE -90 /* have no MA5i chip on board */
+#define ERR_DAC_PLAY_ACTIVE -110 /* DAC playback has been activated */
+#define ERR_DAC_NO_DEVICE -111 /* DAC is not available */
+#define ERR_ADC_REC_ACTIVE -120 /* ADC record has been activated */
+#define ERR_ADC_NO_DEVICE -121 /* ADC is not available */
+#define ERR_IIS_PLAY_ACTIVE -140 /* IIS playback has been activated */
+#define ERR_IIS_REC_ACTIVE -141 /* IIS record has been activated */
+#define ERR_IIS_NO_DEVICE -142 /* has no IIS codec on board */
+#define ERR_WM8753_NO_DEVICE -150 /* has no wm8753 codec on board */
+#define ERR_W5691_PLAY_ACTIVE -160 /* W5691 playback has been activated */
+#define ERR_W5691_NO_DEVICE -161 /* Have no W5691 chip on board */
+
+#define ERR_NO_DEVICE -201 /* audio device not available */
+
+extern WB_AUDIO_CODEC_T wb_ac97_codec;
+extern WB_AUDIO_CODEC_T wb_i2s_codec;
+
+#endif /* _W90N745_AUDIO_H_ */
+
diff --git a/uClinux-2.4.20-uc1/drivers/sound/w90n745_audio_regs.h b/uClinux-2.4.20-uc1/drivers/sound/w90n745_audio_regs.h
index abcfb64..d173c4c 100644
--- a/uClinux-2.4.20-uc1/drivers/sound/w90n745_audio_regs.h
+++ b/uClinux-2.4.20-uc1/drivers/sound/w90n745_audio_regs.h
@@ -1,199 +1,199 @@
-/**************************************************************************************************
- *
- * Copyright (c) 2004 - 2007 Winbond Electronics Corp. All rights reserved.
- *
- * FILENAME
- * w90n745_Audio_REGS.H
- *
- * VERSION
- * 1.0
- *
- * DESCRIPTION
- * This file contains the register map of W90N710 audio controller.
- *
- * HISTORY
- * 05/26/2004 Ver 1.0 Created by PC30 YCHuang
- * 11/24/2005 Ver 1.1 Modified by PC34 QFu
- *
- * REMARK
- * None
- *
- *************************************************************************************************/
-#ifndef _W90N745_AUDIO_REGS_H_
-#define _W90N745_AUDIO_REGS_H_
-
-#define REG_CLKSEL 0xfff0000c
-
-#define GPIO_BA 0xFFF83000
-/**********************************************************************************************************
- *
- * 4. GPIO Control Registers
- *
- **********************************************************************************************************/
-/* GPIO Pins */
-#define REG_GPIO_CFG (GPIO_BA+0x00) /* GPIO Pins Output Enable Control Register */
-#define REG_GPIO_DIR (GPIO_BA+0x04) /* GPIO Pins Data Register */
-#define REG_GPIO_DATAOUT (GPIO_BA+0x08) /* GPIO Pins Status Register */
-
-
-/* GPIO-A Pins */
-#define REG_GPIOA_OE (GPIO_BA+0x20) /* GPIO-A Pins Output Enable Control Register */
-#define REG_GPIOA_DAT (GPIO_BA+0x24) /* GPIO-A Pins Data Register */
-#define REG_GPIOA_STS (GPIO_BA+0x28) /* GPIO-A Pins Status Register */
-#define REG_GPIOA_PE (GPIO_BA+0x2c) /* GPIO-A Pull-Up/Down Enable Control Register */
-
-/* GPIO-B Pins */
-#define REG_GPIOB_OE (GPIO_BA+0x30) /* GPIO-B Pins Output Enable Control Register */
-#define REG_GPIOB_DAT (GPIO_BA+0x34) /* GPIO-B Pins Data Register */
-#define REG_GPIOB_STS (GPIO_BA+0x38) /* GPIO-B Pins Status Register */
-#define REG_GPIOB_PE (GPIO_BA+0x3c) /* GPIO-B Pull-Up/Down Enable Control Register */
-
-/* GPIO-S Pins */
-#define REG_GPIOS_OE (GPIO_BA+0x40) /* GPIO-S Pins Output Enable Control Register */
-#define REG_GPIOS_DAT (GPIO_BA+0x44) /* GPIO-S Pins Data Register */
-#define REG_GPIOS_STS (GPIO_BA+0x48) /* GPIO-S Pins Status Register */
-#define REG_GPIOS_PE (GPIO_BA+0x4c) /* GPIO-S Pull-Up/Down Enable Control Register */
-
-
-/* to be modified in future */
-//#include "w90n745_reg.h" /* in SYSLIB */
-#define ADO_BA 0xfff09000
-#define ADO_RANGE 0x50
-
-/**********************************************************************************************************
- *
- * 8. Audio Interface Control Registers
- *
- **********************************************************************************************************/
-#define REG_ACTL_CON (ADO_BA + 0x00) /* Audio controller control register */
-#define REG_ACTL_RESET (ADO_BA + 0x04) /* Sub block reset control register */
-#define REG_ACTL_RDSTB (ADO_BA + 0x08) /* DMA destination base address register for record */
-#define REG_ACTL_RDST_LENGTH (ADO_BA + 0x0C) /* DMA destination length register for record */
-#define REG_ACTL_RSR (ADO_BA + 0x14) /* Record status register */
-#define REG_ACTL_PDSTB (ADO_BA + 0x18) /* DMA destination base address register for play */
-#define REG_ACTL_PDST_LENGTH (ADO_BA + 0x1C) /* DMA destination length register for play */
-#define REG_ACTL_PDSTC (ADO_BA + 0x20)
-#define REG_ACTL_PSR (ADO_BA + 0x24) /* Play status register */
-#define REG_ACTL_IISCON (ADO_BA + 0x28) /* IIS control register */
-#define REG_ACTL_ACCON (ADO_BA + 0x2C) /* AC-link control register */
-#define REG_ACTL_ACOS0 (ADO_BA + 0x30) /* AC-link out slot 0 */
-#define REG_ACTL_ACOS1 (ADO_BA + 0x34) /* AC-link out slot 1 */
-#define REG_ACTL_ACOS2 (ADO_BA + 0x38) /* AC-link out slot 2 */
-#define REG_ACTL_ACIS0 (ADO_BA + 0x3C) /* AC-link in slot 0 */
-#define REG_ACTL_ACIS1 (ADO_BA + 0x40) /* AC-link in slot 1 */
-#define REG_ACTL_ACIS2 (ADO_BA + 0x44) /* AC-link in slot 2 */
-
-
-
-#define AU_PLAY_INT_NUM 6
-#define AU_REC_INT_NUM 6
-#define GPIO_INT_NUM 4
-
-#define USED_GPIO_NUM 5
-
-#define MISCR 0xC
-#define PADMFC 0x20
-#define DCCS 0x5000
-#define DEVICE_CTRL 0x5004
-
-
-/* bit definition of REG_ACTL_CON register */
-#define AUDCLK_EN 0x8000
-#define PFIFO_EN 0x4000
-#define RFIFO_EN 0x2000
-#define R_DMA_IRQ 0x1000
-#define T_DMA_IRQ 0x0800
-#define IIS_AC_PIN_SEL 0x0100
-#define FIFO_TH 0x0080
-#define DMA_EN 0x0040
-#define DAC_EN 0x0020
-#define ADC_EN 0x0010
-#define M80_EN 0x0008
-#define ACLINK_EN 0x0004
-#define IIS_EN 0x0002
-#define AUDIO_EN 0x0001
-
-/* bit definition of REG_ACTL_RESET register */
-#define W5691_PLAY 0x20000
-#define ACTL_RESET_BIT 0x10000
-#define RECORD_RIGHT_CHNNEL 0x8000
-#define RECORD_LEFT_CHNNEL 0x4000
-#define PLAY_RIGHT_CHNNEL 0x2000
-#define PLAY_LEFT_CHNNEL 0x1000
-#define DAC_PLAY 0x0800
-#define ADC_RECORD 0x0400
-#define M80_PLAY 0x0200
-#define AC_RECORD 0x0100
-#define AC_PLAY 0x0080
-#define IIS_RECORD 0x0040
-#define IIS_PLAY 0x0020
-#define DAC_RESET 0x0010
-#define ADC_RESET 0x0008
-#define M80_RESET 0x0004
-#define AC_RESET 0x0002
-#define IIS_RESET 0x0001
-
-/* bit definition of REG_ACTL_ACCON register */
-#define AC_BCLK_PU_EN 0x20
-#define AC_R_FINISH 0x10
-#define AC_W_FINISH 0x08
-#define AC_W_RES 0x04
-#define AC_C_RES 0x02
-
-/* bit definition of REG_ACTL_RSR register */
-#define R_FIFO_EMPTY 0x04
-#define R_DMA_END_IRQ 0x02
-#define R_DMA_MIDDLE_IRQ 0x01
-
-/* bit definition of REG_ACTL_PSR register */
-#define P_FIFO_EMPTY 0x04
-#define P_DMA_END_IRQ 0x02
-#define P_DMA_MIDDLE_IRQ 0x01
-
-/* bit definition of REG_ACTL_M80CON register */
-#define X86_PCM_TRANS 0x10000
-#define BITS16 0x400
-#define MA3_W5691 0x200
-#define W_IF13_ACT 0x100
-#define BUSY 0x80
-#define R_IF11_ACT 0x40
-#define R_IF10_ACT 0x20
-#define W_IF12_ACT 0x10
-#define W_IF11_ACT 0x08
-#define W_IF10_ACT 0x04
-#define SOFT_CON 0x02
-#define W_GFIFO 0x20000
-
-#define CLK_DIV 0xF800
-
-#define SOFT_CON_A0 0x0
-#define SOFT_CON_A1 0x100
-#define SOFT_CON_R 0x200
-#define SOFT_CON_W 0x400
-#define SOFT_CON_CS 0x800
-#define SOFT_CON_REQ 0x1000
-#define SOFT_CON_REL 0x2000
-
-/* bit definition of REG_ACTL_ADCON register */
-#define ADC_ZCD_EN 0x8
-#define ADC_MUTE 0x2
-
-/* bit definition of REG_ACTL_DACON register */
-#define DAC1_OEB 0x2000
-#define DAC0_OEB 0x1000
-#define DAC_ZCD_EN 0x8
-#define DAC_MUTE 0x2
-
-#define AD_DA_48000 (0x0 << 4)
-#define AD_DA_44100 (0x1 << 4)
-#define AD_DA_32000 (0x2 << 4)
-#define AD_DA_24000 (0x3 << 4)
-#define AD_DA_22050 (0x4 << 4)
-#define AD_DA_16000 (0x5 << 4)
-#define AD_DA_12000 (0x6 << 4)
-#define AD_DA_11025 (0x7 << 4)
-#define AD_DA_8000 (0x8 << 4)
-
-#endif /* _W90N745_AUDIO_REGS_H_ */
-
-
+/**************************************************************************************************
+ *
+ * Copyright (c) 2004 - 2007 Winbond Electronics Corp. All rights reserved.
+ *
+ * FILENAME
+ * w90n745_Audio_REGS.H
+ *
+ * VERSION
+ * 1.0
+ *
+ * DESCRIPTION
+ * This file contains the register map of W90N710 audio controller.
+ *
+ * HISTORY
+ * 05/26/2004 Ver 1.0 Created by PC30 YCHuang
+ * 11/24/2005 Ver 1.1 Modified by PC34 QFu
+ *
+ * REMARK
+ * None
+ *
+ *************************************************************************************************/
+#ifndef _W90N745_AUDIO_REGS_H_
+#define _W90N745_AUDIO_REGS_H_
+
+#define REG_CLKSEL 0xfff0000c
+
+#define GPIO_BA 0xFFF83000
+/**********************************************************************************************************
+ *
+ * 4. GPIO Control Registers
+ *
+ **********************************************************************************************************/
+/* GPIO Pins */
+#define REG_GPIO_CFG (GPIO_BA+0x00) /* GPIO Pins Output Enable Control Register */
+#define REG_GPIO_DIR (GPIO_BA+0x04) /* GPIO Pins Data Register */
+#define REG_GPIO_DATAOUT (GPIO_BA+0x08) /* GPIO Pins Status Register */
+
+
+/* GPIO-A Pins */
+#define REG_GPIOA_OE (GPIO_BA+0x20) /* GPIO-A Pins Output Enable Control Register */
+#define REG_GPIOA_DAT (GPIO_BA+0x24) /* GPIO-A Pins Data Register */
+#define REG_GPIOA_STS (GPIO_BA+0x28) /* GPIO-A Pins Status Register */
+#define REG_GPIOA_PE (GPIO_BA+0x2c) /* GPIO-A Pull-Up/Down Enable Control Register */
+
+/* GPIO-B Pins */
+#define REG_GPIOB_OE (GPIO_BA+0x30) /* GPIO-B Pins Output Enable Control Register */
+#define REG_GPIOB_DAT (GPIO_BA+0x34) /* GPIO-B Pins Data Register */
+#define REG_GPIOB_STS (GPIO_BA+0x38) /* GPIO-B Pins Status Register */
+#define REG_GPIOB_PE (GPIO_BA+0x3c) /* GPIO-B Pull-Up/Down Enable Control Register */
+
+/* GPIO-S Pins */
+#define REG_GPIOS_OE (GPIO_BA+0x40) /* GPIO-S Pins Output Enable Control Register */
+#define REG_GPIOS_DAT (GPIO_BA+0x44) /* GPIO-S Pins Data Register */
+#define REG_GPIOS_STS (GPIO_BA+0x48) /* GPIO-S Pins Status Register */
+#define REG_GPIOS_PE (GPIO_BA+0x4c) /* GPIO-S Pull-Up/Down Enable Control Register */
+
+
+/* to be modified in future */
+//#include "w90n745_reg.h" /* in SYSLIB */
+#define ADO_BA 0xfff09000
+#define ADO_RANGE 0x50
+
+/**********************************************************************************************************
+ *
+ * 8. Audio Interface Control Registers
+ *
+ **********************************************************************************************************/
+#define REG_ACTL_CON (ADO_BA + 0x00) /* Audio controller control register */
+#define REG_ACTL_RESET (ADO_BA + 0x04) /* Sub block reset control register */
+#define REG_ACTL_RDSTB (ADO_BA + 0x08) /* DMA destination base address register for record */
+#define REG_ACTL_RDST_LENGTH (ADO_BA + 0x0C) /* DMA destination length register for record */
+#define REG_ACTL_RSR (ADO_BA + 0x14) /* Record status register */
+#define REG_ACTL_PDSTB (ADO_BA + 0x18) /* DMA destination base address register for play */
+#define REG_ACTL_PDST_LENGTH (ADO_BA + 0x1C) /* DMA destination length register for play */
+#define REG_ACTL_PDSTC (ADO_BA + 0x20)
+#define REG_ACTL_PSR (ADO_BA + 0x24) /* Play status register */
+#define REG_ACTL_IISCON (ADO_BA + 0x28) /* IIS control register */
+#define REG_ACTL_ACCON (ADO_BA + 0x2C) /* AC-link control register */
+#define REG_ACTL_ACOS0 (ADO_BA + 0x30) /* AC-link out slot 0 */
+#define REG_ACTL_ACOS1 (ADO_BA + 0x34) /* AC-link out slot 1 */
+#define REG_ACTL_ACOS2 (ADO_BA + 0x38) /* AC-link out slot 2 */
+#define REG_ACTL_ACIS0 (ADO_BA + 0x3C) /* AC-link in slot 0 */
+#define REG_ACTL_ACIS1 (ADO_BA + 0x40) /* AC-link in slot 1 */
+#define REG_ACTL_ACIS2 (ADO_BA + 0x44) /* AC-link in slot 2 */
+
+
+
+#define AU_PLAY_INT_NUM 6
+#define AU_REC_INT_NUM 6
+#define GPIO_INT_NUM 4
+
+#define USED_GPIO_NUM 5
+
+#define MISCR 0xC
+#define PADMFC 0x20
+#define DCCS 0x5000
+#define DEVICE_CTRL 0x5004
+
+
+/* bit definition of REG_ACTL_CON register */
+#define AUDCLK_EN 0x8000
+#define PFIFO_EN 0x4000
+#define RFIFO_EN 0x2000
+#define R_DMA_IRQ 0x1000
+#define T_DMA_IRQ 0x0800
+#define IIS_AC_PIN_SEL 0x0100
+#define FIFO_TH 0x0080
+#define DMA_EN 0x0040
+#define DAC_EN 0x0020
+#define ADC_EN 0x0010
+#define M80_EN 0x0008
+#define ACLINK_EN 0x0004
+#define IIS_EN 0x0002
+#define AUDIO_EN 0x0001
+
+/* bit definition of REG_ACTL_RESET register */
+#define W5691_PLAY 0x20000
+#define ACTL_RESET_BIT 0x10000
+#define RECORD_RIGHT_CHNNEL 0x8000
+#define RECORD_LEFT_CHNNEL 0x4000
+#define PLAY_RIGHT_CHNNEL 0x2000
+#define PLAY_LEFT_CHNNEL 0x1000
+#define DAC_PLAY 0x0800
+#define ADC_RECORD 0x0400
+#define M80_PLAY 0x0200
+#define AC_RECORD 0x0100
+#define AC_PLAY 0x0080
+#define IIS_RECORD 0x0040
+#define IIS_PLAY 0x0020
+#define DAC_RESET 0x0010
+#define ADC_RESET 0x0008
+#define M80_RESET 0x0004
+#define AC_RESET 0x0002
+#define IIS_RESET 0x0001
+
+/* bit definition of REG_ACTL_ACCON register */
+#define AC_BCLK_PU_EN 0x20
+#define AC_R_FINISH 0x10
+#define AC_W_FINISH 0x08
+#define AC_W_RES 0x04
+#define AC_C_RES 0x02
+
+/* bit definition of REG_ACTL_RSR register */
+#define R_FIFO_EMPTY 0x04
+#define R_DMA_END_IRQ 0x02
+#define R_DMA_MIDDLE_IRQ 0x01
+
+/* bit definition of REG_ACTL_PSR register */
+#define P_FIFO_EMPTY 0x04
+#define P_DMA_END_IRQ 0x02
+#define P_DMA_MIDDLE_IRQ 0x01
+
+/* bit definition of REG_ACTL_M80CON register */
+#define X86_PCM_TRANS 0x10000
+#define BITS16 0x400
+#define MA3_W5691 0x200
+#define W_IF13_ACT 0x100
+#define BUSY 0x80
+#define R_IF11_ACT 0x40
+#define R_IF10_ACT 0x20
+#define W_IF12_ACT 0x10
+#define W_IF11_ACT 0x08
+#define W_IF10_ACT 0x04
+#define SOFT_CON 0x02
+#define W_GFIFO 0x20000
+
+#define CLK_DIV 0xF800
+
+#define SOFT_CON_A0 0x0
+#define SOFT_CON_A1 0x100
+#define SOFT_CON_R 0x200
+#define SOFT_CON_W 0x400
+#define SOFT_CON_CS 0x800
+#define SOFT_CON_REQ 0x1000
+#define SOFT_CON_REL 0x2000
+
+/* bit definition of REG_ACTL_ADCON register */
+#define ADC_ZCD_EN 0x8
+#define ADC_MUTE 0x2
+
+/* bit definition of REG_ACTL_DACON register */
+#define DAC1_OEB 0x2000
+#define DAC0_OEB 0x1000
+#define DAC_ZCD_EN 0x8
+#define DAC_MUTE 0x2
+
+#define AD_DA_48000 (0x0 << 4)
+#define AD_DA_44100 (0x1 << 4)
+#define AD_DA_32000 (0x2 << 4)
+#define AD_DA_24000 (0x3 << 4)
+#define AD_DA_22050 (0x4 << 4)
+#define AD_DA_16000 (0x5 << 4)
+#define AD_DA_12000 (0x6 << 4)
+#define AD_DA_11025 (0x7 << 4)
+#define AD_DA_8000 (0x8 << 4)
+
+#endif /* _W90N745_AUDIO_REGS_H_ */
+
+
diff --git a/uClinux-2.4.20-uc1/drivers/sound/w90n745_i2s.c b/uClinux-2.4.20-uc1/drivers/sound/w90n745_i2s.c
index 87cc6a9..3e31e20 100644
--- a/uClinux-2.4.20-uc1/drivers/sound/w90n745_i2s.c
+++ b/uClinux-2.4.20-uc1/drivers/sound/w90n745_i2s.c
@@ -1,677 +1,677 @@
-/****************************************************************************
- *
- * Copyright (c) 2004 - 2007 Winbond Electronics Corp. All rights reserved.
- *
- *
- * FILENAME
- * w90n745_I2S.c
- *
- * VERSION
- * 1.0
- *
- * DESCRIPTION
- * IIS for PCM3003E codec
- *
- * DATA STRUCTURES
- * None
- *
- * FUNCTIONS
- *
- * HISTORY
- * 2004.07.16 Created by Shih-Jen Lu
- * 2005.11.24 Modified by PC34 QFu
- *
- * REMARK
- * None
- *
- **************************************************************************/
-#include <linux/soundcard.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include "w90n745_audio_regs.h"
-#include "w90n745_audio.h"
-
-#include "w90n745_i2s.h"
-
-//#define I2S_DEBUG
-//#define I2S_DEBUG_ENTER_LEAVE
-//#define I2S_DEBUG_MSG
-//#define I2S_DEBUG_MSG2
-
-
-#ifdef I2S_DEBUG
-#define DBG(fmt, arg...) printk(fmt, ##arg)
-#else
-#define DBG(fmt, arg...)
-#endif
-
-#ifdef I2S_DEBUG_ENTER_LEAVE
-#define ENTER() DBG("[%-10s] : Enter\n", __FUNCTION__)
-#define LEAVE() DBG("[%-10s] : Leave\n", __FUNCTION__)
-#else
-#define ENTER()
-#define LEAVE()
-#endif
-
-#ifdef I2S_DEBUG_MSG
-#define MSG(fmt) DBG("[%-10s] : "fmt, __FUNCTION__)
-#else
-#define MSG(fmt)
-#endif
-
-#ifdef I2S_DEBUG_MSG2
-#define MSG2(fmt, arg...) DBG("[%-10s] : "fmt, __FUNCTION__, ##arg)
-#else
-#define MSG2(fmt, arg...)
-#endif
-
-static AUDIO_T _tIIS;
-
-#define AUDIO_WRITE(addr, val) writel(val, addr)
-#define AUDIO_READ(addr) readl(addr)
-
-#define Delay(time) udelay(time * 10)
-
-#define MSB_FORMAT 1
-#define IIS_FORMAT 2
-
-static int _bIISActive = 0;
-static UINT32 _uIISCR = 0;
-
-#define WMDEVID 0
-
-#define UINT8 unsigned char
-
-/*----- set data format -----*/
-static void IIS_Set_Data_Format(int choose_format)
-{
-
- ENTER();
-
- switch(choose_format){
- case IIS_FORMAT: _uIISCR = _uIISCR | IIS;
- break;
- case MSB_FORMAT: _uIISCR = _uIISCR | MSB_Justified;
- break;
- default:break;
- }
- AUDIO_WRITE(REG_ACTL_IISCON,_uIISCR);
-
- LEAVE();
-}
-
-/*----- set sample Frequency -----*/
-static void IIS_Set_Sample_Frequency(int choose_sf)
-{
-
- ENTER();
-
- switch (choose_sf)
- {
- case AU_SAMPLE_RATE_8000: //8KHz
- _uIISCR = _uIISCR | FS_256 | SCALE_4 | BCLK_48;
-
- break;
- case AU_SAMPLE_RATE_11025: //11.025KHz
- _uIISCR = _uIISCR | FS_256 | SCALE_4 | BCLK_48;
-
- break;
- case AU_SAMPLE_RATE_16000: //16KHz
- _uIISCR = _uIISCR | FS_256 | SCALE_2 | BCLK_48;
-
- break;
- case AU_SAMPLE_RATE_22050: //22.05KHz
- _uIISCR = _uIISCR | FS_256 | SCALE_3 | BCLK_32;
-
- break;
- case AU_SAMPLE_RATE_24000: //24KHz
- _uIISCR = _uIISCR | FS_256 | SCALE_2 | BCLK_32;
-
- break;
- case AU_SAMPLE_RATE_32000: //32KHz
- _uIISCR = _uIISCR | SCALE_1 | FS_256 | BCLK_48;
-
- break;
- case AU_SAMPLE_RATE_44100: //44.1KHz
- _uIISCR = _uIISCR | SCALE_1 | FS_256 | BCLK_48;
-
- break;
- case AU_SAMPLE_RATE_48000: //48KHz
- _uIISCR = _uIISCR | FS_256 | SCALE_1 | BCLK_32;
-
- break;
- default:break;
- }
- AUDIO_WRITE(REG_ACTL_IISCON,_uIISCR);
-
- if(choose_sf == AU_SAMPLE_RATE_44100 || choose_sf ==AU_SAMPLE_RATE_22050 || choose_sf ==AU_SAMPLE_RATE_11025 ){
- //outpw(REG_APLLCON, 0x642D);//16.934
- //outpw(REG_CLKDIV0, (inpw(REG_CLKDIV0) & 0xFF0FFFFF) | 0x300000);
- AUDIO_WRITE(0xfff00010, 0x2601);//PLLCON 390Mhz
- AUDIO_WRITE(0xfff00014, 0x116);// divide by 23
- }else
- {
- AUDIO_WRITE(0xfff00010, 0x2f01);//PLLCON 480Mhz
- AUDIO_WRITE(0xfff00014, 0x126);// divide by 39
- }
-
- LEAVE();
-}
-
-static INT iis_reset(void)
-{
- ENTER();
-
- AUDIO_WRITE(REG_CLKSEL, AUDIO_READ(REG_CLKSEL) | 0x10000);
-
- AUDIO_WRITE(0xFFF83000,0x155);//GPIO_CFG0 PT0CFG0~4
- AUDIO_WRITE(0xFFF83004,0x1d);//GPIO1:In GPIO0,2,3,4:Out
-
- /* reset audio interface */
- AUDIO_WRITE(REG_ACTL_RESET,AUDIO_READ(REG_ACTL_RESET) | ACTL_RESET_BIT);
- Delay(100);
- AUDIO_WRITE(REG_ACTL_RESET,AUDIO_READ(REG_ACTL_RESET) & ~ACTL_RESET_BIT);
- Delay(100);
-
- /* reset IIS interface */
- AUDIO_WRITE(REG_ACTL_RESET,AUDIO_READ(REG_ACTL_RESET) | IIS_RESET);
- Delay(100);
- AUDIO_WRITE(REG_ACTL_RESET,AUDIO_READ(REG_ACTL_RESET) & ~IIS_RESET);
- Delay(100);
-
- /* enable audio controller and IIS interface */
- AUDIO_WRITE(REG_ACTL_CON, AUDIO_READ (REG_ACTL_CON) | AUDCLK_EN | PFIFO_EN | DMA_EN | IIS_EN | AUDIO_EN | RFIFO_EN | T_DMA_IRQ | R_DMA_IRQ);
-
-#if 0
- /* use GPIO 17 18 19 as L3 interface control pin */
- //writew(REG_GPIO_OE,readw(REG_GPIO_OE) & ~(1 << L3MODE_GPIO_NUM | 1<< L3CLOCK_GPIO_NUM | 1<< L3DATA_GPIO_NUM));
- AUDIO_WRITE(REG_GPIO_CFG,AUDIO_READ(REG_GPIO_CFG) & ~(0x3F<<14));
- AUDIO_WRITE(REG_GPIO_DIR,AUDIO_READ(REG_GPIO_DIR) | L3MODE_GPIO_NUM | L3CLOCK_GPIO_NUM | L3DATA_GPIO_NUM);
-
- /* set volume, dsp power up and no de-emph.no mute of external codec, from L3 */
-#endif
-
- _uIISCR = 0;
-
- LEAVE();
-
- return 0;
-}
-
-
-VOID i2sSetPlaySampleRate(INT nSamplingRate)
-{
- _tIIS.nPlaySamplingRate = nSamplingRate;
-}
-
-VOID i2sSetRecordSampleRate(INT nSamplingRate)
-{
- _tIIS.nRecSamplingRate = nSamplingRate;
-}
-
-
-VOID i2sSetPlayCallBackFunction(AU_CB_FUN_T fnCallBack)
-{
- _tIIS.fnPlayCallBack = fnCallBack;
-}
-
-VOID i2sSetRecordCallBackFunction(AU_CB_FUN_T fnCallBack)
-{
- _tIIS.fnRecCallBack = fnCallBack;
-}
-
-/*************************************************************************/
-/* */
-/* FUNCTION */
-/* i2sStartPlay */
-/* */
-/* DESCRIPTION */
-/* Start IIS playback. */
-/* */
-/* INPUTS */
-/* fnCallBack client program provided callback function. The audio */
-/* driver will call back to get next block of PCM data */
-/* nSamplingRate the playback sampling rate. Supported sampling */
-/* rate are 48000, 44100, 32000, 24000, 22050, 16000, */
-/* 11025, and 8000 Hz */
-/* */
-/* OUTPUTS */
-/* None */
-/* */
-/* RETURN */
-/* 0 Success */
-/* Otherwise error */
-/* */
-/*************************************************************************/
-static int i2sStartPlay(AU_CB_FUN_T fnCallBack, INT nSamplingRate,
- INT nChannels)
-{
- INT nStatus /* ,L3status */;
-
- ENTER();
-
- if (_bIISActive & IIS_PLAY_ACTIVE){
- MSG("IIS already playing\n");
- return ERR_IIS_PLAY_ACTIVE; /* IIS was playing */
- }
-
- //printk("SamplingRate : %d Channels : %d\n", nSamplingRate, nChannels);
-
- if (_bIISActive == 0)
- {
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~ PLAY_LEFT_CHNNEL & ~ PLAY_RIGHT_CHNNEL);
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | PLAY_RIGHT_CHNNEL);
- if (nChannels == AU_CH_STEREO)
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | PLAY_LEFT_CHNNEL);
- nStatus = iis_reset();
- if (nStatus < 0)
- return nStatus;
- }
-
-// enable_irq(AU_PLAY_INT_NUM);
- Enable_Int(AU_PLAY_INT_NUM);
-
- i2sSetPlayCallBackFunction(fnCallBack);
- i2sSetPlaySampleRate(nSamplingRate);
-
-#if 0
- /* set play sampling rate and data format */
- //L3status = L3_Set_Sample_Frequency(nSamplingRate);
- //L3status = L3status | L3_Set_Data_Format(data_format);
-
- //L3_Set_Data(EX_DAC_On);
- //L3_Set_Status(L3status);
-#endif
-
-
- IIS_Set_Sample_Frequency(nSamplingRate);
- IIS_Set_Data_Format(MSB_FORMAT);
-
-
- /* set DMA play destination base address */
- AUDIO_WRITE(REG_ACTL_PDSTB, _tIIS.uPlayBufferAddr);
-
- /* set DMA play buffer length */
- AUDIO_WRITE(REG_ACTL_PDST_LENGTH, _tIIS.uPlayBufferLength);
-
- MSG2("DMA Buffer : %x, Length : %x\n", _tIIS.uPlayBufferAddr,_tIIS.uPlayBufferLength);
-
- /* call back to fill DMA play buffer */
- //_tIIS.fnPlayCallBack((UINT8 *)_tIIS.uDMABufferAddr, _tIIS.uDMABufferLength/2);
- //_tIIS.fnPlayCallBack((UINT8 *)(_tIIS.uDMABufferAddr + _tIIS.uDMABufferLength/2),
- // _tIIS.uDMABufferLength/2);
-
- /* start playing */
- MSG("IIS start playing...\n");
- AUDIO_WRITE(REG_ACTL_PSR, 0x3);
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | IIS_PLAY);
- _bIISActive |= IIS_PLAY_ACTIVE;
-
- LEAVE();
-
- return 0;
-}
-
-
-/*************************************************************************/
-/* */
-/* FUNCTION */
-/* i2sStopPlay */
-/* */
-/* DESCRIPTION */
-/* Stop IIS playback immdediately. */
-/* */
-/* INPUTS */
-/* None */
-/* */
-/* OUTPUTS */
-/* None */
-/* */
-/* RETURN */
-/* 0 Success */
-/* Otherwise error */
-/* */
-/*************************************************************************/
-static void i2sStopPlay(void)
-{
- ENTER();
-
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~(PLAY_RIGHT_CHNNEL | PLAY_LEFT_CHNNEL));
-
- if (!(_bIISActive & IIS_PLAY_ACTIVE))
- return;
-
- MSG("IIS stop playing\n");
-
- /* stop playing */
- while( AUDIO_READ(REG_ACTL_RESET) & IIS_PLAY )
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~IIS_PLAY);
-
- _bIISActive &= ~IIS_PLAY_ACTIVE;
-
- /* disable audio play interrupt */
- if (!_bIISActive)
- Disable_Int(AU_PLAY_INT_NUM);
-
-
- LEAVE();
-
- return;
-}
-
-
-/*************************************************************************/
-/* */
-/* FUNCTION */
-/* i2sStartRecord */
-/* */
-/* DESCRIPTION */
-/* Start IIS record. */
-/* */
-/* INPUTS */
-/* fnCallBack client program provided callback function. The audio */
-/* driver will call back to deliver the newly recorded */
-/* block of PCM data */
-/* nSamplingRate the record sampling rate. Supported sampling */
-/* rate are 48000, 44100, 32000, 24000, 22050, 16000, */
-/* 11025, and 8000 Hz */
-/* */
-/* OUTPUTS */
-/* None */
-/* */
-/* RETURN */
-/* 0 Success */
-/* Otherwise error */
-/* */
-/*************************************************************************/
-static int i2sStartRecord(AU_CB_FUN_T fnCallBack, INT nSamplingRate,
- INT nChannels)
-{
- INT nStatus /* ,L3status */;
-
- ENTER();
-
- if (_bIISActive & IIS_REC_ACTIVE)
- return ERR_IIS_REC_ACTIVE; /* IIS was recording */
-
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~(RECORD_LEFT_CHNNEL & RECORD_RIGHT_CHNNEL));
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | RECORD_LEFT_CHNNEL);
- if (nChannels != 1)
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | RECORD_RIGHT_CHNNEL);
-
- if (_bIISActive == 0)
- {
- nStatus = iis_reset();
- if (nStatus < 0)
- return nStatus;
- }
-
- Enable_Int(AU_REC_INT_NUM);
-
- i2sSetRecordCallBackFunction(fnCallBack);
- i2sSetRecordSampleRate(nSamplingRate);
-
-#if 0
- /* set record sampling rate and data format */
- //L3status = L3_Set_Sample_Frequency(nSamplingRate);
- //L3status = L3status | L3_Set_Data_Format(MSB_FORMAT);
-
- //L3_Set_Data(EX_ADC_On);
- //L3_Set_Status(L3status);
-#endif
-
- IIS_Set_Sample_Frequency(nSamplingRate);
- IIS_Set_Data_Format(MSB_FORMAT);
-
-
-
- /* set DMA record destination base address */
- AUDIO_WRITE(REG_ACTL_RDSTB, _tIIS.uRecordBufferAddr);
-
- /* set DMA record buffer length */
- AUDIO_WRITE(REG_ACTL_RDST_LENGTH, _tIIS.uRecordBufferLength);
-
- /* start recording */
- MSG("IIS start recording...\n");
- AUDIO_WRITE(REG_ACTL_RSR, 0x3);
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | IIS_RECORD);
- _bIISActive |= IIS_REC_ACTIVE;
-
- LEAVE();
-
- return 0;
-}
-
-
-/*************************************************************************/
-/* */
-/* FUNCTION */
-/* i2sStopRecord */
-/* */
-/* DESCRIPTION */
-/* Stop IIS record immediately. */
-/* */
-/* INPUTS */
-/* None */
-/* */
-/* OUTPUTS */
-/* None */
-/* */
-/* RETURN */
-/* 0 Success */
-/* Otherwise error */
-/* */
-/*************************************************************************/
-static void i2sStopRecord(void)
-{
- ENTER();
-
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~(RECORD_RIGHT_CHNNEL | RECORD_LEFT_CHNNEL));
-
- if (!(_bIISActive & IIS_REC_ACTIVE))
- return;
-
- MSG("IIS stop recording\n");
-
- /* stop recording */
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~IIS_RECORD);
-
- _bIISActive &= ~IIS_REC_ACTIVE;
- /* disable audio record interrupt */
- if (!_bIISActive)
- Disable_Int(AU_PLAY_INT_NUM);
-
-
- LEAVE();
-
- return;
-}
-
-
-/*************************************************************************/
-/* */
-/* FUNCTION */
-/* i2sSetPlayVolume */
-/* */
-/* DESCRIPTION */
-/* Set i2S left and right channel play volume. */
-/* */
-/* INPUTS */
-/* ucLeftVol play volume of left channel */
-/* ucRightVol play volume of left channel */
-/* 0: mute */
-/* 1: minimal volume */
-/* 31: maxmum volume */
-/* */
-/* OUTPUTS */
-/* None */
-/* */
-/* RETURN */
-/* 0 Success */
-/* Otherwise error */
-/* */
-/*************************************************************************/
-static int i2sSetPlayVolume(UINT32 ucLeftVol, UINT32 ucRightVol) //0~31
-{
- ENTER();
-
- if (ucLeftVol>31)
- ucLeftVol=31;
- if (ucRightVol>31)
- ucRightVol=31;
-
- //printk("Set IIS Play volume to : %d-%d\n", ucLeftVol, ucRightVol);
-
- _tIIS.sPlayVolume = 0x3F - ucLeftVol*2;
-
-#if 0
- /*----- Address Mode -----*/
- L3_Address_Mode(EX_1345ADDR | EX_DATA);//set the DATA(volumn,de-emphasis, mute, and power control)
- /*----- Data Transfer Mode -----*/
- L3_Data_Transfer_Mode((UINT8)_tIIS.sPlayVolume);
-#endif
-
- LEAVE();
-
- return 0;
-}
-
-static int i2sSetRecordVolume(UINT32 ucLeftVol, UINT32 ucRightVol)
-{
- ENTER();
-
- LEAVE();
-
- return 0;
-
-}
-
-static void i2sSetPlayBuffer(UINT32 uDMABufferAddr, UINT32 uDMABufferLength)
-{
- ENTER();
-
- _tIIS.uPlayBufferAddr = uDMABufferAddr;
- _tIIS.uPlayBufferLength = uDMABufferLength;
-
- LEAVE();
-}
-
-static void i2sSetRecordBuffer(UINT32 uDMABufferAddr, UINT32 uDMABufferLength)
-{
- ENTER();
-
- _tIIS.uRecordBufferAddr = uDMABufferAddr;
- _tIIS.uRecordBufferLength = uDMABufferLength;
-
- LEAVE();
-}
-
-static void iis_play_isr(void)
-{
- int bPlayLastBlock = 0;
-
- ENTER();
-
- MSG2("[DMA:S:%x,L:%x,C:%x]\n",
- AUDIO_READ(REG_ACTL_PDSTB),
- AUDIO_READ(REG_ACTL_PDST_LENGTH),
- AUDIO_READ(REG_ACTL_PDSTC));
-
-
- AUDIO_WRITE(REG_ACTL_CON, AUDIO_READ(REG_ACTL_CON) | T_DMA_IRQ);
-
- if (AUDIO_READ(REG_ACTL_PSR) & P_DMA_MIDDLE_IRQ)
- {
- AUDIO_WRITE(REG_ACTL_PSR, P_DMA_MIDDLE_IRQ);
- bPlayLastBlock = _tIIS.fnPlayCallBack(_tIIS.uPlayBufferAddr,
- _tIIS.uPlayBufferLength/2);
- }
- else if (AUDIO_READ(REG_ACTL_PSR) & P_DMA_END_IRQ)
- {
- AUDIO_WRITE(REG_ACTL_PSR, P_DMA_END_IRQ);
- bPlayLastBlock = _tIIS.fnPlayCallBack(_tIIS.uPlayBufferAddr + _tIIS.uPlayBufferLength/2,
- _tIIS.uPlayBufferLength/2);
- }
-
-
- /* check whether the next block is ready. If not, stop play */
-
- if (bPlayLastBlock)
- {
- AUDIO_WRITE(REG_ACTL_PSR, P_DMA_MIDDLE_IRQ | P_DMA_END_IRQ);
-// i2sStopPlay();
- }
-
-
- LEAVE();
-
-}
-
-
-static void iis_rec_isr(void)
-{
- int bPlayLastBlock = 0;
-
- ENTER();
-
- AUDIO_WRITE(REG_ACTL_CON, AUDIO_READ(REG_ACTL_CON) | R_DMA_IRQ);
-
- if (AUDIO_READ(REG_ACTL_RSR) & R_DMA_MIDDLE_IRQ)
- {
- AUDIO_WRITE(REG_ACTL_RSR, R_DMA_MIDDLE_IRQ);
- bPlayLastBlock = _tIIS.fnRecCallBack(_tIIS.uRecordBufferAddr, _tIIS.uRecordBufferLength/2);
- }
- else if (AUDIO_READ(REG_ACTL_RSR) & R_DMA_END_IRQ)
- {
- AUDIO_WRITE(REG_ACTL_RSR, R_DMA_END_IRQ);
- bPlayLastBlock = _tIIS.fnRecCallBack(_tIIS.uRecordBufferAddr + _tIIS.uRecordBufferLength/2,
- _tIIS.uRecordBufferLength/2);
- }
-
- /* check whether the next block is token away. If not, stop record */
-
- if (bPlayLastBlock)
- {
- AUDIO_WRITE(REG_ACTL_RSR, R_DMA_MIDDLE_IRQ | R_DMA_END_IRQ);
- }
-
- LEAVE();
-}
-
-
-INT i2sInit(VOID)
-{
- int nStatus = 0;
-
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) &~PLAY_LEFT_CHNNEL &~PLAY_RIGHT_CHNNEL);
- AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) &~RECORD_LEFT_CHNNEL &~RECORD_RIGHT_CHNNEL);
-
- nStatus = iis_reset();
- if (nStatus < 0)
- return nStatus;
-
- return 0;
-}
-
-static INT i2sGetCapacity(VOID)
-{
- return DSP_CAP_DUPLEX; /* support full duplex */
-}
-
-WB_AUDIO_CODEC_T wb_i2s_codec = {
- dev: AU_DEV_IIS,
- get_capacity: i2sGetCapacity,
- set_play_buffer: i2sSetPlayBuffer,
- set_record_buffer: i2sSetRecordBuffer,
- reset: i2sInit,
- start_play: i2sStartPlay,
- stop_play: i2sStopPlay,
- start_record: i2sStartRecord,
- stop_record: i2sStopRecord,
- set_play_volume: i2sSetPlayVolume,
- set_record_volume: i2sSetRecordVolume, /* not supprted */
- play_interrupt: iis_play_isr,
- record_interrupt: iis_rec_isr,
-};
+/****************************************************************************
+ *
+ * Copyright (c) 2004 - 2007 Winbond Electronics Corp. All rights reserved.
+ *
+ *
+ * FILENAME
+ * w90n745_I2S.c
+ *
+ * VERSION
+ * 1.0
+ *
+ * DESCRIPTION
+ * IIS for PCM3003E codec
+ *
+ * DATA STRUCTURES
+ * None
+ *
+ * FUNCTIONS
+ *
+ * HISTORY
+ * 2004.07.16 Created by Shih-Jen Lu
+ * 2005.11.24 Modified by PC34 QFu
+ *
+ * REMARK
+ * None
+ *
+ **************************************************************************/
+#include <linux/soundcard.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include "w90n745_audio_regs.h"
+#include "w90n745_audio.h"
+
+#include "w90n745_i2s.h"
+
+//#define I2S_DEBUG
+//#define I2S_DEBUG_ENTER_LEAVE
+//#define I2S_DEBUG_MSG
+//#define I2S_DEBUG_MSG2
+
+
+#ifdef I2S_DEBUG
+#define DBG(fmt, arg...) printk(fmt, ##arg)
+#else
+#define DBG(fmt, arg...)
+#endif
+
+#ifdef I2S_DEBUG_ENTER_LEAVE
+#define ENTER() DBG("[%-10s] : Enter\n", __FUNCTION__)
+#define LEAVE() DBG("[%-10s] : Leave\n", __FUNCTION__)
+#else
+#define ENTER()
+#define LEAVE()
+#endif
+
+#ifdef I2S_DEBUG_MSG
+#define MSG(fmt) DBG("[%-10s] : "fmt, __FUNCTION__)
+#else
+#define MSG(fmt)
+#endif
+
+#ifdef I2S_DEBUG_MSG2
+#define MSG2(fmt, arg...) DBG("[%-10s] : "fmt, __FUNCTION__, ##arg)
+#else
+#define MSG2(fmt, arg...)
+#endif
+
+static AUDIO_T _tIIS;
+
+#define AUDIO_WRITE(addr, val) writel(val, addr)
+#define AUDIO_READ(addr) readl(addr)
+
+#define Delay(time) udelay(time * 10)
+
+#define MSB_FORMAT 1
+#define IIS_FORMAT 2
+
+static int _bIISActive = 0;
+static UINT32 _uIISCR = 0;
+
+#define WMDEVID 0
+
+#define UINT8 unsigned char
+
+/*----- set data format -----*/
+static void IIS_Set_Data_Format(int choose_format)
+{
+
+ ENTER();
+
+ switch(choose_format){
+ case IIS_FORMAT: _uIISCR = _uIISCR | IIS;
+ break;
+ case MSB_FORMAT: _uIISCR = _uIISCR | MSB_Justified;
+ break;
+ default:break;
+ }
+ AUDIO_WRITE(REG_ACTL_IISCON,_uIISCR);
+
+ LEAVE();
+}
+
+/*----- set sample Frequency -----*/
+static void IIS_Set_Sample_Frequency(int choose_sf)
+{
+
+ ENTER();
+
+ switch (choose_sf)
+ {
+ case AU_SAMPLE_RATE_8000: //8KHz
+ _uIISCR = _uIISCR | FS_256 | SCALE_4 | BCLK_48;
+
+ break;
+ case AU_SAMPLE_RATE_11025: //11.025KHz
+ _uIISCR = _uIISCR | FS_256 | SCALE_4 | BCLK_48;
+
+ break;
+ case AU_SAMPLE_RATE_16000: //16KHz
+ _uIISCR = _uIISCR | FS_256 | SCALE_2 | BCLK_48;
+
+ break;
+ case AU_SAMPLE_RATE_22050: //22.05KHz
+ _uIISCR = _uIISCR | FS_256 | SCALE_3 | BCLK_32;
+
+ break;
+ case AU_SAMPLE_RATE_24000: //24KHz
+ _uIISCR = _uIISCR | FS_256 | SCALE_2 | BCLK_32;
+
+ break;
+ case AU_SAMPLE_RATE_32000: //32KHz
+ _uIISCR = _uIISCR | SCALE_1 | FS_256 | BCLK_48;
+
+ break;
+ case AU_SAMPLE_RATE_44100: //44.1KHz
+ _uIISCR = _uIISCR | SCALE_1 | FS_256 | BCLK_48;
+
+ break;
+ case AU_SAMPLE_RATE_48000: //48KHz
+ _uIISCR = _uIISCR | FS_256 | SCALE_1 | BCLK_32;
+
+ break;
+ default:break;
+ }
+ AUDIO_WRITE(REG_ACTL_IISCON,_uIISCR);
+
+ if(choose_sf == AU_SAMPLE_RATE_44100 || choose_sf ==AU_SAMPLE_RATE_22050 || choose_sf ==AU_SAMPLE_RATE_11025 ){
+ //outpw(REG_APLLCON, 0x642D);//16.934
+ //outpw(REG_CLKDIV0, (inpw(REG_CLKDIV0) & 0xFF0FFFFF) | 0x300000);
+ AUDIO_WRITE(0xfff00010, 0x2601);//PLLCON 390Mhz
+ AUDIO_WRITE(0xfff00014, 0x116);// divide by 23
+ }else
+ {
+ AUDIO_WRITE(0xfff00010, 0x2f01);//PLLCON 480Mhz
+ AUDIO_WRITE(0xfff00014, 0x126);// divide by 39
+ }
+
+ LEAVE();
+}
+
+static INT iis_reset(void)
+{
+ ENTER();
+
+ AUDIO_WRITE(REG_CLKSEL, AUDIO_READ(REG_CLKSEL) | 0x10000);
+
+ AUDIO_WRITE(0xFFF83000,0x155);//GPIO_CFG0 PT0CFG0~4
+ AUDIO_WRITE(0xFFF83004,0x1d);//GPIO1:In GPIO0,2,3,4:Out
+
+ /* reset audio interface */
+ AUDIO_WRITE(REG_ACTL_RESET,AUDIO_READ(REG_ACTL_RESET) | ACTL_RESET_BIT);
+ Delay(100);
+ AUDIO_WRITE(REG_ACTL_RESET,AUDIO_READ(REG_ACTL_RESET) & ~ACTL_RESET_BIT);
+ Delay(100);
+
+ /* reset IIS interface */
+ AUDIO_WRITE(REG_ACTL_RESET,AUDIO_READ(REG_ACTL_RESET) | IIS_RESET);
+ Delay(100);
+ AUDIO_WRITE(REG_ACTL_RESET,AUDIO_READ(REG_ACTL_RESET) & ~IIS_RESET);
+ Delay(100);
+
+ /* enable audio controller and IIS interface */
+ AUDIO_WRITE(REG_ACTL_CON, AUDIO_READ (REG_ACTL_CON) | AUDCLK_EN | PFIFO_EN | DMA_EN | IIS_EN | AUDIO_EN | RFIFO_EN | T_DMA_IRQ | R_DMA_IRQ);
+
+#if 0
+ /* use GPIO 17 18 19 as L3 interface control pin */
+ //writew(REG_GPIO_OE,readw(REG_GPIO_OE) & ~(1 << L3MODE_GPIO_NUM | 1<< L3CLOCK_GPIO_NUM | 1<< L3DATA_GPIO_NUM));
+ AUDIO_WRITE(REG_GPIO_CFG,AUDIO_READ(REG_GPIO_CFG) & ~(0x3F<<14));
+ AUDIO_WRITE(REG_GPIO_DIR,AUDIO_READ(REG_GPIO_DIR) | L3MODE_GPIO_NUM | L3CLOCK_GPIO_NUM | L3DATA_GPIO_NUM);
+
+ /* set volume, dsp power up and no de-emph.no mute of external codec, from L3 */
+#endif
+
+ _uIISCR = 0;
+
+ LEAVE();
+
+ return 0;
+}
+
+
+VOID i2sSetPlaySampleRate(INT nSamplingRate)
+{
+ _tIIS.nPlaySamplingRate = nSamplingRate;
+}
+
+VOID i2sSetRecordSampleRate(INT nSamplingRate)
+{
+ _tIIS.nRecSamplingRate = nSamplingRate;
+}
+
+
+VOID i2sSetPlayCallBackFunction(AU_CB_FUN_T fnCallBack)
+{
+ _tIIS.fnPlayCallBack = fnCallBack;
+}
+
+VOID i2sSetRecordCallBackFunction(AU_CB_FUN_T fnCallBack)
+{
+ _tIIS.fnRecCallBack = fnCallBack;
+}
+
+/*************************************************************************/
+/* */
+/* FUNCTION */
+/* i2sStartPlay */
+/* */
+/* DESCRIPTION */
+/* Start IIS playback. */
+/* */
+/* INPUTS */
+/* fnCallBack client program provided callback function. The audio */
+/* driver will call back to get next block of PCM data */
+/* nSamplingRate the playback sampling rate. Supported sampling */
+/* rate are 48000, 44100, 32000, 24000, 22050, 16000, */
+/* 11025, and 8000 Hz */
+/* */
+/* OUTPUTS */
+/* None */
+/* */
+/* RETURN */
+/* 0 Success */
+/* Otherwise error */
+/* */
+/*************************************************************************/
+static int i2sStartPlay(AU_CB_FUN_T fnCallBack, INT nSamplingRate,
+ INT nChannels)
+{
+ INT nStatus /* ,L3status */;
+
+ ENTER();
+
+ if (_bIISActive & IIS_PLAY_ACTIVE){
+ MSG("IIS already playing\n");
+ return ERR_IIS_PLAY_ACTIVE; /* IIS was playing */
+ }
+
+ //printk("SamplingRate : %d Channels : %d\n", nSamplingRate, nChannels);
+
+ if (_bIISActive == 0)
+ {
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~ PLAY_LEFT_CHNNEL & ~ PLAY_RIGHT_CHNNEL);
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | PLAY_RIGHT_CHNNEL);
+ if (nChannels == AU_CH_STEREO)
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | PLAY_LEFT_CHNNEL);
+ nStatus = iis_reset();
+ if (nStatus < 0)
+ return nStatus;
+ }
+
+// enable_irq(AU_PLAY_INT_NUM);
+ Enable_Int(AU_PLAY_INT_NUM);
+
+ i2sSetPlayCallBackFunction(fnCallBack);
+ i2sSetPlaySampleRate(nSamplingRate);
+
+#if 0
+ /* set play sampling rate and data format */
+ //L3status = L3_Set_Sample_Frequency(nSamplingRate);
+ //L3status = L3status | L3_Set_Data_Format(data_format);
+
+ //L3_Set_Data(EX_DAC_On);
+ //L3_Set_Status(L3status);
+#endif
+
+
+ IIS_Set_Sample_Frequency(nSamplingRate);
+ IIS_Set_Data_Format(MSB_FORMAT);
+
+
+ /* set DMA play destination base address */
+ AUDIO_WRITE(REG_ACTL_PDSTB, _tIIS.uPlayBufferAddr);
+
+ /* set DMA play buffer length */
+ AUDIO_WRITE(REG_ACTL_PDST_LENGTH, _tIIS.uPlayBufferLength);
+
+ MSG2("DMA Buffer : %x, Length : %x\n", _tIIS.uPlayBufferAddr,_tIIS.uPlayBufferLength);
+
+ /* call back to fill DMA play buffer */
+ //_tIIS.fnPlayCallBack((UINT8 *)_tIIS.uDMABufferAddr, _tIIS.uDMABufferLength/2);
+ //_tIIS.fnPlayCallBack((UINT8 *)(_tIIS.uDMABufferAddr + _tIIS.uDMABufferLength/2),
+ // _tIIS.uDMABufferLength/2);
+
+ /* start playing */
+ MSG("IIS start playing...\n");
+ AUDIO_WRITE(REG_ACTL_PSR, 0x3);
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | IIS_PLAY);
+ _bIISActive |= IIS_PLAY_ACTIVE;
+
+ LEAVE();
+
+ return 0;
+}
+
+
+/*************************************************************************/
+/* */
+/* FUNCTION */
+/* i2sStopPlay */
+/* */
+/* DESCRIPTION */
+/* Stop IIS playback immdediately. */
+/* */
+/* INPUTS */
+/* None */
+/* */
+/* OUTPUTS */
+/* None */
+/* */
+/* RETURN */
+/* 0 Success */
+/* Otherwise error */
+/* */
+/*************************************************************************/
+static void i2sStopPlay(void)
+{
+ ENTER();
+
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~(PLAY_RIGHT_CHNNEL | PLAY_LEFT_CHNNEL));
+
+ if (!(_bIISActive & IIS_PLAY_ACTIVE))
+ return;
+
+ MSG("IIS stop playing\n");
+
+ /* stop playing */
+ while( AUDIO_READ(REG_ACTL_RESET) & IIS_PLAY )
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~IIS_PLAY);
+
+ _bIISActive &= ~IIS_PLAY_ACTIVE;
+
+ /* disable audio play interrupt */
+ if (!_bIISActive)
+ Disable_Int(AU_PLAY_INT_NUM);
+
+
+ LEAVE();
+
+ return;
+}
+
+
+/*************************************************************************/
+/* */
+/* FUNCTION */
+/* i2sStartRecord */
+/* */
+/* DESCRIPTION */
+/* Start IIS record. */
+/* */
+/* INPUTS */
+/* fnCallBack client program provided callback function. The audio */
+/* driver will call back to deliver the newly recorded */
+/* block of PCM data */
+/* nSamplingRate the record sampling rate. Supported sampling */
+/* rate are 48000, 44100, 32000, 24000, 22050, 16000, */
+/* 11025, and 8000 Hz */
+/* */
+/* OUTPUTS */
+/* None */
+/* */
+/* RETURN */
+/* 0 Success */
+/* Otherwise error */
+/* */
+/*************************************************************************/
+static int i2sStartRecord(AU_CB_FUN_T fnCallBack, INT nSamplingRate,
+ INT nChannels)
+{
+ INT nStatus /* ,L3status */;
+
+ ENTER();
+
+ if (_bIISActive & IIS_REC_ACTIVE)
+ return ERR_IIS_REC_ACTIVE; /* IIS was recording */
+
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~(RECORD_LEFT_CHNNEL & RECORD_RIGHT_CHNNEL));
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | RECORD_LEFT_CHNNEL);
+ if (nChannels != 1)
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | RECORD_RIGHT_CHNNEL);
+
+ if (_bIISActive == 0)
+ {
+ nStatus = iis_reset();
+ if (nStatus < 0)
+ return nStatus;
+ }
+
+ Enable_Int(AU_REC_INT_NUM);
+
+ i2sSetRecordCallBackFunction(fnCallBack);
+ i2sSetRecordSampleRate(nSamplingRate);
+
+#if 0
+ /* set record sampling rate and data format */
+ //L3status = L3_Set_Sample_Frequency(nSamplingRate);
+ //L3status = L3status | L3_Set_Data_Format(MSB_FORMAT);
+
+ //L3_Set_Data(EX_ADC_On);
+ //L3_Set_Status(L3status);
+#endif
+
+ IIS_Set_Sample_Frequency(nSamplingRate);
+ IIS_Set_Data_Format(MSB_FORMAT);
+
+
+
+ /* set DMA record destination base address */
+ AUDIO_WRITE(REG_ACTL_RDSTB, _tIIS.uRecordBufferAddr);
+
+ /* set DMA record buffer length */
+ AUDIO_WRITE(REG_ACTL_RDST_LENGTH, _tIIS.uRecordBufferLength);
+
+ /* start recording */
+ MSG("IIS start recording...\n");
+ AUDIO_WRITE(REG_ACTL_RSR, 0x3);
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) | IIS_RECORD);
+ _bIISActive |= IIS_REC_ACTIVE;
+
+ LEAVE();
+
+ return 0;
+}
+
+
+/*************************************************************************/
+/* */
+/* FUNCTION */
+/* i2sStopRecord */
+/* */
+/* DESCRIPTION */
+/* Stop IIS record immediately. */
+/* */
+/* INPUTS */
+/* None */
+/* */
+/* OUTPUTS */
+/* None */
+/* */
+/* RETURN */
+/* 0 Success */
+/* Otherwise error */
+/* */
+/*************************************************************************/
+static void i2sStopRecord(void)
+{
+ ENTER();
+
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~(RECORD_RIGHT_CHNNEL | RECORD_LEFT_CHNNEL));
+
+ if (!(_bIISActive & IIS_REC_ACTIVE))
+ return;
+
+ MSG("IIS stop recording\n");
+
+ /* stop recording */
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) & ~IIS_RECORD);
+
+ _bIISActive &= ~IIS_REC_ACTIVE;
+ /* disable audio record interrupt */
+ if (!_bIISActive)
+ Disable_Int(AU_PLAY_INT_NUM);
+
+
+ LEAVE();
+
+ return;
+}
+
+
+/*************************************************************************/
+/* */
+/* FUNCTION */
+/* i2sSetPlayVolume */
+/* */
+/* DESCRIPTION */
+/* Set i2S left and right channel play volume. */
+/* */
+/* INPUTS */
+/* ucLeftVol play volume of left channel */
+/* ucRightVol play volume of left channel */
+/* 0: mute */
+/* 1: minimal volume */
+/* 31: maxmum volume */
+/* */
+/* OUTPUTS */
+/* None */
+/* */
+/* RETURN */
+/* 0 Success */
+/* Otherwise error */
+/* */
+/*************************************************************************/
+static int i2sSetPlayVolume(UINT32 ucLeftVol, UINT32 ucRightVol) //0~31
+{
+ ENTER();
+
+ if (ucLeftVol>31)
+ ucLeftVol=31;
+ if (ucRightVol>31)
+ ucRightVol=31;
+
+ //printk("Set IIS Play volume to : %d-%d\n", ucLeftVol, ucRightVol);
+
+ _tIIS.sPlayVolume = 0x3F - ucLeftVol*2;
+
+#if 0
+ /*----- Address Mode -----*/
+ L3_Address_Mode(EX_1345ADDR | EX_DATA);//set the DATA(volumn,de-emphasis, mute, and power control)
+ /*----- Data Transfer Mode -----*/
+ L3_Data_Transfer_Mode((UINT8)_tIIS.sPlayVolume);
+#endif
+
+ LEAVE();
+
+ return 0;
+}
+
+static int i2sSetRecordVolume(UINT32 ucLeftVol, UINT32 ucRightVol)
+{
+ ENTER();
+
+ LEAVE();
+
+ return 0;
+
+}
+
+static void i2sSetPlayBuffer(UINT32 uDMABufferAddr, UINT32 uDMABufferLength)
+{
+ ENTER();
+
+ _tIIS.uPlayBufferAddr = uDMABufferAddr;
+ _tIIS.uPlayBufferLength = uDMABufferLength;
+
+ LEAVE();
+}
+
+static void i2sSetRecordBuffer(UINT32 uDMABufferAddr, UINT32 uDMABufferLength)
+{
+ ENTER();
+
+ _tIIS.uRecordBufferAddr = uDMABufferAddr;
+ _tIIS.uRecordBufferLength = uDMABufferLength;
+
+ LEAVE();
+}
+
+static void iis_play_isr(void)
+{
+ int bPlayLastBlock = 0;
+
+ ENTER();
+
+ MSG2("[DMA:S:%x,L:%x,C:%x]\n",
+ AUDIO_READ(REG_ACTL_PDSTB),
+ AUDIO_READ(REG_ACTL_PDST_LENGTH),
+ AUDIO_READ(REG_ACTL_PDSTC));
+
+
+ AUDIO_WRITE(REG_ACTL_CON, AUDIO_READ(REG_ACTL_CON) | T_DMA_IRQ);
+
+ if (AUDIO_READ(REG_ACTL_PSR) & P_DMA_MIDDLE_IRQ)
+ {
+ AUDIO_WRITE(REG_ACTL_PSR, P_DMA_MIDDLE_IRQ);
+ bPlayLastBlock = _tIIS.fnPlayCallBack(_tIIS.uPlayBufferAddr,
+ _tIIS.uPlayBufferLength/2);
+ }
+ else if (AUDIO_READ(REG_ACTL_PSR) & P_DMA_END_IRQ)
+ {
+ AUDIO_WRITE(REG_ACTL_PSR, P_DMA_END_IRQ);
+ bPlayLastBlock = _tIIS.fnPlayCallBack(_tIIS.uPlayBufferAddr + _tIIS.uPlayBufferLength/2,
+ _tIIS.uPlayBufferLength/2);
+ }
+
+
+ /* check whether the next block is ready. If not, stop play */
+
+ if (bPlayLastBlock)
+ {
+ AUDIO_WRITE(REG_ACTL_PSR, P_DMA_MIDDLE_IRQ | P_DMA_END_IRQ);
+// i2sStopPlay();
+ }
+
+
+ LEAVE();
+
+}
+
+
+static void iis_rec_isr(void)
+{
+ int bPlayLastBlock = 0;
+
+ ENTER();
+
+ AUDIO_WRITE(REG_ACTL_CON, AUDIO_READ(REG_ACTL_CON) | R_DMA_IRQ);
+
+ if (AUDIO_READ(REG_ACTL_RSR) & R_DMA_MIDDLE_IRQ)
+ {
+ AUDIO_WRITE(REG_ACTL_RSR, R_DMA_MIDDLE_IRQ);
+ bPlayLastBlock = _tIIS.fnRecCallBack(_tIIS.uRecordBufferAddr, _tIIS.uRecordBufferLength/2);
+ }
+ else if (AUDIO_READ(REG_ACTL_RSR) & R_DMA_END_IRQ)
+ {
+ AUDIO_WRITE(REG_ACTL_RSR, R_DMA_END_IRQ);
+ bPlayLastBlock = _tIIS.fnRecCallBack(_tIIS.uRecordBufferAddr + _tIIS.uRecordBufferLength/2,
+ _tIIS.uRecordBufferLength/2);
+ }
+
+ /* check whether the next block is token away. If not, stop record */
+
+ if (bPlayLastBlock)
+ {
+ AUDIO_WRITE(REG_ACTL_RSR, R_DMA_MIDDLE_IRQ | R_DMA_END_IRQ);
+ }
+
+ LEAVE();
+}
+
+
+INT i2sInit(VOID)
+{
+ int nStatus = 0;
+
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) &~PLAY_LEFT_CHNNEL &~PLAY_RIGHT_CHNNEL);
+ AUDIO_WRITE(REG_ACTL_RESET, AUDIO_READ(REG_ACTL_RESET) &~RECORD_LEFT_CHNNEL &~RECORD_RIGHT_CHNNEL);
+
+ nStatus = iis_reset();
+ if (nStatus < 0)
+ return nStatus;
+
+ return 0;
+}
+
+static INT i2sGetCapacity(VOID)
+{
+ return DSP_CAP_DUPLEX; /* support full duplex */
+}
+
+WB_AUDIO_CODEC_T wb_i2s_codec = {
+ dev: AU_DEV_IIS,
+ get_capacity: i2sGetCapacity,
+ set_play_buffer: i2sSetPlayBuffer,
+ set_record_buffer: i2sSetRecordBuffer,
+ reset: i2sInit,
+ start_play: i2sStartPlay,
+ stop_play: i2sStopPlay,
+ start_record: i2sStartRecord,
+ stop_record: i2sStopRecord,
+ set_play_volume: i2sSetPlayVolume,
+ set_record_volume: i2sSetRecordVolume, /* not supprted */
+ play_interrupt: iis_play_isr,
+ record_interrupt: iis_rec_isr,
+};
diff --git a/uClinux-2.4.20-uc1/drivers/sound/w90n745_i2s.h b/uClinux-2.4.20-uc1/drivers/sound/w90n745_i2s.h
index 3b9aef5..0735025 100644
--- a/uClinux-2.4.20-uc1/drivers/sound/w90n745_i2s.h
+++ b/uClinux-2.4.20-uc1/drivers/sound/w90n745_i2s.h
@@ -1,69 +1,69 @@
-/**************************************************************************************************
- *
- * Copyright (c) 2004 - 2007 Winbond Electronics Corp. All rights reserved.
- *
- * FILENAME
- * w90n745_i2s.h
- *
- * VERSION
- * 1.0
- *
- * DESCRIPTION
- * This file contains the register map of IIS audio interface
- *
- * HISTORY
- * 02/09/2004 Ver 1.0 Created by PC31 SJLu
- *
- * REMARK
- * None
- *
- *************************************************************************************************/
-#ifndef _W90N745_I2S_H_
-#define _W90N745_I2S_H_
-
-/*----- bit definition of REG_ACTL_IISCON register -----*/
-#define IIS 0x0
-#define MSB_Justified 0x0008
-#define SCALE_1 0x0
-#define SCALE_2 0x10000
-#define SCALE_3 0x20000
-#define SCALE_4 0x30000
-#define SCALE_5 0x40000
-#define SCALE_6 0x50000
-#define SCALE_7 0x60000
-#define SCALE_8 0x70000
-#define SCALE_10 0x90000
-#define SCALE_12 0xB0000
-#define SCALE_14 0xD0000
-#define SCALE_16 0xF0000
-#define FS_384 0x20
-#define FS_256 0x0
-#define BCLK_32 0x00
-#define BCLK_48 0x40
-
-/* bit definition of L3DATA register */
-#define EX_256FS 0x20 /*-- system clock --*/
-#define EX_384FS 0x10
-#define EX_IIS 0x00 /*-- data input format --*/
-#define EX_MSB 0x08
-#define EX_1345ADDR 0x14 //The address of the UDA1345TS
-#define EX_STATUS 0x02 //data transfer type (STATUS)
-#define EX_DATA 0x00 //data transfer type (DATA)
-#define EX_ADC_On 0xC2 //turn on the ADC
-#define EX_DAC_On 0xC1 //turn on the DAC
-
-/*----- GPIO NUM -----*/
-#define L3MODE_GPIO_NUM (1<<17)
-#define L3CLOCK_GPIO_NUM (1<<18)
-#define L3DATA_GPIO_NUM (1<<19)
-
-#define MSB_FORMAT 1
-#define IIS_FORMAT 2
-
-#define IIS_ACTIVE 0x1
-#define IIS_PLAY_ACTIVE 0x2
-#define IIS_REC_ACTIVE 0x4
-
-#endif /* _W90N745_I2S_H_ */
-
-
+/**************************************************************************************************
+ *
+ * Copyright (c) 2004 - 2007 Winbond Electronics Corp. All rights reserved.
+ *
+ * FILENAME
+ * w90n745_i2s.h
+ *
+ * VERSION
+ * 1.0
+ *
+ * DESCRIPTION
+ * This file contains the register map of IIS audio interface
+ *
+ * HISTORY
+ * 02/09/2004 Ver 1.0 Created by PC31 SJLu
+ *
+ * REMARK
+ * None
+ *
+ *************************************************************************************************/
+#ifndef _W90N745_I2S_H_
+#define _W90N745_I2S_H_
+
+/*----- bit definition of REG_ACTL_IISCON register -----*/
+#define IIS 0x0
+#define MSB_Justified 0x0008
+#define SCALE_1 0x0
+#define SCALE_2 0x10000
+#define SCALE_3 0x20000
+#define SCALE_4 0x30000
+#define SCALE_5 0x40000
+#define SCALE_6 0x50000
+#define SCALE_7 0x60000
+#define SCALE_8 0x70000
+#define SCALE_10 0x90000
+#define SCALE_12 0xB0000
+#define SCALE_14 0xD0000
+#define SCALE_16 0xF0000
+#define FS_384 0x20
+#define FS_256 0x0
+#define BCLK_32 0x00
+#define BCLK_48 0x40
+
+/* bit definition of L3DATA register */
+#define EX_256FS 0x20 /*-- system clock --*/
+#define EX_384FS 0x10
+#define EX_IIS 0x00 /*-- data input format --*/
+#define EX_MSB 0x08
+#define EX_1345ADDR 0x14 //The address of the UDA1345TS
+#define EX_STATUS 0x02 //data transfer type (STATUS)
+#define EX_DATA 0x00 //data transfer type (DATA)
+#define EX_ADC_On 0xC2 //turn on the ADC
+#define EX_DAC_On 0xC1 //turn on the DAC
+
+/*----- GPIO NUM -----*/
+#define L3MODE_GPIO_NUM (1<<17)
+#define L3CLOCK_GPIO_NUM (1<<18)
+#define L3DATA_GPIO_NUM (1<<19)
+
+#define MSB_FORMAT 1
+#define IIS_FORMAT 2
+
+#define IIS_ACTIVE 0x1
+#define IIS_PLAY_ACTIVE 0x2
+#define IIS_REC_ACTIVE 0x4
+
+#endif /* _W90N745_I2S_H_ */
+
+
diff --git a/uClinux-2.4.20-uc1/drivers/usb/wbusbd/Makefile b/uClinux-2.4.20-uc1/drivers/usb/wbusbd/Makefile
index 67c0de1..9972ba3 100755
--- a/uClinux-2.4.20-uc1/drivers/usb/wbusbd/Makefile
+++ b/uClinux-2.4.20-uc1/drivers/usb/wbusbd/Makefile
@@ -1,13 +1,13 @@
-#
- # Makefile for USB peripheral controller and gadget drivers
- # for kbuild 2.4
- #
-
-O_TARGET := w90n745_usbd.o
-
-obj-$(CONFIG_WINBOND_USBD_MASS) += w90n745_mass.o
-obj-$(CONFIG_WINBOND_USBD_VCOM) += w90n745_vcom.o
-
-#export-objs := w90n745_usb.o
-
-include $(TOPDIR)/Rules.make
+#
+ # Makefile for USB peripheral controller and gadget drivers
+ # for kbuild 2.4
+ #
+
+O_TARGET := w90n745_usbd.o
+
+obj-$(CONFIG_WINBOND_USBD_MASS) += w90n745_mass.o
+obj-$(CONFIG_WINBOND_USBD_VCOM) += w90n745_vcom.o
+
+#export-objs := w90n745_usb.o
+
+include $(TOPDIR)/Rules.make
diff --git a/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_mass.h b/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_mass.h
index 42d0527..655659b 100644
--- a/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_mass.h
+++ b/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_mass.h
@@ -1,250 +1,250 @@
-/****************************************************************************
- * *
- * Copyright (c) 2005 - 2007 Winbond Electronics Corp. All rights reserved. *
- * *
- ****************************************************************************/
-
-/****************************************************************************
- *
- * FILENAME
- * w90n745_mass.h
- *
- * VERSION
- * 1.0
- *
- * DESCRIPTION
- *
- *
- * DATA STRUCTURES
- * None
- *
- * FUNCTIONS
- * None
- *
- * HISTORY
- * 2005/08/01 Ver 1.0 Created by PC34 Lsshi
- *
- *
- * REMARK
- * None
- *************************************************************************/
-
-#ifndef __W90N745_MASS_H
-#define __W90N745_MASS_H
-//types
-
-#define CONST const
-
-#define FALSE 0
-#define TRUE 1
-
-typedef void VOID;
-typedef void * PVOID;
-
-typedef char BOOL;
-typedef char * PBOOL;
-
-typedef char INT8;
-typedef char CHAR;
-typedef char * PINT8;
-typedef char * PCHAR;
-typedef unsigned char UINT8;
-typedef unsigned char UCHAR;
-typedef unsigned char * PUINT8;
-typedef unsigned char * PUCHAR;
-typedef char * PSTR;
-typedef const char * PCSTR;
-
-typedef short SHORT;
-typedef short * PSHORT;
-typedef unsigned short USHORT;
-typedef unsigned short * PUSHORT;
-
-typedef short INT16;
-typedef short * PINT16;
-typedef unsigned short UINT16;
-typedef unsigned short * PUINT16;
-
-typedef int INT;
-typedef int * PINT;
-typedef unsigned int UINT;
-typedef unsigned int * PUINT;
-
-typedef int INT32;
-typedef int * PINT32;
-typedef unsigned int UINT32;
-typedef unsigned int * PUINT32;
-
-
-typedef float FLOAT;
-typedef float * PFLOAT;
-
-typedef double DOUBLE;
-typedef double * PDOUBLE;
-
-typedef int SIZE_T;
-
-typedef unsigned char REG8;
-typedef unsigned short REG16;
-typedef unsigned int REG32;
-
-
-#define outpb(port,value) (*((UINT8 volatile *) (port))=value)
-#define inpb(port) (*((UINT8 volatile *) (port)))
-#define outphw(port,value) (*((UINT16 volatile *) (port))=value)
-#define inphw(port) (*((UINT16 volatile *) (port)))
-#define outpw(port,value) (*((UINT32 volatile *) (port))=value)
-#define inpw(port) (*((UINT32 volatile *) (port)))
-
-
-#define USB_WRITE(addr,data) (*((unsigned int volatile *)(addr))=data)
-#define USB_READ(addr) (*((unsigned int volatile *)(addr)))
-///
-#define ENDPOINTS 2 //bulkin/out
-#define USB_OFFSET 0xB4
-
-#define RSTI 1
-#define SUSI 2
-#define RUMI 3
-#define GDEVI 5
-#define GCFGI 6
-#define GSTRI 7
-#define CLAI 8
-#define CDOI 10
-#define CDII 11
-#define RST_ENDI 15
-
-/**********************************************************************************************************
- *
- * USB Device Control Registers
- *
- **********************************************************************************************************/
-#define REG_USB_CTL (USB_DEVICE+0x00) /* USB control register */
-#define REG_USB_CVCMD (USB_DEVICE+0x04) /* USB class or vendor command register */
-#define REG_USB_IE (USB_DEVICE+0x08) /* USB interrupt enable register */
-#define REG_USB_IS (USB_DEVICE+0x0c) /* USB interrupt status register */
-#define REG_USB_IC (USB_DEVICE+0x10) /* USB interrupt status clear register */
-#define REG_USB_IFSTR (USB_DEVICE+0x14) /* USB interface and string register */
-#define REG_USB_ODATA0 (USB_DEVICE+0x18) /* USB control transfer-out port 0 register */
-#define REG_USB_ODATA1 (USB_DEVICE+0x1C) /* USB control transfer-out port 1 register */
-#define REG_USB_ODATA2 (USB_DEVICE+0x20) /* USB control transfer-out port 2 register */
-#define REG_USB_ODATA3 (USB_DEVICE+0x24) /* USB control transfer-out port 3 register */
-#define REG_USB_IDATA0 (USB_DEVICE+0x28) /* USB control transfer-in data port 0 register */
-#define REG_USB_IDATA1 (USB_DEVICE+0x2C) /* USB control transfer-in data port 1 register */
-#define REG_USB_IDATA2 (USB_DEVICE+0x30) /* USB control transfer-in data port 2 register */
-#define REG_USB_IDATA3 (USB_DEVICE+0x34) /* USB control transfer-in data port 2 register */
-#define REG_USB_SIE (USB_DEVICE+0x38) /* USB SIE status Register */
-#define REG_USB_ENG (USB_DEVICE+0x3c) /* USB Engine Register */
-#define REG_USB_CTLS (USB_DEVICE+0x40) /* USB control transfer status register */
-#define REG_USB_CONFD (USB_DEVICE+0x44) /* USB Configured Value register */
-#define REG_USB_EPA_INFO (USB_DEVICE+0x48) /* USB endpoint A information register */
-#define REG_USB_EPA_CTL (USB_DEVICE+0x4c) /* USB endpoint A control register */
-#define REG_USB_EPA_IE (USB_DEVICE+0x50) /* USB endpoint A Interrupt Enable register */
-#define REG_USB_EPA_IC (USB_DEVICE+0x54) /* USB endpoint A interrupt clear register */
-#define REG_USB_EPA_IS (USB_DEVICE+0x58) /* USB endpoint A interrupt status register */
-#define REG_USB_EPA_ADDR (USB_DEVICE+0x5c) /* USB endpoint A address register */
-#define REG_USB_EPA_LENTH (USB_DEVICE+0x60) /* USB endpoint A transfer length register */
-#define REG_USB_EPB_INFO (USB_DEVICE+0x64) /* USB endpoint B information register */
-#define REG_USB_EPB_CTL (USB_DEVICE+0x68) /* USB endpoint B control register */
-#define REG_USB_EPB_IE (USB_DEVICE+0x6c) /* USB endpoint B Interrupt Enable register */
-#define REG_USB_EPB_IC (USB_DEVICE+0x70) /* USB endpoint B interrupt clear register */
-#define REG_USB_EPB_IS (USB_DEVICE+0x74) /* USB endpoint B interrupt status register */
-#define REG_USB_EPB_ADDR (USB_DEVICE+0x78) /* USB endpoint B address register */
-#define REG_USB_EPB_LENTH (USB_DEVICE+0x7c) /* USB endpoint B transfer length register */
-#define REG_USB_EPC_INFO (USB_DEVICE+0x80) /* USB endpoint C information register */
-#define REG_USB_EPC_CTL (USB_DEVICE+0x84) /* USB endpoint C control register */
-#define REG_USB_EPC_IE (USB_DEVICE+0x88) /* USB endpoint C Interrupt Enable register */
-#define REG_USB_EPC_IC (USB_DEVICE+0x8c) /* USB endpoint C interrupt clear register */
-#define REG_USB_EPC_IS (USB_DEVICE+0x90) /* USB endpoint C interrupt status register */
-#define REG_USB_EPC_ADDR (USB_DEVICE+0x94) /* USB endpoint C address register */
-#define REG_USB_EPC_LENTH (USB_DEVICE+0x98) /* USB endpoint C transfer length register */
-#define REG_USB_EPA_XFER (USB_DEVICE+0x9c) /* USB endpoint A remain transfer length register */
-#define REG_USB_EPA_PKT (USB_DEVICE+0xa0) /* USB endpoint A remain packet length register */
-#define REG_USB_EPB_XFER (USB_DEVICE+0xa4) /* USB endpoint B remain transfer length register */
-#define REG_USB_EPB_PKT (USB_DEVICE+0xa8) /* USB endpoint B remain packet length register */
-#define REG_USB_EPC_XFER (USB_DEVICE+0xac) /* USB endpoint C remain transfer length register */
-#define REG_USB_EPC_PKT (USB_DEVICE+0xb0) /* USB endpoint C remain packet length register */
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#define SizePerSector 512
-
-#define RAMDISK
-
-
-//extern UINT8 volatile USB_Power_Flag; // 0: bus power de-attached; 1: attached
-
-//bulk set
-//extern UINT32 volatile Bulk_set_length;
-//extern UINT8 volatile bulksetflag;
-/* Define Endpoint feature */
-#define Ep_In 0x01
-#define Ep_Out 0x00
-#define Ep_Bulk 0x01
-#define Ep_Int 0x02
-#define Ep_Iso 0x03
-
-#define EP_A 0x00
-#define EP_B 0x01
-
-
-
-typedef struct
-{
- UINT32 dwAddr;
- UINT32 dwValue;
-
-}USB_INIT_T;
-
-typedef struct
-{
- UINT8 Req_Type;
- UINT8 Req;
- UINT16 Value;
- UINT16 Index;
- UINT16 Length;
-}USB_Vender_Cmd_Format_T __attribute__ ((aligned (4))); // each field of vendor command
-
-typedef struct {
- UINT8 EP_Num;
- UINT8 EP_Dir;
- UINT8 EP_Type;
- UINT8 p;
-} USB_EP_Inf_T __attribute__ ((aligned (4)));
-
-/////
-
-//WBUSB Structs
- typedef struct _wbusb_dev {
-
- UINT8 epnum;
- UINT8 usb_online;
- UINT8 bulkonlycmd;
-
- wait_queue_head_t wusbd_wait_a,wusbd_wait_b;
-
- USB_EP_Inf_T ep[2];
- USB_Vender_Cmd_Format_T vcmd ;
-
- enum{
- GET_DEV=1,
- GET_CFG,
- GET_STR,
- CLA_CMD
- }usb_enumstatus;
-
- int (*wait_cbw)(struct _wbusb_dev *dev,void* cbw);
- void (*rw_data)(struct _wbusb_dev *dev,UINT8* buf,UINT32 length);
- void (*rd_data)(struct _wbusb_dev *dev,UINT8* buf,UINT32 length);
-
-}wbusb_dev __attribute__ ((aligned (4)));
-/////
-#define WBUSB_MAJOR 250
-#define WBUSB_IOC_MAXNR 3
-#define WBUSB_IOC_MAGIC 'u'
-#define WBUSB_IOC_GETCBW _IOR(WBUSB_IOC_MAGIC, 0, char *)
-#define WBUSB_GETVLEN _IOR(WBUSB_IOC_MAGIC, 1, unsigned long *)
-#define WBUSB_REPLUG _IOR(WBUSB_IOC_MAGIC, 2, char *)
-void* wbusb_register_driver(void);
-
-#endif /* __WBUSB_H */
+/****************************************************************************
+ * *
+ * Copyright (c) 2005 - 2007 Winbond Electronics Corp. All rights reserved. *
+ * *
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FILENAME
+ * w90n745_mass.h
+ *
+ * VERSION
+ * 1.0
+ *
+ * DESCRIPTION
+ *
+ *
+ * DATA STRUCTURES
+ * None
+ *
+ * FUNCTIONS
+ * None
+ *
+ * HISTORY
+ * 2005/08/01 Ver 1.0 Created by PC34 Lsshi
+ *
+ *
+ * REMARK
+ * None
+ *************************************************************************/
+
+#ifndef __W90N745_MASS_H
+#define __W90N745_MASS_H
+//types
+
+#define CONST const
+
+#define FALSE 0
+#define TRUE 1
+
+typedef void VOID;
+typedef void * PVOID;
+
+typedef char BOOL;
+typedef char * PBOOL;
+
+typedef char INT8;
+typedef char CHAR;
+typedef char * PINT8;
+typedef char * PCHAR;
+typedef unsigned char UINT8;
+typedef unsigned char UCHAR;
+typedef unsigned char * PUINT8;
+typedef unsigned char * PUCHAR;
+typedef char * PSTR;
+typedef const char * PCSTR;
+
+typedef short SHORT;
+typedef short * PSHORT;
+typedef unsigned short USHORT;
+typedef unsigned short * PUSHORT;
+
+typedef short INT16;
+typedef short * PINT16;
+typedef unsigned short UINT16;
+typedef unsigned short * PUINT16;
+
+typedef int INT;
+typedef int * PINT;
+typedef unsigned int UINT;
+typedef unsigned int * PUINT;
+
+typedef int INT32;
+typedef int * PINT32;
+typedef unsigned int UINT32;
+typedef unsigned int * PUINT32;
+
+
+typedef float FLOAT;
+typedef float * PFLOAT;
+
+typedef double DOUBLE;
+typedef double * PDOUBLE;
+
+typedef int SIZE_T;
+
+typedef unsigned char REG8;
+typedef unsigned short REG16;
+typedef unsigned int REG32;
+
+
+#define outpb(port,value) (*((UINT8 volatile *) (port))=value)
+#define inpb(port) (*((UINT8 volatile *) (port)))
+#define outphw(port,value) (*((UINT16 volatile *) (port))=value)
+#define inphw(port) (*((UINT16 volatile *) (port)))
+#define outpw(port,value) (*((UINT32 volatile *) (port))=value)
+#define inpw(port) (*((UINT32 volatile *) (port)))
+
+
+#define USB_WRITE(addr,data) (*((unsigned int volatile *)(addr))=data)
+#define USB_READ(addr) (*((unsigned int volatile *)(addr)))
+///
+#define ENDPOINTS 2 //bulkin/out
+#define USB_OFFSET 0xB4
+
+#define RSTI 1
+#define SUSI 2
+#define RUMI 3
+#define GDEVI 5
+#define GCFGI 6
+#define GSTRI 7
+#define CLAI 8
+#define CDOI 10
+#define CDII 11
+#define RST_ENDI 15
+
+/**********************************************************************************************************
+ *
+ * USB Device Control Registers
+ *
+ **********************************************************************************************************/
+#define REG_USB_CTL (USB_DEVICE+0x00) /* USB control register */
+#define REG_USB_CVCMD (USB_DEVICE+0x04) /* USB class or vendor command register */
+#define REG_USB_IE (USB_DEVICE+0x08) /* USB interrupt enable register */
+#define REG_USB_IS (USB_DEVICE+0x0c) /* USB interrupt status register */
+#define REG_USB_IC (USB_DEVICE+0x10) /* USB interrupt status clear register */
+#define REG_USB_IFSTR (USB_DEVICE+0x14) /* USB interface and string register */
+#define REG_USB_ODATA0 (USB_DEVICE+0x18) /* USB control transfer-out port 0 register */
+#define REG_USB_ODATA1 (USB_DEVICE+0x1C) /* USB control transfer-out port 1 register */
+#define REG_USB_ODATA2 (USB_DEVICE+0x20) /* USB control transfer-out port 2 register */
+#define REG_USB_ODATA3 (USB_DEVICE+0x24) /* USB control transfer-out port 3 register */
+#define REG_USB_IDATA0 (USB_DEVICE+0x28) /* USB control transfer-in data port 0 register */
+#define REG_USB_IDATA1 (USB_DEVICE+0x2C) /* USB control transfer-in data port 1 register */
+#define REG_USB_IDATA2 (USB_DEVICE+0x30) /* USB control transfer-in data port 2 register */
+#define REG_USB_IDATA3 (USB_DEVICE+0x34) /* USB control transfer-in data port 2 register */
+#define REG_USB_SIE (USB_DEVICE+0x38) /* USB SIE status Register */
+#define REG_USB_ENG (USB_DEVICE+0x3c) /* USB Engine Register */
+#define REG_USB_CTLS (USB_DEVICE+0x40) /* USB control transfer status register */
+#define REG_USB_CONFD (USB_DEVICE+0x44) /* USB Configured Value register */
+#define REG_USB_EPA_INFO (USB_DEVICE+0x48) /* USB endpoint A information register */
+#define REG_USB_EPA_CTL (USB_DEVICE+0x4c) /* USB endpoint A control register */
+#define REG_USB_EPA_IE (USB_DEVICE+0x50) /* USB endpoint A Interrupt Enable register */
+#define REG_USB_EPA_IC (USB_DEVICE+0x54) /* USB endpoint A interrupt clear register */
+#define REG_USB_EPA_IS (USB_DEVICE+0x58) /* USB endpoint A interrupt status register */
+#define REG_USB_EPA_ADDR (USB_DEVICE+0x5c) /* USB endpoint A address register */
+#define REG_USB_EPA_LENTH (USB_DEVICE+0x60) /* USB endpoint A transfer length register */
+#define REG_USB_EPB_INFO (USB_DEVICE+0x64) /* USB endpoint B information register */
+#define REG_USB_EPB_CTL (USB_DEVICE+0x68) /* USB endpoint B control register */
+#define REG_USB_EPB_IE (USB_DEVICE+0x6c) /* USB endpoint B Interrupt Enable register */
+#define REG_USB_EPB_IC (USB_DEVICE+0x70) /* USB endpoint B interrupt clear register */
+#define REG_USB_EPB_IS (USB_DEVICE+0x74) /* USB endpoint B interrupt status register */
+#define REG_USB_EPB_ADDR (USB_DEVICE+0x78) /* USB endpoint B address register */
+#define REG_USB_EPB_LENTH (USB_DEVICE+0x7c) /* USB endpoint B transfer length register */
+#define REG_USB_EPC_INFO (USB_DEVICE+0x80) /* USB endpoint C information register */
+#define REG_USB_EPC_CTL (USB_DEVICE+0x84) /* USB endpoint C control register */
+#define REG_USB_EPC_IE (USB_DEVICE+0x88) /* USB endpoint C Interrupt Enable register */
+#define REG_USB_EPC_IC (USB_DEVICE+0x8c) /* USB endpoint C interrupt clear register */
+#define REG_USB_EPC_IS (USB_DEVICE+0x90) /* USB endpoint C interrupt status register */
+#define REG_USB_EPC_ADDR (USB_DEVICE+0x94) /* USB endpoint C address register */
+#define REG_USB_EPC_LENTH (USB_DEVICE+0x98) /* USB endpoint C transfer length register */
+#define REG_USB_EPA_XFER (USB_DEVICE+0x9c) /* USB endpoint A remain transfer length register */
+#define REG_USB_EPA_PKT (USB_DEVICE+0xa0) /* USB endpoint A remain packet length register */
+#define REG_USB_EPB_XFER (USB_DEVICE+0xa4) /* USB endpoint B remain transfer length register */
+#define REG_USB_EPB_PKT (USB_DEVICE+0xa8) /* USB endpoint B remain packet length register */
+#define REG_USB_EPC_XFER (USB_DEVICE+0xac) /* USB endpoint C remain transfer length register */
+#define REG_USB_EPC_PKT (USB_DEVICE+0xb0) /* USB endpoint C remain packet length register */
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define SizePerSector 512
+
+#define RAMDISK
+
+
+//extern UINT8 volatile USB_Power_Flag; // 0: bus power de-attached; 1: attached
+
+//bulk set
+//extern UINT32 volatile Bulk_set_length;
+//extern UINT8 volatile bulksetflag;
+/* Define Endpoint feature */
+#define Ep_In 0x01
+#define Ep_Out 0x00
+#define Ep_Bulk 0x01
+#define Ep_Int 0x02
+#define Ep_Iso 0x03
+
+#define EP_A 0x00
+#define EP_B 0x01
+
+
+
+typedef struct
+{
+ UINT32 dwAddr;
+ UINT32 dwValue;
+
+}USB_INIT_T;
+
+typedef struct
+{
+ UINT8 Req_Type;
+ UINT8 Req;
+ UINT16 Value;
+ UINT16 Index;
+ UINT16 Length;
+}USB_Vender_Cmd_Format_T __attribute__ ((aligned (4))); // each field of vendor command
+
+typedef struct {
+ UINT8 EP_Num;
+ UINT8 EP_Dir;
+ UINT8 EP_Type;
+ UINT8 p;
+} USB_EP_Inf_T __attribute__ ((aligned (4)));
+
+/////
+
+//WBUSB Structs
+ typedef struct _wbusb_dev {
+
+ UINT8 epnum;
+ UINT8 usb_online;
+ UINT8 bulkonlycmd;
+
+ wait_queue_head_t wusbd_wait_a,wusbd_wait_b;
+
+ USB_EP_Inf_T ep[2];
+ USB_Vender_Cmd_Format_T vcmd ;
+
+ enum{
+ GET_DEV=1,
+ GET_CFG,
+ GET_STR,
+ CLA_CMD
+ }usb_enumstatus;
+
+ int (*wait_cbw)(struct _wbusb_dev *dev,void* cbw);
+ void (*rw_data)(struct _wbusb_dev *dev,UINT8* buf,UINT32 length);
+ void (*rd_data)(struct _wbusb_dev *dev,UINT8* buf,UINT32 length);
+
+}wbusb_dev __attribute__ ((aligned (4)));
+/////
+#define WBUSB_MAJOR 250
+#define WBUSB_IOC_MAXNR 3
+#define WBUSB_IOC_MAGIC 'u'
+#define WBUSB_IOC_GETCBW _IOR(WBUSB_IOC_MAGIC, 0, char *)
+#define WBUSB_GETVLEN _IOR(WBUSB_IOC_MAGIC, 1, unsigned long *)
+#define WBUSB_REPLUG _IOR(WBUSB_IOC_MAGIC, 2, char *)
+void* wbusb_register_driver(void);
+
+#endif /* __WBUSB_H */
diff --git a/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_vcom.h b/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_vcom.h
index b27dfd9..e44b657 100644
--- a/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_vcom.h
+++ b/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_vcom.h
@@ -1,261 +1,261 @@
-/****************************************************************************
- * *
- * Copyright (c) 2005 - 2007 Winbond Electronics Corp. All rights reserved. *
- * *
- ****************************************************************************/
-
-/****************************************************************************
- *
- * FILENAME
- * w90n745_vcom .h
- *
- * VERSION
- * 1.0
- *
- * DESCRIPTION
- *
- *
- * DATA STRUCTURES
- * None
- *
- * FUNCTIONS
- * None
- *
- * HISTORY
- * 2005/08/01 Ver 1.0 Created by PC34 Lsshi
- *
- *
- * REMARK
- * None
- *************************************************************************/
-
-#ifndef __W90N745_VCOM_H
-#define __W90N745_VCOM_H
-//types
-
-#define CONST const
-
-#define FALSE 0
-#define TRUE 1
-
-typedef void VOID;
-typedef void * PVOID;
-
-typedef char BOOL;
-typedef char * PBOOL;
-
-typedef char INT8;
-typedef char CHAR;
-typedef char * PINT8;
-typedef char * PCHAR;
-typedef unsigned char UINT8;
-typedef unsigned char UCHAR;
-typedef unsigned char * PUINT8;
-typedef unsigned char * PUCHAR;
-typedef char * PSTR;
-typedef const char * PCSTR;
-
-typedef short SHORT;
-typedef short * PSHORT;
-typedef unsigned short USHORT;
-typedef unsigned short * PUSHORT;
-
-typedef short INT16;
-typedef short * PINT16;
-typedef unsigned short UINT16;
-typedef unsigned short * PUINT16;
-
-typedef int INT;
-typedef int * PINT;
-typedef unsigned int UINT;
-typedef unsigned int * PUINT;
-
-typedef int INT32;
-typedef int * PINT32;
-typedef unsigned int UINT32;
-typedef unsigned int * PUINT32;
-
-
-typedef float FLOAT;
-typedef float * PFLOAT;
-
-typedef double DOUBLE;
-typedef double * PDOUBLE;
-
-typedef int SIZE_T;
-
-typedef unsigned char REG8;
-typedef unsigned short REG16;
-typedef unsigned int REG32;
-
-
-#define outpb(port,value) (*((UINT8 volatile *) (port))=value)
-#define inpb(port) (*((UINT8 volatile *) (port)))
-#define outphw(port,value) (*((UINT16 volatile *) (port))=value)
-#define inphw(port) (*((UINT16 volatile *) (port)))
-#define outpw(port,value) (*((UINT32 volatile *) (port))=value)
-#define inpw(port) (*((UINT32 volatile *) (port)))
-
-
-#define USB_WRITE(addr,data) (*((unsigned int volatile *)(addr))=data)
-#define USB_READ(addr) (*((unsigned int volatile *)(addr)))
-///
-#define ENDPOINTS 2 //bulkin/out
-#define USB_OFFSET 0xB4
-
-#define RSTI 1
-#define SUSI 2
-#define RUMI 3
-#define GDEVI 5
-#define GCFGI 6
-#define GSTRI 7
-#define CLAI 8
-#define VENI 9
-#define CDOI 10
-#define CDII 11
-#define RST_ENDI 15
-#define RST_ENDI 15
-
-/**********************************************************************************************************
- *
- * USB Device Control Registers
- *
- **********************************************************************************************************/
-#define W90N745_USB_DEVICE 0xfff06000
-#define REG_USB_CTL (W90N745_USB_DEVICE+0x00) /* USB control register */
-#define REG_USB_CVCMD (W90N745_USB_DEVICE+0x04) /* USB class or vendor command register */
-#define REG_USB_IE (W90N745_USB_DEVICE+0x08) /* USB interrupt enable register */
-#define REG_USB_IS (W90N745_USB_DEVICE+0x0c) /* USB interrupt status register */
-#define REG_USB_IC (W90N745_USB_DEVICE+0x10) /* USB interrupt status clear register */
-#define REG_USB_IFSTR (W90N745_USB_DEVICE+0x14) /* USB interface and string register */
-#define REG_USB_ODATA0 (W90N745_USB_DEVICE+0x18) /* USB control transfer-out port 0 register */
-#define REG_USB_ODATA1 (W90N745_USB_DEVICE+0x1C) /* USB control transfer-out port 1 register */
-#define REG_USB_ODATA2 (W90N745_USB_DEVICE+0x20) /* USB control transfer-out port 2 register */
-#define REG_USB_ODATA3 (W90N745_USB_DEVICE+0x24) /* USB control transfer-out port 3 register */
-#define REG_USB_IDATA0 (W90N745_USB_DEVICE+0x28) /* USB control transfer-in data port 0 register */
-#define REG_USB_IDATA1 (W90N745_USB_DEVICE+0x2C) /* USB control transfer-in data port 1 register */
-#define REG_USB_IDATA2 (W90N745_USB_DEVICE+0x30) /* USB control transfer-in data port 2 register */
-#define REG_USB_IDATA3 (W90N745_USB_DEVICE+0x34) /* USB control transfer-in data port 2 register */
-#define REG_USB_SIE (W90N745_USB_DEVICE+0x38) /* USB SIE status Register */
-#define REG_USB_ENG (W90N745_USB_DEVICE+0x3c) /* USB Engine Register */
-#define REG_USB_CTLS (W90N745_USB_DEVICE+0x40) /* USB control transfer status register */
-#define REG_USB_CONFD (W90N745_USB_DEVICE+0x44) /* USB Configured Value register */
-#define REG_USB_EPA_INFO (W90N745_USB_DEVICE+0x48) /* USB endpoint A information register */
-#define REG_USB_EPA_CTL (W90N745_USB_DEVICE+0x4c) /* USB endpoint A control register */
-#define REG_USB_EPA_IE (W90N745_USB_DEVICE+0x50) /* USB endpoint A Interrupt Enable register */
-#define REG_USB_EPA_IC (W90N745_USB_DEVICE+0x54) /* USB endpoint A interrupt clear register */
-#define REG_USB_EPA_IS (W90N745_USB_DEVICE+0x58) /* USB endpoint A interrupt status register */
-#define REG_USB_EPA_ADDR (W90N745_USB_DEVICE+0x5c) /* USB endpoint A address register */
-#define REG_USB_EPA_LENTH (W90N745_USB_DEVICE+0x60) /* USB endpoint A transfer length register */
-#define REG_USB_EPB_INFO (W90N745_USB_DEVICE+0x64) /* USB endpoint B information register */
-#define REG_USB_EPB_CTL (W90N745_USB_DEVICE+0x68) /* USB endpoint B control register */
-#define REG_USB_EPB_IE (W90N745_USB_DEVICE+0x6c) /* USB endpoint B Interrupt Enable register */
-#define REG_USB_EPB_IC (W90N745_USB_DEVICE+0x70) /* USB endpoint B interrupt clear register */
-#define REG_USB_EPB_IS (W90N745_USB_DEVICE+0x74) /* USB endpoint B interrupt status register */
-#define REG_USB_EPB_ADDR (W90N745_USB_DEVICE+0x78) /* USB endpoint B address register */
-#define REG_USB_EPB_LENTH (W90N745_USB_DEVICE+0x7c) /* USB endpoint B transfer length register */
-#define REG_USB_EPC_INFO (W90N745_USB_DEVICE+0x80) /* USB endpoint C information register */
-#define REG_USB_EPC_CTL (W90N745_USB_DEVICE+0x84) /* USB endpoint C control register */
-#define REG_USB_EPC_IE (W90N745_USB_DEVICE+0x88) /* USB endpoint C Interrupt Enable register */
-#define REG_USB_EPC_IC (W90N745_USB_DEVICE+0x8c) /* USB endpoint C interrupt clear register */
-#define REG_USB_EPC_IS (W90N745_USB_DEVICE+0x90) /* USB endpoint C interrupt status register */
-#define REG_USB_EPC_ADDR (W90N745_USB_DEVICE+0x94) /* USB endpoint C address register */
-#define REG_USB_EPC_LENTH (W90N745_USB_DEVICE+0x98) /* USB endpoint C transfer length register */
-#define REG_USB_EPA_XFER (W90N745_USB_DEVICE+0x9c) /* USB endpoint A remain transfer length register */
-#define REG_USB_EPA_PKT (W90N745_USB_DEVICE+0xa0) /* USB endpoint A remain packet length register */
-#define REG_USB_EPB_XFER (W90N745_USB_DEVICE+0xa4) /* USB endpoint B remain transfer length register */
-#define REG_USB_EPB_PKT (W90N745_USB_DEVICE+0xa8) /* USB endpoint B remain packet length register */
-#define REG_USB_EPC_XFER (W90N745_USB_DEVICE+0xac) /* USB endpoint C remain transfer length register */
-#define REG_USB_EPC_PKT (W90N745_USB_DEVICE+0xb0) /* USB endpoint C remain packet length register */
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#define SizePerSector 512
-
-#define RAMDISK
-
-
-//extern UINT8 volatile USB_Power_Flag; // 0: bus power de-attached; 1: attached
-
-//bulk set
-//extern UINT32 volatile Bulk_set_length;
-//extern UINT8 volatile bulksetflag;
-/* Define Endpoint feature */
-#define Ep_In 0x01
-#define Ep_Out 0x00
-#define Ep_Bulk 0x01
-#define Ep_Int 0x02
-#define Ep_Iso 0x03
-
-#define EP_A 0x00
-#define EP_B 0x01
-
-
-
-typedef struct
-{
- UINT32 dwAddr;
- UINT32 dwValue;
-
-}USB_INIT_T;
-
-typedef struct
-{
- UINT8 Req_Type;
- UINT8 Req;
- UINT16 Value;
- UINT16 Index;
- UINT16 Length;
-}USB_Vender_Cmd_Format_T __attribute__ ((aligned (4))); // each field of vendor command
-
-typedef struct {
- UINT8 EP_Num;
- UINT8 EP_Dir;
- UINT8 EP_Type;
- UINT8 p;
-} USB_EP_Inf_T __attribute__ ((aligned (4)));
-
-/////
-
-//WBUSB Structs
- typedef struct _wbusb_dev {
-
- UINT8 epnum;
- UINT8 usb_online;
- UINT8 bulkonlycmd;
- UINT32 bulk_len;
-
- wait_queue_head_t wusbd_wait_a,wusbd_wait_b,wusbd_wait_c;
-
- USB_EP_Inf_T ep[2];
- USB_Vender_Cmd_Format_T vcmd ;
-
- enum{
- GET_DEV=1,
- GET_CFG,
- GET_STR,
- CLA_CMDIN,
- VEN_CMDIN,
- VEN_CMDOUT
- }usb_enumstatus;
-
- int (*wait_cbw)(struct _wbusb_dev *dev,void* cbw);
- void (*rw_data)(struct _wbusb_dev *dev,UINT8* buf,UINT32 length);
- void (*rd_data)(struct _wbusb_dev *dev,UINT8* buf,UINT32 length);
-
-}wbusb_dev __attribute__ ((aligned (4)));
-/////
-
-#define WBUSB_MAJOR 250
-
-#define WBUSB_IOC_MAXNR 3
-
-#define WBUSB_IOC_MAGIC 'u'
-
-#define WBUSB_IOC_GETCBW _IOR(WBUSB_IOC_MAGIC, 0, char *)
-#define WBUSB_GETVLEN _IOR(WBUSB_IOC_MAGIC, 1, unsigned long *)
-#define WBUSB_REPLUG _IOR(WBUSB_IOC_MAGIC, 2, char *)
-
-#define INT_USBD 22
-
-#endif /* __WBUSB_H */
+/****************************************************************************
+ * *
+ * Copyright (c) 2005 - 2007 Winbond Electronics Corp. All rights reserved. *
+ * *
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FILENAME
+ * w90n745_vcom .h
+ *
+ * VERSION
+ * 1.0
+ *
+ * DESCRIPTION
+ *
+ *
+ * DATA STRUCTURES
+ * None
+ *
+ * FUNCTIONS
+ * None
+ *
+ * HISTORY
+ * 2005/08/01 Ver 1.0 Created by PC34 Lsshi
+ *
+ *
+ * REMARK
+ * None
+ *************************************************************************/
+
+#ifndef __W90N745_VCOM_H
+#define __W90N745_VCOM_H
+//types
+
+#define CONST const
+
+#define FALSE 0
+#define TRUE 1
+
+typedef void VOID;
+typedef void * PVOID;
+
+typedef char BOOL;
+typedef char * PBOOL;
+
+typedef char INT8;
+typedef char CHAR;
+typedef char * PINT8;
+typedef char * PCHAR;
+typedef unsigned char UINT8;
+typedef unsigned char UCHAR;
+typedef unsigned char * PUINT8;
+typedef unsigned char * PUCHAR;
+typedef char * PSTR;
+typedef const char * PCSTR;
+
+typedef short SHORT;
+typedef short * PSHORT;
+typedef unsigned short USHORT;
+typedef unsigned short * PUSHORT;
+
+typedef short INT16;
+typedef short * PINT16;
+typedef unsigned short UINT16;
+typedef unsigned short * PUINT16;
+
+typedef int INT;
+typedef int * PINT;
+typedef unsigned int UINT;
+typedef unsigned int * PUINT;
+
+typedef int INT32;
+typedef int * PINT32;
+typedef unsigned int UINT32;
+typedef unsigned int * PUINT32;
+
+
+typedef float FLOAT;
+typedef float * PFLOAT;
+
+typedef double DOUBLE;
+typedef double * PDOUBLE;
+
+typedef int SIZE_T;
+
+typedef unsigned char REG8;
+typedef unsigned short REG16;
+typedef unsigned int REG32;
+
+
+#define outpb(port,value) (*((UINT8 volatile *) (port))=value)
+#define inpb(port) (*((UINT8 volatile *) (port)))
+#define outphw(port,value) (*((UINT16 volatile *) (port))=value)
+#define inphw(port) (*((UINT16 volatile *) (port)))
+#define outpw(port,value) (*((UINT32 volatile *) (port))=value)
+#define inpw(port) (*((UINT32 volatile *) (port)))
+
+
+#define USB_WRITE(addr,data) (*((unsigned int volatile *)(addr))=data)
+#define USB_READ(addr) (*((unsigned int volatile *)(addr)))
+///
+#define ENDPOINTS 2 //bulkin/out
+#define USB_OFFSET 0xB4
+
+#define RSTI 1
+#define SUSI 2
+#define RUMI 3
+#define GDEVI 5
+#define GCFGI 6
+#define GSTRI 7
+#define CLAI 8
+#define VENI 9
+#define CDOI 10
+#define CDII 11
+#define RST_ENDI 15
+#define RST_ENDI 15
+
+/**********************************************************************************************************
+ *
+ * USB Device Control Registers
+ *
+ **********************************************************************************************************/
+#define W90N745_USB_DEVICE 0xfff06000
+#define REG_USB_CTL (W90N745_USB_DEVICE+0x00) /* USB control register */
+#define REG_USB_CVCMD (W90N745_USB_DEVICE+0x04) /* USB class or vendor command register */
+#define REG_USB_IE (W90N745_USB_DEVICE+0x08) /* USB interrupt enable register */
+#define REG_USB_IS (W90N745_USB_DEVICE+0x0c) /* USB interrupt status register */
+#define REG_USB_IC (W90N745_USB_DEVICE+0x10) /* USB interrupt status clear register */
+#define REG_USB_IFSTR (W90N745_USB_DEVICE+0x14) /* USB interface and string register */
+#define REG_USB_ODATA0 (W90N745_USB_DEVICE+0x18) /* USB control transfer-out port 0 register */
+#define REG_USB_ODATA1 (W90N745_USB_DEVICE+0x1C) /* USB control transfer-out port 1 register */
+#define REG_USB_ODATA2 (W90N745_USB_DEVICE+0x20) /* USB control transfer-out port 2 register */
+#define REG_USB_ODATA3 (W90N745_USB_DEVICE+0x24) /* USB control transfer-out port 3 register */
+#define REG_USB_IDATA0 (W90N745_USB_DEVICE+0x28) /* USB control transfer-in data port 0 register */
+#define REG_USB_IDATA1 (W90N745_USB_DEVICE+0x2C) /* USB control transfer-in data port 1 register */
+#define REG_USB_IDATA2 (W90N745_USB_DEVICE+0x30) /* USB control transfer-in data port 2 register */
+#define REG_USB_IDATA3 (W90N745_USB_DEVICE+0x34) /* USB control transfer-in data port 2 register */
+#define REG_USB_SIE (W90N745_USB_DEVICE+0x38) /* USB SIE status Register */
+#define REG_USB_ENG (W90N745_USB_DEVICE+0x3c) /* USB Engine Register */
+#define REG_USB_CTLS (W90N745_USB_DEVICE+0x40) /* USB control transfer status register */
+#define REG_USB_CONFD (W90N745_USB_DEVICE+0x44) /* USB Configured Value register */
+#define REG_USB_EPA_INFO (W90N745_USB_DEVICE+0x48) /* USB endpoint A information register */
+#define REG_USB_EPA_CTL (W90N745_USB_DEVICE+0x4c) /* USB endpoint A control register */
+#define REG_USB_EPA_IE (W90N745_USB_DEVICE+0x50) /* USB endpoint A Interrupt Enable register */
+#define REG_USB_EPA_IC (W90N745_USB_DEVICE+0x54) /* USB endpoint A interrupt clear register */
+#define REG_USB_EPA_IS (W90N745_USB_DEVICE+0x58) /* USB endpoint A interrupt status register */
+#define REG_USB_EPA_ADDR (W90N745_USB_DEVICE+0x5c) /* USB endpoint A address register */
+#define REG_USB_EPA_LENTH (W90N745_USB_DEVICE+0x60) /* USB endpoint A transfer length register */
+#define REG_USB_EPB_INFO (W90N745_USB_DEVICE+0x64) /* USB endpoint B information register */
+#define REG_USB_EPB_CTL (W90N745_USB_DEVICE+0x68) /* USB endpoint B control register */
+#define REG_USB_EPB_IE (W90N745_USB_DEVICE+0x6c) /* USB endpoint B Interrupt Enable register */
+#define REG_USB_EPB_IC (W90N745_USB_DEVICE+0x70) /* USB endpoint B interrupt clear register */
+#define REG_USB_EPB_IS (W90N745_USB_DEVICE+0x74) /* USB endpoint B interrupt status register */
+#define REG_USB_EPB_ADDR (W90N745_USB_DEVICE+0x78) /* USB endpoint B address register */
+#define REG_USB_EPB_LENTH (W90N745_USB_DEVICE+0x7c) /* USB endpoint B transfer length register */
+#define REG_USB_EPC_INFO (W90N745_USB_DEVICE+0x80) /* USB endpoint C information register */
+#define REG_USB_EPC_CTL (W90N745_USB_DEVICE+0x84) /* USB endpoint C control register */
+#define REG_USB_EPC_IE (W90N745_USB_DEVICE+0x88) /* USB endpoint C Interrupt Enable register */
+#define REG_USB_EPC_IC (W90N745_USB_DEVICE+0x8c) /* USB endpoint C interrupt clear register */
+#define REG_USB_EPC_IS (W90N745_USB_DEVICE+0x90) /* USB endpoint C interrupt status register */
+#define REG_USB_EPC_ADDR (W90N745_USB_DEVICE+0x94) /* USB endpoint C address register */
+#define REG_USB_EPC_LENTH (W90N745_USB_DEVICE+0x98) /* USB endpoint C transfer length register */
+#define REG_USB_EPA_XFER (W90N745_USB_DEVICE+0x9c) /* USB endpoint A remain transfer length register */
+#define REG_USB_EPA_PKT (W90N745_USB_DEVICE+0xa0) /* USB endpoint A remain packet length register */
+#define REG_USB_EPB_XFER (W90N745_USB_DEVICE+0xa4) /* USB endpoint B remain transfer length register */
+#define REG_USB_EPB_PKT (W90N745_USB_DEVICE+0xa8) /* USB endpoint B remain packet length register */
+#define REG_USB_EPC_XFER (W90N745_USB_DEVICE+0xac) /* USB endpoint C remain transfer length register */
+#define REG_USB_EPC_PKT (W90N745_USB_DEVICE+0xb0) /* USB endpoint C remain packet length register */
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define SizePerSector 512
+
+#define RAMDISK
+
+
+//extern UINT8 volatile USB_Power_Flag; // 0: bus power de-attached; 1: attached
+
+//bulk set
+//extern UINT32 volatile Bulk_set_length;
+//extern UINT8 volatile bulksetflag;
+/* Define Endpoint feature */
+#define Ep_In 0x01
+#define Ep_Out 0x00
+#define Ep_Bulk 0x01
+#define Ep_Int 0x02
+#define Ep_Iso 0x03
+
+#define EP_A 0x00
+#define EP_B 0x01
+
+
+
+typedef struct
+{
+ UINT32 dwAddr;
+ UINT32 dwValue;
+
+}USB_INIT_T;
+
+typedef struct
+{
+ UINT8 Req_Type;
+ UINT8 Req;
+ UINT16 Value;
+ UINT16 Index;
+ UINT16 Length;
+}USB_Vender_Cmd_Format_T __attribute__ ((aligned (4))); // each field of vendor command
+
+typedef struct {
+ UINT8 EP_Num;
+ UINT8 EP_Dir;
+ UINT8 EP_Type;
+ UINT8 p;
+} USB_EP_Inf_T __attribute__ ((aligned (4)));
+
+/////
+
+//WBUSB Structs
+ typedef struct _wbusb_dev {
+
+ UINT8 epnum;
+ UINT8 usb_online;
+ UINT8 bulkonlycmd;
+ UINT32 bulk_len;
+
+ wait_queue_head_t wusbd_wait_a,wusbd_wait_b,wusbd_wait_c;
+
+ USB_EP_Inf_T ep[2];
+ USB_Vender_Cmd_Format_T vcmd ;
+
+ enum{
+ GET_DEV=1,
+ GET_CFG,
+ GET_STR,
+ CLA_CMDIN,
+ VEN_CMDIN,
+ VEN_CMDOUT
+ }usb_enumstatus;
+
+ int (*wait_cbw)(struct _wbusb_dev *dev,void* cbw);
+ void (*rw_data)(struct _wbusb_dev *dev,UINT8* buf,UINT32 length);
+ void (*rd_data)(struct _wbusb_dev *dev,UINT8* buf,UINT32 length);
+
+}wbusb_dev __attribute__ ((aligned (4)));
+/////
+
+#define WBUSB_MAJOR 250
+
+#define WBUSB_IOC_MAXNR 3
+
+#define WBUSB_IOC_MAGIC 'u'
+
+#define WBUSB_IOC_GETCBW _IOR(WBUSB_IOC_MAGIC, 0, char *)
+#define WBUSB_GETVLEN _IOR(WBUSB_IOC_MAGIC, 1, unsigned long *)
+#define WBUSB_REPLUG _IOR(WBUSB_IOC_MAGIC, 2, char *)
+
+#define INT_USBD 22
+
+#endif /* __WBUSB_H */
diff --git a/uClinux-2.4.20-uc1/include/asm-armnommu/arch-W90N745/flash.h b/uClinux-2.4.20-uc1/include/asm-armnommu/arch-W90N745/flash.h
index 49451df..4a8867d 100644
--- a/uClinux-2.4.20-uc1/include/asm-armnommu/arch-W90N745/flash.h
+++ b/uClinux-2.4.20-uc1/include/asm-armnommu/arch-W90N745/flash.h
@@ -1,103 +1,103 @@
-#ifndef FLASH_H
-#define FLASH_H
-//---------------------------------------------------------------------------
-#include <asm/arch/cdefs.h>
-#include <asm/arch/bib.h>
-
-
-// if no platform.h
-#ifndef FLASH_BASE
-#define FLASH_BASE (0x7F000000)
-#define FLASH_BLOCK_SIZE (0x10000)
-#endif
-
-#ifndef ROMCON
-#define ROMCON (0xFFF01004)
-#endif
-
-#define EXT3CON (0xFFF01024)
-
-#define FLASH_NAME_SIZE 16
-
-#define VP_int(x) (*((volatile unsigned int*)(x)))
-#define VP_short(x) (*((volatile unsigned short*)(x)))
-#define VP_char(x) (*((volatile unsigned char*)(x)))
-#define CAHCNF_R VP_int(0xFFF02000)
-#define CAHCON_R VP_int(0xFFF02004)
-
-#if 0
-#define inph(x) VP_short(x)
-#define outph(x,y) VP_short(x)=(y)
-#define inpb(x) VP_char(x)
-#define outpb(x,y) VP_char(x)=(y)
-#endif
-
-
-#define inpw(port) *((volatile unsigned int *)port)
-#define outpw(port,x) *((volatile unsigned int *)port)=x
-#define inph(port) *((volatile unsigned short *)port)
-#define outph(port,x) *((volatile unsigned short *)port)=x
-#define inpb(port) *((volatile unsigned char *)port)
-#define outpb(port,x) *((volatile unsigned char *)port)=x
-
-
-#define BLOCK_LOCK 0
-#define BLOCK_UNLOCK 1
-
-
-typedef struct
-{
- char PID0;
- char PID1;
- char name[FLASH_NAME_SIZE];
- int (*BlockSize)(UINT32 address);
- int (*BlockErase)(UINT32 address,UINT32 size);
- int (*BlockWrite)(UINT32 address, UCHAR * data, UINT32 size);
- int (*ReadPID)(UINT32 address, UCHAR *PID0, UCHAR *PID1 );
- int (*BlockLock)(UINT32 address, UINT32 op);
-} flash_t;
-
-
-
-#define IMAGE_ACTIVE 0x1 // Only the active image will be processed by bootloader
-#define IMAGE_COPY2RAM 0x2 // copy this image to ram
-#define IMAGE_EXEC 0x4 // execute this image
-#define IMAGE_FILE 0x8 // file image
-#define IMAGE_COMPRESSED 0x10 // compressed image, bootloader will unzip it
-#define SIGNATURE_WORD 0xA0FFFF9F
-
-typedef struct t_footer
-{
- UINT32 num;
- UINT32 base;
- UINT32 length;
- UINT32 load_address;
- UINT32 exec_address;
- CHAR name[16];
- UINT32 image_checksum;
- UINT32 signature;
- UINT32 type;
- UINT32 checksum;
-} tfooter;
-
-
-#define MAX_FOOTER_NUM 8
-
-
-#define BOOTER_BLOCK_LENGTH FLASH_BLOCK_SIZE
-extern flash_t flash[];// The supported flash types
-extern int flash_type;
-extern UINT32 _flash_size;
-extern char * _flash_buffer;
-
-extern int FindFlash(void); // function to identify the flash type
-extern int FindFooter(tfooter *** image_footer); //function to find the image footers
-int sys_DelImage(UINT32 image_num);
-int sys_FindImage(UINT32 image_num, tfooter ** image_footer);
-extern int sys_CorruptCheck(tfooter * image_footer);//function to check if data corrupt
-extern tbl_info info;
-extern int GetImgAddr(unsigned int default_addr);
-extern int GetLoadImage();
-extern int get_flash_type_num(void);
-//---------------------------------------------------------------------------
-#endif
+#ifndef FLASH_H
+#define FLASH_H
+//---------------------------------------------------------------------------
+#include <asm/arch/cdefs.h>
+#include <asm/arch/bib.h>
+
+
+// if no platform.h
+#ifndef FLASH_BASE
+#define FLASH_BASE (0x7F000000)
+#define FLASH_BLOCK_SIZE (0x10000)
+#endif
+
+#ifndef ROMCON
+#define ROMCON (0xFFF01004)
+#endif
+
+#define EXT3CON (0xFFF01024)
+
+#define FLASH_NAME_SIZE 16
+
+#define VP_int(x) (*((volatile unsigned int*)(x)))
+#define VP_short(x) (*((volatile unsigned short*)(x)))
+#define VP_char(x) (*((volatile unsigned char*)(x)))
+#define CAHCNF_R VP_int(0xFFF02000)
+#define CAHCON_R VP_int(0xFFF02004)
+
+#if 0
+#define inph(x) VP_short(x)
+#define outph(x,y) VP_short(x)=(y)
+#define inpb(x) VP_char(x)
+#define outpb(x,y) VP_char(x)=(y)
+#endif
+
+
+#define inpw(port) *((volatile unsigned int *)port)
+#define outpw(port,x) *((volatile unsigned int *)port)=x
+#define inph(port) *((volatile unsigned short *)port)
+#define outph(port,x) *((volatile unsigned short *)port)=x
+#define inpb(port) *((volatile unsigned char *)port)
+#define outpb(port,x) *((volatile unsigned char *)port)=x
+
+
+#define BLOCK_LOCK 0
+#define BLOCK_UNLOCK 1
+
+
+typedef struct
+{
+ char PID0;
+ char PID1;
+ char name[FLASH_NAME_SIZE];
+ int (*BlockSize)(UINT32 address);
+ int (*BlockErase)(UINT32 address,UINT32 size);
+ int (*BlockWrite)(UINT32 address, UCHAR * data, UINT32 size);
+ int (*ReadPID)(UINT32 address, UCHAR *PID0, UCHAR *PID1 );
+ int (*BlockLock)(UINT32 address, UINT32 op);
+} flash_t;
+
+
+
+#define IMAGE_ACTIVE 0x1 // Only the active image will be processed by bootloader
+#define IMAGE_COPY2RAM 0x2 // copy this image to ram
+#define IMAGE_EXEC 0x4 // execute this image
+#define IMAGE_FILE 0x8 // file image
+#define IMAGE_COMPRESSED 0x10 // compressed image, bootloader will unzip it
+#define SIGNATURE_WORD 0xA0FFFF9F
+
+typedef struct t_footer
+{
+ UINT32 num;
+ UINT32 base;
+ UINT32 length;
+ UINT32 load_address;
+ UINT32 exec_address;
+ CHAR name[16];
+ UINT32 image_checksum;
+ UINT32 signature;
+ UINT32 type;
+ UINT32 checksum;
+} tfooter;
+
+
+#define MAX_FOOTER_NUM 8
+
+
+#define BOOTER_BLOCK_LENGTH FLASH_BLOCK_SIZE
+extern flash_t flash[];// The supported flash types
+extern int flash_type;
+extern UINT32 _flash_size;
+extern char * _flash_buffer;
+
+extern int FindFlash(void); // function to identify the flash type
+extern int FindFooter(tfooter *** image_footer); //function to find the image footers
+int sys_DelImage(UINT32 image_num);
+int sys_FindImage(UINT32 image_num, tfooter ** image_footer);
+extern int sys_CorruptCheck(tfooter * image_footer);//function to check if data corrupt
+extern tbl_info info;
+extern int GetImgAddr(unsigned int default_addr);
+extern int GetLoadImage();
+extern int get_flash_type_num(void);
+//---------------------------------------------------------------------------
+#endif
diff --git a/uClinux-2.4.20-uc1/include/gpio/gpio_interface.h b/uClinux-2.4.20-uc1/include/gpio/gpio_interface.h
index e371810..fe34c2d 100644
--- a/uClinux-2.4.20-uc1/include/gpio/gpio_interface.h
+++ b/uClinux-2.4.20-uc1/include/gpio/gpio_interface.h
@@ -1,40 +1,40 @@
-#define GPIO_OUT 1
-#define GPIO_IN 0
-
-#define GPIO_TIMEOUT (-2)
-#define GPIO_ERROR (-1)
-#define GPIO_OK (0)
-
-#define GPIO_LOW 0
-#define GPIO_HIGH 1
-
-#define GPIO_CHANNEL_0_3 0xFFFFFFFC
-#define GPIO_CHANNEL_9_4 0xFFFFFFF3
-#define GPIO_CHANNEL_11_10 0xFFFFFFCF
-#define GPIO_CHANNEL_12 0xFFFFFF3F
-#define GPIO_CHANNEL_13 0xFFFFFCFF
-#define GPIO_CHANNEL_14 0xFFFFF3FF
-#define GPIO_CHANNEL_16_15 0xFFFFCFFF
-#define GPIO_CHANNEL_17 0xFFFFCFFF
-#define GPIO_CHANNEL_18 0xFFFCFFFF
-#define GPIO_CHANNEL_19 0xFFF3FFFF
-#define GPIO_CHANNEL_20 0xFFCFFFFF
-
-
-extern void GPIO_Enable_Channel(int channel);//normal I/O mode
-
-extern int Set_Dir(int channel, int dir);
-extern void GPIO_SET(int channel_num, int sig_status);
-extern int GPIO_GET(int channel_num);//0-20
-
-extern int GPIO_EnableChannel0_3(int mode);
-extern int GPIO_EnableChannel4_9(int mode);
-extern int GPIO_EnableChannel10_11(int mode);
-extern int GPIO_EnableChannel12(int mode);
-extern int GPIO_EnableChannel13(int mode);
-extern int GPIO_EnableChannel14(int mode);
-extern int GPIO_EnableChannel15_16(int mode);
-extern int GPIO_EnableChannel17(int mode);
-extern int GPIO_EnableChannel18(int mode);
-extern int GPIO_EnableChannel19(int mode);
-extern int GPIO_EnableChannel20(int mode);
+#define GPIO_OUT 1
+#define GPIO_IN 0
+
+#define GPIO_TIMEOUT (-2)
+#define GPIO_ERROR (-1)
+#define GPIO_OK (0)
+
+#define GPIO_LOW 0
+#define GPIO_HIGH 1
+
+#define GPIO_CHANNEL_0_3 0xFFFFFFFC
+#define GPIO_CHANNEL_9_4 0xFFFFFFF3
+#define GPIO_CHANNEL_11_10 0xFFFFFFCF
+#define GPIO_CHANNEL_12 0xFFFFFF3F
+#define GPIO_CHANNEL_13 0xFFFFFCFF
+#define GPIO_CHANNEL_14 0xFFFFF3FF
+#define GPIO_CHANNEL_16_15 0xFFFFCFFF
+#define GPIO_CHANNEL_17 0xFFFFCFFF
+#define GPIO_CHANNEL_18 0xFFFCFFFF
+#define GPIO_CHANNEL_19 0xFFF3FFFF
+#define GPIO_CHANNEL_20 0xFFCFFFFF
+
+
+extern void GPIO_Enable_Channel(int channel);//normal I/O mode
+
+extern int Set_Dir(int channel, int dir);
+extern void GPIO_SET(int channel_num, int sig_status);
+extern int GPIO_GET(int channel_num);//0-20
+
+extern int GPIO_EnableChannel0_3(int mode);
+extern int GPIO_EnableChannel4_9(int mode);
+extern int GPIO_EnableChannel10_11(int mode);
+extern int GPIO_EnableChannel12(int mode);
+extern int GPIO_EnableChannel13(int mode);
+extern int GPIO_EnableChannel14(int mode);
+extern int GPIO_EnableChannel15_16(int mode);
+extern int GPIO_EnableChannel17(int mode);
+extern int GPIO_EnableChannel18(int mode);
+extern int GPIO_EnableChannel19(int mode);
+extern int GPIO_EnableChannel20(int mode);