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

📄 w90n745_ebi2.c

📁 winbond w90n745 ebi驱动代码
💻 C
字号:
/****************************************************************************
 *                                                                          *
 * Copyright (c) 2006 - 2007 Gtm Electronics Corp. All rights reserved. *
 *                                                                          *
 ***************************************************************************/
 
/****************************************************************************
 * 
 * FILENAME
 *     w90n745_ebi2.c
 *
 * VERSION
 *     1.0
 *
 * DESCRIPTION 
 *     This file is the driver of ebi 2 Module driver
 *      8-16 Bit Bus Control 
 * DATA STRUCTURES
 *     NONE
 *
 * FUNCTIONS
 *        static int ebi2ledc_init(void);
 *        static int ebi2ledc_ioctl(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg);
 *        static int ebi2ledc_open(struct inode *inode,struct file *filp); *        static int ebi2ledc_close(struct inode *inode,struct file *filp);
 *        static int ebi2ledc_write(struct file *filp, const char *buff, size_t count, loff_t *f_pos);
 *        static int ebi2ledc_read(struct file *flip,char * buff,size_t count, loff_t * f_pos);
 *
 * HISTORY
 *     2007/12/12	       Ver 1.0 Created by gtm ymy
 *     2007/12/24               Modified  ymy * REMARK
 *     None
 **************************************************************************/
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/hardware.h>
#include <asm/errno.h>#include <asm/uaccess.h>
#include <asm/delay.h>
#include <gpio/gpio_interface.h>
#include "w90n745_ebi2.h"

#define EBI2_MEM_SIZE	 2//buffsize
#define ebi2drv_major  232
#define DEVICE_NAME   "led"  /*name */

#define BIT_FF(x)  ((x)&0xff)
//Modified  2007/12/20


//file operation
static struct file_operations ebi2ledc_fops = 
{        owner: 		THIS_MODULE,
	open:		 ebi2ledc_open,
	//close:		 ebi2ledc_close,
	write:		 ebi2ledc_write,        read:             ebi2ledc_read,
	ioctl:		 ebi2ledc_ioctl,
	release:           ebi2ledc_close,
};

