xref: /netbsd-src/sys/dev/pci/cy82c693.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /* $NetBSD: cy82c693.c,v 1.9 2014/03/20 06:48:54 skrll Exp $ */
2 
3 /*-
4  * Copyright (c) 2000 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
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.
18  *
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.
30  */
31 
32 /*
33  * Common routines to read/write control registers on the Cypress 82c693
34  * hyperCache(tm) Stand-Alone PCI Peripheral Controller with USB.
35  */
36 
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: cy82c693.c,v 1.9 2014/03/20 06:48:54 skrll Exp $");
39 
40 #include <sys/param.h>
41 #include <sys/device.h>
42 #include <sys/systm.h>
43 #include <sys/bus.h>
44 #include <sys/once.h>
45 
46 #include <dev/pci/pcireg.h>
47 #include <dev/pci/pcivar.h>
48 
49 #include <dev/pci/cy82c693reg.h>
50 #include <dev/pci/cy82c693var.h>
51 
52 ONCE_DECL(cyhc_once);
53 
54 static struct cy82c693_handle cyhc_handle;
55 static int cyhc_initialized;
56 
57 static kmutex_t cyhc_slock;
58 
59 static int
60 cy82c693_onceinit(void)
61 {
62 
63 	mutex_init(&cyhc_slock, MUTEX_DEFAULT, IPL_HIGH);
64 
65 	return 0;
66 }
67 
68 const struct cy82c693_handle *
69 cy82c693_init(bus_space_tag_t iot)
70 {
71 	bus_space_handle_t ioh;
72 	int err;
73 
74 	err = RUN_ONCE(&cyhc_once, cy82c693_onceinit);
75 	if (err)
76 		return NULL;
77 
78 	mutex_spin_enter(&cyhc_slock);
79 
80 	if (cyhc_initialized) {
81 		mutex_spin_exit(&cyhc_slock);;
82 		KASSERT(bus_space_is_equal(iot, cyhc_handle.cyhc_iot));
83 		return &cyhc_handle;
84 	}
85 
86 	if (bus_space_map(iot, CYHC_CONFIG_ADDR, 2, 0, &ioh) != 0) {
87 		mutex_spin_exit(&cyhc_slock);;
88 		return NULL;
89 	}
90 
91 	cyhc_handle.cyhc_iot = iot;
92 	cyhc_handle.cyhc_ioh = ioh;
93 
94 	cyhc_initialized = 1;
95 
96 	mutex_spin_exit(&cyhc_slock);;
97 
98 	return &cyhc_handle;
99 }
100 
101 u_int8_t
102 cy82c693_read(const struct cy82c693_handle *cyhc, int reg)
103 {
104 	uint8_t rv;
105 
106 	mutex_spin_enter(&cyhc_slock);
107 
108 	if (cyhc_initialized == 0) {
109 		mutex_spin_exit(&cyhc_slock);;
110 		panic("cy82c693_read");
111 	}
112 
113 	bus_space_write_1(cyhc->cyhc_iot, cyhc->cyhc_ioh, 0, reg);
114 	rv = bus_space_read_1(cyhc->cyhc_iot, cyhc->cyhc_ioh, 1);
115 
116 	mutex_spin_exit(&cyhc_slock);;
117 
118 	return rv;
119 }
120 
121 void
122 cy82c693_write(const struct cy82c693_handle *cyhc, int reg, u_int8_t val)
123 {
124 
125 	mutex_spin_enter(&cyhc_slock);
126 
127 	if (cyhc_initialized == 0) {
128 		mutex_spin_exit(&cyhc_slock);;
129 		panic("cy82c693_write");
130 	}
131 
132 	bus_space_write_1(cyhc->cyhc_iot, cyhc->cyhc_ioh, 0, reg);
133 	bus_space_write_1(cyhc->cyhc_iot, cyhc->cyhc_ioh, 1, val);
134 
135 	mutex_spin_exit(&cyhc_slock);;
136 }
137