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

📄 proc_zlg7289.c

📁 基于linux操作系统ATMELARM9200 开发平台的7289控制器驱动程序
💻 C
字号:
/* * proc_zlg7289 v1.0 09/05/05 * www.himai.com * * * Copyright (C) 2004 by Himai Tech * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* * proc_zlg7289.c is based on procfs_example.c by Erik Mouw. * For more information, please see The Linux Kernel Procfs Guide, Erik Mouw * http://kernelnewbies.org/documents/kdoc/procfs-guide/lkprocfsguide.html **//* proc_zlg7289 * This device driver demonstrates communication with a zlg7289as LED  * controller using SPI signalling. This routine implements SPI communication * in software (bit-banging). The driver creates a /proc directory entry  * called /proc/zlg7289/led. Scripts can write 0~9 A~F to this file for display. * * This device driver communicates with zlg7289  * connected in the following manner. * *    RM9200                        zlg7289as *     Port            Direction     *      PA1    43         ->        DIO    8 *      PA2    44         ->        CLK    7 *       *     cpld7128   52      ->        /CS    6 *     *//*gcc -O2 -D__KERNEL__ -DMODULE -I/home/HM901ESP/linux-2.4.27/include -c proc_zlg7289.c -o proc_zlg7289.o*/#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/proc_fs.h>#include <linux/delay.h>#include <asm/io.h>#include <asm/arch/hardware.h>	/* atmel RM9200           	*/      #include <asm/arch/pio.h>//#undef  DEBUG_ZLG7289#define DEBUG_ZLG7289	1#ifdef DEBUG_ZLG7289#define DBG_ZLG7289(fmt, args...) printk(fmt,##args)#else#define DBG_ZLG7289(fmt, args...)#endif#define MODULE_VERSION "1.0"#define MODULE_NAME    "proc_zlg7289"MODULE_LICENSE("GPL");static struct proc_dir_entry  *tb_dir,                              *led_file;#define ZLG7289CS      0x808c0020 /* data port bit definitions */#define nCS             0x0f7#define CLK             AT91C_PIO_PA2#define DIO             AT91C_PIO_PA1/* bit delay time, in usecs */#define DELAY           500unsigned char data;#define clkLow()       	AT91_SYS->PIOA_CODR = AT91C_PIO_PA2 #define clkHigh()       AT91_SYS->PIOA_SODR = AT91C_PIO_PA2#define assertCS()      writeb(0xf7, zlg7289_base)#define deassertCS()    writeb(0xff, zlg7289_base)#define TRAN_CMD	1#define TRAN_CMD_DATA	2/* User CMD */#define ULED1_CONTROL	1#define ULED2_CONTROL	2#define ULED3_CONTROL	3#define ULED4_CONTROL	4#define ZLG_CMD		5#define ZLG_CMD_DATA	6static void* zlg7289_base;static int position;/* function zlg7289_transform * type: TANS_CMD        1 byte command *       TANS_CMD_DATA   1 byte command + 1 byte data * * */static unsigned char zlg7289_transform (unsigned char cmd, unsigned char data, int type){	int i;	unsigned char bit, read_data=0;		DBG_ZLG7289("zlg7289_transform cmd=%x, data=%x, type=%x\n", cmd, data, type);	/* CS# Low */	assertCS();	udelay(DELAY);		/* Transform CMD */	for(i=1; i<=8; i++){		/* CMD Output */		bit = ( cmd >> (8-i) ) & 0x01 ;		//DBG_ZLG7289("zlg7289_transform bit %x\n", bit);		if( bit )			AT91_SYS->PIOA_SODR |= AT91C_PIO_PA1;	        else			AT91_SYS->PIOA_CODR |= AT91C_PIO_PA1;		udelay(DELAY);			/* CLK High */		clkHigh();		udelay(DELAY);		/* CLK Low */		clkLow();		udelay(DELAY);	}		switch (type) {		case TRAN_CMD:			break;		case TRAN_CMD_DATA:			/* Transform DATA */        		for(i=7; i>=0; i--){			       	/* DATA Output */				bit = ( data >> i ) & 0x01 ;		                if( bit )		     			AT91_SYS->PIOA_SODR |= AT91C_PIO_PA1;					else   					AT91_SYS->PIOA_CODR |= AT91C_PIO_PA1;				udelay(DELAY);				/* CLK High */				clkHigh();				udelay(DELAY);				/* CLK Low */				clkLow();				udelay(DELAY);			}		        break;			default:			DBG_ZLG7289("zlg7289_transform error type %x\n", type);			break;		}//end switch		/* CS# High */	deassertCS();	udelay(DELAY);	return read_data;}/* *  function proc_write_display *  This function gets called when user writes something to *  /proc/zlg7289/led. It contains a mapping array from numbers *  (0-9,a-f) to what segments to turn on */static int proc_write_display(struct file *file,				const char *buffer,				unsigned long count, void *data){//  unsigned char e, displaybuffer[9];//  int i;/* seg is a segment mapping table. Element 0, 0x7E, tells zlg7289 to * turn on the segments to display a 0. Likewise, seg's other entries  * map to 1 through 9 *///  unsigned char seg[] = { 0x7E, 0x30, 0x6D, 0x79, 0x33, //         		  0x5B, 0x5F, 0x70, 0x7F, 0x7B   };    if (count == 0)      return 0;   DBG_ZLG7289("count = %ld  buffer = %c\n", count, buffer[0]);         switch (buffer[0]) {  	case  't':             /* test command */		zlg7289_transform(0xbf, 0, TRAN_CMD);                break;	case  's':             /* reset command */		zlg7289_transform(0xa4, 0, TRAN_CMD);		break; 	case  'l':	       /* left shiffit  */		zlg7289_transform(0xa1, 0, TRAN_CMD);		break;	case  'r':             /* right shiffit */		zlg7289_transform(0xa0, 0, TRAN_CMD);		break;	default:		if ( ((buffer[0] >= '0') && (buffer[0] <= '9')) ||                   ((buffer[0] >= 'a') && (buffer[0] <= 'f')) ) 		{  			if ((buffer[0] >= '0') && (buffer[0] <= '9'))   				zlg7289_transform(0xc8 | position, buffer[0] - '0', TRAN_CMD_DATA);			else				zlg7289_transform(0xc8 | position, (buffer[0] -'a')+0xa, TRAN_CMD_DATA); 		} else {			zlg7289_transform(0x80, 0x0f, TRAN_CMD_DATA);				}		position = (position + 1) & 0x7;		break;  }  return 1;		}/* * function zlg7289_hardware_init * This function initializes PA1 PA2 for output * virtual address for zlg8279-CS * port. The /CS and DIO lines are then put in an initialization state. * */static void zlg7289_hardware_init (void){  	DBG_ZLG7289("zlg7289_hardware_init\n");	AT91_SYS->PIOA_PER |= AT91C_PIO_PA1 | AT91C_PIO_PA2;		AT91_SYS->PMC_PCER |= 0x00000004;	AT91_SYS->PIOA_OER |= AT91C_PIO_PA1 | AT91C_PIO_PA2;	zlg7289_base = ioremap_nocache(ZLG7289CS, 0x20);	DBG_ZLG7289("zlg7289_base = 0x%08X\n", (int)zlg7289_base);	clkHigh();	deassertCS();        udelay(1000);        zlg7289_transform(0xbf,0,TRAN_CMD);     /* zlg7289 test command */	writeb(0x00, zlg7289_base + 0x18);}/* * function init_zlg8279 * This initialization function creates the /proc/zlg7289 * directory and a "led" entry in it then initializes the * zlg7289as controller * */static int __init init_zlg7289(void){  int rv = 0;/* Create the zlg7289 /proc entry */  tb_dir = proc_mkdir("zlg7289", NULL);  if(tb_dir == NULL) {          rv = -ENOMEM;          goto out;  }  tb_dir->owner = THIS_MODULE;/* Create led and make it writable by all - 0666 */  led_file = create_proc_entry("led", 0666, tb_dir);  if(led_file == NULL) {          rv = -ENOMEM;          goto no_led_file;  }  led_file->data 	= NULL;  led_file->read_proc 	= NULL;  led_file->write_proc 	= &proc_write_display;  led_file->owner 	= THIS_MODULE;  zlg7289_hardware_init();/* everything initialized */  printk(KERN_INFO "%s %s initialized\n",         MODULE_NAME, MODULE_VERSION);  return 0;no_led_file:  remove_proc_entry("zlg7289", NULL);out:  return rv;}/* * function cleanup_zlg7289 *   * the /proc/zlg7289 directory and the "led" entry. */static void __exit cleanup_zlg7289(void){  remove_proc_entry("led", tb_dir);  remove_proc_entry("zlg7289", NULL);  writeb(0xff, zlg7289_base + 0x20);  iounmap (zlg7289_base);  printk(KERN_INFO "%s %s removed\n", MODULE_NAME, MODULE_VERSION);}module_init(init_zlg7289);module_exit(cleanup_zlg7289);MODULE_AUTHOR("Feng JInFei");MODULE_DESCRIPTION("ZLG7289AS LED");EXPORT_NO_SYMBOLS;

⌨️ 快捷键说明

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