From 979d729439057488023d5ba6f095b9256d5d242e Mon Sep 17 00:00:00 2001 From: Oliver Schinagl Date: Tue, 19 Apr 2011 11:10:12 +0000 Subject: convert to unix file format --- uClinux-2.4.20-uc1/drivers/block/export.c | 76 +- uClinux-2.4.20-uc1/drivers/block/wbflash/cfi.c | 558 +++--- uClinux-2.4.20-uc1/drivers/block/wbflash/cfi.h | 78 +- uClinux-2.4.20-uc1/drivers/block/wbflash/flash.c | 2112 ++++++++++---------- uClinux-2.4.20-uc1/drivers/block/wbflash/flash_u.c | 492 ++--- uClinux-2.4.20-uc1/drivers/block/wbflash/image.c | 356 ++-- uClinux-2.4.20-uc1/drivers/char/vdd.c | 944 ++++----- uClinux-2.4.20-uc1/drivers/char/w90n745_i2c.c | 1200 +++++------ uClinux-2.4.20-uc1/drivers/char/w90n745_i2c.h | 246 +-- uClinux-2.4.20-uc1/drivers/char/w90n745_keypad.c | 506 ++--- uClinux-2.4.20-uc1/drivers/char/w90n745_keypad.h | 114 +- uClinux-2.4.20-uc1/drivers/char/w90n745_usi.c | 662 +++--- uClinux-2.4.20-uc1/drivers/char/w90n745_usi.h | 146 +- uClinux-2.4.20-uc1/drivers/sound/w90n745_ac97.c | 1674 ++++++++-------- uClinux-2.4.20-uc1/drivers/sound/w90n745_ac97.h | 120 +- uClinux-2.4.20-uc1/drivers/sound/w90n745_audio.h | 290 +-- .../drivers/sound/w90n745_audio_regs.h | 398 ++-- uClinux-2.4.20-uc1/drivers/sound/w90n745_i2s.c | 1354 ++++++------- uClinux-2.4.20-uc1/drivers/sound/w90n745_i2s.h | 138 +- uClinux-2.4.20-uc1/drivers/usb/wbusbd/Makefile | 26 +- .../drivers/usb/wbusbd/w90n745_mass.h | 500 ++--- .../drivers/usb/wbusbd/w90n745_vcom.h | 522 ++--- .../include/asm-armnommu/arch-W90N745/flash.h | 206 +- uClinux-2.4.20-uc1/include/gpio/gpio_interface.h | 80 +- 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 -#include - -#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 +#include + +#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 -//#include -//#include -//#include "wblib.h" -#include -#include -#include - -#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 +//#include +//#include +//#include "wblib.h" +#include +#include +#include + +#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 -#include -#include -// 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= 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= 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 +#include +#include +// 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= 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= 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#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)>=cfiGetBlockSize(dest))) - { - if((dest&(blockSize-1))||(dest+i-addr)<=blockSize) - { -#ifdef _DEBUG -printk("Write direct\n"); -#endif - if(i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#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)>=cfiGetBlockSize(dest))) + { + if((dest&(blockSize-1))||(dest+i-addr)<=blockSize) + { +#ifdef _DEBUG +printk("Write direct\n"); +#endif + if(i -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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>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;inum == 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;inum == 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;ibase; - 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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>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;inum == 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;inum == 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;ibase; + 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#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 -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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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 +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 -#include -#include -#include -#include -#include -#include -#include -#include - -#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;ino] + 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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;ino] + 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 -#include - -#include - -#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 +#include + +#include + +#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 -#include -#include -#include -//#include -#include -#include -#include -#include -#include -#include -#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 +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#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;ibit_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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#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;ibit_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 -#include - -#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 +#include + +#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 -#include -#include -#include - -#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 +#include +#include +#include + +#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 -#include - -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 +#include + +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 -#include -#include -#include - -#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 +#include +#include +#include + +#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 -#include - - -// 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 +#include + + +// 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); -- cgit v0.12