Annotation of sys/dev/pci/gtp.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: gtp.c,v 1.3 2006/04/20 20:30:29 miod Exp $ */
2:
3: /*
4: * Copyright (c) 2002 Vladimir Popov <jumbo@narod.ru>
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19: * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26: */
27:
28: /* Gemtek PCI Radio Card Device Driver */
29:
30: #include <sys/param.h>
31: #include <sys/systm.h>
32: #include <sys/device.h>
33: #include <sys/errno.h>
34: #include <sys/ioctl.h>
35: #include <sys/proc.h>
36: #include <sys/radioio.h>
37:
38: #include <machine/bus.h>
39:
40: #include <dev/pci/pcireg.h>
41: #include <dev/pci/pcivar.h>
42: #include <dev/pci/pcidevs.h>
43:
44: #include <dev/ic/tea5757.h>
45: #include <dev/radio_if.h>
46:
47: int gtp_match(struct device *, void *, void *);
48: void gtp_attach(struct device *, struct device *, void *);
49:
50: int gtp_get_info(void *, struct radio_info *);
51: int gtp_set_info(void *, struct radio_info *);
52: int gtp_search(void *, int);
53:
54: #define GEMTEK_PCI_CAPS RADIO_CAPS_DETECT_SIGNAL | \
55: RADIO_CAPS_DETECT_STEREO | \
56: RADIO_CAPS_SET_MONO | \
57: RADIO_CAPS_HW_SEARCH | \
58: RADIO_CAPS_HW_AFC | \
59: RADIO_CAPS_LOCK_SENSITIVITY
60:
61: #define GEMTEK_PCI_MUTE 0x00
62: #define GEMTEK_PCI_RSET 0x10
63:
64: #define GEMTEK_PCI_SIGNAL 0x08
65: #define GEMTEK_PCI_STEREO 0x08
66:
67: #define GTP_WREN_ON (1 << 2)
68: #define GTP_WREN_OFF (0 << 2)
69:
70: #define GTP_DATA_ON (1 << 1)
71: #define GTP_DATA_OFF (0 << 1)
72:
73: #define GTP_CLCK_ON (1 << 0)
74: #define GTP_CLCK_OFF (0 << 0)
75:
76: #define GTP_READ_CLOCK_LOW (GTP_WREN_OFF | GTP_DATA_ON | GTP_CLCK_OFF)
77: #define GTP_READ_CLOCK_HIGH (GTP_WREN_OFF | GTP_DATA_ON | GTP_CLCK_ON)
78:
79: /* define our interface to the high-level radio driver */
80:
81: struct radio_hw_if gtp_hw_if = {
82: NULL, /* open */
83: NULL, /* close */
84: gtp_get_info,
85: gtp_set_info,
86: gtp_search
87: };
88:
89: struct gtp_softc {
90: struct device sc_dev;
91:
92: int mute;
93: u_int8_t vol;
94: u_int32_t freq;
95: u_int32_t stereo;
96: u_int32_t lock;
97:
98: struct tea5757_t tea;
99: };
100:
101: struct cfattach gtp_ca = {
102: sizeof(struct gtp_softc), gtp_match, gtp_attach
103: };
104:
105: struct cfdriver gtp_cd = {
106: NULL, "gtp", DV_DULL
107: };
108:
109: void gtp_set_mute(struct gtp_softc *);
110: void gtp_write_bit(bus_space_tag_t, bus_space_handle_t, bus_size_t, int);
111: void gtp_init(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
112: void gtp_rset(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
113: int gtp_state(bus_space_tag_t, bus_space_handle_t);
114: u_int32_t gtp_hardware_read(bus_space_tag_t, bus_space_handle_t,
115: bus_size_t);
116:
117: int
118: gtp_match(struct device *parent, void *match, void *aux)
119: {
120: struct pci_attach_args *pa = aux;
121: /* FIXME:
122: * Guillemot produces the card that
123: * was originally developed by Gemtek
124: */
125: if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_GEMTEK &&
126: PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_GEMTEK_PR103)
127: return (1);
128: return (0);
129: }
130:
131: void
132: gtp_attach(struct device *parent, struct device *self, void *aux)
133: {
134: struct gtp_softc *sc = (struct gtp_softc *) self;
135: struct pci_attach_args *pa = aux;
136: struct cfdata *cf = sc->sc_dev.dv_cfdata;
137:
138: if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0, &sc->tea.iot,
139: &sc->tea.ioh, NULL, NULL, 0)) {
140: printf(": can't map i/o space\n");
141: return;
142: }
143:
144: sc->vol = 0;
145: sc->mute = 0;
146: sc->freq = MIN_FM_FREQ;
147: sc->stereo = TEA5757_STEREO;
148: sc->lock = TEA5757_S030;
149: sc->tea.offset = 0;
150: sc->tea.flags = cf->cf_flags;
151: sc->tea.init = gtp_init;
152: sc->tea.rset = gtp_rset;
153: sc->tea.write_bit = gtp_write_bit;
154: sc->tea.read = gtp_hardware_read;
155:
156: printf(": Gemtek PR103\n");
157:
158: radio_attach_mi(>p_hw_if, sc, &sc->sc_dev);
159: }
160:
161: int
162: gtp_get_info(void *v, struct radio_info *ri)
163: {
164: struct gtp_softc *sc = v;
165:
166: ri->mute = sc->mute;
167: ri->volume = sc->vol ? 255 : 0;
168: ri->stereo = sc->stereo == TEA5757_STEREO ? 1 : 0;
169: ri->caps = GEMTEK_PCI_CAPS;
170: ri->rfreq = 0;
171: ri->lock = tea5757_decode_lock(sc->lock);
172:
173: /* Frequency read unsupported */
174: ri->freq = sc->freq;
175:
176: ri->info = gtp_state(sc->tea.iot, sc->tea.ioh);
177: gtp_set_mute(sc);
178:
179: return (0);
180: }
181:
182: int
183: gtp_set_info(void *v, struct radio_info *ri)
184: {
185: struct gtp_softc *sc = v;
186:
187: sc->mute = ri->mute ? 1 : 0;
188: sc->vol = ri->volume ? 255 : 0;
189: sc->stereo = ri->stereo ? TEA5757_STEREO: TEA5757_MONO;
190: sc->lock = tea5757_encode_lock(ri->lock);
191: ri->freq = sc->freq = tea5757_set_freq(&sc->tea,
192: sc->lock, sc->stereo, ri->freq);
193: gtp_set_mute(sc);
194:
195: return (0);
196: }
197:
198: int
199: gtp_search(void *v, int f)
200: {
201: struct gtp_softc *sc = v;
202:
203: tea5757_search(&sc->tea, sc->lock, sc->stereo, f);
204: gtp_set_mute(sc);
205:
206: return (0);
207: }
208:
209: void
210: gtp_set_mute(struct gtp_softc *sc)
211: {
212: if (sc->mute || !sc->vol)
213: bus_space_write_2(sc->tea.iot, sc->tea.ioh, 0, GEMTEK_PCI_MUTE);
214: else
215: sc->freq = tea5757_set_freq(&sc->tea,
216: sc->lock, sc->stereo, sc->freq);
217: }
218:
219: void
220: gtp_write_bit(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off,
221: int bit)
222: {
223: u_int8_t data;
224:
225: data = bit ? GTP_DATA_ON : GTP_DATA_OFF;
226: bus_space_write_1(iot, ioh, off, GTP_WREN_ON | GTP_CLCK_OFF | data);
227: bus_space_write_1(iot, ioh, off, GTP_WREN_ON | GTP_CLCK_ON | data);
228: bus_space_write_1(iot, ioh, off, GTP_WREN_ON | GTP_CLCK_OFF | data);
229: }
230:
231: void
232: gtp_init(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off, u_int32_t d)
233: {
234: bus_space_write_1(iot, ioh, off, GTP_WREN_ON | GTP_DATA_ON | GTP_CLCK_OFF);
235: }
236:
237: void
238: gtp_rset(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off, u_int32_t d)
239: {
240: bus_space_write_1(iot, ioh, off, GEMTEK_PCI_RSET);
241: }
242:
243: u_int32_t
244: gtp_hardware_read(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off)
245: {
246: /* UNSUPPORTED */
247: return 0;
248: }
249:
250: int
251: gtp_state(bus_space_tag_t iot, bus_space_handle_t ioh)
252: {
253: int ret;
254:
255: bus_space_write_2(iot, ioh, 0,
256: GTP_DATA_ON | GTP_WREN_OFF | GTP_CLCK_OFF);
257: ret = bus_space_read_2(iot, ioh, 0) &
258: GEMTEK_PCI_STEREO? 0 : RADIO_INFO_STEREO;
259: bus_space_write_2(iot, ioh, 0,
260: GTP_DATA_ON | GTP_WREN_OFF | GTP_CLCK_ON);
261: ret |= bus_space_read_2(iot, ioh, 0) &
262: GEMTEK_PCI_SIGNAL? 0 : RADIO_INFO_SIGNAL;
263:
264: return ret;
265: }
CVSweb