📄 pd6700.c
字号:
/****************************************Copyright (c)**************************************************** Guangzhou ZHIYUAN electronics Co.,LTD.** ** http://www.zyinside.com****--------------File Info-------------------------------------------------------------------------------** File Name: pd6700.c** Last modified Date: 2006-01-14 ** Last Version: v1.0** Description: ** Note: **------------------------------------------------------------------------------------------------------** Created By: 周立山** Created date: 2006-01-01 ** Version: v1.0** Descriptions:****------------------------------------------------------------------------------------------------------** Modified by:** Modified date:** Version:** Description:**********************************************************************************************************/#ifndef __KERNEL__ #define __KERNEL__#endif#ifndef MODULE #define MODULE#endif#include <linux/module.h>#include <linux/init.h>#include <linux/config.h>#include <linux/types.h>#include <linux/fcntl.h>#include <linux/string.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/timer.h>#include <linux/sched.h>#include <linux/slab.h>#include <linux/ioport.h>#include <linux/delay.h>#include <linux/proc_fs.h>#include <asm/irq.h>#include <asm/io.h>#include <asm/bitops.h>#include <asm/segment.h>#include <asm/system.h>// PCMCIA相关头文件#include <pcmcia/version.h>#include <pcmcia/cs_types.h>#include <pcmcia/ss.h>#include <pcmcia/cs.h>#include "pd6700.h"#include <asm/hardware.h>#define io_base(port) (*(volatile u_char *)(vCF_IO_BASE + port))//===========================================================================#define PCMCIA_DEBUG 5 // 是否打印调试信息//===========================================================================#ifdef PCMCIA_DEBUG static int pc_debug = PCMCIA_DEBUG; MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) \ if (n <= pc_debug) { \ printk(KERN_INFO args); \ } static const char *version ="pd6700.c 1.265 2005/12/08 zhoulishan";#else #define DEBUG(n, args...)#endif/*====================================================================*//* Parameters that can be set with 'insmod' *//* Default base address for pd6700sl and other ISA chips */static int pd67_base = 0x3e0;/* The card status change interrupt -- 0 means autoselect */static int cs_irq = IRQ_nCF_INS;/* Poll status interval -- 0 means default to interrupt */static int poll_interval = 0;/* External clock time, in nanoseconds. 120 ns = 8.33 MHz */static int cycle_time = 120;/* Cirrus options *///#ifdef CONFIG_S3C2410_SMDKstatic int has_led = -1;static int has_ring = -1;static int dynamic_mode = 1;static int freq_bypass = 1;static int setup_time = 5; /* 80ns (no spec) */static int cmd_time = 20; /* 320ns (by spec, 25Mhz clock) */static int recov_time = 5; /* 80ns (no spec) */static int wakeup = 0;MODULE_PARM(pd67_base, "i");MODULE_PARM(cs_irq, "i");MODULE_PARM(wakeup, "i");MODULE_PARM(poll_interval, "i");MODULE_PARM(cycle_time, "i");MODULE_PARM(has_led, "i");MODULE_PARM(has_ring, "i");MODULE_PARM(dynamic_mode, "i");MODULE_PARM(freq_bypass, "i");MODULE_PARM(setup_time, "i");MODULE_PARM(cmd_time, "i");MODULE_PARM(recov_time, "i");/*====================================================================*/typedef struct cirrus_state_t { // PCMCIA接口状态数据结构 u_char misc1, misc2; u_char timer[6];} cirrus_state_t;typedef struct socket_info_t { // PCMCIA卡接口信息 u_short type, flags; // 接口类型及标志位 socket_cap_t cap; // PCMCIA接口能力 ioaddr_t ioaddr; // IO 接口地址 u_short psock; // 接口号 u_char cs_irq, intr; // 中断号 void (*handler)(void *info, u_int events); // 事件处理函数指针 void *info; // 处理事件信息#ifdef CONFIG_PROC_FS struct proc_dir_entry *proc; // 处理入口指针#endif union { cirrus_state_t cirrus; // 这里可以添加更多的桥芯片 } state; // 状态} socket_info_t;/* Where we keep track of our sockets... */static int sockets /* = 0 */;static socket_info_t socket[8] /* = { { 0, },} */;#ifdef CONFIG_ISA// static int grab_irq; static spinlock_t isa_lock = SPIN_LOCK_UNLOCKED; #define ISA_LOCK(n, f) spin_lock_irqsave(&isa_lock, f) // 关中断 #define ISA_UNLOCK(n, f) spin_unlock_irqrestore(&isa_lock, f) // 开中断#else #define ISA_LOCK(n, f) do { } while (0) #define ISA_UNLOCK(n, f) do { } while (0)#endifstatic struct timer_list poll_timer;/* These definitions must match the pcic table! */typedef enum pcic_id { IS_PD6710, IS_PD6722, } pcic_id;/* Flags for classifying groups of controllers */#define IS_VADEM 0x0001#define IS_CIRRUS 0x0002#define IS_TI 0x0004#define IS_O2MICRO 0x0008#define IS_VIA 0x0010#define IS_TOPIC 0x0020#define IS_RICOH 0x0040#define IS_UNKNOWN 0x0400#define IS_VG_PWR 0x0800#define IS_DF_PWR 0x1000#define IS_PCI 0x2000#define IS_ALIVE 0x8000typedef struct pcic_t { char *name; // 控制器名称 u_short flags; // 标志位} pcic_t;static pcic_t pcic[] = { { "Cirrus PD6710", IS_CIRRUS }, { "Cirrus PD672x", IS_CIRRUS },};#define PCIC_COUNT (sizeof(pcic)/sizeof(pcic_t))/*====================================================================*/static spinlock_t bus_lock = SPIN_LOCK_UNLOCKED;/*********************************************************************************************************** Function name: pd67_get** Descriptions: 获取接口寄存器的值** Input:sock,接口号** reg,寄存器索引** Output :** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/static u_char pd67_get(u_short sock, u_short reg){ unsigned long flags; spin_lock_irqsave(&bus_lock,flags); // 关中断 { ioaddr_t port = socket[sock].ioaddr; // IO地址 u_char val; reg = PD67_REG(socket[sock].psock, reg); // 获取寄存器索引 io_base(port) = (u_char) reg; // 写寄存器地址 val = io_base(port+1); // 读寄存器值 spin_unlock_irqrestore(&bus_lock,flags); // 开中断 return val; }}/*********************************************************************************************************** Function name: pd67_set** Descriptions: 写入指定寄存器的值** Input:** Output :** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/static void pd67_set(u_short sock, u_short reg, u_char data){ unsigned long flags; spin_lock_irqsave(&bus_lock,flags); { ioaddr_t port = socket[sock].ioaddr; u_char val = PD67_REG(socket[sock].psock, reg); io_base(port) = (u_char)val; io_base(port+1) = (u_char)data; spin_unlock_irqrestore(&bus_lock,flags); }}/*********************************************************************************************************** Function name: pd67_bset** Descriptions: 设置寄存器标记位.先读出寄存器的值,再将该值与mask求或,最后写入到寄存器** Input:sock, 接口索引号** reg,寄存器索引号** mask,屏蔽位** Output : 无** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/static void pd67_bset(u_short sock, u_short reg, u_char mask){ u_char d = pd67_get(sock, reg); d |= mask; pd67_set(sock, reg, d);}/*********************************************************************************************************** Function name: pd67_bclr** Descriptions: 清零标志位,将寄存器中mask相应的位清零** Input:sock, 接口索引号** reg,寄存器索引号** mask,屏蔽位** Output :** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/static void pd67_bclr(u_short sock, u_short reg, u_char mask){ u_char d = pd67_get(sock, reg); d &= ~mask; pd67_set(sock, reg, d);}/*********************************************************************************************************** Function name: pd67_bflip** Descriptions: 该函数集成了pd67_bset和pd67_bclr的功能,通过b的值选择相关的操作,b为0清标志位,反之置标志位** Input:sock,接口索引** reg, 寄存器索引** mask, 屏蔽位** b, 操作标志位** Output : 无** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/static void pd67_bflip(u_short sock, u_short reg, u_char mask, int b){ u_char d = pd67_get(sock, reg); // 读出寄存器原值 if (b) d |= mask; else d &= ~mask; pd67_set(sock, reg, d); // 写入寄存器}/*********************************************************************************************************** Function name: pd67_get_pair** Descriptions: 获取寄存器连续两个值,将寄存器reg和reg+1(高8位)组成一个16位的值,** Input:sock , 接口号** reg , 寄存器索引** Output : 返回16位的值** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -