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

📄 i82365.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 4 页
字号:
		printk("activate failed\n");		break;	    }	    if ((i365_base = pci_resource_start(dev, 0))) {		printk("no resources ?\n");		break;	    }	    i82365_pnpdev = dev;	    break;	}    }#endif    if (check_region(i365_base, 2) != 0) {	if (sockets == 0)	    printk("port conflict at %#x\n", i365_base);	return;    }    id = identify(i365_base, 0);    if ((id == IS_I82365DF) && (identify(i365_base, 1) != id)) {	for (i = 0; i < 4; i++) {	    if (i == ignore) continue;	    port = i365_base + ((i & 1) << 2) + ((i & 2) << 1);	    sock = (i & 1) << 1;	    if (identify(port, sock) == IS_I82365DF) {		    add_socket(port, sock, IS_VLSI);		    add_pcic(1, IS_VLSI);	    }	}    } else {#ifdef CONFIG_S3C2410_SMDK	/* There is just one socket */	add_socket(i365_base, 0, id);	add_pcic(1, id);#else	for (i = 0; i < (extra_sockets ? 8 : 4); i += 2) {	    port = i365_base + 2*(i>>2);	    sock = (i & 3);	    id = identify(port, sock);	    if (id < 0) continue;	    for (j = ns = 0; j < 2; j++) {		/* Does the socket exist? */		if ((ignore == i+j) || (identify(port, sock+j) < 0))		    continue;		/* Check for bad socket decode */		for (k = 0; k <= sockets; k++)		    i365_set(k, I365_MEM(0)+I365_W_OFF, k);		for (k = 0; k <= sockets; k++)		    if (i365_get(k, I365_MEM(0)+I365_W_OFF) != k)			break;		if (k <= sockets) break;		add_socket(port, sock+j, id); ns++;	    }	    if (ns != 0)		add_pcic(ns, id);	}#endif    }}#endif/*====================================================================*/static u_int pending_events[8];static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;static void pcic_bh(void *dummy){	u_int events;	int i;	for (i=0; i < sockets; i++) {		spin_lock_irq(&pending_event_lock);		events = pending_events[i];		pending_events[i] = 0;		spin_unlock_irq(&pending_event_lock);		/* 		SS_DETECT events need a small delay here. The reason for this is that 		the "is there a card" electronics need time to see the card after the		"we have a card coming in" electronics have seen it. 		*/		if (events & SS_DETECT) 			mdelay(4);		if (socket[i].handler)			socket[i].handler(socket[i].info, events);	}}static struct tq_struct pcic_task = {	routine:	pcic_bh};static unsigned long last_detect_jiffies;static void pcic_interrupt(int irq, void *dev,				    struct pt_regs *regs){    int i, j, csc;    u_int events, active;#ifdef CONFIG_ISA    u_long flags = 0;#endif    for (j = 0; j < 20; j++) {	active = 0;	for (i = 0; i < sockets; i++) {	    if ((socket[i].cs_irq != irq) &&		(socket[i].cap.pci_irq != irq))		continue;	    ISA_LOCK(i, flags);	    csc = i365_get(i, I365_CSC);	    if ((csc == 0) || (!socket[i].handler) || 		(i365_get(i, I365_IDENT) & 0x70)) {		ISA_UNLOCK(i, flags);		continue;	    }	    events = (csc & I365_CSC_DETECT) ? SS_DETECT : 0;	    	    	    /* Several sockets will send multiple "new card detected"	       events in rapid succession. However, the rest of the pcmcia expects 	       only one such event. We just ignore these events by having a               timeout */	    if (events) {	    	if ((jiffies - last_detect_jiffies)<(HZ/20)) 	    		events = 0;	    	last_detect_jiffies = jiffies;	    		    }		    if (i365_get(i, I365_INTCTL) & I365_PC_IOCARD)		events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0;	    else {		events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0;		events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;		events |= (csc & I365_CSC_READY) ? SS_READY : 0;	    }	    ISA_UNLOCK(i, flags);	    DEBUG(2, "i82365: socket %d event 0x%02x\n", i, events);	    if (events) {		    spin_lock(&pending_event_lock);		    pending_events[i] |= events;		    spin_unlock(&pending_event_lock);		    schedule_task(&pcic_task);	    }	    active |= events;	}	if (!active) break;    }    if (j == 20)	printk(KERN_NOTICE "i82365: infinite loop in interrupt handler\n");    DEBUG(4, "i82365: interrupt done\n");} /* pcic_interrupt */static void pcic_interrupt_wrapper(u_long data){    pcic_interrupt(0, NULL, NULL);    poll_timer.expires = jiffies + poll_interval;    add_timer(&poll_timer);}/*====================================================================*/static int pcic_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info){    socket[sock].handler = handler;    socket[sock].info = info;    if (handler == NULL) {	MOD_DEC_USE_COUNT;    } else {	MOD_INC_USE_COUNT;    }    return 0;} /* pcic_register_callback *//*====================================================================*/static int pcic_inquire_socket(unsigned int sock, socket_cap_t *cap){    *cap = socket[sock].cap;    return 0;} /* pcic_inquire_socket *//*====================================================================*/static int i365_get_status(u_short sock, u_int *value){    u_int status;    status = i365_get(sock, I365_STATUS);    *value = ((status & I365_CS_DETECT) == I365_CS_DETECT)	? SS_DETECT : 0;	    if (i365_get(sock, I365_INTCTL) & I365_PC_IOCARD)	*value |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;    else {	*value |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;	*value |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;    }    *value |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;    *value |= (status & I365_CS_READY) ? SS_READY : 0;    *value |= (status & I365_CS_POWERON) ? SS_POWERON : 0;#ifdef CONFIG_ISA    if (socket[sock].type == IS_VG469) {	status = i365_get(sock, VG469_VSENSE);	if (socket[sock].psock & 1) {	    *value |= (status & VG469_VSENSE_B_VS1) ? 0 : SS_3VCARD;	    *value |= (status & VG469_VSENSE_B_VS2) ? 0 : SS_XVCARD;	} else {	    *value |= (status & VG469_VSENSE_A_VS1) ? 0 : SS_3VCARD;	    *value |= (status & VG469_VSENSE_A_VS2) ? 0 : SS_XVCARD;	}    }#endif        DEBUG(1, "i82365: GetStatus(%d) = %#4.4x\n", sock, *value);    return 0;} /* i365_get_status *//*====================================================================*/static int i365_get_socket(u_short sock, socket_state_t *state){    socket_info_t *t = &socket[sock];    u_char reg, vcc, vpp;    reg = i365_get(sock, I365_POWER);    state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;    state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;    vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK;    state->Vcc = state->Vpp = 0;    if (t->flags & IS_CIRRUS) {	printk("t->flags & IS_CIRRUS =%d\n",t->flags & IS_CIRRUS);	if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_VCC_3V) {    	    if (reg & I365_VCC_5V) state->Vcc = 33;	    if (vpp == I365_VPP1_5V) state->Vpp = 33;	} else {	    if (reg & I365_VCC_5V) state->Vcc = 50;	    if (vpp == I365_VPP1_5V) state->Vpp = 50;	}	printk("%d state->Vcc = %d\n",__LINE__,state->Vcc);	if (vpp == I365_VPP1_12V) state->Vpp = 120;    } else if (t->flags & IS_VG_PWR) {	if (i365_get(sock, VG469_VSELECT) & VG469_VSEL_VCC) {	    if (reg & I365_VCC_5V) state->Vcc = 33;	    if (vpp == I365_VPP1_5V) state->Vpp = 33;	} else {	    if (reg & I365_VCC_5V) state->Vcc = 50;	    if (vpp == I365_VPP1_5V) state->Vpp = 50;	}	 printk("%d state->Vcc = %d\n",__LINE__,state->Vcc);	if (vpp == I365_VPP1_12V) state->Vpp = 120;    } else if (t->flags & IS_DF_PWR) {	if (vcc == I365_VCC_3V) state->Vcc = 33;	if (vcc == I365_VCC_5V) state->Vcc = 50;	if (vpp == I365_VPP1_5V) state->Vpp = 50;	if (vpp == I365_VPP1_12V) state->Vpp = 120;    } else {	if (reg & I365_VCC_5V) {	    state->Vcc = 50;	    if (vpp == I365_VPP1_5V) state->Vpp = 50;	    if (vpp == I365_VPP1_12V) state->Vpp = 120;	}    }     printk("%d state->Vcc = %d\n",__LINE__,state->Vcc);    /* IO card, RESET flags, IO interrupt */    reg = i365_get(sock, I365_INTCTL);    state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET;    if (reg & I365_PC_IOCARD) state->flags |= SS_IOCARD;    state->io_irq = REG2SOCKIRQ(sock, reg & I365_IRQ_MASK);        /* speaker control */    if (t->flags & IS_CIRRUS) {	if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_SPKR_ENA)	    state->flags |= SS_SPKR_ENA;    }        /* Card status change mask */    reg = i365_get(sock, I365_CSCINT);    state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0;    if (state->flags & SS_IOCARD)	state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0;    else {	state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0;	state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0;	state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0;    }        DEBUG(1, "i82365: 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;} /* i365_get_socket *//*====================================================================*/static int i365_set_socket(u_short sock, socket_state_t *state){    socket_info_t *t = &socket[sock];    u_char reg;        DEBUG(1, "i82365: 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);        /* IO card, RESET flag, IO interrupt */    reg = t->intr;    if (state->io_irq != t->cap.pci_irq) reg |= SOCKIRQ2REG(sock, state->io_irq);    reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;    reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;    i365_set(sock, I365_INTCTL, reg);    reg = I365_PWR_NORESET;    if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO;    if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT;    if (t->flags & IS_CIRRUS) {	if (state->Vpp != 0) {	    if (state->Vpp == 120)		reg |= I365_VPP1_12V;	    else if (state->Vpp == state->Vcc)		reg |= I365_VPP1_5V;	    else return -EINVAL;	}	if (state->Vcc != 0) {	    reg |= I365_VCC_5V;	    if (state->Vcc == 33)		i365_bset(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);	    else if (state->Vcc == 50)	//	i365_bclr(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);		i365_bset(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);	    else return -EINVAL;	}    } else if (t->flags & IS_VG_PWR) {	if (state->Vpp != 0) {	    if (state->Vpp == 120)		reg |= I365_VPP1_12V;	    else if (state->Vpp == state->Vcc)		reg |= I365_VPP1_5V;	    else return -EINVAL;	}	if (state->Vcc != 0) {	    reg |= I365_VCC_5V;	    if (state->Vcc == 33)		i365_bset(sock, VG469_VSELECT, VG469_VSEL_VCC);	    else if (state->Vcc == 50)	//	i365_bclr(sock, VG469_VSELECT, VG469_VSEL_VCC);		i365_bset(sock, VG469_VSELECT, VG469_VSEL_VCC);	    else return -EINVAL;	}    } else if (t->flags & IS_DF_PWR) {	switch (state->Vcc) {	case 0:		break;	case 33:   	reg |= I365_VCC_3V; break;	case 50:	reg |= I365_VCC_5V; break;	default:	return -EINVAL;	}	switch (state->Vpp) {	case 0:		break;	case 50:   	reg |= I365_VPP1_5V; break;	case 120:	reg |= I365_VPP1_12V; break;	default:	return -EINVAL;	}    } else {	switch (state->Vcc) {	case 0:		break;	case 50:	reg |= I365_VCC_5V; break;	default:	return -EINVAL;	}	switch (state->Vpp) {	case 0:		break;	case 50:	reg |= I365_VPP1_5V | I365_VPP2_5V; break;	case 120:	reg |= I365_VPP1_12V | I365_VPP2_12V; break;	default:	return -EINVAL;	}    }        if (reg != i365_get(sock, I365_POWER))	i365_set(sock, I365_POWER, reg);    /* Chipset-specific functions */    if (t->flags & IS_CIRRUS) {	/* Speaker control */	i365_bflip(sock, PD67_MISC_CTL_1, PD67_MC1_SPKR_ENA,		   state->flags & SS_SPKR_ENA);    }        /* Card status change interrupt mask */#ifdef CONFIG_S3C2410_SMDK    /* Use INTR signal as the Management Interrupt on SMDK2410. */    reg = 0;#else    reg = SOCKIRQ2REG(sock, t->cs_irq) << 4;#endif    if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT;    if (state->flags & SS_IOCARD) {	if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG;    } else {	if (state->csc_mask & SS_BATDEAD) reg |= I365_CSC_BVD1;	if (state->csc_mask & SS_BATWARN) reg |= I365_CSC_BVD2;	if (state->csc_mask & SS_READY) reg |= I365_CSC_READY;    }    i365_set(sock, I365_CSCINT, reg);    i365_get(sock, I365_CSC);        return 0;} /* i365_set_socket *//*====================================================================*/static int i365_get_io_map(u_short sock, struct pccard_io_map *io){    u_char map, ioctl, addr;    map = io->map;    if (map > 1) return -EINVAL;    io->start = i365_get_pair(sock, I365_IO(map)+I365_W_START);    io->stop = i365_get_pair(sock, I365_IO(map)+I365_W_STOP);    ioctl = i365_get(sock, I365_IOCTL);    addr = i365_get(sock, I365_ADDRWIN);    io->speed = to_ns(ioctl & I365_IOCTL_WAIT(map)) ? 1 : 0;    io->flags  = (addr & I365_ENA_IO(map)) ? MAP_ACTIVE : 0;    io->flags |= (ioctl & I365_IOCTL_0WS(map)) ? MAP_0WS : 0;    io->flags |= (ioctl & I365_IOCTL_16BIT(map)) ? MAP_16BIT : 0;    io->flags |= (ioctl & I365_IOCTL_IOCS16(map)) ? MAP_AUTOSZ : 0;    DEBUG(1, "i82365: GetIOMap(%d, %d) = %#2.2x, %d ns, "	  "%#4.4x-%#4.4x\n", sock, map, io->flags, io->speed,	  io->start, io->stop);

⌨️ 快捷键说明

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