^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * PCMCIA socket code for the Alchemy Db1xxx/Pb1xxx boards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2009 Manuel Lauss <manuel.lauss@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) /* This is a fairly generic PCMCIA socket driver suitable for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * following Alchemy Development boards:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Db1000, Db/Pb1500, Db/Pb1100, Db/Pb1550, Db/Pb1200, Db1300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * The Db1000 is used as a reference: Per-socket card-, carddetect- and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * statuschange IRQs connected to SoC GPIOs, control and status register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * bits arranged in per-socket groups in an external PLD. All boards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * listed here use this layout, including bit positions and meanings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Of course there are exceptions in later boards:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * - Pb1100/Pb1500: single socket only; voltage key bits VS are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * at STATUS[5:4] (instead of STATUS[1:0]).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * - Au1200-based: additional card-eject irqs, irqs not gpios!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * - Db1300: Db1200-like, no pwr ctrl, single socket (#1).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/resource.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <pcmcia/ss.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <asm/mach-au1x00/au1000.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <asm/mach-db1x00/bcsr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define MEM_MAP_SIZE 0x400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define IO_MAP_SIZE 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct db1x_pcmcia_sock {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct pcmcia_socket socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) int nr; /* socket number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) void *virt_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) phys_addr_t phys_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) phys_addr_t phys_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) phys_addr_t phys_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* previous flags for set_socket() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unsigned int old_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* interrupt sources: linux irq numbers! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int insert_irq; /* default carddetect irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) int stschg_irq; /* card-status-change irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int card_irq; /* card irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) int eject_irq; /* db1200/pb1200 have these */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int insert_gpio; /* db1000 carddetect gpio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define BOARD_TYPE_DEFAULT 0 /* most boards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define BOARD_TYPE_DB1200 1 /* IRQs aren't gpios */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define BOARD_TYPE_PB1100 2 /* VS bits slightly different */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define BOARD_TYPE_DB1300 3 /* no power control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) int board_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define to_db1x_socket(x) container_of(x, struct db1x_pcmcia_sock, socket)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static int db1300_card_inserted(struct db1x_pcmcia_sock *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return bcsr_read(BCSR_SIGSTAT) & (1 << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* DB/PB1200: check CPLD SIGSTATUS register bit 10/12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static int db1200_card_inserted(struct db1x_pcmcia_sock *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) unsigned short sigstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) sigstat = bcsr_read(BCSR_SIGSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return sigstat & 1 << (8 + 2 * sock->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /* carddetect gpio: low-active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static int db1000_card_inserted(struct db1x_pcmcia_sock *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return !gpio_get_value(sock->insert_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static int db1x_card_inserted(struct db1x_pcmcia_sock *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) switch (sock->board_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) case BOARD_TYPE_DB1200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return db1200_card_inserted(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) case BOARD_TYPE_DB1300:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return db1300_card_inserted(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return db1000_card_inserted(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* STSCHG tends to bounce heavily when cards are inserted/ejected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * To avoid this, the interrupt is normally disabled and only enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * after reset to a card has been de-asserted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static inline void set_stschg(struct db1x_pcmcia_sock *sock, int en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (sock->stschg_irq != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) enable_irq(sock->stschg_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) disable_irq(sock->stschg_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static irqreturn_t db1000_pcmcia_cdirq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct db1x_pcmcia_sock *sock = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) pcmcia_parse_events(&sock->socket, SS_DETECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static irqreturn_t db1000_pcmcia_stschgirq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct db1x_pcmcia_sock *sock = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) pcmcia_parse_events(&sock->socket, SS_STSCHG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* Db/Pb1200 have separate per-socket insertion and ejection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * interrupts which stay asserted as long as the card is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * inserted/missing. The one which caused us to be called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * needs to be disabled and the other one enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static irqreturn_t db1200_pcmcia_cdirq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) disable_irq_nosync(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return IRQ_WAKE_THREAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static irqreturn_t db1200_pcmcia_cdirq_fn(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct db1x_pcmcia_sock *sock = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* Wait a bit for the signals to stop bouncing. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (irq == sock->insert_irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) enable_irq(sock->eject_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) enable_irq(sock->insert_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) pcmcia_parse_events(&sock->socket, SS_DETECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (sock->stschg_irq != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ret = request_irq(sock->stschg_irq, db1000_pcmcia_stschgirq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 0, "pcmcia_stschg", sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* Db/Pb1200 have separate per-socket insertion and ejection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * interrupts, which should show edge behaviour but don't.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * So interrupts are disabled until both insertion and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * ejection handler have been registered and the currently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * active one disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if ((sock->board_type == BOARD_TYPE_DB1200) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) (sock->board_type == BOARD_TYPE_DB1300)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) ret = request_threaded_irq(sock->insert_irq, db1200_pcmcia_cdirq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) db1200_pcmcia_cdirq_fn, 0, "pcmcia_insert", sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ret = request_threaded_irq(sock->eject_irq, db1200_pcmcia_cdirq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) db1200_pcmcia_cdirq_fn, 0, "pcmcia_eject", sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) free_irq(sock->insert_irq, sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* enable the currently silent one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (db1x_card_inserted(sock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) enable_irq(sock->eject_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) enable_irq(sock->insert_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /* all other (older) Db1x00 boards use a GPIO to show
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * card detection status: use both-edge triggers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) irq_set_irq_type(sock->insert_irq, IRQ_TYPE_EDGE_BOTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ret = request_irq(sock->insert_irq, db1000_pcmcia_cdirq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 0, "pcmcia_carddetect", sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return 0; /* all done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (sock->stschg_irq != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) free_irq(sock->stschg_irq, sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static void db1x_pcmcia_free_irqs(struct db1x_pcmcia_sock *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (sock->stschg_irq != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) free_irq(sock->stschg_irq, sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) free_irq(sock->insert_irq, sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (sock->eject_irq != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) free_irq(sock->eject_irq, sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * configure a PCMCIA socket on the Db1x00 series of boards (and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * compatibles).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * 2 external registers are involved:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * pcmcia_status (offset 0x04): bits [0:1/2:3]: read card voltage id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * pcmcia_control(offset 0x10):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * bits[0:1] set vcc for card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * bits[2:3] set vpp for card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * bit 4: enable data buffers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * bit 7: reset# for card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * add 8 for second socket.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static int db1x_pcmcia_configure(struct pcmcia_socket *skt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct socket_state_t *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct db1x_pcmcia_sock *sock = to_db1x_socket(skt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) unsigned short cr_clr, cr_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) unsigned int changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) int v, p, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* card voltage setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) cr_clr = (0xf << (sock->nr * 8)); /* clear voltage settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) cr_set = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) v = p = ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) switch (state->Vcc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) case 50:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ++v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) case 33:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) ++v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) printk(KERN_INFO "pcmcia%d unsupported Vcc %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) sock->nr, state->Vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) switch (state->Vpp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) case 12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) ++p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) case 33:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) case 50:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) ++p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) printk(KERN_INFO "pcmcia%d unsupported Vpp %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) sock->nr, state->Vpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /* sanity check: Vpp must be 0, 12, or Vcc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (((state->Vcc == 33) && (state->Vpp == 50)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) ((state->Vcc == 50) && (state->Vpp == 33))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) printk(KERN_INFO "pcmcia%d bad Vcc/Vpp combo (%d %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) sock->nr, state->Vcc, state->Vpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) v = p = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /* create new voltage code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (sock->board_type != BOARD_TYPE_DB1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) cr_set |= ((v << 2) | p) << (sock->nr * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) changed = state->flags ^ sock->old_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (changed & SS_RESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (state->flags & SS_RESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) set_stschg(sock, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* assert reset, disable io buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) cr_clr |= (1 << (7 + (sock->nr * 8)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) cr_clr |= (1 << (4 + (sock->nr * 8)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /* de-assert reset, enable io buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) cr_set |= 1 << (7 + (sock->nr * 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) cr_set |= 1 << (4 + (sock->nr * 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* update PCMCIA configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) bcsr_mod(BCSR_PCMCIA, cr_clr, cr_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) sock->old_flags = state->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* reset was taken away: give card time to initialize properly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if ((changed & SS_RESET) && !(state->flags & SS_RESET)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) msleep(500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) set_stschg(sock, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* VCC bits at [3:2]/[11:10] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) #define GET_VCC(cr, socknr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) ((((cr) >> 2) >> ((socknr) * 8)) & 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) /* VS bits at [0:1]/[3:2] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) #define GET_VS(sr, socknr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) (((sr) >> (2 * (socknr))) & 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /* reset bits at [7]/[15] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) #define GET_RESET(cr, socknr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ((cr) & (1 << (7 + (8 * (socknr)))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static int db1x_pcmcia_get_status(struct pcmcia_socket *skt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) unsigned int *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct db1x_pcmcia_sock *sock = to_db1x_socket(skt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) unsigned short cr, sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) status = db1x_card_inserted(sock) ? SS_DETECT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) cr = bcsr_read(BCSR_PCMCIA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) sr = bcsr_read(BCSR_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) /* PB1100/PB1500: voltage key bits are at [5:4] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (sock->board_type == BOARD_TYPE_PB1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) sr >>= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /* determine card type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) switch (GET_VS(sr, sock->nr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) status |= SS_3VCARD; /* 3V card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) break; /* 5V card: set nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) status |= SS_XVCARD; /* treated as unsupported in core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /* if Vcc is not zero, we have applied power to a card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) status |= GET_VCC(cr, sock->nr) ? SS_POWERON : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /* DB1300: power always on, but don't tell when no card present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if ((sock->board_type == BOARD_TYPE_DB1300) && (status & SS_DETECT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) status = SS_POWERON | SS_3VCARD | SS_DETECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* reset de-asserted? then we're ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) status |= (GET_RESET(cr, sock->nr)) ? SS_READY : SS_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) *value = status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) static int db1x_pcmcia_sock_init(struct pcmcia_socket *skt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static int db1x_pcmcia_sock_suspend(struct pcmcia_socket *skt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static int au1x00_pcmcia_set_io_map(struct pcmcia_socket *skt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) struct pccard_io_map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct db1x_pcmcia_sock *sock = to_db1x_socket(skt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) map->start = (u32)sock->virt_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) map->stop = map->start + IO_MAP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static int au1x00_pcmcia_set_mem_map(struct pcmcia_socket *skt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct pccard_mem_map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct db1x_pcmcia_sock *sock = to_db1x_socket(skt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (map->flags & MAP_ATTRIB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) map->static_start = sock->phys_attr + map->card_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) map->static_start = sock->phys_mem + map->card_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static struct pccard_operations db1x_pcmcia_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) .init = db1x_pcmcia_sock_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) .suspend = db1x_pcmcia_sock_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) .get_status = db1x_pcmcia_get_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) .set_socket = db1x_pcmcia_configure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) .set_io_map = au1x00_pcmcia_set_io_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) .set_mem_map = au1x00_pcmcia_set_mem_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static int db1x_pcmcia_socket_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct db1x_pcmcia_sock *sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct resource *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) int ret, bid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) sock = kzalloc(sizeof(struct db1x_pcmcia_sock), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (!sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) sock->nr = pdev->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) bid = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) switch (bid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) case BCSR_WHOAMI_PB1500:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) case BCSR_WHOAMI_PB1500R2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) case BCSR_WHOAMI_PB1100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) sock->board_type = BOARD_TYPE_PB1100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) case BCSR_WHOAMI_DB1000 ... BCSR_WHOAMI_PB1550_SDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) sock->board_type = BOARD_TYPE_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) case BCSR_WHOAMI_PB1200 ... BCSR_WHOAMI_DB1200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) sock->board_type = BOARD_TYPE_DB1200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) case BCSR_WHOAMI_DB1300:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) sock->board_type = BOARD_TYPE_DB1300;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) printk(KERN_INFO "db1xxx-ss: unknown board %d!\n", bid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * gather resources necessary and optional nice-to-haves to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * operate a socket:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * This includes IRQs for Carddetection/ejection, the card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * itself and optional status change detection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * Also, the memory areas covered by a socket. For these
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * we require the real 36bit addresses (see the au1000.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * header for more information).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) /* card: irq assigned to the card itself. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "card");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) sock->card_irq = r ? r->start : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /* insert: irq which triggers on card insertion/ejection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * BIG FAT NOTE: on DB1000/1100/1500/1550 we pass a GPIO here!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "insert");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) sock->insert_irq = r ? r->start : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (sock->board_type == BOARD_TYPE_DEFAULT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) sock->insert_gpio = r ? r->start : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) sock->insert_irq = r ? gpio_to_irq(r->start) : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /* stschg: irq which trigger on card status change (optional) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "stschg");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) sock->stschg_irq = r ? r->start : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /* eject: irq which triggers on ejection (DB1200/PB1200 only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "eject");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) sock->eject_irq = r ? r->start : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /* 36bit PCMCIA Attribute area address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcmcia-attr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (!r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) printk(KERN_ERR "pcmcia%d has no 'pseudo-attr' resource!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) sock->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) sock->phys_attr = r->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) /* 36bit PCMCIA Memory area address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcmcia-mem");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (!r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) printk(KERN_ERR "pcmcia%d has no 'pseudo-mem' resource!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) sock->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) sock->phys_mem = r->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /* 36bit PCMCIA IO area address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcmcia-io");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if (!r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) printk(KERN_ERR "pcmcia%d has no 'pseudo-io' resource!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) sock->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) sock->phys_io = r->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * PCMCIA client drivers use the inb/outb macros to access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * the IO registers. Since mips_io_port_base is added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) * to the access address of the mips implementation of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * inb/outb, we need to subtract it here because we want
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * to access the I/O or MEM address directly, without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) * going through this "mips_io_port_base" mechanism.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) sock->virt_io = (void *)(ioremap(sock->phys_io, IO_MAP_SIZE) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) mips_io_port_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (!sock->virt_io) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) printk(KERN_ERR "pcmcia%d: cannot remap IO area\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) sock->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) sock->socket.ops = &db1x_pcmcia_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) sock->socket.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) sock->socket.pci_irq = sock->card_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) sock->socket.features = SS_CAP_STATIC_MAP | SS_CAP_PCCARD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) sock->socket.map_size = MEM_MAP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) sock->socket.io_offset = (unsigned long)sock->virt_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) sock->socket.dev.parent = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) sock->socket.resource_ops = &pccard_static_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) platform_set_drvdata(pdev, sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) ret = db1x_pcmcia_setup_irqs(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) printk(KERN_ERR "pcmcia%d cannot setup interrupts\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) sock->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) set_stschg(sock, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) ret = pcmcia_register_socket(&sock->socket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) printk(KERN_ERR "pcmcia%d failed to register\n", sock->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) goto out2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) printk(KERN_INFO "Alchemy Db/Pb1xxx pcmcia%d @ io/attr/mem %09llx"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) "(%p) %09llx %09llx card/insert/stschg/eject irqs @ %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) "%d %d %d\n", sock->nr, sock->phys_io, sock->virt_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) sock->phys_attr, sock->phys_mem, sock->card_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) sock->insert_irq, sock->stschg_irq, sock->eject_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) out2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) db1x_pcmcia_free_irqs(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) iounmap((void *)(sock->virt_io + (u32)mips_io_port_base));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) out0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) kfree(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) static int db1x_pcmcia_socket_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct db1x_pcmcia_sock *sock = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) db1x_pcmcia_free_irqs(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) pcmcia_unregister_socket(&sock->socket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) iounmap((void *)(sock->virt_io + (u32)mips_io_port_base));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) kfree(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) static struct platform_driver db1x_pcmcia_socket_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) .name = "db1xxx_pcmcia",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) .probe = db1x_pcmcia_socket_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) .remove = db1x_pcmcia_socket_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) module_platform_driver(db1x_pcmcia_socket_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) MODULE_DESCRIPTION("PCMCIA Socket Services for Alchemy Db/Pb1x00 boards");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) MODULE_AUTHOR("Manuel Lauss");