/****************************************************************************************
*
*	FUNCTION 
*
*   	WB_SetExternalIO
*
*   DESCRIPTION
*		
*   	To set base address, address size , and bus width for external I/O device.
*
*	INPUTS
*		extNo			External I/O bank number. 
*		extBaseAddr		External I/O bank base address.
*		extSize			External I/O size.
*		extBusWidth	  	External I/O bus width.
*
*	OUTPUTS
*		none
*
*****************************************************************************************/
static void GTM_SetExternalIO(int extNo, unsigned int extBaseAddr, unsigned int extSize, int extBusWidth)
{
	unsigned int reg;

	switch (extNo)
	{
		case EXT0:
			reg = DWORD_READ(EXT0CON);
		
			// Set Bus width
			switch (extBusWidth)
			{
				case BUS_BIT_8:
					reg = (reg & 0xfffffffc) | 0x01;
					break;

				case BUS_BIT_16:
					reg = (reg & 0xfffffffc) | 0x02;
					break;

				case BUS_BIT_32:
					reg = (reg & 0xfffffffc) | 0x03;
					break;

				case BUS_DISABLE:
					reg = reg & 0xfffffffc;
					break;
			}

			// Set size
			switch (extSize)
			{
				case SIZE_256K:
					reg = reg & 0xfff8ffff;
					break;

				case SIZE_512K:
					reg = (reg & 0xfff8ffff)|0x00010000;
					break;

				case SIZE_1M:
					reg = (reg & 0xfff8ffff)|0x00020000;
					break;

				case SIZE_2M:
					reg = (reg & 0xfff8ffff)|0x00030000;
					break;

				case SIZE_4M:
					reg = (reg & 0xfff8ffff)|0x00040000;
					break;

				case SIZE_8M:
					reg = (reg & 0xfff8ffff)|0x00050000;
					break;

				case SIZE_16M:
					reg = (reg & 0xfff8ffff)|0x00060000;
					break;

				case SIZE_32M:
					reg = (reg & 0xfff8ffff)|0x00070000;
					break;
			}

			// Set Base address
			extBaseAddr = (extBaseAddr << 1) & 0xfff80000;
			reg = reg | extBaseAddr;

			// set the reg value into register
			reg = reg |0x7870;  // CYH tACC
			DWORD_WRITE(EXT0CON, reg);
			break;

		case EXT1:
			reg = DWORD_READ(EXT1CON);
		
			// Set Bus width
			switch (extBusWidth)
			{
				case BUS_BIT_8:
					reg = (reg & 0xfffffffc) | 0x01;
					break;

				case BUS_BIT_16:
					reg = (reg & 0xfffffffc) | 0x02;
					break;

				case BUS_BIT_32:
					reg = (reg & 0xfffffffc) | 0x03;
					break;

				case BUS_DISABLE:
					reg = reg & 0xfffffffc;
					break;
			}

			// Set size
			switch (extSize)
			{
				case SIZE_256K:
					reg = reg & 0xfff8ffff;
					break;

				case SIZE_512K:
					reg = (reg & 0xfff8ffff)|0x00010000;
					break;

				case SIZE_1M:
					reg = (reg & 0xfff8ffff)|0x00020000;
					break;

				case SIZE_2M:
					reg = (reg & 0xfff8ffff)|0x00030000;
					break;

				case SIZE_4M:
					reg = (reg & 0xfff8ffff)|0x00040000;
					break;

				case SIZE_8M:
					reg = (reg & 0xfff8ffff)|0x00050000;
					break;

				case SIZE_16M:
					reg = (reg & 0xfff8ffff)|0x00060000;
					break;

				case SIZE_32M:
					reg = (reg & 0xfff8ffff)|0x00070000;
					break;
			}

			// Set Base address
			extBaseAddr = (extBaseAddr << 1) & 0xfff80000;
			reg = reg | extBaseAddr;

			// set the reg value into register
			DWORD_WRITE(EXT1CON, reg);
			break;

		case EXT2:
			reg = DWORD_READ(EXT2CON);
		
			// Set Bus width
			switch (extBusWidth)
			{
				case BUS_BIT_8:
					reg = (reg & 0xfffffffc) | 0x01;
					break;

				case BUS_BIT_16:
					reg = (reg & 0xfffffffc) | 0x02;
					break;

				case BUS_BIT_32:
					reg = (reg & 0xfffffffc) | 0x03;
					break;

				case BUS_DISABLE:
					reg = reg & 0xfffffffc;
					break;
			}

			// Set size
			switch (extSize)
			{
				case SIZE_256K:
					reg = reg & 0xfff8ffff;
					break;

				case SIZE_512K:
					reg = (reg & 0xfff8ffff)|0x00010000;
					break;

				case SIZE_1M:
					reg = (reg & 0xfff8ffff)|0x00020000;
					break;

				case SIZE_2M:
					reg = (reg & 0xfff8ffff)|0x00030000;
					break;

				case SIZE_4M:
					reg = (reg & 0xfff8ffff)|0x00040000;
					break;

				case SIZE_8M:
					reg = (reg & 0xfff8ffff)|0x00050000;
					break;

				case SIZE_16M:
					reg = (reg & 0xfff8ffff)|0x00060000;
					break;

				case SIZE_32M:
					reg = (reg & 0xfff8ffff)|0x00070000;
					break;
			}

			// Set Base address
			extBaseAddr = (extBaseAddr << 1) & 0xfff80000;
			reg = reg | extBaseAddr;

			// set the reg value into register
			DWORD_WRITE(EXT2CON, reg);
			break;

		case EXT3:
			reg = DWORD_READ(EXT3CON);
		
			// Set Bus width
			switch (extBusWidth)
			{
				case BUS_BIT_8:
					reg = (reg & 0xfffffffc) | 0x01;
					break;

				case BUS_BIT_16:
					reg = (reg & 0xfffffffc) | 0x02;
					break;

				case BUS_BIT_32:
					reg = (reg & 0xfffffffc) | 0x03;
					break;

				case BUS_DISABLE:
					reg = reg & 0xfffffffc;
					break;
			}

			// Set size
			switch (extSize)
			{
				case SIZE_256K:
					reg = reg & 0xfff8ffff;
					break;

				case SIZE_512K:
					reg = (reg & 0xfff8ffff)|0x00010000;
					break;

				case SIZE_1M:
					reg = (reg & 0xfff8ffff)|0x00020000;
					break;

				case SIZE_2M:
					reg = (reg & 0xfff8ffff)|0x00030000;
					break;

				case SIZE_4M:
					reg = (reg & 0xfff8ffff)|0x00040000;
					break;

				case SIZE_8M:
					reg = (reg & 0xfff8ffff)|0x00050000;
					break;

				case SIZE_16M:
					reg = (reg & 0xfff8ffff)|0x00060000;
					break;

				case SIZE_32M:
					reg = (reg & 0xfff8ffff)|0x00070000;
					break;
			}

			// Set Base address
			extBaseAddr = (extBaseAddr << 1) & 0xfff80000;
			reg = reg | extBaseAddr;

			// set the reg value into register
			DWORD_WRITE(EXT3CON, reg);
			break;

		default:
			;
	}
}	/* end WB_SetExternalIO */

