This source file includes following definitions.
- rtattach
- rt_set_info
- rt_get_info
- rt_set_mute
- rt_set_freq
- rt_state
- rt_conv_vol
- rt_unconv_vol
- sfi_lm700x_init
- rt_lm700x_init
- rt_lm700x_rset
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/ioctl.h>
39 #include <sys/device.h>
40 #include <sys/radioio.h>
41
42 #include <machine/bus.h>
43
44 #include <dev/ic/lm700x.h>
45 #include <dev/isa/isavar.h>
46 #include <dev/isa/rtreg.h>
47 #include <dev/isa/rtvar.h>
48 #include <dev/radio_if.h>
49
50 void rtattach(struct rt_softc *);
51 int rt_get_info(void *, struct radio_info *);
52 int rt_set_info(void *, struct radio_info *);
53
54 struct radio_hw_if rt_hw_if = {
55 NULL,
56 NULL,
57 rt_get_info,
58 rt_set_info,
59 NULL
60 };
61
62 struct cfdriver rt_cd = {
63 NULL, "rt", DV_DULL
64 };
65
66 void rt_set_mute(struct rt_softc *, int);
67 void rt_set_freq(struct rt_softc *, u_int32_t);
68 u_int8_t rt_state(bus_space_tag_t, bus_space_handle_t);
69
70 void sfi_lm700x_init(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
71 void rt_lm700x_init(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
72 void rt_lm700x_rset(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
73
74 u_int8_t rt_conv_vol(u_int8_t);
75 u_int8_t rt_unconv_vol(u_int8_t);
76
77 void
78 rtattach(struct rt_softc *sc) {
79 sc->sc_freq = MIN_FM_FREQ;
80 sc->sc_mute = 0;
81 sc->sc_vol = 0;
82 sc->sc_rf = LM700X_REF_050;
83 sc->sc_stereo = LM700X_STEREO;
84
85 sc->lm.wzcl = RT_WREN_ON | RT_CLCK_OFF | RT_DATA_OFF;
86 sc->lm.wzch = RT_WREN_ON | RT_CLCK_ON | RT_DATA_OFF;
87 sc->lm.wocl = RT_WREN_ON | RT_CLCK_OFF | RT_DATA_ON;
88 sc->lm.woch = RT_WREN_ON | RT_CLCK_ON | RT_DATA_ON;
89
90 switch (sc->sc_ct) {
91 case CARD_RADIOTRACK:
92 sc->lm.initdata = 0;
93 sc->lm.rsetdata = RT_SIGNAL_METER;
94 sc->lm.init = rt_lm700x_init;
95 sc->lm.rset = rt_lm700x_rset;
96 break;
97 case CARD_SF16FMI:
98 sc->lm.initdata = RT_CARD_OFF;
99 sc->lm.rsetdata = RT_CARD_ON;
100 sc->lm.init = sfi_lm700x_init;
101 sc->lm.rset = sfi_lm700x_init;
102 break;
103 }
104
105 rt_set_freq(sc, sc->sc_freq);
106 rt_set_mute(sc, sc->sc_vol);
107
108 radio_attach_mi(&rt_hw_if, sc, &sc->sc_dev);
109 }
110
111 int
112 rt_set_info(void *v, struct radio_info *ri)
113 {
114 struct rt_softc *sc = v;
115
116 sc->sc_mute = ri->mute ? 1 : 0;
117 sc->sc_rf = lm700x_encode_ref(ri->rfreq);
118
119 switch (sc->sc_ct) {
120 case CARD_RADIOTRACK:
121 sc->sc_vol = rt_conv_vol(ri->volume);
122 break;
123 case CARD_SF16FMI:
124 sc->sc_vol = ri->volume ? 1 : 0;
125 break;
126 }
127
128
129
130
131 sc->sc_stereo = ri->stereo ? LM700X_STEREO : LM700X_MONO;
132
133 rt_set_freq(sc, ri->freq);
134 rt_set_mute(sc, sc->sc_vol);
135
136 return (0);
137 }
138
139 int
140 rt_get_info(void *v, struct radio_info *ri)
141 {
142 struct rt_softc *sc = v;
143
144 switch (sc->sc_ct) {
145 case CARD_RADIOTRACK:
146 ri->caps = RTRACK_CAPABILITIES;
147 ri->info = 3 & rt_state(sc->lm.iot, sc->lm.ioh);
148 ri->volume = rt_unconv_vol(sc->sc_vol);
149 break;
150 case CARD_SF16FMI:
151 ri->caps = SF16FMI_CAPABILITIES;
152 ri->volume = sc->sc_vol ? 255 : 0;
153 ri->info = 0;
154 break;
155 default:
156
157 return (1);
158 }
159
160 ri->mute = sc->sc_mute;
161 ri->stereo = sc->sc_stereo == LM700X_STEREO ? 0 : 1;
162 ri->rfreq = lm700x_decode_ref(sc->sc_rf);
163 ri->freq = sc->sc_freq;
164
165
166 ri->lock = 0;
167
168 return (0);
169 }
170
171
172
173
174 void
175 rt_set_mute(struct rt_softc *sc, int vol)
176 {
177 int val;
178
179 if (sc->sc_ct == CARD_UNKNOWN)
180 return;
181
182 if (sc->sc_ct == CARD_SF16FMI) {
183 val = vol ? RT_CARD_ON : RT_CARD_OFF;
184 bus_space_write_1(sc->lm.iot, sc->lm.ioh, 0,
185 sc->sc_mute ? RT_CARD_OFF : val);
186 return;
187 }
188
189
190 if (sc->sc_mute) {
191 bus_space_write_1(sc->lm.iot, sc->lm.ioh, 0,
192 RT_VOLUME_DOWN | RT_CARD_ON);
193 DELAY(MAX_VOL * RT_VOLUME_DELAY);
194 bus_space_write_1(sc->lm.iot, sc->lm.ioh, 0,
195 RT_VOLUME_STEADY | RT_CARD_ON);
196 bus_space_write_1(sc->lm.iot, sc->lm.ioh, 0, RT_CARD_OFF);
197 bus_space_write_1(sc->lm.iot, sc->lm.ioh, 0, RT_CARD_OFF);
198 } else {
199 val = sc->sc_vol - vol;
200 if (val < 0) {
201 val *= -1;
202 bus_space_write_1(sc->lm.iot, sc->lm.ioh, 0,
203 RT_VOLUME_DOWN | RT_CARD_ON);
204 } else {
205 bus_space_write_1(sc->lm.iot, sc->lm.ioh, 0,
206 RT_VOLUME_UP | RT_CARD_ON);
207 }
208 DELAY(val * RT_VOLUME_DELAY);
209 bus_space_write_1(sc->lm.iot, sc->lm.ioh, 0,
210 RT_VOLUME_STEADY | RT_CARD_ON);
211 }
212 }
213
214 void
215 rt_set_freq(struct rt_softc *sc, u_int32_t nfreq)
216 {
217 u_int32_t reg;
218
219 if (nfreq > MAX_FM_FREQ)
220 nfreq = MAX_FM_FREQ;
221 if (nfreq < MIN_FM_FREQ)
222 nfreq = MIN_FM_FREQ;
223
224 sc->sc_freq = nfreq;
225
226 reg = lm700x_encode_freq(nfreq, sc->sc_rf);
227 reg |= sc->sc_stereo | sc->sc_rf | LM700X_DIVIDER_FM;
228
229 lm700x_hardware_write(&sc->lm, reg, RT_VOLUME_STEADY);
230
231 rt_set_mute(sc, sc->sc_vol);
232 }
233
234
235
236
237 u_int8_t
238 rt_state(bus_space_tag_t iot, bus_space_handle_t ioh)
239 {
240 u_int8_t ret;
241
242 bus_space_write_1(iot, ioh, 0,
243 RT_VOLUME_STEADY | RT_SIGNAL_METER | RT_CARD_ON);
244 DELAY(RT_SIGNAL_METER_DELAY);
245 ret = bus_space_read_1(iot, ioh, 0);
246
247 switch (ret) {
248 case 0xFD:
249 ret = RADIO_INFO_SIGNAL | RADIO_INFO_STEREO;
250 break;
251 case 0xFF:
252 ret = 0;
253 break;
254 default:
255 ret = RADIO_INFO_SIGNAL;
256 break;
257 }
258
259 return ret;
260 }
261
262
263
264
265 u_int8_t
266 rt_conv_vol(u_int8_t vol)
267 {
268 if (vol < VOLUME_RATIO(1))
269 return 0;
270 else if (vol >= VOLUME_RATIO(1) && vol < VOLUME_RATIO(2))
271 return 1;
272 else if (vol >= VOLUME_RATIO(2) && vol < VOLUME_RATIO(3))
273 return 2;
274 else if (vol >= VOLUME_RATIO(3) && vol < VOLUME_RATIO(4))
275 return 3;
276 else
277 return 4;
278 }
279
280
281
282
283 u_int8_t
284 rt_unconv_vol(u_int8_t vol)
285 {
286 return VOLUME_RATIO(vol);
287 }
288
289 void
290 sfi_lm700x_init(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off,
291 u_int32_t data)
292 {
293 bus_space_write_1(iot, ioh, off, data);
294 }
295
296 void
297 rt_lm700x_init(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off,
298 u_int32_t data)
299 {
300
301 return;
302 }
303
304 void
305 rt_lm700x_rset(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off,
306 u_int32_t data)
307 {
308 DELAY(1000);
309 bus_space_write_1(iot, ioh, off, RT_CARD_OFF | data);
310 DELAY(50000);
311 bus_space_write_1(iot, ioh, off, RT_VOLUME_STEADY | RT_CARD_ON | data);
312 }