/* au1x00_pcmcia_set_socket() * Implements the set_socket() operation for the in-kernel PCMCIA * service (formerly SS_SetSocket in Card Services). We more or * less punt all of this work and let the kernel handle the details * of power configuration, reset, &c. We also record the value of * `state' in order to regurgitate it to the PCMCIA core later. * * Returns: 0 */ static int au1x00_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state) { struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); debug("for sock %u\n", skt->nr); debug("\tmask: %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n", (state->csc_mask==0)?"<NONE>":"", (state->csc_mask&SS_DETECT)?"DETECT ":"", (state->csc_mask&SS_READY)?"READY ":"", (state->csc_mask&SS_BATDEAD)?"BATDEAD ":"", (state->csc_mask&SS_BATWARN)?"BATWARN ":"", (state->csc_mask&SS_STSCHG)?"STSCHG ":"", (state->flags==0)?"<NONE>":"", (state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"", (state->flags&SS_IOCARD)?"IOCARD ":"", (state->flags&SS_RESET)?"RESET ":"", (state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"", (state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":""); debug("\tVcc %d Vpp %d irq %d\n", state->Vcc, state->Vpp, state->io_irq); return au1x00_pcmcia_config_skt(skt, state); }
static int au1x00_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map) { struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); unsigned short speed = map->speed; if(map->map>=MAX_WIN){ debug("map (%d) out of range\n", map->map); return -1; } if (map->flags & MAP_ATTRIB) { skt->spd_attr[map->map] = speed; skt->spd_mem[map->map] = 0; } else { skt->spd_attr[map->map] = 0; skt->spd_mem[map->map] = speed; } if (map->flags & MAP_ATTRIB) { map->static_start = skt->phys_attr + map->card_start; } else { map->static_start = skt->phys_mem + map->card_start; } debug("set_mem_map %d start %08lx card_start %08x\n", map->map, map->static_start, map->card_start); return 0; } /* au1x00_pcmcia_set_mem_map() */
/* au1x00_pcmcia_sock_init() * * (Re-)Initialise the socket, turning on status interrupts * and PCMCIA bus. This must wait for power to stabilise * so that the card status signals report correctly. * * Returns: 0 */ static int au1x00_pcmcia_sock_init(struct pcmcia_socket *sock) { struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); debug("initializing socket %u\n", skt->nr); skt->ops->socket_init(skt); return 0; }
/* au1x00_pcmcia_get_socket() * Implements the get_socket() operation for the in-kernel PCMCIA * service (formerly SS_GetSocket in Card Services). Not a very * exciting routine. * * Returns: 0 */ static int au1x00_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state) { struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); debug("for sock %u\n", skt->nr); *state = skt->cs_state; return 0; }
/* au1x00_pcmcia_get_status() * * From the sa11xx_core.c: * Implements the get_status() operation for the in-kernel PCMCIA * service (formerly SS_GetStatus in Card Services). Essentially just * fills in bits in `status' according to internal driver state or * the value of the voltage detect chipselect register. * * As a debugging note, during card startup, the PCMCIA core issues * three set_socket() commands in a row the first with RESET deasserted, * the second with RESET asserted, and the last with RESET deasserted * again. Following the third set_socket(), a get_status() command will * be issued. The kernel is looking for the SS_READY flag (see * setup_socket(), reset_socket(), and unreset_socket() in cs.c). * * Returns: 0 */ static int au1x00_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status) { struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); skt->status = au1x00_pcmcia_skt_state(skt); *status = skt->status; return 0; }
/* * au1x00_pcmcia_suspend() * * Remove power on the socket, disable IRQs from the card. * Turn off status interrupts, and disable the PCMCIA bus. * * Returns: 0 */ static int au1x00_pcmcia_suspend(struct pcmcia_socket *sock) { struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); debug("suspending socket %u\n", skt->nr); skt->ops->socket_suspend(skt); return 0; }
int au1x00_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map) { struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); unsigned int speed; if(map->map>=MAX_IO_WIN){ debug("map (%d) out of range\n", map->map); return -1; } if(map->flags&MAP_ACTIVE){ speed=(map->speed>0)?map->speed:AU1000_PCMCIA_IO_SPEED; skt->spd_io[map->map] = speed; } map->start=(unsigned int)(u32)skt->virt_io; map->stop=map->start+MAP_SIZE; return 0; } /* au1x00_pcmcia_set_io_map() */