/****************************************************************************************
*
*	FUNCTION 
*
*   	WB_SetExternalIOTiming1
*
*   DESCRIPTION
*		
*   	To set access cycles & address set-up before nECS for the specified External I/O bank.
*
*	INPUTS
*		extNo			External I/O bank number. 
*		tACC			Access cycle for the specified External I/O bank.
*		tACS			Address set-up before nECS for the specified External I/O bank.
*
*	OUTPUTS
*		none
*
*****************************************************************************************/
void GTM_SetExternalIOTiming1(int extNo, int a, int b)
{
	UINT32 reg;

	switch (extNo)
	{
		case EXT0:
			reg = DWORD_READ(EXT0CON);

			if ((a >= 0) && (a <= 0x7))
				reg = (reg & 0xffff78ff) | (a << 11);
			else if ((a > 0x8) && (a <= 0x17))
				reg = (reg & 0xffff78ff) | (((a - 0x8)/2 + 0x8) << 11);
			else 
				reg = (reg & 0xffff78ff);

			if ((b >= 0) && (b <= 0x7))
				reg = (reg & 0xffffff1f) | (b << 5);

			DWORD_WRITE(EXT0CON, reg);
			break;

		case EXT1:
			reg = DWORD_READ(EXT1CON);

			if ((a >= 0) && (a <= 0x7))
				reg = (reg & 0xffff78ff) | (a << 11);
			else if ((a > 0x8) && (a <= 0x17))
				reg = (reg & 0xffff78ff) | (((a - 0x8)/2 + 0x8) << 11);
			else 
				reg = (reg & 0xffff78ff);

			if ((b >= 0) && (b <= 0x7))
				reg = (reg & 0xffffff1f) | (b << 5);

			DWORD_WRITE(EXT1CON, reg);
			break;

		case EXT2:
			reg = DWORD_READ(EXT2CON);

			if ((a >= 0) && (a <= 0x7))
				reg = (reg & 0xffff78ff) | (a << 11);
			else if ((a > 0x8) && (a <= 0x17))
				reg = (reg & 0xffff78ff) | (((a - 0x8)/2 + 0x8) << 11);
			else 
				reg = (reg & 0xffff78ff);

			if ((b >= 0) && (b <= 0x7))
				reg = (reg & 0xffffff1f) | (b << 5);

			DWORD_WRITE(EXT2CON, reg);
			break;

		case EXT3:

			if ((a >= 0) && (a <= 0x7))
				reg = (reg & 0xffff78ff) | (a << 11);
			else if ((a > 0x8) && (a <= 0x17))
				reg = (reg & 0xffff78ff) | (((a - 0x8)/2 + 0x8) << 11);
			else 
				reg = (reg & 0xffff78ff);

			if ((b >= 0) && (b <= 0x7))
				reg = (reg & 0xffffff1f) | (b << 5);

			reg = DWORD_READ(EXT3CON);
			DWORD_WRITE(EXT3CON, reg);
			break;
	}

}	/* end WB_SetExternalIOTiming1 */

/****************************************************************************************
*
*	FUNCTION 
*
*   	WB_SetExternalIOTiming2
*
*   DESCRIPTION
*		
*   	To set chip select hold-on time & chip select set-up time for the specified External I/O bank.
*
*	INPUTS
*		extNo			External I/O bank number. 
*		tCOH			Chip select hold-on time on nOE or nWBE for the specified External I/O bank.
*		tCOS			Chip select set-up time on nOE or nWBE for the specified External I/O bank.
*
*	OUTPUTS
*		none
*
*****************************************************************************************/
void GTM_SetExternalIOTiming2(int extNo, int a, int b)
{
	unsigned int reg;

	switch (extNo)
	{
		case EXT0:
			reg = DWORD_READ(EXT0CON);

			if ((a >= 0) && (a <= 0x7))
				reg = (reg & 0xfffff8ff) | (a << 8);

			if ((b >= 0) && (b <= 0x7))
				reg = (reg & 0xffffffe3) | (b << 2);

			DWORD_WRITE(EXT0CON, reg);
			break;

		case EXT1:
			reg = DWORD_READ(EXT1CON);

			if ((a >= 0) && (a <= 0x7))
				reg = (reg & 0xfffff8ff) | (a << 8);

			if ((b >= 0) && (b <= 0x7))
				reg = (reg & 0xffffffe3) | (b << 2);

			DWORD_WRITE(EXT1CON, reg);
			break;

		case EXT2:
			reg = DWORD_READ(EXT2CON);

			if ((a >= 0) && (a <= 0x7))
				reg = (reg & 0xfffff8ff) | (a << 8);

			if ((b >= 0) && (b <= 0x7))
				reg = (reg & 0xffffffe3) | (b << 2);

			DWORD_WRITE(EXT2CON, reg);
			break;

		case EXT3:

			if ((a >= 0) && (a <= 0x7))
				reg = (reg & 0xfffff8ff) | (a << 8);

			if ((b >= 0) && (b <= 0x7))
				reg = (reg & 0xffffffe3) | (b << 2);

			reg = DWORD_READ(EXT3CON);
			DWORD_WRITE(EXT3CON, reg);
			
			break;
	}
}	/* end WB_SetExternalIOTiming2 */

