⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 w83977.c

📁 华邦的超级IO芯片W83977TF的驱动程序。当初我是搞了好久的
💻 C
字号:
#include "def.h"
#include "2410lib.h"
#include "2410addr.h"
#include "w83977.h"

/**************************************************
*  *date:2007-08-15 (created)
*  *author: baijb
*  *version: v1.0
*  *function: winbond W83977TF configuration
**************************************************/
static unsigned int efbase[] = { W977_EFIO_BASE+nGCS7, W977_EFIO2_BASE+nGCS7 };
static unsigned int efio = W977_EFIO_BASE;

#define readb(x)    		(*(volatile unsigned char *)x)  
#define writeb(val, x)   	(*(volatile unsigned char *)x)=val
#define readw(x)		(*(volatile unsigned short *)x)
#define writew(val, x)	(*(volatile unsigned short *)x)=val

/*
 * Enter extended function mode
 */
static void w977_efm_enter(unsigned int efio)
{
        writeb(0x87, efio);
        writeb(0x87, efio);
}

/*
 * Select a device to configure 
 * devnum:	UARTA:2                  KBC:5
 */

static void w977_select_device(unsigned char devnum, unsigned int efio)
{
	unsigned int addr;
	writeb(0x07, efio);
	addr=efio+1;
	writeb(devnum, addr);
} 

/* 
 * Write a byte to a register
 */
static void w977_write_reg(unsigned char reg, unsigned char value, unsigned int efio)
{
	unsigned int addr;
	
	writeb(reg, efio);
	addr=efio+1;
	writeb(value, addr);
}

/*
 * read a byte from a register
 */
static unsigned char w977_read_reg(unsigned char reg, unsigned int efio)
{
	unsigned int addr;
	writeb(reg, efio);
	addr=efio+1;
	return readb(addr);
}

/*
 * Exit extended function mode
 */
static  void w977_efm_exit(unsigned int efio)
{
	writeb(0xAA, efio);
}

/*******************************************************
*  *logic device operation
*******************************************************/
static unsigned char w83977_read_state(unsigned int addr)
{
	addr +=nGCS7;
	return readb(addr);
}

static unsigned char w83977_write_device(unsigned char val, unsigned int io_addr)
{
	io_addr +=nGCS7;
	return writeb(val, io_addr);
}

static void uart8250_init(unsigned int base_port, unsigned char divisor, unsigned char lcs)
 {
         lcs &= 0x7f;
         /* disable interrupts */
         w83977_write_device(0x0, base_port + UART_IER);
         /* enable fifo's */
         //w83977_write_device(0x01, base_port + UART_FCR);
         /* assert DTR and RTS so the other end is happy */
         //w83977_write_device(0x03, base_port + UART_MCR);
         /* Set Baud Rate Divisor to 12 ==> 115200 Baud */
         w83977_write_device(0x80 | lcs, base_port + UART_LCR);
         w83977_write_device(divisor & 0xFF,   base_port + UART_DLL);
         w83977_write_device((divisor >> 8) & 0xFF,    base_port + UART_DLM);
         w83977_write_device(lcs, base_port + UART_LCR);
 }


 static unsigned char check_w83977tf(void)
 {
 	unsigned char device_id, device_version;
	
 	w977_efm_enter(efbase[1]);
	device_id=w977_read_reg(0x20, efbase[1]);
	device_version=w977_read_reg(0x21, efbase[1]);

	printf("device_id(0x97)=0x%x, device_version(0x73)=0x%x\n", device_id, device_version);

	if(device_id != 0x97 || device_version !=0x73) {
		printf("there is no W83977 device!\n");
		return -1;
	}
	printf("W83977 device detected!\n");
	return 0;
 }	

