Annotation of sys/dev/pci/fmsradio.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: fmsradio.c,v 1.6 2002/06/06 16:29:37 mickey 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26: * SUCH DAMAGE.
27: */
28:
29: /* Device Driver for FM Tuners attached to FM801 */
30:
31: /* Currently supported tuners:
32: * o SoundForte RadioLink SF64-PCR PCI Radio Card
33: * o SoundForte Quad X-treme SF256-PCP-R PCI Sound Card with FM Radio
34: * o SoundForte Theatre X-treme 5.1 SF256-PCS-R PCI Sound Card with FM Radio
35: */
36:
37: #include <sys/param.h>
38: #include <sys/systm.h>
39: #include <sys/malloc.h>
40: #include <sys/device.h>
41: #include <sys/errno.h>
42: #include <sys/ioctl.h>
43: #include <sys/audioio.h>
44: #include <sys/radioio.h>
45:
46: #include <machine/bus.h>
47:
48: #include <dev/pci/pcireg.h>
49: #include <dev/pci/pcivar.h>
50: #include <dev/pci/pcidevs.h>
51:
52: #include <dev/audio_if.h>
53: #include <dev/radio_if.h>
54:
55: #include <dev/ic/ac97.h>
56:
57: #include <dev/pci/fmsreg.h>
58: #include <dev/pci/fmsvar.h>
59:
60: #include <dev/ic/tea5757.h>
61:
62: #define TUNER_UNKNOWN 0
63: #define TUNER_SF256PCPR 1
64: #define TUNER_SF64PCR 2
65: #define TUNER_SF256PCS 3
66:
67: #define SF64PCR_CAPS RADIO_CAPS_DETECT_STEREO | \
68: RADIO_CAPS_DETECT_SIGNAL | \
69: RADIO_CAPS_SET_MONO | \
70: RADIO_CAPS_HW_SEARCH | \
71: RADIO_CAPS_HW_AFC | \
72: RADIO_CAPS_LOCK_SENSITIVITY
73:
74: #define SF256PCPR_CAPS RADIO_CAPS_DETECT_STEREO | \
75: RADIO_CAPS_SET_MONO | \
76: RADIO_CAPS_HW_SEARCH | \
77: RADIO_CAPS_HW_AFC | \
78: RADIO_CAPS_LOCK_SENSITIVITY
79:
80: #define SF256PCS_CAPS RADIO_CAPS_SET_MONO | \
81: RADIO_CAPS_HW_SEARCH | \
82: RADIO_CAPS_HW_AFC | \
83: RADIO_CAPS_LOCK_SENSITIVITY
84:
85: #define PCR_WREN_ON 0
86: #define PCR_WREN_OFF FM_IO_PIN1
87: #define PCR_CLOCK_ON FM_IO_PIN0
88: #define PCR_CLOCK_OFF 0
89: #define PCR_DATA_ON FM_IO_PIN2
90: #define PCR_DATA_OFF 0
91:
92: #define PCR_SIGNAL 0x80
93: #define PCR_STEREO 0x80
94: #define PCR_INFO_SIGNAL (1 << 24)
95: #define PCR_INFO_STEREO (1 << 25)
96:
97: #define PCPR_WREN_ON 0
98: #define PCPR_WREN_OFF FM_IO_PIN2
99: #define PCPR_CLOCK_ON FM_IO_PIN0
100: #define PCPR_CLOCK_OFF 0
101: #define PCPR_DATA_ON FM_IO_PIN1
102: #define PCPR_DATA_OFF 0
103: #define PCPR_INFO_STEREO 0x04
104:
105: #define PCS_WREN_ON 0
106: #define PCS_WREN_OFF FM_IO_PIN2
107: #define PCS_CLOCK_ON FM_IO_PIN3
108: #define PCS_CLOCK_OFF 0
109: #define PCS_DATA_ON FM_IO_PIN1
110: #define PCS_DATA_OFF 0
111:
112: /*
113: * Function prototypes
114: */
115: void fmsradio_set_mute(struct fms_softc *);
116:
117: void sf64pcr_init(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
118: void sf64pcr_rset(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
119: void sf64pcr_write_bit(bus_space_tag_t, bus_space_handle_t, bus_size_t, int);
120: u_int32_t sf64pcr_hw_read(bus_space_tag_t, bus_space_handle_t, bus_size_t);
121: int sf64pcr_probe(struct fms_softc *);
122:
123: void sf256pcpr_init(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
124: void sf256pcpr_rset(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
125: void sf256pcpr_write_bit(bus_space_tag_t, bus_space_handle_t, bus_size_t, int);
126: u_int32_t sf256pcpr_hw_read(bus_space_tag_t, bus_space_handle_t, bus_size_t);
127: int sf256pcpr_probe(struct fms_softc *);
128:
129: void sf256pcs_init(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
130: void sf256pcs_rset(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
131: void sf256pcs_write_bit(bus_space_tag_t, bus_space_handle_t, bus_size_t, int);
132: u_int32_t sf256pcs_hw_read(bus_space_tag_t, bus_space_handle_t, bus_size_t);
133: int sf256pcs_probe(struct fms_softc *);
134:
135: int fmsradio_get_info(void *, struct radio_info *);
136: int fmsradio_set_info(void *, struct radio_info *);
137: int fmsradio_search(void *, int);
138:
139: struct radio_hw_if fmsradio_hw_if = {
140: NULL, /* open */
141: NULL, /* close */
142: fmsradio_get_info,
143: fmsradio_set_info,
144: fmsradio_search
145: };
146:
147: struct fmsradio_if {
148: int type; /* Card type */
149:
150: int mute;
151: u_int8_t vol;
152: u_int32_t freq;
153: u_int32_t stereo;
154: u_int32_t lock;
155:
156: struct tea5757_t tea;
157: };
158:
159: int
160: fmsradio_attach(struct fms_softc *sc)
161: {
162: struct fmsradio_if *r;
163:
164: r = malloc(sizeof(struct fmsradio_if), M_DEVBUF, M_NOWAIT);
165: if (r == NULL) {
166: printf("%s: cannot allocate memory for FM tuner config\n",
167: sc->sc_dev.dv_xname);
168: return TUNER_UNKNOWN;
169: }
170:
171: sc->radio = r;
172: r->tea.iot = sc->sc_iot;
173: r->tea.ioh = sc->sc_ioh;
174: r->tea.offset = FM_IO_CTL;
175: r->tea.flags = sc->sc_dev.dv_cfdata->cf_flags;
176: r->vol = 0;
177: r->mute = 0;
178: r->freq = MIN_FM_FREQ;
179: r->stereo = TEA5757_STEREO;
180: r->lock = TEA5757_S030;
181:
182: r->type = TUNER_UNKNOWN;
183: if ((r->type = sf64pcr_probe(sc)) == TUNER_SF64PCR)
184: printf("%s: SF64-PCR FM Radio\n", sc->sc_dev.dv_xname);
185: else if ((r->type = sf256pcpr_probe(sc)) == TUNER_SF256PCPR)
186: printf("%s: SF256-PCP-R FM Radio\n", sc->sc_dev.dv_xname);
187: else if ((r->type = sf256pcs_probe(sc)) == TUNER_SF256PCS)
188: printf("%s: SF256-PCS-R FM Radio\n", sc->sc_dev.dv_xname);
189: else
190: return TUNER_UNKNOWN;
191:
192: fmsradio_set_mute(sc);
193: radio_attach_mi(&fmsradio_hw_if, sc, &sc->sc_dev);
194: return r->type;
195: }
196:
197: /* SF256-PCS specific routines */
198: int
199: sf256pcs_probe(struct fms_softc *sc)
200: {
201: struct fmsradio_if *radio = (struct fmsradio_if *)sc->radio;
202: u_int32_t freq;
203:
204: radio->tea.init = sf256pcs_init;
205: radio->tea.rset = sf256pcs_rset;
206: radio->tea.write_bit = sf256pcs_write_bit;
207: radio->tea.read = sf256pcs_hw_read;
208:
209: tea5757_set_freq(&radio->tea, radio->stereo,
210: radio->lock, radio->freq);
211: freq = tea5757_decode_freq(sf256pcs_hw_read(radio->tea.iot,
212: radio->tea.ioh, radio->tea.offset),
213: radio->tea.flags & TEA5757_TEA5759);
214: if (freq != radio->freq)
215: return TUNER_UNKNOWN;
216:
217: return TUNER_SF256PCS;
218: }
219:
220: u_int32_t
221: sf256pcs_hw_read(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t offset)
222: {
223: u_int32_t res = 0ul;
224: u_int16_t i, d;
225:
226: d = FM_IO_GPIO(FM_IO_PIN1 | FM_IO_PIN2 | FM_IO_PIN3) | PCS_WREN_OFF;
227:
228: /* Now read data in */
229: d |= FM_IO_GPIO_IN(PCS_DATA_ON) | PCS_DATA_ON;
230:
231: bus_space_write_2(iot, ioh, offset, d | PCS_CLOCK_OFF);
232:
233: /* Read the register */
234: i = 24;
235: while (i--) {
236: res <<= 1;
237: bus_space_write_2(iot, ioh, offset, d | PCS_CLOCK_ON);
238: bus_space_write_2(iot, ioh, offset, d | PCS_CLOCK_OFF);
239: res |= bus_space_read_2(iot, ioh, offset) &
240: PCS_DATA_ON ? 1 : 0;
241: }
242:
243: return (res & (TEA5757_DATA | TEA5757_FREQ));
244: }
245:
246: void
247: sf256pcs_write_bit(bus_space_tag_t iot, bus_space_handle_t ioh,
248: bus_size_t off, int bit)
249: {
250: u_int16_t data, wren;
251:
252: wren = FM_IO_GPIO(FM_IO_PIN1 | FM_IO_PIN2 | FM_IO_PIN3);
253: wren |= PCS_WREN_ON;
254: data = bit ? PCPR_DATA_ON : PCS_DATA_OFF;
255:
256: bus_space_write_2(iot, ioh, off, PCS_CLOCK_OFF | wren | data);
257: bus_space_write_2(iot, ioh, off, PCS_CLOCK_ON | wren | data);
258: bus_space_write_2(iot, ioh, off, PCS_CLOCK_OFF | wren | data);
259: }
260:
261: void
262: sf256pcs_init(bus_space_tag_t iot, bus_space_handle_t ioh,
263: bus_size_t offset, u_int32_t d)
264: {
265: d = FM_IO_GPIO(FM_IO_PIN1 | FM_IO_PIN2 | FM_IO_PIN3);
266: d |= PCS_WREN_ON | PCS_DATA_OFF | PCS_CLOCK_OFF;
267:
268: bus_space_write_2(iot, ioh, offset, d);
269: bus_space_write_2(iot, ioh, offset, d);
270: }
271:
272: void
273: sf256pcs_rset(bus_space_tag_t iot, bus_space_handle_t ioh,
274: bus_size_t offset, u_int32_t d)
275: {
276: d = FM_IO_GPIO(FM_IO_PIN1 | FM_IO_PIN2 | FM_IO_PIN3);
277: d |= PCS_WREN_OFF | PCS_DATA_OFF | PCS_CLOCK_OFF;
278:
279: bus_space_write_2(iot, ioh, offset, d);
280: bus_space_write_2(iot, ioh, offset, d);
281: }
282:
283: /* SF256-PCP-R specific routines */
284: int
285: sf256pcpr_probe(struct fms_softc *sc)
286: {
287: struct fmsradio_if *radio = (struct fmsradio_if *)sc->radio;
288: u_int32_t freq;
289:
290: radio->tea.init = sf256pcpr_init;
291: radio->tea.rset = sf256pcpr_rset;
292: radio->tea.write_bit = sf256pcpr_write_bit;
293: radio->tea.read = sf256pcpr_hw_read;
294:
295: tea5757_set_freq(&radio->tea, radio->stereo,
296: radio->lock, radio->freq);
297: freq = tea5757_decode_freq(sf256pcpr_hw_read(radio->tea.iot,
298: radio->tea.ioh, radio->tea.offset),
299: radio->tea.flags & TEA5757_TEA5759);
300: if (freq != radio->freq)
301: return TUNER_UNKNOWN;
302:
303: return TUNER_SF256PCPR;
304: }
305:
306: u_int32_t
307: sf256pcpr_hw_read(bus_space_tag_t iot, bus_space_handle_t ioh,
308: bus_size_t offset)
309: {
310: u_int32_t res = 0ul;
311: u_int16_t i, d;
312:
313: d = FM_IO_GPIO_ALL | FM_IO_GPIO_IN(PCPR_DATA_ON | FM_IO_PIN3);
314:
315: /* Now read data in */
316: d |= PCPR_WREN_OFF | PCPR_DATA_ON;
317:
318: bus_space_write_2(iot, ioh, offset, d | PCPR_CLOCK_OFF);
319:
320: /* Read the register */
321: i = 24;
322: while (i--) {
323: res <<= 1;
324: bus_space_write_2(iot, ioh, offset, d | PCPR_CLOCK_ON);
325: bus_space_write_2(iot, ioh, offset, d | PCPR_CLOCK_OFF);
326: res |= bus_space_read_2(iot, ioh, offset) &
327: PCPR_DATA_ON ? 1 : 0;
328: }
329:
330: return (res & (TEA5757_DATA | TEA5757_FREQ));
331: }
332:
333: void
334: sf256pcpr_write_bit(bus_space_tag_t iot, bus_space_handle_t ioh,
335: bus_size_t off, int bit)
336: {
337: u_int16_t data, wren;
338:
339: wren = FM_IO_GPIO_ALL | FM_IO_GPIO_IN(FM_IO_PIN3) | PCPR_WREN_ON;
340: data = bit ? PCPR_DATA_ON : PCPR_DATA_OFF;
341:
342: bus_space_write_2(iot, ioh, off, PCPR_CLOCK_OFF | wren | data);
343: bus_space_write_2(iot, ioh, off, PCPR_CLOCK_ON | wren | data);
344: bus_space_write_2(iot, ioh, off, PCPR_CLOCK_OFF | wren | data);
345: }
346:
347: void
348: sf256pcpr_init(bus_space_tag_t iot, bus_space_handle_t ioh,
349: bus_size_t offset, u_int32_t d)
350: {
351: d = FM_IO_GPIO_ALL | FM_IO_GPIO_IN(FM_IO_PIN3);
352: d |= PCPR_WREN_ON | PCPR_DATA_OFF | PCPR_CLOCK_OFF;
353:
354: bus_space_write_2(iot, ioh, offset, d);
355: bus_space_write_2(iot, ioh, offset, d);
356: }
357:
358: void
359: sf256pcpr_rset(bus_space_tag_t iot, bus_space_handle_t ioh,
360: bus_size_t offset, u_int32_t d)
361: {
362: d = FM_IO_GPIO_ALL | FM_IO_GPIO_IN(FM_IO_PIN3);
363: d |= PCPR_WREN_OFF | PCPR_DATA_OFF | PCPR_CLOCK_OFF;
364:
365: bus_space_write_2(iot, ioh, offset, d);
366: bus_space_write_2(iot, ioh, offset, d);
367: }
368:
369: /* SF64-PCR specific routines */
370: int
371: sf64pcr_probe(struct fms_softc *sc)
372: {
373: struct fmsradio_if *radio = (struct fmsradio_if *)sc->radio;
374: u_int32_t freq;
375:
376: radio->tea.init = sf64pcr_init;
377: radio->tea.rset = sf64pcr_rset;
378: radio->tea.write_bit = sf64pcr_write_bit;
379: radio->tea.read = sf64pcr_hw_read;
380:
381: tea5757_set_freq(&radio->tea, radio->stereo,
382: radio->lock, radio->freq);
383: freq = tea5757_decode_freq(sf64pcr_hw_read(radio->tea.iot,
384: radio->tea.ioh, radio->tea.offset),
385: radio->tea.flags & TEA5757_TEA5759);
386: if (freq != radio->freq)
387: return TUNER_UNKNOWN;
388:
389: return TUNER_SF64PCR;
390: }
391:
392: u_int32_t
393: sf64pcr_hw_read(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t offset)
394: {
395: u_int32_t res = 0ul;
396: u_int16_t d, i, ind = 0;
397:
398: d = FM_IO_GPIO_ALL | FM_IO_GPIO_IN(PCR_DATA_ON | FM_IO_PIN3);
399:
400: /* Now read data in */
401: d |= PCR_WREN_OFF | PCR_DATA_ON;
402:
403: bus_space_write_2(iot, ioh, offset, d | PCR_CLOCK_OFF);
404: DELAY(4);
405:
406: /* Read the register */
407: i = 23;
408: while (i--) {
409: bus_space_write_2(iot, ioh, offset, d | PCR_CLOCK_ON);
410: DELAY(4);
411:
412: bus_space_write_2(iot, ioh, offset, d | PCR_CLOCK_OFF);
413: DELAY(4);
414:
415: res |= bus_space_read_2(iot, ioh, offset) & PCR_DATA_ON ? 1 : 0;
416: res <<= 1;
417: }
418:
419: bus_space_write_2(iot, ioh, offset, d | PCR_CLOCK_ON);
420: DELAY(4);
421:
422: i = bus_space_read_1(iot, ioh, offset);
423: ind = i & PCR_SIGNAL ? (1 << 1) : (0 << 1); /* Tuning */
424:
425: bus_space_write_2(iot, ioh, offset, d | PCR_CLOCK_OFF);
426:
427: i = bus_space_read_2(iot, ioh, offset);
428: ind |= i & PCR_STEREO ? (1 << 0) : (0 << 0); /* Mono */
429: res |= i & PCR_DATA_ON ? (1 << 0) : (0 << 0);
430:
431: return (res & (TEA5757_DATA | TEA5757_FREQ)) | (ind << 24);
432: }
433:
434: void
435: sf64pcr_write_bit(bus_space_tag_t iot, bus_space_handle_t ioh,
436: bus_size_t off, int bit)
437: {
438: u_int16_t data, wren;
439:
440: wren = FM_IO_GPIO_ALL | FM_IO_GPIO_IN(FM_IO_PIN3) | PCR_WREN_ON;
441: data = bit ? PCR_DATA_ON : PCR_DATA_OFF;
442:
443: bus_space_write_2(iot, ioh, off, PCR_CLOCK_OFF | wren | data);
444: DELAY(4);
445: bus_space_write_2(iot, ioh, off, PCR_CLOCK_ON | wren | data);
446: DELAY(4);
447: bus_space_write_2(iot, ioh, off, PCR_CLOCK_OFF | wren | data);
448: DELAY(4);
449: }
450:
451: void
452: sf64pcr_init(bus_space_tag_t iot, bus_space_handle_t ioh,
453: bus_size_t offset, u_int32_t d)
454: {
455: d = FM_IO_GPIO_ALL | FM_IO_GPIO_IN(FM_IO_PIN3);
456: d |= PCR_WREN_ON | PCR_DATA_ON | PCR_CLOCK_OFF;
457:
458: bus_space_write_2(iot, ioh, offset, d);
459: DELAY(4);
460: }
461:
462: void
463: sf64pcr_rset(bus_space_tag_t iot, bus_space_handle_t ioh,
464: bus_size_t offset, u_int32_t d)
465: {
466: /* Do nothing */
467: return;
468: }
469:
470:
471: /* Common tuner routines */
472: /*
473: * Mute/unmute
474: */
475: void
476: fmsradio_set_mute(struct fms_softc *sc)
477: {
478: struct fmsradio_if *radio = (struct fmsradio_if *)sc->radio;
479: u_int16_t v, mute, unmute;
480:
481: switch (radio->type) {
482: case TUNER_SF256PCS:
483: mute = FM_IO_GPIO(FM_IO_PIN1 | FM_IO_PIN2 | FM_IO_PIN3);
484: unmute = mute | PCS_WREN_OFF;
485: break;
486: case TUNER_SF256PCPR:
487: mute = FM_IO_GPIO_ALL | FM_IO_GPIO_IN(FM_IO_PIN3);
488: unmute = mute | PCPR_WREN_OFF;
489: break;
490: case TUNER_SF64PCR:
491: mute = FM_IO_GPIO_ALL | FM_IO_GPIO_IN(FM_IO_PIN3);
492: unmute = mute | PCR_WREN_OFF;
493: break;
494: default:
495: return;
496: }
497: v = (radio->mute || !radio->vol) ? mute : unmute;
498: bus_space_write_2(radio->tea.iot, radio->tea.ioh,
499: radio->tea.offset, v);
500: DELAY(64);
501: bus_space_write_2(radio->tea.iot, radio->tea.ioh,
502: radio->tea.offset, v);
503: }
504:
505: int
506: fmsradio_get_info(void *v, struct radio_info *ri)
507: {
508: struct fms_softc *sc = v;
509: struct fmsradio_if *radio = (struct fmsradio_if *)sc->radio;
510: u_int32_t buf;
511:
512: ri->mute = radio->mute;
513: ri->volume = radio->vol ? 255 : 0;
514: ri->stereo = radio->stereo == TEA5757_STEREO ? 1 : 0;
515: ri->lock = tea5757_decode_lock(radio->lock);
516:
517: switch (radio->type) {
518: case TUNER_SF256PCS:
519: ri->caps = SF256PCS_CAPS;
520: buf = sf256pcs_hw_read(radio->tea.iot, radio->tea.ioh,
521: radio->tea.offset);
522: ri->info = 0; /* UNSUPPORTED */
523: break;
524: case TUNER_SF256PCPR:
525: ri->caps = SF256PCPR_CAPS;
526: buf = sf256pcpr_hw_read(radio->tea.iot, radio->tea.ioh,
527: radio->tea.offset);
528: ri->info = bus_space_read_2(radio->tea.iot, radio->tea.ioh,
529: FM_VOLUME) == PCPR_INFO_STEREO ?
530: RADIO_INFO_STEREO : 0;
531: break;
532: case TUNER_SF64PCR:
533: ri->caps = SF64PCR_CAPS;
534: buf = sf64pcr_hw_read(radio->tea.iot, radio->tea.ioh,
535: radio->tea.offset);
536: ri->info = buf & PCR_INFO_SIGNAL ? 0 : RADIO_INFO_SIGNAL;
537: ri->info |= buf & PCR_INFO_STEREO ? 0 : RADIO_INFO_STEREO;
538: break;
539: default:
540: break;
541: }
542:
543: ri->freq = radio->freq = tea5757_decode_freq(buf,
544: sc->sc_dev.dv_cfdata->cf_flags & TEA5757_TEA5759);
545:
546: fmsradio_set_mute(sc);
547:
548: /* UNSUPPORTED */
549: ri->rfreq = 0;
550:
551: return (0);
552: }
553:
554: int
555: fmsradio_set_info(void *v, struct radio_info *ri)
556: {
557: struct fms_softc *sc = v;
558: struct fmsradio_if *radio = (struct fmsradio_if *)sc->radio;
559:
560: radio->mute = ri->mute ? 1 : 0;
561: radio->vol = ri->volume ? 255 : 0;
562: radio->stereo = ri->stereo ? TEA5757_STEREO: TEA5757_MONO;
563: radio->lock = tea5757_encode_lock(ri->lock);
564: ri->freq = radio->freq = tea5757_set_freq(&radio->tea,
565: radio->lock, radio->stereo, ri->freq);
566: fmsradio_set_mute(sc);
567:
568: return (0);
569: }
570:
571: int
572: fmsradio_search(void *v, int f)
573: {
574: struct fms_softc *sc = v;
575: struct fmsradio_if *radio = (struct fmsradio_if *)sc->radio;
576:
577: tea5757_search(&radio->tea, radio->lock,
578: radio->stereo, f);
579: fmsradio_set_mute(sc);
580:
581: return (0);
582: }
CVSweb