1 /* $NetBSD: sa11x1_pcic.c,v 1.19 2008/06/03 13:45:22 rafal Exp $ */
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by IWAMOTO Toshihiro.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: sa11x1_pcic.c,v 1.19 2008/06/03 13:45:22 rafal Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/types.h>
40 #include <sys/device.h>
41 #include <sys/kernel.h>
42 #include <sys/kthread.h>
43 #include <sys/malloc.h>
45 #include <machine/bus.h>
47 #include <dev/pcmcia/pcmciachip.h>
48 #include <dev/pcmcia/pcmciavar.h>
49 #include <arm/sa11x0/sa11x0_reg.h>
50 #include <arm/sa11x0/sa11x0_var.h>
51 #include <arm/sa11x0/sa1111_reg.h>
52 #include <arm/sa11x0/sa1111_var.h>
53 #include <arm/sa11x0/sa11x1_pcicreg.h>
54 #include <arm/sa11x0/sa11xx_pcicvar.h>
55 #include <arm/sa11x0/sa11x1_pcicvar.h>
59 static int sacpcic_print(void *, const char *);
62 sacpcic_config_deferred(device_t dev
)
64 struct sacpcic_softc
*sc
= device_private(dev
);
65 struct sapcic_socket
*so
;
68 for (i
= 0; i
< 2; i
++) {
69 so
= &sc
->sc_socket
[i
];
70 sapcic_kthread_create(so
);
72 sacc_intr_establish((sacc_chipset_tag_t
)so
->pcictag_cookie
,
73 i
? IRQ_S1_CDVALID
: IRQ_S0_CDVALID
,
74 IST_EDGE_RAISE
, IPL_BIO
, sapcic_intr
, so
);
79 sacpcic_attach_common(struct sacc_softc
*psc
, struct sacpcic_softc
*sc
,
80 void *aux
, void (* socket_setup_hook
)(struct sapcic_socket
*))
83 struct pcmciabus_attach_args paa
;
87 sc
->sc_pc
.sc_iot
= psc
->sc_iot
;
88 sc
->sc_ioh
= psc
->sc_ioh
;
90 mutex_init(&sc
->sc_pc
.sc_lock
, MUTEX_DEFAULT
, IPL_NONE
);
92 for (i
= 0; i
< 2; i
++) {
93 sc
->sc_socket
[i
].sc
= (struct sapcic_softc
*)sc
;
94 sc
->sc_socket
[i
].socket
= i
;
95 sc
->sc_socket
[i
].pcictag_cookie
= psc
;
96 sc
->sc_socket
[i
].pcictag
= NULL
;
97 sc
->sc_socket
[i
].event_thread
= NULL
;
98 sc
->sc_socket
[i
].event
= 0;
99 sc
->sc_socket
[i
].laststatus
= SAPCIC_CARD_INVALID
;
100 sc
->sc_socket
[i
].shutdown
= 0;
102 socket_setup_hook(&sc
->sc_socket
[i
]);
104 paa
.paa_busname
= "pcmcia";
105 paa
.pct
= (pcmcia_chipset_tag_t
)&sa11x0_pcmcia_functions
;
106 paa
.pch
= (pcmcia_chipset_handle_t
)&sc
->sc_socket
[i
];
108 paa
.iosize
= 0x4000000;
110 sc
->sc_socket
[i
].pcmcia
=
111 config_found_ia(sc
->sc_pc
.sc_dev
, "pcmciabus", &paa
,
115 config_interrupts(sc
->sc_pc
.sc_dev
, sacpcic_config_deferred
);
119 sacpcic_print(void *aux
, const char *name
)
126 sacpcic_read(struct sapcic_socket
*so
, int reg
)
129 struct sacpcic_softc
*sc
= (struct sacpcic_softc
*)so
->sc
;
131 cr
= bus_space_read_4(sc
->sc_pc
.sc_iot
, sc
->sc_ioh
, SACPCIC_SR
);
134 case SAPCIC_STATUS_CARD
:
135 bit
= (so
->socket
? SR_S1_CARDDETECT
: SR_S0_CARDDETECT
) & cr
;
137 return SAPCIC_CARD_INVALID
;
139 return SAPCIC_CARD_VALID
;
141 case SAPCIC_STATUS_VS1
:
142 bit
= (so
->socket
? SR_S1_VS1
: SR_S0_VS1
);
145 case SAPCIC_STATUS_VS2
:
146 bit
= (so
->socket
? SR_S1_VS2
: SR_S0_VS2
);
149 case SAPCIC_STATUS_READY
:
150 bit
= (so
->socket
? SR_S1_READY
: SR_S0_READY
);
154 panic("sacpcic_read: bogus register");
159 sacpcic_write(struct sapcic_socket
*so
, int reg
, int arg
)
161 int s
, oldvalue
, newvalue
, mask
;
162 struct sacpcic_softc
*sc
= (struct sacpcic_softc
*)so
->sc
;
165 oldvalue
= bus_space_read_4(sc
->sc_pc
.sc_iot
, sc
->sc_ioh
, SACPCIC_CR
);
168 case SAPCIC_CONTROL_RESET
:
169 mask
= so
->socket
? CR_S1_RST
: CR_S0_RST
;
171 newvalue
= (oldvalue
& ~mask
) | (arg
? mask
: 0);
174 case SAPCIC_CONTROL_LINEENABLE
:
175 mask
= so
->socket
? CR_S1_FLT
: CR_S0_FLT
;
177 newvalue
= (oldvalue
& ~mask
) | (arg
? mask
: 0);
180 case SAPCIC_CONTROL_WAITENABLE
:
181 mask
= so
->socket
? CR_S1_PWAITEN
: CR_S0_PWAITEN
;
183 newvalue
= (oldvalue
& ~mask
) | (arg
? mask
: 0);
186 case SAPCIC_CONTROL_POWERSELECT
:
187 mask
= so
->socket
? CR_S1_PSE
: CR_S0_PSE
;
188 newvalue
= oldvalue
& ~mask
;
191 case SAPCIC_POWER_3V
:
193 case SAPCIC_POWER_5V
:
198 panic("sacpcic_write: bogus arg");
204 panic("sacpcic_write: bogus register");
206 bus_space_write_4(sc
->sc_pc
.sc_iot
, sc
->sc_ioh
, SACPCIC_CR
, newvalue
);
211 sacpcic_clear_intr(int arg
)
213 /* sacc_intr_dispatch takes care of intr status */
217 sacpcic_intr_establish(struct sapcic_socket
*so
, int level
,
218 int (*ih_fun
)(void *), void *ih_arg
)
222 irq
= so
->socket
? IRQ_S1_READY
: IRQ_S0_READY
;
223 return sacc_intr_establish((sacc_chipset_tag_t
)so
->pcictag_cookie
, irq
,
224 IST_EDGE_FALL
, level
, ih_fun
, ih_arg
);
228 sacpcic_intr_disestablish(struct sapcic_socket
*so
, void *ih
)
230 sacc_intr_disestablish((sacc_chipset_tag_t
)so
->pcictag_cookie
, ih
);