void init_w83977(void)
{
 	unsigned char  tmp1, tmp2;

   	rBANKCON7=0;             //w83977
   	rBANKCON7|= 0<<15 | 2<<13 | 2<<11 | 7<<8 | 3<<6 | 3<<4;   //Tacc=14clk  ROM
/*
	printf("rBWSCON=0x%x\n", (rBWSCON>>28)&0x0f);    	//BANK7
	printf("rBANKCON7=0x%x\n", rBANKCON7);				//BANK7
*/	
	if(check_w83977tf()) { 
		//exit the extend function setting
 		w977_efm_exit(efbase[1]);
		return ;
	}

	//GPI014 port------------------------------------------
	w977_select_device(W977_DEVICE_GP14, efbase[1]);    //select logic device
	w977_write_reg(0x2c, 0x01, efbase[1]);            //pin config for GP14------	
	//set GP1 base address--0x200
	w977_write_reg(0x60, (GPIO14_IO_BASE>>8) & 0xff, efbase[1]);     //address
	w977_write_reg(0x61, GPIO14_IO_BASE & 0xff, efbase[1]);     //address
	w977_write_reg(0xe4, 0x00, efbase[1]);     //config GP14---noninvert output 
	 /* Activate device */
 	w977_write_reg(0x30, 0x01, efbase[1]);  
	 
	//KBD port--------------------------------------------
	w977_select_device(W977_DEVICE_KBC, efbase[1]); 		//select logic device
	w977_write_reg(0x60, 0x0, efbase[1]);     	//address
	w977_write_reg(0x61, 0x60, efbase[1]);    	//address--0x060
	w977_write_reg(0x62, 0x0, efbase[1]);     	//address
	w977_write_reg(0x63, 0x64, efbase[1]);     	//address--0x064

	//set irq number
	w977_write_reg(0x70, 0x05, efbase[1]);    //irq for keyboard   irq5--active H
	w977_write_reg(0x72, 0x04, efbase[1]);    //irq for mouse       irq4--active H

	//12MHZ, disable port 92
	w977_write_reg(0xf0, 0x80, efbase[1]); 
 	/* Activate device */
 	w977_write_reg(0x30, 0x01, efbase[1]); 
	
	//parport port------------------------------------------
	w977_select_device(W977_DEVICE_PARPORT, efbase[1]);
	//set  base address--0x378
	w977_write_reg(0x60, (PARPORT_IO_BASE>>8) & 0xff, efbase[1]);     	//address
	w977_write_reg(0x61, PARPORT_IO_BASE & 0xff, efbase[1]);     		//address
 	/* Activate device */
 	w977_write_reg(0x30, 0x01, efbase[1]);

	//uart--a
	w977_select_device(W977_DEVICE_UARTA, efbase[1]);
	//set  base address--0x3f8
	w977_write_reg(0x60, (TTYS0_BASE>>8) & 0xff, efbase[1]);    	 //address
	w977_write_reg(0x61, TTYS0_BASE & 0xff, efbase[1]);     		//address
	//set irq number
	w977_write_reg(0x70, 0x03, efbase[1]);    	//irq for serial port A   irq3----s3c2410-EINT6
	w977_write_reg(0xf0, 0x00, efbase[1]);  	//1.8461MHZ
 	/* Activate device */                                         	//active H
 	w977_write_reg(0x30, 0x01, efbase[1]);
/*
	tmp1=w977_read_reg(0x60, efbase[1]);
	tmp2=w977_read_reg(0x61, efbase[1]);
	printf("serial port: 0x60=0x%x,0x61=%x\n", tmp1, tmp2);

	tmp1=w977_read_reg(0x30, efbase[1]);
	tmp2=w977_read_reg(0x70, efbase[1]);
	printf("serial port: active 0x30=0x%x,irq 0x70=0x%x\n",tmp1, tmp2);
*/

	//serial port B------------------------UART A clock source is 1.8462 Mhz
	w977_select_device(W977_DEVICE_UARTB, efbase[1]);
	//set  base address--0x2f8
	w977_write_reg(0x60, (TTYS1_BASE>>8) & 0xff, efbase[1]);     	//address
	w977_write_reg(0x61, TTYS1_BASE & 0xff, efbase[1]);     		//address
	//set irq number
	w977_write_reg(0x70, 0x01, efbase[1]);    	//irq for serial port B   irq1----s3c2410-EINT0
	w977_write_reg(0xf0, 0x00, efbase[1]);  	//1.8461MHZ
 	// Activate device                                        		//active H
 	w977_write_reg(0x30, 0x01, efbase[1]); 

	//exit set config registers---------------------------
 	w977_efm_exit(efbase[1]);

	tmp1=w83977_read_state(TTYS0_BASE+UART_MCR);				//uarta--enable inttrupt pin ----
	w83977_write_device(tmp1 | 0x08, TTYS0_BASE+UART_MCR);    	//
	tmp1=w83977_read_state(TTYS1_BASE+UART_MCR);				//uartb--enable inttrupt pin ----
	w83977_write_device(tmp1 | 0x08, TTYS1_BASE+UART_MCR);    	//
	
 	//uart8250_init(TTYS0_BASE, 3, 3);		//8bit ,38400
	//uart8250_init(TTYS1_BASE, 3, 3);		//8bit ,38400

	//--------------------------------------serial port self test!!!
	/*
	tmp1=w83977_read_state(TTYS0_BASE+UART_LCR);
	printf("LCR--read:0x%x\n", tmp1);
	tmp1=w83977_read_state(TTYS0_BASE+UART_IER);
	printf("ier--read:0x%x\n", tmp1);
	w83977_write_device(0x00, TTYS0_BASE+UART_IER);
	tmp1=w83977_read_state(TTYS0_BASE+UART_IER);
	w83977_write_device(0xff, TTYS0_BASE+UART_IER);
	tmp2=w83977_read_state(TTYS0_BASE+UART_IER);
	printf("ier----1th:0x%.2x, 2nd:0x%.2x\n", tmp1, tmp2);  	
	*/
}

//-------------------------the end-------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -