Пример #1
0
/* 
 * This function should only ever be called with interrupts disabled.
 */
static void hs_unmap_irq(hs_socket_t *sp, unsigned int irq)
{
    	DPRINTK("hs_unmap_irq(sock=%d irq=%d)\n", hs_sockno(sp), irq);
	
	if (irq >= HS_NUM_MAPPED_IRQS)
	    return;
		
	/* restore the original irq controller */
	irq_desc[irq].handler = hs_mapped_irq[irq].old_handler;
}
Пример #2
0
static void hs_socket_disable_ireq(hs_socket_t *sp)
{
    	unsigned short cscier;
	
    	DPRINTK("hs_socket_disable_ireq(sock=%d)\n", hs_sockno(sp));
	
    	cscier = hs_in(sp, CSCIER);
	cscier &= ~HD64465_PCCCSCIER_PIREQE_MASK;
	hs_out(sp, cscier, CSCIER);
}
/* 
 * This function should only ever be called with interrupts disabled.
 */
static void hs_map_irq(hs_socket_t *sp, unsigned int irq)
{
    	DPRINTK("hs_map_irq(sock=%d irq=%d)\n", hs_sockno(sp), irq);
	
	if (irq >= HS_NUM_MAPPED_IRQS)
	    return;

    	hs_mapped_irq[irq].sock = sp;
	/* insert ourselves as the irq controller */
	hs_mapped_irq[irq].old_handler = irq_desc[irq].handler;
	irq_desc[irq].handler = &hd64465_ss_irq_type;
}
Пример #4
0
/* 
 * This function should only ever be called with interrupts disabled.
 */
static void hs_map_irq(hs_socket_t *sp, unsigned int irq)
{
    	DPRINTK("hs_map_irq(sock=%d irq=%d)\n", hs_sockno(sp), irq);
	
	if (irq >= HS_NUM_MAPPED_IRQS)
	    return;

    	hs_mapped_irq[irq].sock = sp;
	/* insert ourselves as the irq controller */
	hs_mapped_irq[irq].old_handler = irq_desc[irq].handler;
	irq_desc[irq].handler = &hd64465_ss_irq_type;
	/*
	 * some drivers may not ever mess with there interrupts, so
	 * we must make sure the interrupt for the slot is in the right state
	 */
	if (irq_desc[irq].status & IRQ_DISABLED)
		hs_socket_disable_ireq(hs_mapped_irq[irq].sock);
	else if ((irq_desc[irq].status & IRQ_INPROGRESS) == 0)
		hs_socket_enable_ireq(hs_mapped_irq[irq].sock);
}
Пример #5
0
static int hs_set_voltages(hs_socket_t *sp, int Vcc, int Vpp)
{
    	u_int psr;
	u_int vcci = 0;
	u_int sock = hs_sockno(sp);
	
    	DPRINTK("hs_set_voltage(%d, %d, %d)\n", sock, Vcc, Vpp);

    	switch (Vcc)
	{
	case 0:  vcci = 0; break;
	case 33: vcci = 1; break;
	case 50: vcci = 2; break;
	default: return 0;
	}

    	/* Note: Vpp = 120 not supported -- Greg Banks */
	if (Vpp != 0 && Vpp != Vcc)
	    return 0;
	
	/* The PSR register holds 8 of the 9 bits which control
	 * the TPS2206 via its serial interface.
	 */
	psr = inw(HD64465_REG_PCCPSR);
	switch (sock)
	{
	case 0:
	    psr &= 0x0f;
	    psr |= hs_tps2206_avcc[vcci];
	    psr |= (Vpp == 0 ? 0x00 : 0x02);
	    break;
	case 1:
	    psr &= 0xf0;
	    psr |= hs_tps2206_bvcc[vcci];
	    psr |= (Vpp == 0 ? 0x00 : 0x20);
	    break;
	};
	outw(psr, HD64465_REG_PCCPSR);
	
	return 1;
}
Пример #6
0
static void hs_interrupt(int irq, void *dev, struct pt_regs *regs)
{
    	hs_socket_t *sp = (hs_socket_t *)dev;
	u_int events = 0;
	u_int cscr;
	
	
	cscr = hs_in(sp, CSCR);
	
	DPRINTK("hs_interrupt, cscr=%04x\n", cscr);

	/* check for bus-related changes to be reported to Socket Services */
	if (cscr & HD64465_PCCCSCR_PCDC) {
	    /* double-check for a 16-bit card, as we don't support CardBus */
	    if ((hs_in(sp, ISR) & HD64465_PCCISR_PCD_MASK) != 0) {
	    	printk(KERN_NOTICE MODNAME
		    ": socket %d, card not a supported card type or not inserted correctly\n",
		    hs_sockno(sp));
		/* Don't do the rest unless a card is present */
		cscr &= ~(HD64465_PCCCSCR_PCDC|
		    	  HD64465_PCCCSCR_PRC|
			  HD64465_PCCCSCR_PBW|
		    	  HD64465_PCCCSCR_PBD|
			  HD64465_PCCCSCR_PSC);
	    } else {
	    	cscr &= ~HD64465_PCCCSCR_PCDC;
		events |= SS_DETECT;    	/* card insertion or removal */
    	    }
	}
	if (cscr & HD64465_PCCCSCR_PRC) {
	    cscr &= ~HD64465_PCCCSCR_PRC;
	    events |= SS_READY;     	/* ready signal changed */
	}
	if (cscr & HD64465_PCCCSCR_PBW) {
	    cscr &= ~HD64465_PCCCSCR_PSC;
	    events |= SS_BATWARN;     	/* battery warning */
	}
	if (cscr & HD64465_PCCCSCR_PBD) {
	    cscr &= ~HD64465_PCCCSCR_PSC;
	    events |= SS_BATDEAD;     	/* battery dead */
	}
	if (cscr & HD64465_PCCCSCR_PSC) {
	    cscr &= ~HD64465_PCCCSCR_PSC;
	    events |= SS_STSCHG;     	/* STSCHG (status changed) signal */
	}
	
	if (cscr & HD64465_PCCCSCR_PIREQ) {
	    cscr &= ~HD64465_PCCCSCR_PIREQ;

    	    /* This should have been dealt with during irq demux */	    
	    printk(KERN_NOTICE MODNAME ": unexpected IREQ from card\n");
	}

	hs_out(sp, cscr, CSCR);

	if (events) {
	    /*
    	     * Arrange for events to be reported to the registered
	     * event handler function (from CardServices) in a process
	     * context (keventd) "soon".
	     */
	    spin_lock(&hs_pending_event_lock);
	    sp->pending_events |= events;
	    spin_unlock(&hs_pending_event_lock);
	    
	    schedule_task(&hs_events_task);
	}
}