1 /* $NetBSD: eppcic.c,v 1.3 2007/10/17 19:53:40 garbled Exp $ */
4 * Copyright (c) 2005 HAMAJIMA Katsuomi. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: eppcic.c,v 1.3 2007/10/17 19:53:40 garbled Exp $");
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/kernel.h>
34 #include <sys/malloc.h>
35 #include <sys/device.h>
36 #include <sys/kthread.h>
37 #include <uvm/uvm_param.h>
38 #include <machine/bus.h>
39 #include <dev/pcmcia/pcmciareg.h>
40 #include <dev/pcmcia/pcmciavar.h>
41 #include <dev/pcmcia/pcmciachip.h>
42 #include <arm/ep93xx/epsocvar.h>
43 #include <arm/ep93xx/epgpiovar.h>
44 #include <arm/ep93xx/eppcicvar.h>
45 #include <arm/ep93xx/ep93xxreg.h>
46 #include <arm/ep93xx/epsmcreg.h>
49 #include <arm/ep93xx/epledvar.h>
54 #error "epgpio requires in eppcic"
58 int eppcic_debug
= EPPCIC_DEBUG
;
59 #define DPRINTFN(n,x) if (eppcic_debug>(n)) printf x;
65 #define SOCKET0_MCCD1 1 /* pin36/pin26 (negative) Card Detect 1 */
66 #define SOCKET0_MCCD2 2 /* pin67/pin25 (negative) Card Detect 2 */
67 #define SOCKET0_VS1 5 /* pin33/pin43 (negative) Voltage Sense 1 */
68 #define SOCKET0_VS2 7 /* pin57/pin40 (negative) Voltage Sense 2 */
70 #define SOCKET0_WP 0 /* pin33/pin24 Write Protect */
71 #define SOCKET0_MCBVD1 3 /* pin63/pin46 Battery Voltage Detect 1 */
72 #define SOCKET0_MCBVD2 4 /* pin62/pin45 Battery Voltage Detect 2 */
73 #define SOCKET0_READY 6 /* pin16/pin37 Ready */
75 #define SOCKET0_STSCHG 3 /* pin63/pin46 (negative) Status Change */
76 #define SOCKET0_SPKR 4 /* pin62/pin45 (negative) Speaker */
77 #define SOCKET0_IREQ 6 /* pin16/pin37 Interrupt Request */
79 struct eppcic_handle
{
80 int ph_socket
; /* socket number */
81 struct eppcic_softc
*ph_sc
;
82 struct device
*ph_card
;
83 int (*ph_ih_func
)(void *);
85 lwp_t
*ph_event_thread
;
86 int ph_run
; /* ktread running */
87 int ph_width
; /* 8 or 16 */
88 int ph_vcc
; /* 3 or 5 */
89 int ph_status
[2]; /* cd1 and cd2 */
90 int ph_port
; /* GPIO port */
91 int ph_cd
[2]; /* card detect */
92 int ph_vs
[2]; /* voltage sense */
93 int ph_ireq
; /* interrupt request */
104 static int eppcic_intr_carddetect(void *);
105 static int eppcic_intr_socket(void *);
106 static int eppcic_print(void *, const char *);
107 static void eppcic_event_thread(void *);
108 void eppcic_shutdown(void *);
110 static int eppcic_mem_alloc(pcmcia_chipset_handle_t
, bus_size_t
,
111 struct pcmcia_mem_handle
*);
112 static void eppcic_mem_free(pcmcia_chipset_handle_t
,
113 struct pcmcia_mem_handle
*);
114 static int eppcic_mem_map(pcmcia_chipset_handle_t
, int, bus_addr_t
, bus_size_t
,
115 struct pcmcia_mem_handle
*, bus_size_t
*, int *);
116 static void eppcic_mem_unmap(pcmcia_chipset_handle_t
, int);
117 static int eppcic_io_alloc(pcmcia_chipset_handle_t
, bus_addr_t
, bus_size_t
,
118 bus_size_t
, struct pcmcia_io_handle
*);
119 static void eppcic_io_free(pcmcia_chipset_handle_t
, struct pcmcia_io_handle
*);
120 static int eppcic_io_map(pcmcia_chipset_handle_t
, int, bus_addr_t
, bus_size_t
,
121 struct pcmcia_io_handle
*, int *);
122 static void eppcic_io_unmap(pcmcia_chipset_handle_t
, int);
123 static void *eppcic_intr_establish(pcmcia_chipset_handle_t
,
124 struct pcmcia_function
*,
125 int, int (*)(void *), void *);
126 static void eppcic_intr_disestablish(pcmcia_chipset_handle_t
, void *);
127 static void eppcic_socket_enable(pcmcia_chipset_handle_t
);
128 static void eppcic_socket_disable(pcmcia_chipset_handle_t
);
129 static void eppcic_socket_settype(pcmcia_chipset_handle_t
, int);
131 static void eppcic_attach_socket(struct eppcic_handle
*);
132 static void eppcic_config_socket(struct eppcic_handle
*);
133 static int eppcic_get_voltage(struct eppcic_handle
*);
134 static void eppcic_set_pcreg(struct eppcic_handle
*, int);
136 static struct pcmcia_chip_functions eppcic_functions
= {
137 eppcic_mem_alloc
, eppcic_mem_free
,
138 eppcic_mem_map
, eppcic_mem_unmap
,
139 eppcic_io_alloc
, eppcic_io_free
,
140 eppcic_io_map
, eppcic_io_unmap
,
141 eppcic_intr_establish
, eppcic_intr_disestablish
,
142 eppcic_socket_enable
, eppcic_socket_disable
,
143 eppcic_socket_settype
147 eppcic_attach_common(struct device
*parent
, struct device
*self
, void *aux
,
148 eppcic_chipset_tag_t pcic
)
150 struct eppcic_softc
*sc
= (struct eppcic_softc
*)self
;
151 struct epsoc_attach_args
*sa
= aux
;
152 struct eppcic_handle
*ph
;
157 printf("%s: epgpio requires\n", self
->dv_xname
);
160 sc
->sc_gpio
= sa
->sa_gpio
;
161 sc
->sc_iot
= sa
->sa_iot
;
162 sc
->sc_hclk
= sa
->sa_hclk
;
165 if (bus_space_map(sa
->sa_iot
, sa
->sa_addr
,
166 sa
->sa_size
, 0, &sc
->sc_ioh
)){
167 printf("%s: Cannot map registers\n", self
->dv_xname
);
177 if (!(ph
= malloc(sizeof(struct eppcic_handle
), M_DEVBUF
, M_NOWAIT
))) {
178 printf("%s: Cannot allocate memory\n", self
->dv_xname
);
184 ph
->ph_port
= PORT_F
;
185 ph
->ph_cd
[0] = SOCKET0_MCCD1
;
186 ph
->ph_cd
[1] = SOCKET0_MCCD2
;
187 ph
->ph_vs
[0] = SOCKET0_VS1
;
188 ph
->ph_vs
[1] = SOCKET0_VS2
;
189 ph
->ph_ireq
= SOCKET0_IREQ
;
190 ph
->ph_space
[IO
].reg
= EP93XX_PCMCIA0_IO
;
191 ph
->ph_space
[IO
].base
= EP93XX_PCMCIA0_HWBASE
+ EP93XX_PCMCIA_IO
;
192 ph
->ph_space
[IO
].size
= EP93XX_PCMCIA_IO_SIZE
;
193 ph
->ph_space
[COMMON
].reg
= EP93XX_PCMCIA0_Common
;
194 ph
->ph_space
[COMMON
].base
= EP93XX_PCMCIA0_HWBASE
195 + EP93XX_PCMCIA_COMMON
;
196 ph
->ph_space
[COMMON
].size
= EP93XX_PCMCIA_COMMON_SIZE
;
197 ph
->ph_space
[ATTRIBUTE
].reg
= EP93XX_PCMCIA0_Attribute
;
198 ph
->ph_space
[ATTRIBUTE
].base
= EP93XX_PCMCIA0_HWBASE
199 + EP93XX_PCMCIA_ATTRIBUTE
;
200 ph
->ph_space
[ATTRIBUTE
].size
= EP93XX_PCMCIA_ATTRIBUTE_SIZE
;
201 eppcic_attach_socket(ph
);
203 reg
= EP93XX_PCMCIA_WEN
| (pcic
->socket_type
)(sc
, 0);
204 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, EP93XX_PCMCIA_Ctrl
,
205 EP93XX_PCMCIA_RST
| reg
);
207 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, EP93XX_PCMCIA_Ctrl
, reg
);
210 for (i
= 0; i
< EP93XX_PCMCIA_NSOCKET
; i
++)
211 eppcic_config_socket(sc
->sc_ph
[i
]);
218 eppcic_attach_socket(struct eppcic_handle
*ph
)
220 struct eppcic_softc
*sc
= ph
->ph_sc
;
224 ph
->ph_event_thread
= NULL
;
226 ph
->ph_ih_func
= NULL
;
227 ph
->ph_ih_arg
= NULL
;
228 epgpio_in(sc
->sc_gpio
, ph
->ph_port
, ph
->ph_cd
[0]);
229 epgpio_in(sc
->sc_gpio
, ph
->ph_port
, ph
->ph_cd
[1]);
230 epgpio_in(sc
->sc_gpio
, ph
->ph_port
, ph
->ph_vs
[0]);
231 epgpio_in(sc
->sc_gpio
, ph
->ph_port
, ph
->ph_vs
[1]);
232 ph
->ph_status
[0] = epgpio_read(sc
->sc_gpio
, ph
->ph_port
, ph
->ph_cd
[0]);
233 ph
->ph_status
[1] = epgpio_read(sc
->sc_gpio
, ph
->ph_port
, ph
->ph_cd
[1]);
237 eppcic_config_socket(struct eppcic_handle
*ph
)
239 struct eppcic_softc
*sc
= ph
->ph_sc
;
240 eppcic_chipset_tag_t pcic
= sc
->sc_pcic
;
241 struct pcmciabus_attach_args paa
;
244 paa
.paa_busname
= "pcmcia";
245 paa
.pct
= (pcmcia_chipset_tag_t
)&eppcic_functions
;
246 paa
.pch
= (pcmcia_chipset_handle_t
)ph
;
247 paa
.iobase
= ph
->ph_space
[IO
].base
;
248 paa
.iosize
= ph
->ph_space
[IO
].size
;
249 ph
->ph_card
= config_found_ia((void*)sc
, "pcmciabus", &paa
,
252 epgpio_intr_establish(sc
->sc_gpio
, ph
->ph_port
, ph
->ph_cd
[0],
253 EDGE_TRIGGER
| FALLING_EDGE
| DEBOUNCE
,
254 IPL_TTY
, eppcic_intr_carddetect
, ph
);
255 epgpio_intr_establish(sc
->sc_gpio
, ph
->ph_port
, ph
->ph_cd
[1],
256 EDGE_TRIGGER
| RISING_EDGE
| DEBOUNCE
,
257 IPL_TTY
, eppcic_intr_carddetect
, ph
);
258 wait
= (pcic
->power_ctl
)(sc
, ph
->ph_socket
, POWER_OFF
);
262 ph
->ph_status
[0] = epgpio_read(sc
->sc_gpio
, ph
->ph_port
, ph
->ph_cd
[0]);
263 ph
->ph_status
[1] = epgpio_read(sc
->sc_gpio
, ph
->ph_port
, ph
->ph_cd
[1]);
265 DPRINTFN(1, ("eppcic_config_socket: cd1=%d, cd2=%d\n",ph
->ph_status
[0],ph
->ph_status
[1]));
268 kthread_create(PRI_NONE
, 0, NULL
, eppcic_event_thread
, ph
,
269 &ph
->ph_event_thread
, "%s,%d", sc
->sc_dev
.dv_xname
,
274 eppcic_print(void *arg
, const char *pnp
)
280 eppcic_event_thread(void *arg
)
282 struct eppcic_handle
*ph
= arg
;
284 if (!(ph
->ph_status
[0] | ph
->ph_status
[1]))
285 pcmcia_card_attach(ph
->ph_card
);
288 tsleep(ph
, PWAIT
, "CSC wait", 0);
292 DPRINTFN(1, ("eppcic_event_thread: cd1=%d, cd2=%d\n",ph
->ph_status
[0],ph
->ph_status
[1]));
294 if (!ph
->ph_status
[0] && !ph
->ph_status
[1])
295 pcmcia_card_attach(ph
->ph_card
);
296 else if (ph
->ph_status
[0] && ph
->ph_status
[1])
297 pcmcia_card_detach(ph
->ph_card
, DETACH_FORCE
);
300 DPRINTFN(1, ("eppcic_event_thread: run=%d\n",ph
->ph_run
));
301 ph
->ph_event_thread
= NULL
;
306 eppcic_shutdown(void *arg
)
308 struct eppcic_handle
*ph
= arg
;
310 DPRINTFN(1, ("eppcic_shutdown\n"));
316 eppcic_intr_carddetect(void *arg
)
318 struct eppcic_handle
*ph
= arg
;
319 struct eppcic_softc
*sc
= ph
->ph_sc
;
322 nstatus
[0] = epgpio_read(sc
->sc_gpio
, ph
->ph_port
, ph
->ph_cd
[0]);
323 nstatus
[1] = epgpio_read(sc
->sc_gpio
, ph
->ph_port
, ph
->ph_cd
[1]);
325 DPRINTFN(1, ("eppcic_intr: cd1=%#x, cd2=%#x\n",nstatus
[0],nstatus
[1]));
327 if (nstatus
[0] != ph
->ph_status
[0] || nstatus
[1] != ph
->ph_status
[1]) {
328 ph
->ph_status
[0] = nstatus
[0];
329 ph
->ph_status
[1] = nstatus
[1];
336 eppcic_mem_alloc(pcmcia_chipset_handle_t pch
, bus_size_t size
,
337 struct pcmcia_mem_handle
*pmh
)
339 struct eppcic_handle
*ph
= (struct eppcic_handle
*)pch
;
340 struct eppcic_softc
*sc
= ph
->ph_sc
;
342 DPRINTFN(1, ("eppcic_mem_alloc: size=%#x\n",(unsigned)size
));
344 pmh
->memt
= sc
->sc_iot
;
349 eppcic_mem_free(pcmcia_chipset_handle_t pch
, struct pcmcia_mem_handle
*pmh
)
351 DPRINTFN(1, ("eppcic_mem_free\n"));
355 eppcic_mem_map(pcmcia_chipset_handle_t pch
, int kind
, bus_addr_t addr
,
356 bus_size_t size
, struct pcmcia_mem_handle
*pmh
,
357 bus_size_t
*offsetp
, int *windowp
)
359 struct eppcic_handle
*ph
= (struct eppcic_handle
*)pch
;
360 struct eppcic_softc
*sc
= ph
->ph_sc
;
364 DPRINTFN(1, ("eppcic_mem_map: kind=%d, addr=%#x, size=%#x\n",kind
,(unsigned)addr
,(unsigned)size
));
368 size
= round_page(size
);
369 pmh
->realsize
= size
;
370 if (kind
& PCMCIA_WIDTH_MEM8
)
374 switch (kind
& ~PCMCIA_WIDTH_MEM_MASK
) {
375 case PCMCIA_MEM_ATTR
:
376 eppcic_set_pcreg(ph
, ATTRIBUTE
);
377 pa
+= ph
->ph_space
[ATTRIBUTE
].base
;
379 case PCMCIA_MEM_COMMON
:
380 eppcic_set_pcreg(ph
, COMMON
);
381 pa
+= ph
->ph_space
[COMMON
].base
;
387 DPRINTFN(1, ("eppcic_mem_map: pa=%#x, *offsetp=%#x, size=%#x\n",(unsigned)pa
,(unsigned)addr
,(unsigned)size
));
389 if (!(err
= bus_space_map(sc
->sc_iot
, pa
, size
, 0, &pmh
->memh
)))
390 *windowp
= (int)pmh
->memh
;
395 eppcic_mem_unmap(pcmcia_chipset_handle_t pch
, int window
)
397 struct eppcic_handle
*ph
= (struct eppcic_handle
*)pch
;
398 struct eppcic_softc
*sc
= ph
->ph_sc
;
400 DPRINTFN(1, ("eppcic_mem_unmap: window=%#x\n",window
));
402 bus_space_unmap(sc
->sc_iot
, (bus_addr_t
)window
, 0x400);
406 eppcic_io_alloc(pcmcia_chipset_handle_t pch
, bus_addr_t start
, bus_size_t size
,
407 bus_size_t align
, struct pcmcia_io_handle
*pih
)
409 struct eppcic_handle
*ph
= (struct eppcic_handle
*)pch
;
410 struct eppcic_softc
*sc
= ph
->ph_sc
;
413 DPRINTFN(1, ("eppcic_io_alloc: start=%#x, size=%#x, align=%#x\n",(unsigned)start
,(unsigned)size
,(unsigned)align
));
415 pih
->iot
= sc
->sc_iot
;
418 pa
= pih
->addr
+ ph
->ph_space
[IO
].base
;
419 return bus_space_map(sc
->sc_iot
, pa
, size
, 0, &pih
->ioh
);
423 eppcic_io_free(pcmcia_chipset_handle_t pch
, struct pcmcia_io_handle
*pih
)
425 struct eppcic_handle
*ph
= (struct eppcic_handle
*)pch
;
426 struct eppcic_softc
*sc
= ph
->ph_sc
;
428 DPRINTFN(1, ("eppcic_io_free\n"));
430 bus_space_unmap(sc
->sc_iot
, pih
->ioh
, pih
->size
);
434 eppcic_io_map(pcmcia_chipset_handle_t pch
, int width
, bus_addr_t offset
,
435 bus_size_t size
, struct pcmcia_io_handle
*pih
, int *windowp
)
437 struct eppcic_handle
*ph
= (struct eppcic_handle
*)pch
;
439 DPRINTFN(1, ("eppcic_io_map: offset=%#x, size=%#x, width=%d",(unsigned)offset
,(unsigned)size
,width
));
442 case PCMCIA_WIDTH_IO8
:
443 DPRINTFN(1, ("(8bit)\n"));
446 case PCMCIA_WIDTH_IO16
:
447 case PCMCIA_WIDTH_AUTO
: /* I don't understand how I check it */
448 DPRINTFN(1, ("(16bit)\n"));
452 DPRINTFN(1, ("(unknown)\n"));
455 eppcic_set_pcreg(ph
, IO
);
456 *windowp
= 0; /* unused */
461 eppcic_io_unmap(pcmcia_chipset_handle_t pch
, int window
)
463 DPRINTFN(1, ("eppcic_io_unmap: window=%#x\n",window
));
467 eppcic_intr_establish(pcmcia_chipset_handle_t pch
, struct pcmcia_function
*pf
,
468 int ipl
, int (*ih_func
)(void *), void *ih_arg
)
470 struct eppcic_handle
*ph
= (struct eppcic_handle
*)pch
;
471 struct eppcic_softc
*sc
= ph
->ph_sc
;
473 DPRINTFN(1, ("eppcic_intr_establish\n"));
478 ph
->ph_ih_func
= ih_func
;
479 ph
->ph_ih_arg
= ih_arg
;
480 return epgpio_intr_establish(sc
->sc_gpio
, ph
->ph_port
, ph
->ph_ireq
,
481 LEVEL_SENSE
| LOW_LEVEL
,
482 ipl
, eppcic_intr_socket
, ph
);
486 eppcic_intr_disestablish(pcmcia_chipset_handle_t pch
, void *ih
)
488 struct eppcic_handle
*ph
= (struct eppcic_handle
*)pch
;
489 struct eppcic_softc
*sc
= ph
->ph_sc
;
491 DPRINTFN(1, ("eppcic_intr_disestablish\n"));
493 ph
->ph_ih_func
= NULL
;
494 ph
->ph_ih_arg
= NULL
;
495 epgpio_intr_disestablish(sc
->sc_gpio
, ph
->ph_port
, ph
->ph_ireq
);
499 eppcic_intr_socket(void *arg
)
501 struct eppcic_handle
*ph
= arg
;
504 if (ph
->ph_ih_func
) {
508 err
= (*ph
->ph_ih_func
)(ph
->ph_ih_arg
);
518 eppcic_socket_enable(pcmcia_chipset_handle_t pch
)
520 struct eppcic_handle
*ph
= (struct eppcic_handle
*)pch
;
521 struct eppcic_softc
*sc
= ph
->ph_sc
;
522 eppcic_chipset_tag_t pcic
= sc
->sc_pcic
;
525 DPRINTFN(1, ("eppcic_socket_enable\n"));
527 wait
= (pcic
->power_ctl
)(sc
, ph
->ph_socket
, POWER_ON
);
530 if (!sc
->sc_enable
++)
533 ph
->ph_vcc
= eppcic_get_voltage(ph
);
537 eppcic_socket_disable(pcmcia_chipset_handle_t pch
)
539 struct eppcic_handle
*ph
= (struct eppcic_handle
*)pch
;
540 struct eppcic_softc
*sc
= ph
->ph_sc
;
541 eppcic_chipset_tag_t pcic
= sc
->sc_pcic
;
544 DPRINTFN(1, ("eppcic_socket_disable\n"));
546 wait
= (pcic
->power_ctl
)(sc
, ph
->ph_socket
, POWER_OFF
);
549 if (!--sc
->sc_enable
)
555 eppcic_socket_settype(pcmcia_chipset_handle_t pch
, int type
)
557 DPRINTFN(1, ("eppcic_socket_settype: type=%d",type
));
560 case PCMCIA_IFTYPE_MEMORY
:
561 DPRINTFN(1, ("(Memory)\n"));
563 case PCMCIA_IFTYPE_IO
:
564 DPRINTFN(1, ("(I/O)\n"));
567 DPRINTFN(1, ("(unknown)\n"));
573 eppcic_get_voltage(struct eppcic_handle
*ph
)
575 struct eppcic_softc
*sc
= ph
->ph_sc
;
576 eppcic_chipset_tag_t pcic
= sc
->sc_pcic
;
579 cap
= (pcic
->power_capability
)(sc
, ph
->ph_socket
);
580 if (epgpio_read(sc
->sc_gpio
, ph
->ph_port
, ph
->ph_vs
[0])) {
584 printf("%s: unsupported Vcc 5 Volts",
585 sc
->sc_dev
.dv_xname
);
590 printf("%s: unsupported Vcc 3.3 Volts",
591 sc
->sc_dev
.dv_xname
);
593 DPRINTFN(1, ("eppcic_get_voltage: vs1=%d, vs2=%d (%dV)\n",epgpio_read_bit(sc
->sc_gpio
, ph
->ph_port
, ph
->ph_vs
[0]),epgpio_read_bit(sc
->sc_gpio
, ph
->ph_port
, ph
->ph_vs
[1]),vcc
));
597 #define EXTRA_DELAY 40
600 eppcic_set_pcreg(struct eppcic_handle
*ph
, int kind
)
602 struct eppcic_softc
*sc
= ph
->ph_sc
;
603 int atiming
, htiming
, ptiming
;
604 int period
= 1000000000 / sc
->sc_hclk
;
607 switch (ph
->ph_width
) {
612 width
= EP93XX_PCMCIA_WIDTH_16
;
619 atiming
= 165; htiming
= 20; ptiming
= 70;
622 #if linux_timing!=hamajima20050816
623 switch (ph
->ph_vcc
) {
625 atiming
= 465; htiming
= 35; ptiming
= 100;
628 atiming
= 200; htiming
= 20; ptiming
= 30;
636 switch (ph
->ph_vcc
) {
638 #if linux_timing!=hamajima20050816
639 atiming
= 465; htiming
= 35; ptiming
= 100;
641 atiming
= 600; htiming
= 35; ptiming
= 100;
645 #if linux_timing!=hamajima20050816
646 atiming
= 250; htiming
= 20; ptiming
= 30;
648 atiming
= 300; htiming
= 20; ptiming
= 30;
659 #if linux_timing!=hamajima20050816
660 period
= 1000000000 / 50000000;
661 width
= EP93XX_PCMCIA_WIDTH_16
;
664 atiming
= (atiming
+ EXTRA_DELAY
) / period
;
667 htiming
= ((htiming
+ EXTRA_DELAY
) / period
) + 1;
670 ptiming
= (ptiming
+ EXTRA_DELAY
) / period
;
674 DPRINTFN(1, ("eppcic_set_pcreg: width=%d, access=%d, hold=%d, pre-charge=%d\n",ph
->ph_width
,atiming
,htiming
,ptiming
));
676 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, ph
->ph_space
[kind
].reg
,
678 | (atiming
<<EP93XX_PCMCIA_ACCESS_SHIFT
)
679 | (htiming
<<EP93XX_PCMCIA_HOLD_SHIFT
)
680 | (ptiming
<<EP93XX_PCMCIA_PRECHARGE_SHIFT
));
681 tsleep(ph
->ph_space
, PWAIT
, "eppcic_set_pcreg", hz
/ 4);