📄 pd6700.c
字号:
** Function name: pd67_get_socket** Descriptions: 获取接口当前信息** Input:sock,接口序号** *state ,返回接口状态数据指针** Output :返回0** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/static int pd67_get_socket(unsigned int sock, socket_state_t *state){ socket_info_t *t = &socket[sock]; u_char reg, vcc, vpp; if (socket[sock].flags & IS_ALIVE) return -EINVAL; reg = pd67_get(sock, PD67_POWER); // 读取电源管理寄存器 state->flags = (reg & PD67_PWR_AUTO) ? SS_PWR_AUTO : 0; state->flags |= (reg & PD67_PWR_OUT) ? SS_OUTPUT_ENA : 0; vcc = reg & PD67_VCC_MASK; vpp = reg & PD67_VPP1_MASK; state->Vcc = state->Vpp = 0; // 设置供电状态 printk("t->flags & IS_CIRRUS =%d\n",t->flags & IS_CIRRUS); if (pd67_get(sock, PD67_MISC_CTL_1) & PD67_MC1_VCC_3V) { if (reg & PD67_VCC_5V) state->Vcc = 33; if (vpp == PD67_VPP1_5V) state->Vpp = 33; } else { if (reg & PD67_VCC_5V) state->Vcc = 50; if (vpp == PD67_VPP1_5V) state->Vpp = 50; } if (vpp == PD67_VPP1_12V) state->Vpp = 120; printk("%d state->Vcc = %d\n",__LINE__,state->Vcc); printk("%d state->Vpp = %d\n",__LINE__,state->Vpp); /* IO card, RESET flags, IO interrupt */ reg = pd67_get(sock, PD67_INTCTL); state->flags |= (reg & PD67_PC_RESET) ? 0 : SS_RESET; if (reg & PD67_PC_IOCARD) state->flags |= SS_IOCARD; state->io_irq = reg & PD67_IRQ_MASK ; /* speaker control */ if (t->flags & IS_CIRRUS) { if (pd67_get(sock, PD67_MISC_CTL_1) & PD67_MC1_SPKR_ENA) // 是否设置了speaker state->flags |= SS_SPKR_ENA; } /* Card status change mask */ reg = pd67_get(sock, PD67_CSCINT); // 读中断管理寄存器 state->csc_mask = (reg & PD67_CSC_DETECT) ? SS_DETECT : 0; // 发现卡 if (state->flags & SS_IOCARD) state->csc_mask |= (reg & PD67_CSC_STSCHG) ? SS_STSCHG : 0; // IO 卡模式 else { // MEMORY模式 state->csc_mask |= (reg & PD67_CSC_BVD1) ? SS_BATDEAD : 0; state->csc_mask |= (reg & PD67_CSC_BVD2) ? SS_BATWARN : 0; state->csc_mask |= (reg & PD67_CSC_READY) ? SS_READY : 0; } DEBUG(1, "pd6700: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " "io_irq %d, csc_mask %#2.2x\n", sock, state->flags, state->Vcc, state->Vpp, state->io_irq, state->csc_mask); return 0;} /* pd67_get_socket *//*====================================================================*//*********************************************************************************************************** Function name: pd67_set_socket** Descriptions: 设置SOCKET接口参数** Input:sock, 接口索引** *state,接口状态参数指针** Output : 出错返回非0** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/static int pd67_set_socket(unsigned int sock, socket_state_t *state){ socket_info_t *t = &socket[sock]; // 接口信息描述指针 u_char reg; if (socket[sock].flags & IS_ALIVE) // 接口已是活动的,所以不能设置 return -EINVAL; DEBUG(1, "pd6700: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags, state->Vcc, state->Vpp, state->io_irq, state->csc_mask); /* First set global controller options */ set_bridge_state(sock); // 设置PCMCIW桥状态,MISC Control1 2、总线时序和中断 /* IO card, RESET flag, IO interrupt */ reg = t->intr; // 获取中断和一般控制寄存器原值 if (state->io_irq != t->cap.pci_irq) // 申请的中断与原中断是否一样? reg |= state->io_irq; // 设置PCMCIA桥中,由于系统只使用了IRQ3引脚,客户驱动不应该申请基它的中断 reg |= (state->flags & SS_RESET) ? 0 : PD67_PC_RESET; // 复位卡 reg |= (state->flags & SS_IOCARD) ? PD67_PC_IOCARD : 0; // 判断是否设置为IO卡模式 pd67_set(sock, PD67_INTCTL, reg); // 设置 中断和一般控制寄存器 // 设置电源管理寄存器 reg = PD67_PWR_NORESET; if (state->flags & SS_PWR_AUTO) reg |= PD67_PWR_AUTO; if (state->flags & SS_OUTPUT_ENA) reg |= PD67_PWR_OUT; if (t->flags & IS_CIRRUS) { if (state->Vpp != 0) { // 需要设置Vpp if (state->Vpp == 120) // 设置Vpp为12V reg |= PD67_VPP1_12V; else if (state->Vpp == state->Vcc) // 设置Vpp为5V reg |= PD67_VPP1_5V; else return -EINVAL; } if (state->Vcc != 0) { // 需要设置VCC reg |= PD67_VCC_5V; if (state->Vcc == 33) pd67_bset(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V); // 设置VCC为3.3V else if (state->Vcc == 50) pd67_bclr(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V); // 设置VCC为5.0V // pd67_bset(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V); else return -EINVAL; } } if (reg != pd67_get(sock, PD67_POWER)) pd67_set(sock, PD67_POWER, reg); // 设置电源管理寄存器 /* Chipset-specific functions */ if (t->flags & IS_CIRRUS) { /* Speaker control */ pd67_bflip(sock, PD67_MISC_CTL_1, PD67_MC1_SPKR_ENA, state->flags & SS_SPKR_ENA); // 如果请求Speaker,则设置使用 } /* Card status change interrupt mask */ /* Use INTR signal as the Management Interrupt on SMDK2410. */ reg = 0; if (state->csc_mask & SS_DETECT) reg |= PD67_CSC_DETECT; if (state->flags & SS_IOCARD) { if (state->csc_mask & SS_STSCHG) reg |= PD67_CSC_STSCHG; // 如果是IO卡中断设置 } else { // MEMORY卡中断设置 if (state->csc_mask & SS_BATDEAD) reg |= PD67_CSC_BVD1; if (state->csc_mask & SS_BATWARN) reg |= PD67_CSC_BVD2; if (state->csc_mask & SS_READY) reg |= PD67_CSC_READY; } pd67_set(sock, PD67_CSCINT, reg); // 设置中断管理寄存器 pd67_get(sock, PD67_CSC); // 读取状态寄存器 return 0;} /* pd67_set_socket *//*====================================================================*//*********************************************************************************************************** Function name: pd67_get_io_map** Descriptions: 获取IO MAP 配置信息** Input:sock, 接口序号** *io, IO MAP 设置参数结构指针** Output : 错出返回非0** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/static int pd67_get_io_map(unsigned int sock, struct pccard_io_map *io){ u_char map, ioctl, addr; if (socket[sock].flags & IS_ALIVE) return -EINVAL; map = io->map; if (map > 1) return -EINVAL; io->start = pd67_get_pair(sock, PD67_IO(map)+PD67_W_START); // 获取当前设置的开始地址 io->stop = pd67_get_pair(sock, PD67_IO(map)+PD67_W_STOP); // 获取当前设置的结束地址 ioctl = pd67_get(sock, PD67_IOCTL); // 获取当前IO控制寄存器值 addr = pd67_get(sock, PD67_MAP_ENA); // 获取当前MAP使能寄存器值 io->speed = to_ns(ioctl & PD67_IOCTL_WAIT(map)) ? 1 : 0; io->flags = (addr & PD67_ENA_IO(map)) ? MAP_ACTIVE : 0; // IO地址是否使能 io->flags |= (ioctl & PD67_IOCTL_0WS(map)) ? MAP_0WS : 0; // PD7610不使用,但为了兼容 io->flags |= (ioctl & PD67_IOCTL_16BIT(map)) ? MAP_16BIT : 0; // 16位总线 io->flags |= (ioctl & PD67_IOCTL_IOCS16(map)) ? MAP_AUTOSZ : 0; // 自动总线 DEBUG(1, "pd6700: GetIOMap(%d, %d) = %#2.2x, %d ns, " "%#4.4x-%#4.4x\n", sock, map, io->flags, io->speed, io->start, io->stop); io->start += vCF_IO_BASE; // 系统中的开始地址 io->stop += vCF_IO_BASE; // 系统中的结束地址 return 0;} /* pd67_get_io_map *//*====================================================================*//*********************************************************************************************************** Function name: pd67_set_io_map** Descriptions: 设置 IO MAP 处理函数** Input:sock, 接口序号** *io, IO MAP 设置参数结构指针** Output : 错出返回非0** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/static int pd67_set_io_map(unsigned int sock, struct pccard_io_map *io){ u_char map, ioctl; if (socket[sock].flags & IS_ALIVE) return -EINVAL; if (io->start >= vCF_IO_BASE) io->start -= vCF_IO_BASE; if (io->stop >= vCF_IO_BASE) io->stop -= vCF_IO_BASE; map = io->map; // 设置的IO MAP号 DEBUG(1, "pd6700: SetIOMap(%d, %d, %#2.2x, %d ns, " // 打印调试信息 "%#4.4x-%#4.4x)\n", sock, io->map, io->flags, io->speed, io->start, io->stop); if ((map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||(io->stop < io->start)) // 检验参数合法性 return -EINVAL; /* Turn off the window before changing anything */ if (pd67_get(sock, PD67_MAP_ENA) & PD67_ENA_IO(map)) // 如果IO MAP已使能, pd67_bclr(sock, PD67_MAP_ENA, PD67_ENA_IO(map)); // 则关闭MAP使能 pd67_set_pair(sock, PD67_IO(map)+PD67_W_START, io->start); // 设置IO口开始地址 pd67_set_pair(sock, PD67_IO(map)+PD67_W_STOP, io->stop); // 设置IO口结束地址 ioctl = pd67_get(sock, PD67_IOCTL) & ~PD67_IOCTL_MASK(map); if (io->speed) ioctl |= PD67_IOCTL_WAIT(map); // IO 时序 if (io->flags & MAP_0WS) ioctl |= PD67_IOCTL_0WS(map); // PD6710该位没使用 if (io->flags & MAP_16BIT) ioctl |= PD67_IOCTL_16BIT(map); // 设16位总线 if (io->flags & MAP_AUTOSZ) ioctl |= PD67_IOCTL_IOCS16(map); // 自动适应总线 pd67_set(sock, PD67_IOCTL, ioctl); // 设置IO 控制寄存器,寄存器索引07 /* Turn on the window if necessary */ if (io->flags & MAP_ACTIVE) // 是否激活 IO MAP pd67_bset(sock, PD67_MAP_ENA, PD67_ENA_IO(map)); // 使能 IO MAP io->start += vCF_IO_BASE; io->stop += vCF_IO_BASE; return 0;} /* pd67_set_io_map *//*====================================================================*//*********************************************************************************************************** Function name: pd67_get_mem_map** Descriptions: 获取MEMORY MAP设置参数** Input:sock, 接口序号** *mem,MEMORY 参数描述结构指针** Output : 出错返回非0值** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/static int pd67_get_mem_map(unsigned int sock, struct pccard_mem_map *mem){ u32 base, i; u_char map, addr; if (socket[sock].flags & IS_ALIVE) return -EINVAL; map = mem->map; if (map > 4) return -EINVAL; addr = pd67_get(sock, PD67_MAP_ENA); mem->flags = (addr & PD67_ENA_MEM(map)) ? MAP_ACTIVE : 0; base = PD67_MEM(map); i = pd67_get_pair(sock, base+PD67_W_START); mem->flags |= (i & PD67_MEM_16BIT) ? MAP_16BIT : 0; mem->flags |= (i & PD67_MEM_0WS) ? MAP_0WS : 0; mem->sys_start = ((u_long)(i & 0x0fff) << 12); i = pd67_get_pair(sock, base+PD67_W_STOP); mem->speed = (i & PD67_MEM_WS0) ? 1 : 0; mem->speed += (i & PD67_MEM_WS1) ? 2 : 0; mem->speed = to_ns(mem->speed); // 时序 mem->sys_stop = ((u_long)(i & 0x0fff) << 12) + 0x0fff; i = pd67_get_pair(sock, base+PD67_W_OFF); mem->flags |= (i & PD67_MEM_WRPROT) ? MAP_WRPROT : 0; mem->flags |= (i & PD67_MEM_REG) ? MAP_ATTRIB : 0; mem->card_start = ((u_int)(i & 0x3fff) << 12) + mem->sys_start; mem->card_start &= 0x3ffffff; DEBUG(1, "pd6700: GetMemMap(%d, %d) = %#2.2x, %d ns, %#5.5lx-%#5." "5lx, %#5.5x\n", sock, mem->map, mem->flags, mem->speed, mem->sys_start, mem->sys_stop, mem->card_start); mem->sys_start += pCF_MEM_BASE; mem->sys_stop += pCF_MEM_BASE; return 0;} /* pd67_get_mem_map *//*====================================================================*/ /*********************************************************************************************************** Function name: pd67_set_mem_map** Descriptions: 设置 MEM MAP参数** Input:sock, 接口序号** *mem,MEMORY 参数描述结构指针** Output : 出错返回非0值** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -