예제 #1
0
static int _pcc_set_socket(u_short sock, socket_state_t *state)
{
	debug(3, "m32r_cfc: 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);

#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
	if (state->Vcc) {
		if ((state->Vcc != 50) && (state->Vcc != 33))
			return -EINVAL;
		/* accept 5V and 3.3V */
	}
#endif
	if (state->flags & SS_RESET) {
		debug(3, ":RESET\n");
		pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x101);
	}else{
		pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x100);
	}
	if (state->flags & SS_OUTPUT_ENA){
		debug(3, ":OUTPUT_ENA\n");
		/* bit clear */
		pcc_set(sock,(unsigned int)PLD_CFBUFCR,0);
	} else {
		pcc_set(sock,(unsigned int)PLD_CFBUFCR,1);
	}

#ifdef DEBUG
	if(state->flags & SS_IOCARD){
		debug(3, ":IOCARD");
	}
	if (state->flags & SS_PWR_AUTO) {
		debug(3, ":PWR_AUTO");
	}
	if (state->csc_mask & SS_DETECT)
		debug(3, ":csc-SS_DETECT");
	if (state->flags & SS_IOCARD) {
		if (state->csc_mask & SS_STSCHG)
			debug(3, ":STSCHG");
	} else {
		if (state->csc_mask & SS_BATDEAD)
			debug(3, ":BATDEAD");
		if (state->csc_mask & SS_BATWARN)
			debug(3, ":BATWARN");
		if (state->csc_mask & SS_READY)
			debug(3, ":READY");
	}
	debug(3, "\n");
#endif
	return 0;
} /* _set_socket */
예제 #2
0
static int _pcc_get_status(u_short sock, u_int *value)
{
	u_int status;

	pr_debug("m32r_cfc: _pcc_get_status:\n");
	status = pcc_get(sock, (unsigned int)PLD_CFSTS);
	*value = (status) ? SS_DETECT : 0;
	pr_debug("m32r_cfc: _pcc_get_status: status=0x%08x\n", status);

#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
	if ( status ) {
		/* enable CF power */
		status = inw((unsigned int)PLD_CPCR);
		if (!(status & PLD_CPCR_CF)) {
			pr_debug("m32r_cfc: _pcc_get_status: "
				 "power on (CPCR=0x%08x)\n", status);
			status |= PLD_CPCR_CF;
			outw(status, (unsigned int)PLD_CPCR);
			udelay(100);
		}
		*value |= SS_POWERON;

		pcc_set(sock, (unsigned int)PLD_CFBUFCR,0);/* enable buffer */
		udelay(100);

		*value |= SS_READY; 		/* always ready */
		*value |= SS_3VCARD;
	} else {
		/* disable CF power */
		status = inw((unsigned int)PLD_CPCR);
		status &= ~PLD_CPCR_CF;
		outw(status, (unsigned int)PLD_CPCR);
		udelay(100);
		pr_debug("m32r_cfc: _pcc_get_status: "
			 "power off (CPCR=0x%08x)\n", status);
	}
#elif defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
	if ( status ) {
		status = pcc_get(sock, (unsigned int)PLD_CPCR);
		if (status == 0) { /* power off */
			pcc_set(sock, (unsigned int)PLD_CPCR, 1);
			pcc_set(sock, (unsigned int)PLD_CFBUFCR,0); /* force buffer off for ZA-36 */
			udelay(50);
		}
		*value |= SS_POWERON;

		pcc_set(sock, (unsigned int)PLD_CFBUFCR,0);
		udelay(50);
		pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0101);
		udelay(25); /* for IDE reset */
		pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0100);
		mdelay(2);  /* for IDE reset */

		*value |= SS_READY;
		*value |= SS_3VCARD;
	} else {
		/* disable CF power */
	        pcc_set(sock, (unsigned int)PLD_CPCR, 0);
		udelay(100);
		pr_debug("m32r_cfc: _pcc_get_status: "
			 "power off (CPCR=0x%08x)\n", status);
	}
