/* note: hardware cannot control socket power, so we will
* always report SS_POWERON */
/* apply socket reset */
val = pcmcia_readl(skt, PCMCIA_C1_REG); if (state->flags & SS_RESET)
val |= PCMCIA_C1_RESET_MASK; else
val &= ~PCMCIA_C1_RESET_MASK;
/* reverse reset logic for cardbus card */ if (skt->card_detected && (skt->card_type & CARD_CARDBUS))
val ^= PCMCIA_C1_RESET_MASK;
pcmcia_writel(skt, val, PCMCIA_C1_REG);
/* keep requested state for event reporting */
skt->requested_state = *state;
/* check CD for card presence */
val = pcmcia_readl(skt, PCMCIA_C1_REG);
if (!(val & PCMCIA_C1_CD1_MASK) && !(val & PCMCIA_C1_CD2_MASK))
stat |= SS_DETECT;
/* if new insertion, detect cardtype */ if ((stat & SS_DETECT) && !skt->card_detected) { unsignedint stat = 0;
/* float VS1, float VS2 */
val |= PCMCIA_C1_VS1OE_MASK;
val |= PCMCIA_C1_VS2OE_MASK;
pcmcia_writel(skt, val, PCMCIA_C1_REG);
/* wait for output to stabilize and read VS[12] */
udelay(10);
val = pcmcia_readl(skt, PCMCIA_C1_REG);
stat |= (val & PCMCIA_C1_VS1_MASK) ? IN_VS1 : 0;
stat |= (val & PCMCIA_C1_VS2_MASK) ? IN_VS2 : 0;
/* drive VS1 low, float VS2 */
val &= ~PCMCIA_C1_VS1OE_MASK;
val |= PCMCIA_C1_VS2OE_MASK;
pcmcia_writel(skt, val, PCMCIA_C1_REG);
/* wait for output to stabilize and read CD[12] */
udelay(10);
val = pcmcia_readl(skt, PCMCIA_C1_REG);
stat |= (val & PCMCIA_C1_CD1_MASK) ? IN_CD1_VS2H : 0;
stat |= (val & PCMCIA_C1_CD2_MASK) ? IN_CD2_VS2H : 0;
/* float VS1, drive VS2 low */
val |= PCMCIA_C1_VS1OE_MASK;
val &= ~PCMCIA_C1_VS2OE_MASK;
pcmcia_writel(skt, val, PCMCIA_C1_REG);
/* wait for output to stabilize and read CD[12] */
udelay(10);
val = pcmcia_readl(skt, PCMCIA_C1_REG);
stat |= (val & PCMCIA_C1_CD1_MASK) ? IN_CD1_VS1H : 0;
stat |= (val & PCMCIA_C1_CD2_MASK) ? IN_CD2_VS1H : 0;
/* guess cardtype from all this */
skt->card_type = vscd_to_cardtype[stat]; if (!skt->card_type)
dev_err(&skt->socket.dev, "unsupported card type\n");
/* drive both VS pin to 0 again */
val &= ~(PCMCIA_C1_VS1OE_MASK | PCMCIA_C1_VS2OE_MASK);
/* enable correct logic */
val &= ~(PCMCIA_C1_EN_PCMCIA_MASK | PCMCIA_C1_EN_CARDBUS_MASK); if (skt->card_type & CARD_PCCARD)
val |= PCMCIA_C1_EN_PCMCIA_MASK; else
val |= PCMCIA_C1_EN_CARDBUS_MASK;
/* report card type/voltage */ if (skt->card_type & CARD_CARDBUS)
stat |= SS_CARDBUS; if (skt->card_type & CARD_3V)
stat |= SS_3VCARD; if (skt->card_type & CARD_XV)
stat |= SS_XVCARD;
stat |= SS_POWERON;
if (gpio_get_value(skt->pd->ready_gpio))
stat |= SS_READY;
/* keep only changed bits, and mask with required one from the
* core */
events = (stat ^ skt->old_status) & skt->requested_state.csc_mask;
skt->old_status = stat;
spin_unlock_bh(&skt->lock);
if (events)
pcmcia_parse_events(&skt->socket, events);
staticint bcm63xx_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map)
{ /* this doesn't seem to be called by pcmcia layer if static
* mapping is used */ return0;
}
err: if (skt->io_base)
iounmap(skt->io_base); if (skt->base)
iounmap(skt->base); if (skt->reg_res)
release_mem_region(skt->reg_res->start, regmem_size);
kfree(skt); return ret;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.