1 /* fm.c - simple v4l compatible tuner for radio cards
3 Copyright (C) 1998 Russell Kroll <rkroll@exploits.org>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <asm/types.h>
28 #include <sys/ioctl.h>
29 #include <linux/videodev.h>
33 printf ("usage: %s [-h] [-o] [-q] [-t <tuner>] <freq>|on|off [<volume>]\n", prog
);
35 printf ("-h - display this help\n");
36 printf ("-o - override frequency range limits in card\n");
37 printf ("-q - quiet mode\n");
38 printf ("-t <tuner> - select tuner <tuner>\n");
39 printf ("<tuner> - tuner number - first one is 0, next one 1, etc\n");
40 printf ("<freq> - frequency in MHz (i.e. 94.3)\n");
41 printf ("on - turn radio on\n");
42 printf ("off - turn radio off (mute)\n");
43 printf ("+ - increase volume\n");
44 printf ("- - decrease volume\n");
45 printf ("<volume> - intensity (0-65535)\n");
50 void getconfig(int *defaultvol
, int *increment
)
53 char buf
[256], fn
[256];
55 sprintf (fn
, "%s/.fmrc", getenv("HOME"));
56 conf
= fopen (fn
, "r");
61 while (fgets(buf
, sizeof(buf
), conf
)) {
62 buf
[strlen(buf
)-1] = 0;
63 if (strncmp (buf
, "VOL", 3) == 0)
64 sscanf (buf
, "%*s %i", defaultvol
);
65 if (strncmp (buf
, "INCR", 3) == 0)
66 sscanf (buf
, "%*s %i", increment
);
74 int main(int argc
, char **argv
)
76 int fd
, ret
, tunevol
, quiet
=0, i
, override
= 0;
77 int defaultvol
= 8192; /* default volume = 12.5% */
78 int increment
= 6554; /* default change = 10% */
81 struct video_audio va
;
82 struct video_tuner vt
;
85 extern int optind
, opterr
, optopt
;
88 if ((argc
< 2) || (argc
> 4)) {
89 printf ("usage: %s [-h] [-o] [-q] [-t <tuner>] <freq>|on|off [<volume>]\n", argv
[0]);
93 progname
= argv
[0]; /* used after getopt munges argv[] */
95 getconfig(&defaultvol
, &increment
);
97 while ((i
= getopt(argc
, argv
, "+qhot:")) != EOF
) {
106 tuner
= atoi(optarg
);
119 tunevol
= atoi (argv
[1]);
121 tunevol
= defaultvol
;
123 if (argc
== 0) /* no frequency, on|off, or +|- given */
126 /* moved here so -h works without a device */
127 fd
= open ("/dev/radio0", O_RDONLY
);
129 perror ("Unable to open /dev/radio0");
133 if (!strcmp("off", argv
[0])) { /* mute the radio */
136 va
.flags
= VIDEO_AUDIO_MUTE
;
137 ret
= ioctl (fd
, VIDIOCSAUDIO
, &va
);
139 printf ("Radio muted\n");
143 if (!strcmp("on", argv
[0])) { /* turn radio on */
147 ret
= ioctl (fd
, VIDIOCSAUDIO
, &va
);
149 printf ("Radio on at %2.2f%% volume\n",
154 ret
= ioctl (fd
, VIDIOCGAUDIO
, &va
);
156 if (argv
[0][0] == '+') { /* volume up */
157 if ((va
.volume
+ increment
) > 65535)
158 va
.volume
= 65535; /* catch overflows in __u16 */
160 va
.volume
+= increment
;
163 printf ("Setting volume to %2.2f%%\n",
164 (va
.volume
/ 655.35));
165 ret
= ioctl (fd
, VIDIOCSAUDIO
, &va
);
169 if (argv
[0][0] == '-') { /* volume down */
170 if ((va
.volume
- increment
) < 0)
171 va
.volume
= 0; /* catch negative numbers */
173 va
.volume
-= increment
;
176 printf ("Setting volume to %2.2f%%\n",
177 (va
.volume
/ 655.35));
178 ret
= ioctl (fd
, VIDIOCSAUDIO
, &va
);
182 /* at this point, we are trying to tune to a frequency */
185 ret
= ioctl(fd
, VIDIOCSTUNER
, &vt
); /* set tuner # */
187 perror ("set tuner");
191 ret
= ioctl(fd
, VIDIOCGTUNER
, &vt
); /* get frequency range */
193 if (ret
== -1 || (vt
.flags
& VIDEO_TUNER_LOW
) == 0)
197 freq
= ceil(atof(argv
[0]) * fact
); /* rounding up matters */
199 if ((freq
< vt
.rangelow
) || (freq
> vt
.rangehigh
)) {
201 printf ("Frequency %2.1f out of range (%2.1f - %2.1f MHz)\n",
202 (freq
/ fact
), (vt
.rangelow
/ fact
),
203 (vt
.rangehigh
/ fact
));
208 /* frequency sanity checked, proceed */
209 ret
= ioctl (fd
, VIDIOCSFREQ
, &freq
);
218 va
.mode
= VIDEO_SOUND_STEREO
;
220 ret
= ioctl (fd
, VIDIOCSAUDIO
, &va
); /* set the volume */
223 printf ("Radio tuned to %2.1f MHz at %2.2f%% volume\n",
224 (freq
/ fact
), (tunevol
/ 655.35));