# Bazaar revision bundle v0.9
#
# message:
#   Fix some bugs in radio_init() so the "fd" variable gets cleared in case of 
#   an error.
#   
# committer: James Henstridge <james@jamesh.id.au>
# date: Fri 2007-04-13 10:15:56.552999973 +0800

=== modified file src/tech.c
--- src/tech.c
+++ src/tech.c
@@ -23,12 +23,13 @@
 #include <sys/ioctl.h>
 #include <assert.h>
 
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <sys/soundcard.h>
 
 #include "tech.h"
 
 static int freq_fact, fd = -1, mixer_fd = -1, mixer_src = -1;
+static int radio_rangelow, radio_rangehigh;
 static char *devices[] = SOUND_DEVICE_NAMES;
 
 /*
@@ -177,25 +178,50 @@
  
 int radio_init(char *device)
 {
-	struct video_tuner tuner;
+	struct v4l2_capability caps;
+	struct v4l2_tuner tuner;
 	
 	if ((fd = open(device, O_RDONLY))< 0)
-		return 0;
+		goto err;
 	
-	tuner.tuner = 0;
-	if (ioctl (fd, VIDIOCGTUNER, &tuner) < 0)
+	/* does this device provide a tuner? */
+	memset(&caps, 0, sizeof(caps));
+	if (ioctl(fd, VIDIOC_QUERYCAP, &caps) < 0) {
+		perror("VIDIOC_QUERYCAP");
+		goto err;
+	}
+	if ((caps.capabilities & V4L2_CAP_TUNER) == 0) {
+		fprintf(stderr, "Not a radio tuner\n");
+		goto err;
+	}
+
+	/* check the tuner */
+	memset(&tuner, 0, sizeof(tuner));
+	tuner.index = 0;
+	if (ioctl(fd, VIDIOC_G_TUNER, &tuner) < 0) {
+		perror("VIDIOC_G_TUNER");
+		goto err;
+	}
+	if (tuner.type != V4L2_TUNER_RADIO) {
+		fprintf(stderr, "Not a radio tuner\n");
+		goto err;
+	}
+	/* Does this tuner expect data in 62.5Hz or 62.5kHz multiples? */
+	radio_rangelow = tuner.rangelow;
+	radio_rangehigh = tuner.rangehigh;
+	if ((tuner.capability & V4L2_TUNER_CAP_LOW) != 0)
+		freq_fact = 16000;
+	else
 		freq_fact = 16;
-	else
-	{
-		if ((tuner.flags & VIDEO_TUNER_LOW) == 0)
-			freq_fact = 16;
-		else 
-			freq_fact = 16000;
-	}		
-	
 	radio_unmute();
 	
 	return 1;
+
+ err:
+	if (fd >= 0)
+		close(fd);
+	fd = -1;
+	return 0;
 }
 
 int radio_is_init(void)
@@ -209,24 +235,25 @@
 	
 	if (fd >= 0)
 		close(fd);
+	fd = -1;
 }
 
-int radio_setfreq(float freq)
+int radio_setfreq(float frequency)
 {
-    int ifreq = (freq+1.0/32)*freq_fact;
-    if (fd<0)
-    	return 0;
-    
-#if 0
-	printf("Setting to %i (= %.2f)\n", ifreq, freq);
-#endif
-	
-	if ((freq > 108) || (freq < 65))
+	struct v4l2_frequency freq;
+
+	if (fd<0)
+		return 0;
+
+	memset(&freq, 0, sizeof(freq));
+	freq.tuner = 0;
+	freq.type = V4L2_TUNER_RADIO;
+	freq.frequency = frequency * freq_fact;
+
+	if (freq.frequency < radio_rangelow ||
+	    freq.frequency > radio_rangehigh)
 		return 1;
-
-	assert ((freq <= 108) && (freq > 65));
-
-    return ioctl(fd, VIDIOCSFREQ, &ifreq);
+	return ioctl(fd, VIDIOC_S_FREQUENCY, &freq);
 }
 
 int radio_check_station(float freq)