#else
#error no platform configuration
#endif
	pr_debug("m32r_cfc: _pcc_get_status: GetStatus(%d) = %#4.4x\n",
		 sock, *value);
	return 0;
} /* _get_status */
예제 #3
0
static void add_pcc_socket(ulong base, int irq, ulong mapaddr,
			   unsigned int ioaddr)
{
	pcc_socket_t *t = &socket[pcc_sockets];

	pr_debug("m32r_cfc: add_pcc_socket: base=%#lx, irq=%d, "
		 "mapaddr=%#lx, ioaddr=%08x\n",
		 base, irq, mapaddr, ioaddr);

	/* add sockets */
	t->ioaddr = ioaddr;
	t->mapaddr = mapaddr;
#if !defined(CONFIG_PLAT_USRV)
	t->base = 0;
	t->flags = 0;
	t->cs_irq1 = irq;		// insert irq
	t->cs_irq2 = irq + 1;		// eject irq
#else	/* CONFIG_PLAT_USRV */
	t->base = base;
	t->flags = 0;
	t->cs_irq1 = 0;			// insert irq
	t->cs_irq2 = 0;			// eject irq
#endif	/* CONFIG_PLAT_USRV */

	if (is_alive(pcc_sockets))
		t->flags |= IS_ALIVE;

	/* add pcc */
#if !defined(CONFIG_PLAT_USRV)
	request_region((unsigned int)PLD_CFRSTCR, 0x20, "m32r_cfc");
#else	/* CONFIG_PLAT_USRV */
	{
		unsigned int reg_base;

		reg_base = (unsigned int)PLD_CFRSTCR;
		reg_base |= pcc_sockets << 8;
		request_region(reg_base, 0x20, "m32r_cfc");
	}
#endif	/* CONFIG_PLAT_USRV */
	printk(KERN_INFO "  %s ", pcc[pcc_sockets].name);
	printk("pcc at 0x%08lx\n", t->base);

	/* Update socket interrupt information, capabilities */
	t->socket.features |= (SS_CAP_PCCARD | SS_CAP_STATIC_MAP);
	t->socket.map_size = M32R_PCC_MAPSIZE;
	t->socket.io_offset = ioaddr;	/* use for io access offset */
	t->socket.irq_mask = 0;
#if !defined(CONFIG_PLAT_USRV)
	t->socket.pci_irq = PLD_IRQ_CFIREQ ;	/* card interrupt */
#else	/* CONFIG_PLAT_USRV */
	t->socket.pci_irq = PLD_IRQ_CF0 + pcc_sockets;
#endif	/* CONFIG_PLAT_USRV */

#ifndef CONFIG_PLAT_USRV
	/* insert interrupt */
	request_irq(irq, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
#ifndef CONFIG_PLAT_MAPPI3
	/* eject interrupt */
	request_irq(irq+1, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
#endif
	pr_debug("m32r_cfc: enable CFMSK, RDYSEL\n");
	pcc_set(pcc_sockets, (unsigned int)PLD_CFIMASK, 0x01);
#endif	/* CONFIG_PLAT_USRV */
#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
	pcc_set(pcc_sockets, (unsigned int)PLD_CFCR1, 0x0200);
#endif
	pcc_sockets++;

	return;
}
예제 #4
0
static int __init init_m32r_pcc(void)
{
	int i, ret;

	ret = platform_driver_register(&pcc_driver);
	if (ret)
		return ret;

	ret = platform_device_register(&pcc_device);
	if (ret){
		platform_driver_unregister(&pcc_driver);
		return ret;
	}

#if defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
	pcc_set(0, (unsigned int)PLD_CFCR0, 0x0f0f);
	pcc_set(0, (unsigned int)PLD_CFCR1, 0x0200);
#endif

	pcc_sockets = 0;

#if !defined(CONFIG_PLAT_USRV)
	add_pcc_socket(M32R_PCC0_BASE, PLD_IRQ_CFC_INSERT, CFC_ATTR_MAPBASE,
		       CFC_IOPORT_BASE);
#else	/* CONFIG_PLAT_USRV */
	{
		ulong base, mapaddr;
		unsigned int ioaddr;

		for (i = 0 ; i < M32R_MAX_PCC ; i++) {
			base = (ulong)PLD_CFRSTCR;
			base = base | (i << 8);
			ioaddr = (i + 1) << 12;
			mapaddr = CFC_ATTR_MAPBASE | (i << 20);
			add_pcc_socket(base, 0, mapaddr, ioaddr);
		}
	}
#endif	/* CONFIG_PLAT_USRV */

	if (pcc_sockets == 0) {
		printk("socket is not found.\n");
		platform_device_unregister(&pcc_device);
		platform_driver_unregister(&pcc_driver);
		return -ENODEV;
	}

	/* Set up interrupt handler(s) */

	for (i = 0 ; i < pcc_sockets ; i++) {
		socket[i].socket.dev.parent = &pcc_device.dev;
		socket[i].socket.ops = &pcc_operations;
		socket[i].socket.resource_ops = &pccard_static_ops;
		socket[i].socket.owner = THIS_MODULE;
		socket[i].number = i;
		ret = pcmcia_register_socket(&socket[i].socket);
		if (!ret)
			socket[i].flags |= IS_REGISTERED;

	}

	/* Finally, schedule a polling interrupt */
	if (poll_interval != 0) {
		poll_timer.function = pcc_interrupt_wrapper;
		poll_timer.data = 0;
		init_timer(&poll_timer);
		poll_timer.expires = jiffies + poll_interval;
		add_timer(&poll_timer);
	}

	return 0;
} /* init_m32r_pcc */