xref: /netbsd-src/sys/dev/isa/aztech.c (revision cbab9cadce21ae72fac13910001079fff214cc29)
1*cbab9cadSchs /* $NetBSD: aztech.c,v 1.17 2012/10/27 17:18:24 chs Exp $ */
21c06f6a4Saugustss /* $OpenBSD: aztech.c,v 1.2 2001/12/05 10:27:06 mickey Exp $ */
31c06f6a4Saugustss /* $RuOBSD: aztech.c,v 1.11 2001/10/20 13:23:47 pva Exp $ */
41c06f6a4Saugustss 
51c06f6a4Saugustss /*
61c06f6a4Saugustss  * Copyright (c) 2001 Maxim Tsyplakov <tm@oganer.net>,
71c06f6a4Saugustss  *                    Vladimir Popov <jumbo@narod.ru>
81c06f6a4Saugustss  * All rights reserved.
91c06f6a4Saugustss  *
101c06f6a4Saugustss  * Redistribution and use in source and binary forms, with or without
111c06f6a4Saugustss  * modification, are permitted provided that the following conditions
121c06f6a4Saugustss  * are met:
131c06f6a4Saugustss  * 1. Redistributions of source code must retain the above copyright
141c06f6a4Saugustss  *    notice, this list of conditions and the following disclaimer.
151c06f6a4Saugustss  * 2. Redistributions in binary form must reproduce the above copyright
161c06f6a4Saugustss  *    notice, this list of conditions and the following disclaimer in the
171c06f6a4Saugustss  *    documentation and/or other materials provided with the distribution.
181c06f6a4Saugustss  *
191c06f6a4Saugustss  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
201c06f6a4Saugustss  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
211c06f6a4Saugustss  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
221c06f6a4Saugustss  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
231c06f6a4Saugustss  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
241c06f6a4Saugustss  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
251c06f6a4Saugustss  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
261c06f6a4Saugustss  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
271c06f6a4Saugustss  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
281c06f6a4Saugustss  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
291c06f6a4Saugustss  */
301c06f6a4Saugustss 
311c06f6a4Saugustss /* Aztech/PackardBell FM Radio Card device driver */
321c06f6a4Saugustss 
331c06f6a4Saugustss /*
341c06f6a4Saugustss  * Sanyo LM7001J Direct PLL Frequency Synthesizer:
351c06f6a4Saugustss  *     ??? See http://www.redsword.com/tjacobs/geeb/fmcard.htm
361c06f6a4Saugustss  *
371c06f6a4Saugustss  * Philips TEA5712T AM/FM Stereo DTS Radio:
381c06f6a4Saugustss  *     http://www.semiconductors.philips.com/pip/TEA5712
391c06f6a4Saugustss  */
401c06f6a4Saugustss 
41365cbd94Slukem #include <sys/cdefs.h>
42*cbab9cadSchs __KERNEL_RCSID(0, "$NetBSD: aztech.c,v 1.17 2012/10/27 17:18:24 chs Exp $");
43365cbd94Slukem 
441c06f6a4Saugustss #include <sys/param.h>
451c06f6a4Saugustss #include <sys/systm.h>
461c06f6a4Saugustss #include <sys/proc.h>
471c06f6a4Saugustss #include <sys/errno.h>
481c06f6a4Saugustss #include <sys/ioctl.h>
491c06f6a4Saugustss #include <sys/device.h>
501c06f6a4Saugustss #include <sys/radioio.h>
511c06f6a4Saugustss 
52a2a38285Sad #include <sys/bus.h>
531c06f6a4Saugustss 
541c06f6a4Saugustss #include <dev/isa/isavar.h>
551c06f6a4Saugustss #include <dev/ic/lm700x.h>
561c06f6a4Saugustss #include <dev/radio_if.h>
571c06f6a4Saugustss 
581c06f6a4Saugustss #define RF_25K	25
591c06f6a4Saugustss #define RF_50K	50
601c06f6a4Saugustss #define RF_100K	100
611c06f6a4Saugustss 
621c06f6a4Saugustss #define MAX_VOL	3
631c06f6a4Saugustss #define VOLUME_RATIO(x)	(255 * x / MAX_VOL)
641c06f6a4Saugustss 
651c06f6a4Saugustss #define AZ_BASE_VALID(x)	((x == 0x350) || (x == 0x358))
661c06f6a4Saugustss #define AZTECH_CAPABILITIES	RADIO_CAPS_DETECT_STEREO | 		\
671c06f6a4Saugustss 				RADIO_CAPS_DETECT_SIGNAL | 		\
681c06f6a4Saugustss 				RADIO_CAPS_SET_MONO | 			\
691c06f6a4Saugustss 				RADIO_CAPS_REFERENCE_FREQ
701c06f6a4Saugustss 
711c06f6a4Saugustss #define	AZ_WREN_ON	(1 << 1)
721c06f6a4Saugustss #define	AZ_WREN_OFF	(0 << 1)
731c06f6a4Saugustss 
741c06f6a4Saugustss #define AZ_CLCK_ON	(1 << 6)
751c06f6a4Saugustss #define AZ_CLCK_OFF	(0 << 6)
761c06f6a4Saugustss 
771c06f6a4Saugustss #define AZ_DATA_ON	(1 << 7)
781c06f6a4Saugustss #define AZ_DATA_OFF	(0 << 7)
791c06f6a4Saugustss 
80ab57cc6fScegger int	az_probe(device_t, cfdata_t, void *);
81*cbab9cadSchs void	az_attach(device_t, device_t, void *);
821c06f6a4Saugustss 
831c06f6a4Saugustss int	az_get_info(void *, struct radio_info *);
841c06f6a4Saugustss int	az_set_info(void *, struct radio_info *);
851c06f6a4Saugustss 
8618f717bbSyamt const struct radio_hw_if az_hw_if = {
871c06f6a4Saugustss 	NULL,	/* open */
881c06f6a4Saugustss 	NULL,	/* close */
891c06f6a4Saugustss 	az_get_info,
901c06f6a4Saugustss 	az_set_info,
911c06f6a4Saugustss 	NULL
921c06f6a4Saugustss };
931c06f6a4Saugustss 
941c06f6a4Saugustss struct az_softc {
951c06f6a4Saugustss 	int		mute;
961c06f6a4Saugustss 	u_int8_t	vol;
971c06f6a4Saugustss 	u_int32_t	freq;
981c06f6a4Saugustss 	u_int32_t	rf;
991c06f6a4Saugustss 	u_int32_t	stereo;
1001c06f6a4Saugustss 
1011c06f6a4Saugustss 	struct lm700x_t	lm;
1021c06f6a4Saugustss };
1031c06f6a4Saugustss 
104*cbab9cadSchs CFATTACH_DECL_NEW(az, sizeof(struct az_softc),
1050dac35b5Sthorpej     az_probe, az_attach, NULL, NULL);
1061c06f6a4Saugustss 
1071c06f6a4Saugustss u_int	az_find(bus_space_tag_t, bus_space_handle_t);
1081c06f6a4Saugustss void	az_set_mute(struct az_softc *);
1091c06f6a4Saugustss void	az_set_freq(struct az_softc *, u_int32_t);
1101c06f6a4Saugustss u_int8_t	az_state(bus_space_tag_t, bus_space_handle_t);
1111c06f6a4Saugustss 
1121c06f6a4Saugustss void	az_lm700x_init(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
1131c06f6a4Saugustss void	az_lm700x_rset(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
1141c06f6a4Saugustss 
1151c06f6a4Saugustss u_int8_t	az_conv_vol(u_int8_t);
1161c06f6a4Saugustss u_int8_t	az_unconv_vol(u_int8_t);
1171c06f6a4Saugustss 
1181c06f6a4Saugustss int
az_probe(device_t parent,cfdata_t cf,void * aux)119ab57cc6fScegger az_probe(device_t parent, cfdata_t cf, void *aux)
1201c06f6a4Saugustss {
1211c06f6a4Saugustss 	struct isa_attach_args *ia = aux;
1221c06f6a4Saugustss 	bus_space_tag_t iot = ia->ia_iot;
1231c06f6a4Saugustss 	bus_space_handle_t ioh;
124c41bbdceSaugustss 	u_int r;
1253835413bSthorpej 	int iosize = 1, iobase;
1263835413bSthorpej 
1273835413bSthorpej 	if (ISA_DIRECT_CONFIG(ia))
1283835413bSthorpej 		return 0;
1293835413bSthorpej 
1303835413bSthorpej 	if (ia->ia_nio < 1)
1313835413bSthorpej 		return 0;
1323835413bSthorpej 
1333835413bSthorpej 	iobase = ia->ia_io[0].ir_addr;
1341c06f6a4Saugustss 
1351c06f6a4Saugustss 	if (!AZ_BASE_VALID(iobase)) {
1361c06f6a4Saugustss 		printf("az: configured iobase 0x%x invalid", iobase);
1371c06f6a4Saugustss 		return 0;
1381c06f6a4Saugustss 	}
1391c06f6a4Saugustss 
1401c06f6a4Saugustss 	if (bus_space_map(iot, iobase, iosize, 0, &ioh))
1411c06f6a4Saugustss 		return 0;
1421c06f6a4Saugustss 
143c41bbdceSaugustss 	r = az_find(iot, ioh);
144c41bbdceSaugustss 
1451c06f6a4Saugustss 	bus_space_unmap(iot, ioh, iosize);
1461c06f6a4Saugustss 
1473835413bSthorpej 	if (r != 0) {
1483835413bSthorpej 		ia->ia_nio = 1;
1493835413bSthorpej 		ia->ia_io[0].ir_size = iosize;
150c41bbdceSaugustss 
1513835413bSthorpej 		ia->ia_niomem = 0;
1523835413bSthorpej 		ia->ia_nirq = 0;
1533835413bSthorpej 		ia->ia_ndrq = 0;
1543835413bSthorpej 
1553835413bSthorpej 		return (1);
1563835413bSthorpej 	}
1573835413bSthorpej 
1583835413bSthorpej 	return (0);
1591c06f6a4Saugustss }
1601c06f6a4Saugustss 
1611c06f6a4Saugustss void
az_attach(device_t parent,device_t self,void * aux)162ab57cc6fScegger az_attach(device_t parent, device_t self, void *aux)
1631c06f6a4Saugustss {
164*cbab9cadSchs 	struct az_softc *sc = device_private(self);
1651c06f6a4Saugustss 	struct isa_attach_args *ia = aux;
1661c06f6a4Saugustss 
1671c06f6a4Saugustss 	sc->lm.iot = ia->ia_iot;
1681c06f6a4Saugustss 	sc->rf = LM700X_REF_050;
1691c06f6a4Saugustss 	sc->stereo = LM700X_STEREO;
1701c06f6a4Saugustss 	sc->mute = 0;
1711c06f6a4Saugustss 	sc->freq = MIN_FM_FREQ;
1721c06f6a4Saugustss 	sc->vol = 0;
1731c06f6a4Saugustss 
1741c06f6a4Saugustss 	/* remap I/O */
1753835413bSthorpej 	if (bus_space_map(sc->lm.iot, ia->ia_io[0].ir_addr,
1763835413bSthorpej 	    ia->ia_io[0].ir_size, 0, &sc->lm.ioh))
177*cbab9cadSchs 		panic(": bus_space_map() of %s failed", device_xname(self));
1781c06f6a4Saugustss 
179d083e37fSaugustss 	printf(": Aztech/PackardBell\n");
1801c06f6a4Saugustss 
1811c06f6a4Saugustss 	/* Configure struct lm700x_t lm */
1821c06f6a4Saugustss 	sc->lm.offset = 0;
1831c06f6a4Saugustss 	sc->lm.wzcl = AZ_WREN_ON | AZ_CLCK_OFF | AZ_DATA_OFF;
1841c06f6a4Saugustss 	sc->lm.wzch = AZ_WREN_ON | AZ_CLCK_ON  | AZ_DATA_OFF;
1851c06f6a4Saugustss 	sc->lm.wocl = AZ_WREN_ON | AZ_CLCK_OFF | AZ_DATA_ON;
1861c06f6a4Saugustss 	sc->lm.woch = AZ_WREN_ON | AZ_CLCK_ON  | AZ_DATA_ON;
1871c06f6a4Saugustss 	sc->lm.initdata = 0;
1881c06f6a4Saugustss 	sc->lm.rsetdata = AZ_DATA_ON | AZ_CLCK_ON | AZ_WREN_OFF;
1891c06f6a4Saugustss 	sc->lm.init = az_lm700x_init;
1901c06f6a4Saugustss 	sc->lm.rset = az_lm700x_rset;
1911c06f6a4Saugustss 
1921c06f6a4Saugustss 	az_set_freq(sc, sc->freq);
1931c06f6a4Saugustss 
194*cbab9cadSchs 	radio_attach_mi(&az_hw_if, sc, self);
1951c06f6a4Saugustss }
1961c06f6a4Saugustss 
1971c06f6a4Saugustss /*
1981c06f6a4Saugustss  * Mute the card
1991c06f6a4Saugustss  */
2001c06f6a4Saugustss void
az_set_mute(struct az_softc * sc)2011c06f6a4Saugustss az_set_mute(struct az_softc *sc)
2021c06f6a4Saugustss {
2031c06f6a4Saugustss 	bus_space_write_1(sc->lm.iot, sc->lm.ioh, 0,
2041c06f6a4Saugustss 	    sc->mute ? 0 : sc->vol);
2051c06f6a4Saugustss 	delay(6);
2061c06f6a4Saugustss 	bus_space_write_1(sc->lm.iot, sc->lm.ioh, 0,
2071c06f6a4Saugustss 	    sc->mute ? 0 : sc->vol);
2081c06f6a4Saugustss }
2091c06f6a4Saugustss 
2101c06f6a4Saugustss void
az_set_freq(struct az_softc * sc,u_int32_t nfreq)2111c06f6a4Saugustss az_set_freq(struct az_softc *sc, u_int32_t nfreq)
2121c06f6a4Saugustss {
2131c06f6a4Saugustss 	u_int8_t vol;
2141c06f6a4Saugustss 	u_int32_t reg;
2151c06f6a4Saugustss 
2161c06f6a4Saugustss 	vol = sc->mute ? 0 : sc->vol;
2171c06f6a4Saugustss 
2181c06f6a4Saugustss 	if (nfreq > MAX_FM_FREQ)
2191c06f6a4Saugustss 		nfreq = MAX_FM_FREQ;
2201c06f6a4Saugustss 	if (nfreq < MIN_FM_FREQ)
2211c06f6a4Saugustss 		nfreq = MIN_FM_FREQ;
2221c06f6a4Saugustss 
2231c06f6a4Saugustss 	sc->freq = nfreq;
2241c06f6a4Saugustss 
2251c06f6a4Saugustss 	reg = lm700x_encode_freq(nfreq, sc->rf);
2261c06f6a4Saugustss 	reg |= sc->stereo | sc->rf | LM700X_DIVIDER_FM;
2271c06f6a4Saugustss 
2281c06f6a4Saugustss 	lm700x_hardware_write(&sc->lm, reg, vol);
2291c06f6a4Saugustss 
2301c06f6a4Saugustss 	az_set_mute(sc);
2311c06f6a4Saugustss }
2321c06f6a4Saugustss 
2331c06f6a4Saugustss /*
2341c06f6a4Saugustss  * Return state of the card - tuned/not tuned, mono/stereo
2351c06f6a4Saugustss  */
2361c06f6a4Saugustss u_int8_t
az_state(bus_space_tag_t iot,bus_space_handle_t ioh)2371c06f6a4Saugustss az_state(bus_space_tag_t iot, bus_space_handle_t ioh)
2381c06f6a4Saugustss {
2391c06f6a4Saugustss 	return (3 ^ bus_space_read_1(iot, ioh, 0)) & 3;
2401c06f6a4Saugustss }
2411c06f6a4Saugustss 
2421c06f6a4Saugustss /*
2431c06f6a4Saugustss  * Convert volume to hardware representation.
2441c06f6a4Saugustss  * The card uses bits 00000x0x to set volume.
2451c06f6a4Saugustss  */
2461c06f6a4Saugustss u_int8_t
az_conv_vol(u_int8_t vol)2471c06f6a4Saugustss az_conv_vol(u_int8_t vol)
2481c06f6a4Saugustss {
2491c06f6a4Saugustss 	if (vol < VOLUME_RATIO(1))
2501c06f6a4Saugustss 		return 0;
2511c06f6a4Saugustss 	else if (vol >= VOLUME_RATIO(1) && vol < VOLUME_RATIO(2))
2521c06f6a4Saugustss 		return 1;
2531c06f6a4Saugustss 	else if (vol >= VOLUME_RATIO(2) && vol < VOLUME_RATIO(3))
2541c06f6a4Saugustss 		return 4;
2551c06f6a4Saugustss 	else
2561c06f6a4Saugustss 		return 5;
2571c06f6a4Saugustss }
2581c06f6a4Saugustss 
2591c06f6a4Saugustss /*
2601c06f6a4Saugustss  * Convert volume from hardware representation
2611c06f6a4Saugustss  */
2621c06f6a4Saugustss u_int8_t
az_unconv_vol(u_int8_t vol)2631c06f6a4Saugustss az_unconv_vol(u_int8_t vol)
2641c06f6a4Saugustss {
2651c06f6a4Saugustss 	switch (vol) {
2661c06f6a4Saugustss 	case 0:
2671c06f6a4Saugustss 		return VOLUME_RATIO(0);
2681c06f6a4Saugustss 	case 1:
2691c06f6a4Saugustss 		return VOLUME_RATIO(1);
2701c06f6a4Saugustss 	case 4:
2711c06f6a4Saugustss 		return VOLUME_RATIO(2);
2721c06f6a4Saugustss 	}
2731c06f6a4Saugustss 	return VOLUME_RATIO(3);
2741c06f6a4Saugustss }
2751c06f6a4Saugustss 
2761c06f6a4Saugustss u_int
az_find(bus_space_tag_t iot,bus_space_handle_t ioh)2771c06f6a4Saugustss az_find(bus_space_tag_t iot, bus_space_handle_t ioh)
2781c06f6a4Saugustss {
2791c06f6a4Saugustss 	struct az_softc sc;
2801c06f6a4Saugustss 	u_int i, scanres = 0;
2811c06f6a4Saugustss 
2821c06f6a4Saugustss 	sc.lm.iot = iot;
2831c06f6a4Saugustss 	sc.lm.ioh = ioh;
2841c06f6a4Saugustss 	sc.lm.offset = 0;
2851c06f6a4Saugustss 	sc.lm.wzcl = AZ_WREN_ON | AZ_CLCK_OFF | AZ_DATA_OFF;
2861c06f6a4Saugustss 	sc.lm.wzch = AZ_WREN_ON | AZ_CLCK_ON  | AZ_DATA_OFF;
2871c06f6a4Saugustss 	sc.lm.wocl = AZ_WREN_ON | AZ_CLCK_OFF | AZ_DATA_ON;
2881c06f6a4Saugustss 	sc.lm.woch = AZ_WREN_ON | AZ_CLCK_ON  | AZ_DATA_ON;
2891c06f6a4Saugustss 	sc.lm.initdata = 0;
2901c06f6a4Saugustss 	sc.lm.rsetdata = AZ_DATA_ON | AZ_CLCK_ON | AZ_WREN_OFF;
2911c06f6a4Saugustss 	sc.lm.init = az_lm700x_init;
2921c06f6a4Saugustss 	sc.lm.rset = az_lm700x_rset;
2931c06f6a4Saugustss 	sc.rf = LM700X_REF_050;
2941c06f6a4Saugustss 	sc.mute = 0;
2951c06f6a4Saugustss 	sc.stereo = LM700X_STEREO;
2961c06f6a4Saugustss 	sc.vol = 0;
2971c06f6a4Saugustss 
2981c06f6a4Saugustss 	/*
2991c06f6a4Saugustss 	 * Scan whole FM range. If there is a card it'll
3001c06f6a4Saugustss 	 * respond on some frequency.
3011c06f6a4Saugustss 	 */
3021c06f6a4Saugustss 	for (i = MIN_FM_FREQ; !scanres && i < MAX_FM_FREQ; i += 10) {
3031c06f6a4Saugustss 		az_set_freq(&sc, i);
3041c06f6a4Saugustss 		scanres += 3 - az_state(iot, ioh);
3051c06f6a4Saugustss 	}
3061c06f6a4Saugustss 
3071c06f6a4Saugustss 	return scanres;
3081c06f6a4Saugustss }
3091c06f6a4Saugustss 
3101c06f6a4Saugustss void
az_lm700x_init(bus_space_tag_t iot,bus_space_handle_t ioh,bus_size_t off,u_int32_t data)311168cd830Schristos az_lm700x_init(bus_space_tag_t iot, bus_space_handle_t ioh,
312168cd830Schristos     bus_size_t off, u_int32_t data)
3131c06f6a4Saugustss {
3141c06f6a4Saugustss 	/* Do nothing */
3151c06f6a4Saugustss 	return;
3161c06f6a4Saugustss }
3171c06f6a4Saugustss 
3181c06f6a4Saugustss void
az_lm700x_rset(bus_space_tag_t iot,bus_space_handle_t ioh,bus_size_t off,u_int32_t data)3191c06f6a4Saugustss az_lm700x_rset(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off,
3201c06f6a4Saugustss 		u_int32_t data)
3211c06f6a4Saugustss {
3221c06f6a4Saugustss 	bus_space_write_1(iot, ioh, off, data);
3231c06f6a4Saugustss }
3241c06f6a4Saugustss 
3251c06f6a4Saugustss int
az_get_info(void * v,struct radio_info * ri)3261c06f6a4Saugustss az_get_info(void *v, struct radio_info *ri)
3271c06f6a4Saugustss {
3281c06f6a4Saugustss 	struct az_softc *sc = v;
3291c06f6a4Saugustss 
3301c06f6a4Saugustss 	ri->mute = sc->mute;
3311c06f6a4Saugustss 	ri->volume = az_unconv_vol(sc->vol);
3321c06f6a4Saugustss 	ri->stereo = sc->stereo == LM700X_STEREO ? 1 : 0;
3331c06f6a4Saugustss 	ri->caps = AZTECH_CAPABILITIES;
3341c06f6a4Saugustss 	ri->rfreq = lm700x_decode_ref(sc->rf);
3351c06f6a4Saugustss 	ri->info = az_state(sc->lm.iot, sc->lm.ioh);
3361c06f6a4Saugustss 	ri->freq = sc->freq;
3371c06f6a4Saugustss 
3381c06f6a4Saugustss 	/* UNSUPPORTED */
3391c06f6a4Saugustss 	ri->lock = 0;
3401c06f6a4Saugustss 
3411c06f6a4Saugustss 	return (0);
3421c06f6a4Saugustss }
3431c06f6a4Saugustss 
3441c06f6a4Saugustss int
az_set_info(void * v,struct radio_info * ri)3451c06f6a4Saugustss az_set_info(void *v, struct radio_info *ri)
3461c06f6a4Saugustss {
3471c06f6a4Saugustss 	struct az_softc *sc = v;
3481c06f6a4Saugustss 
3491c06f6a4Saugustss 	sc->mute = ri->mute ? 1 : 0;
3501c06f6a4Saugustss 	sc->vol = az_conv_vol(ri->volume);
3511c06f6a4Saugustss 	sc->stereo = ri->stereo ? LM700X_STEREO : LM700X_MONO;
3521c06f6a4Saugustss 	sc->rf = lm700x_encode_ref(ri->rfreq);
3531c06f6a4Saugustss 
3541c06f6a4Saugustss 	az_set_freq(sc, ri->freq);
3551c06f6a4Saugustss 	az_set_mute(sc);
3561c06f6a4Saugustss 
3571c06f6a4Saugustss 	return (0);
3581c06f6a4Saugustss }
359