@@ -253,63 +280,58 @@
 
 void radio_unmute(void)
 {
-    struct video_audio vid_aud;
-
-    if (fd<0)
-    	return;
-
-    if (ioctl(fd, VIDIOCGAUDIO, &vid_aud))
-		perror("VIDIOCGAUDIO");
-    /*if (vid_aud.volume == 0)*/
-	vid_aud.volume = 0xFFFF;
-    vid_aud.flags &= ~VIDEO_AUDIO_MUTE;
-	vid_aud.mode = VIDEO_SOUND_STEREO;
-	
-    if (ioctl(fd, VIDIOCSAUDIO, &vid_aud))
-		perror("VIDIOCSAUDIO");
+	struct v4l2_control control;
+
+	if (fd<0)
+		return;
+
+	memset(&control, 0, sizeof(control));
+	control.id = V4L2_CID_AUDIO_MUTE;
+	control.value = 0;
+	if (ioctl(fd, VIDIOC_S_CTRL, &control))
+		perror("VIDIOC_S_CTRL");
 }
 
 void radio_mute(void)
 {
-    struct video_audio vid_aud;
-
-    if (fd<0)
-    	return;
-
-    if (ioctl(fd, VIDIOCGAUDIO, &vid_aud))
-		perror("VIDIOCGAUDIO");
-    vid_aud.flags |= VIDEO_AUDIO_MUTE;
-    if (ioctl(fd, VIDIOCSAUDIO, &vid_aud))
-		perror("VIDIOCSAUDIO");
+	struct v4l2_control control;
+
+	if (fd<0)
+		return;
+
+	memset(&control, 0, sizeof(control));
+	control.id = V4L2_CID_AUDIO_MUTE;
+	control.value = 1;
+	if (ioctl(fd, VIDIOC_S_CTRL, &control))
+		perror("VIDIOC_S_CTRL");
 }
 
 int radio_getstereo()
 {
-    struct video_audio va;
-    va.mode=-1;
-
-    if (fd<0)
-    	return -1;
-    
-    if (ioctl (fd, VIDIOCGAUDIO, &va) < 0)
-		return -1;
-	if (va.mode == VIDEO_SOUND_STEREO)
-		return 1;
-	else 
-		return 0;
+	struct v4l2_tuner tuner;
+
+	if (fd<0)
+		return -1;
+
+	memset(&tuner, 0, sizeof(tuner));
+	tuner.index = 0;
+	if (ioctl(fd, VIDIOC_G_TUNER, &tuner) < 0)
+		return -1;
+
+	return tuner.audmode == V4L2_TUNER_MODE_STEREO;
 }
 
 int radio_getsignal()
 {
-    struct video_tuner vt;
-    int signal;
-
-    if (fd<0)
-    	return -1;
-
-    memset(&vt,0,sizeof(vt));
-    ioctl (fd, VIDIOCGTUNER, &vt);
-    signal=vt.signal>>13;
-
-    return signal;
+	struct v4l2_tuner tuner;
+
+	if (fd<0)
+		return -1;
+
+	memset(&tuner, 0, sizeof(tuner));
+	tuner.index = 0;
+	if (ioctl(fd, VIDIOC_G_TUNER, &tuner) < 0)
+		return -1;
+
+	return tuner.signal >> 13;
 }

=== modified directory  // last-changed:james@jamesh.id.au-20070413021556-huob4
... wi3alcids7h
# revision id: james@jamesh.id.au-20070413021556-huob4wi3alcids7h
# sha1: c1e2158015aa850a8864a0aafbb3c6ee04f61744
# inventory sha1: f96a7295003261a4a769b0300eaf55d7caa470c6
# parent ids:
#   james@jamesh.id.au-20070412135647-bz9dlesz0vifvy7m
# base id: svn-v2:172@ba97a3d1-ec25-0410-b1c6-e06ad936ea6c-trunk
# properties:
#   branch-nick: gnomeradio

# message:
#   Port radio tuner code over to V4L2 API.
#   
# committer: James Henstridge <james@jamesh.id.au>
# date: Thu 2007-04-12 21:56:47.592999935 +0800

