in yenta_socket.c [330:403]
static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
{
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
u16 bridge;
/* if powering down: do it immediately */
if (state->Vcc == 0)
yenta_set_power(socket, state);
socket->io_irq = state->io_irq;
bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~(CB_BRIDGE_CRST | CB_BRIDGE_INTR);
if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) {
u8 intr;
bridge |= (state->flags & SS_RESET) ? CB_BRIDGE_CRST : 0;
/* ISA interrupt control? */
intr = exca_readb(socket, I365_INTCTL);
intr = (intr & ~0xf);
if (!socket->dev->irq) {
intr |= socket->cb_irq ? socket->cb_irq : state->io_irq;
bridge |= CB_BRIDGE_INTR;
}
exca_writeb(socket, I365_INTCTL, intr);
} else {
u8 reg;
reg = exca_readb(socket, I365_INTCTL) & (I365_RING_ENA | I365_INTR_ENA);
reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
if (state->io_irq != socket->dev->irq) {
reg |= state->io_irq;
bridge |= CB_BRIDGE_INTR;
}
exca_writeb(socket, I365_INTCTL, reg);
reg = exca_readb(socket, I365_POWER) & (I365_VCC_MASK|I365_VPP1_MASK);
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 (exca_readb(socket, I365_POWER) != reg)
exca_writeb(socket, I365_POWER, reg);
/* CSC interrupt: no ISA irq for CSC */
reg = exca_readb(socket, I365_CSCINT);
reg &= I365_CSC_IRQ_MASK;
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;
}
exca_writeb(socket, I365_CSCINT, reg);
exca_readb(socket, I365_CSC);
if (sock->zoom_video)
sock->zoom_video(sock, state->flags & SS_ZVCARD);
}
config_writew(socket, CB_BRIDGE_CONTROL, bridge);
/* Socket event mask: get card insert/remove events.. */
cb_writel(socket, CB_SOCKET_EVENT, -1);
cb_writel(socket, CB_SOCKET_MASK, CB_CDMASK);
/* if powering up: do it as the last step when the socket is configured */
if (state->Vcc != 0)
yenta_set_power(socket, state);
return 0;
}