//setup ebi
void ebi_Init(void)
{	/*for bank2   0x74000000->LED Use it*/
        int t_ACC =23, t_ACS = 0;
	int t_COH = 0, t_COS = 0;

	GTM_SetExternalIO(2, EXT2_BASS, SIZE_256K, BUS_BIT_8);
	GTM_SetExternalIOTiming1(2, t_ACC, t_ACS);
	GTM_SetExternalIOTiming2(2, t_COH, t_COS);	
		
}

//NULL
static int ebi2ledc_ioctl(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg)
{
        unsigned char* buffer = NULL;

	//memset(buffer, 0, EBI2_MEM_SIZE);
       printk("CMD=%d\n",cmd);//test
	switch (cmd)
	{
		case 1:
		 
		
			break;
			
		case 2:
			 
		
			break;
			
		case 3:
			 
			break;
			
		case 4:
			
			 
			
			break;
			
		case 5:
		
			 
		
			break;
			
		case 6:
			 
			break;
			
		case 7:
		
			break;
			
		default:
			//printk("default\n");
			return -EINVAL;
	}
	
	return 0;	
	
	
	
	
	
	}

//read data from ebi2 
static int ebi2ledc_read(struct file *flip,char * buff,size_t count, loff_t *f_pos)
{
      unsigned char* buffer = NULL;
      int total_count=0;
      total_count=count;     // memset(buffer, 0, EBI2_MEM_SIZE);
      buffer[0] = BYTE_READ(LED_BASE_ADDR);      //buffer[0] =98;
      copy_to_user(buff, buffer, total_count);
      
      return total_count;
}


//write
static int ebi2ledc_write(struct file *filp, const char *buff, size_t count, loff_t *f_pos)
{
	
	unsigned char *buffer = NULL;
	unsigned long wr_count = 0, total_wr_count = 0;
	
	total_wr_count=count;
	//memset(buffer, 0, EBI2_MEM_SIZE);
	if (total_wr_count > EBI2_MEM_SIZE)
		{
		return -EFAULT;
		}
		//if(buff==NULL)
		//return -EFAULT;
        if (copy_from_user(buffer, buff, count))
		{
			printk("copy_from_user failed!\n");
			return -EFAULT;
		}
		    
	BYTE_WRITE(LED_BASE_ADDR,*buffer);
		          /*test No123*/         //printk("buff=%x",*buff);         //printk("buffer[0]=%d\n",*buffer);
			
	return total_wr_count;
}
//open fd
static int ebi2ledc_open(struct inode *inode,struct file *filp)
{
	MOD_INC_USE_COUNT;		
	ebi_Init();
	//printk("ebi2 open !\n");	

	return 0;
}


//close fd
static int ebi2ledc_close(struct inode *inode,struct file *filp)
 {
 	 	
 	//printk("ebi2 close !\n");
	MOD_DEC_USE_COUNT;
	return 0;
 		
 }
 	
 //init register device
static int __init ebi2ledc_init(void)
 {
 	int error;
 	
	error = register_chrdev(ebi2drv_major, DEVICE_NAME,&ebi2ledc_fops);
	if (error)
	{                unregister_chrdev(ebi2drv_major, DEVICE_NAME);
		printk("Register ebi2 device error!\n");
		return error;
	}        else
	printk("EBI2 for LED has been registered!\n");

	return 0;
 }
 	
static __exit void ebi2ledc_cleanup(void)
{

  unregister_chrdev(ebi2drv_major, DEVICE_NAME);
  printk("unregister device succeed!\n");
  printk("88!\n");

   // return ;
} 	
 

module_init(ebi2ledc_init);
module_exit(ebi2ledc_cleanup);
 
 //end!

⌨️ 快捷键说明

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