=== modified file src/tech.c // encoding:base64
LS0tIHNyYy90ZWNoLmMKKysrIHNyYy90ZWNoLmMKQEAgLTIzLDEyICsyMywxMyBAQAogI2luY2x1
ZGUgPHN5cy9pb2N0bC5oPgogI2luY2x1ZGUgPGFzc2VydC5oPgogCi0jaW5jbHVkZSA8bGludXgv
dmlkZW9kZXYuaD4KKyNpbmNsdWRlIDxsaW51eC92aWRlb2RldjIuaD4KICNpbmNsdWRlIDxzeXMv
c291bmRjYXJkLmg+CiAKICNpbmNsdWRlICJ0ZWNoLmgiCiAKIHN0YXRpYyBpbnQgZnJlcV9mYWN0
LCBmZCA9IC0xLCBtaXhlcl9mZCA9IC0xLCBtaXhlcl9zcmMgPSAtMTsKK3N0YXRpYyBpbnQgcmFk
aW9fcmFuZ2Vsb3csIHJhZGlvX3JhbmdlaGlnaDsKIHN0YXRpYyBjaGFyICpkZXZpY2VzW10gPSBT
T1VORF9ERVZJQ0VfTkFNRVM7CiAKIC8qCkBAIC0xNzcsMjIgKzE3OCw0NSBAQAogIAogaW50IHJh
ZGlvX2luaXQoY2hhciAqZGV2aWNlKQogewotCXN0cnVjdCB2aWRlb190dW5lciB0dW5lcjsKKwlz
dHJ1Y3QgdjRsMl9jYXBhYmlsaXR5IGNhcHM7CisJc3RydWN0IHY0bDJfdHVuZXIgdHVuZXI7CiAJ
CiAJaWYgKChmZCA9IG9wZW4oZGV2aWNlLCBPX1JET05MWSkpPCAwKQogCQlyZXR1cm4gMDsKIAkK
LQl0dW5lci50dW5lciA9IDA7Ci0JaWYgKGlvY3RsIChmZCwgVklESU9DR1RVTkVSLCAmdHVuZXIp
IDwgMCkKKwkvKiBkb2VzIHRoaXMgZGV2aWNlIHByb3ZpZGUgYSB0dW5lcj8gKi8KKwltZW1zZXQo
JmNhcHMsIDAsIHNpemVvZihjYXBzKSk7CisJaWYgKGlvY3RsKGZkLCBWSURJT0NfUVVFUllDQVAs
ICZjYXBzKSA8IDApIHsKKwkJcGVycm9yKCJWSURJT0NfUVVFUllDQVAiKTsKKwkJY2xvc2UoZmQp
OworCQlyZXR1cm4gMDsKKwl9CisJaWYgKChjYXBzLmNhcGFiaWxpdGllcyAmIFY0TDJfQ0FQX1RV
TkVSKSA9PSAwKSB7CisJCWZwcmludGYoc3RkZXJyLCAiTm90IGEgdHVuZXIgZGV2aWNlXG4iKTsK
KwkJY2xvc2UoZmQpOworCQlyZXR1cm4gMDsKKwl9CisKKwkvKiBjaGVjayB0aGUgdHVuZXIgKi8K
KwltZW1zZXQoJnR1bmVyLCAwLCBzaXplb2YodHVuZXIpKTsKKwl0dW5lci5pbmRleCA9IDA7CisJ
aWYgKGlvY3RsKGZkLCBWSURJT0NfR19UVU5FUiwgJnR1bmVyKSA8IDApIHsKKwkJcGVycm9yKCJW
SURJT0NfR19UVU5FUiIpOworCQljbG9zZShmZCk7CisJCXJldHVybiAwOworCX0KKwlpZiAodHVu
ZXIudHlwZSAhPSBWNEwyX1RVTkVSX1JBRElPKSB7CisJCWZwcmludGYoc3RkZXJyLCAiTm90IGEg
cmFkaW8gdHVuZXJcbiIpOworCQljbG9zZShmZCk7CisJCXJldHVybiAwOworCX0KKwkvKiBEb2Vz
IHRoaXMgdHVuZXIgZXhwZWN0IGRhdGEgaW4gNjIuNUh6IG9yIDYyLjVrSHogbXVsdGlwbGVzPyAq
LworCXJhZGlvX3JhbmdlbG93ID0gdHVuZXIucmFuZ2Vsb3c7CisJcmFkaW9fcmFuZ2VoaWdoID0g
dHVuZXIucmFuZ2VoaWdoOworCWlmICgodHVuZXIuY2FwYWJpbGl0eSAmIFY0TDJfVFVORVJfQ0FQ
X0xPVykgIT0gMCkKKwkJZnJlcV9mYWN0ID0gMTYwMDA7CisJZWxzZQogCQlmcmVxX2ZhY3QgPSAx
NjsKLQllbHNlCi0JewotCQlpZiAoKHR1bmVyLmZsYWdzICYgVklERU9fVFVORVJfTE9XKSA9PSAw
KQotCQkJZnJlcV9mYWN0ID0gMTY7Ci0JCWVsc2UgCi0JCQlmcmVxX2ZhY3QgPSAxNjAwMDsKLQl9
CQkKLQkKIAlyYWRpb191bm11dGUoKTsKIAkKIAlyZXR1cm4gMTsKQEAgLTIxMSwyMiArMjM1LDIy
IEBACiAJCWNsb3NlKGZkKTsKIH0KIAotaW50IHJhZGlvX3NldGZyZXEoZmxvYXQgZnJlcSkKK2lu
dCByYWRpb19zZXRmcmVxKGZsb2F0IGZyZXF1ZW5jeSkKIHsKLSAgICBpbnQgaWZyZXEgPSAoZnJl
cSsxLjAvMzIpKmZyZXFfZmFjdDsKLSAgICBpZiAoZmQ8MCkKLSAgICAJcmV0dXJuIDA7Ci0gICAg
Ci0jaWYgMAotCXByaW50ZigiU2V0dGluZyB0byAlaSAoPSAlLjJmKVxuIiwgaWZyZXEsIGZyZXEp
OwotI2VuZGlmCi0JCi0JaWYgKChmcmVxID4gMTA4KSB8fCAoZnJlcSA8IDY1KSkKKwlzdHJ1Y3Qg
djRsMl9mcmVxdWVuY3kgZnJlcTsKKworCWlmIChmZDwwKQorCQlyZXR1cm4gMDsKKworCW1lbXNl
dCgmZnJlcSwgMCwgc2l6ZW9mKGZyZXEpKTsKKwlmcmVxLnR1bmVyID0gMDsKKwlmcmVxLnR5cGUg
PSBWNEwyX1RVTkVSX1JBRElPOworCWZyZXEuZnJlcXVlbmN5ID0gZnJlcXVlbmN5ICogZnJlcV9m
YWN0OworCisJaWYgKGZyZXEuZnJlcXVlbmN5IDwgcmFkaW9fcmFuZ2Vsb3cgfHwKKwkgICAgZnJl
cS5mcmVxdWVuY3kgPiByYWRpb19yYW5nZWhpZ2gpCiAJCXJldHVybiAxOwotCi0JYXNzZXJ0ICgo
ZnJlcSA8PSAxMDgpICYmIChmcmVxID4gNjUpKTsKLQotICAgIHJldHVybiBpb2N0bChmZCwgVklE
SU9DU0ZSRVEsICZpZnJlcSk7CisJcmV0dXJuIGlvY3RsKGZkLCBWSURJT0NfU19GUkVRVUVOQ1ks
ICZmcmVxKTsKIH0KIAogaW50IHJhZGlvX2NoZWNrX3N0YXRpb24oZmxvYXQgZnJlcSkKQEAgLTI1
Myw2MyArMjc3LDU4IEBACiAKIHZvaWQgcmFkaW9fdW5tdXRlKHZvaWQpCiB7Ci0gICAgc3RydWN0
IHZpZGVvX2F1ZGlvIHZpZF9hdWQ7Ci0KLSAgICBpZiAoZmQ8MCkKLSAgICAJcmV0dXJuOwotCi0g
ICAgaWYgKGlvY3RsKGZkLCBWSURJT0NHQVVESU8sICZ2aWRfYXVkKSkKLQkJcGVycm9yKCJWSURJ
T0NHQVVESU8iKTsKLSAgICAvKmlmICh2aWRfYXVkLnZvbHVtZSA9PSAwKSovCi0JdmlkX2F1ZC52
b2x1bWUgPSAweEZGRkY7Ci0gICAgdmlkX2F1ZC5mbGFncyAmPSB+VklERU9fQVVESU9fTVVURTsK
LQl2aWRfYXVkLm1vZGUgPSBWSURFT19TT1VORF9TVEVSRU87Ci0JCi0gICAgaWYgKGlvY3RsKGZk
LCBWSURJT0NTQVVESU8sICZ2aWRfYXVkKSkKLQkJcGVycm9yKCJWSURJT0NTQVVESU8iKTsKKwlz
dHJ1Y3QgdjRsMl9jb250cm9sIGNvbnRyb2w7CisKKwlpZiAoZmQ8MCkKKwkJcmV0dXJuOworCisJ
bWVtc2V0KCZjb250cm9sLCAwLCBzaXplb2YoY29udHJvbCkpOworCWNvbnRyb2wuaWQgPSBWNEwy
X0NJRF9BVURJT19NVVRFOworCWNvbnRyb2wudmFsdWUgPSAwOworCWlmIChpb2N0bChmZCwgVklE
SU9DX1NfQ1RSTCwgJmNvbnRyb2wpKQorCQlwZXJyb3IoIlZJRElPQ19TX0NUUkwiKTsKIH0KIAog
dm9pZCByYWRpb19tdXRlKHZvaWQpCiB7Ci0gICAgc3RydWN0IHZpZGVvX2F1ZGlvIHZpZF9hdWQ7
Ci0KLSAgICBpZiAoZmQ8MCkKLSAgICAJcmV0dXJuOwotCi0gICAgaWYgKGlvY3RsKGZkLCBWSURJ
T0NHQVVESU8sICZ2aWRfYXVkKSkKLQkJcGVycm9yKCJWSURJT0NHQVVESU8iKTsKLSAgICB2aWRf
YXVkLmZsYWdzIHw9IFZJREVPX0FVRElPX01VVEU7Ci0gICAgaWYgKGlvY3RsKGZkLCBWSURJT0NT
QVVESU8sICZ2aWRfYXVkKSkKLQkJcGVycm9yKCJWSURJT0NTQVVESU8iKTsKKwlzdHJ1Y3QgdjRs
Ml9jb250cm9sIGNvbnRyb2w7CisKKwlpZiAoZmQ8MCkKKwkJcmV0dXJuOworCisJbWVtc2V0KCZj
b250cm9sLCAwLCBzaXplb2YoY29udHJvbCkpOworCWNvbnRyb2wuaWQgPSBWNEwyX0NJRF9BVURJ
T19NVVRFOworCWNvbnRyb2wudmFsdWUgPSAxOworCWlmIChpb2N0bChmZCwgVklESU9DX1NfQ1RS
TCwgJmNvbnRyb2wpKQorCQlwZXJyb3IoIlZJRElPQ19TX0NUUkwiKTsKIH0KIAogaW50IHJhZGlv
X2dldHN0ZXJlbygpCiB7Ci0gICAgc3RydWN0IHZpZGVvX2F1ZGlvIHZhOwotICAgIHZhLm1vZGU9
LTE7Ci0KLSAgICBpZiAoZmQ8MCkKLSAgICAJcmV0dXJuIC0xOwotICAgIAotICAgIGlmIChpb2N0
bCAoZmQsIFZJRElPQ0dBVURJTywgJnZhKSA8IDApCi0JCXJldHVybiAtMTsKLQlpZiAodmEubW9k
ZSA9PSBWSURFT19TT1VORF9TVEVSRU8pCi0JCXJldHVybiAxOwotCWVsc2UgCi0JCXJldHVybiAw
OworCXN0cnVjdCB2NGwyX3R1bmVyIHR1bmVyOworCisJaWYgKGZkPDApCisJCXJldHVybiAtMTsK
KworCW1lbXNldCgmdHVuZXIsIDAsIHNpemVvZih0dW5lcikpOworCXR1bmVyLmluZGV4ID0gMDsK
KwlpZiAoaW9jdGwoZmQsIFZJRElPQ19HX1RVTkVSLCAmdHVuZXIpIDwgMCkKKwkJcmV0dXJuIC0x
OworCisJcmV0dXJuIHR1bmVyLmF1ZG1vZGUgPT0gVjRMMl9UVU5FUl9NT0RFX1NURVJFTzsKIH0K
IAogaW50IHJhZGlvX2dldHNpZ25hbCgpCiB7Ci0gICAgc3RydWN0IHZpZGVvX3R1bmVyIHZ0Owot
ICAgIGludCBzaWduYWw7Ci0KLSAgICBpZiAoZmQ8MCkKLSAgICAJcmV0dXJuIC0xOwotCi0gICAg
bWVtc2V0KCZ2dCwwLHNpemVvZih2dCkpOwotICAgIGlvY3RsIChmZCwgVklESU9DR1RVTkVSLCAm
dnQpOwotICAgIHNpZ25hbD12dC5zaWduYWw+PjEzOwotCi0gICAgcmV0dXJuIHNpZ25hbDsKKwlz
dHJ1Y3QgdjRsMl90dW5lciB0dW5lcjsKKworCWlmIChmZDwwKQorCQlyZXR1cm4gLTE7CisKKwlt
ZW1zZXQoJnR1bmVyLCAwLCBzaXplb2YodHVuZXIpKTsKKwl0dW5lci5pbmRleCA9IDA7CisJaWYg
KGlvY3RsKGZkLCBWSURJT0NfR19UVU5FUiwgJnR1bmVyKSA8IDApCisJCXJldHVybiAtMTsKKwor
CXJldHVybiB0dW5lci5zaWduYWwgPj4gMTM7CiB9Cgo=

=== modified directory  // last-changed:james@jamesh.id.au-20070412135647-bz9dl
... esz0vifvy7m
# revision id: james@jamesh.id.au-20070412135647-bz9dlesz0vifvy7m
# sha1: 15d91a76e8e72cb6235c358beb90e5001bf07d19
# inventory sha1: caa257e758124ea760b4347369926073631057a1
# parent ids:
#   svn-v2:172@ba97a3d1-ec25-0410-b1c6-e06ad936ea6c-trunk
# properties:
#   branch-nick: gnomeradio

