diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2006-03-30 17:50:34 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-04-02 03:56:06 -0400 |
commit | 0020d3ef915fc01a0184bc96eeb3c240bded5d8e (patch) | |
tree | 89685985691405ae3c407b699a1f8cefa19425ce /drivers/media/video/bt8xx | |
parent | 9bc7400a9d01b1fe05c7f0200e7384e17794f6e4 (diff) |
V4L/DVB (3693): Fix msp3400c and bttv stereo/mono/bilingual detection/handling
- msp3400c did not detect the second carrier, thus being always mono.
- properly mute the msp3400c while detecting the carrier.
- fix checks on the presence of scart2/3 inputs and scart 2 output.
- implement proper audio mode fallbacks for msp3400c/d, identical to the
way msp3400g works.
- MODE_STEREO no longer produces dual languages when set for a bilingual
transmission, instead it falls back to LANG1. Use LANG1_LANG2 to hear
both languages of a bilingual transmission. This is much more intuitive
for the user and is in accordance with the preferred usage in the v4l2
specification.
- bttv tried to implement v4l2 calls with v4l1 calls to the i2c devices,
completely mangling the audmode/rxsubchans handling. v4l2 calls now do
v4l2 calls to the i2c devices.
- fixed broken i2c_vidiocschan in bttv.
- add start/end lines to LOG_STATUS.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/bt8xx')
-rw-r--r-- | drivers/media/video/bt8xx/bttv-driver.c | 147 |
1 files changed, 75 insertions, 72 deletions
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 74def9c23952..7913e2ec7a5b 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -1023,14 +1023,12 @@ audio_input(struct bttv *btv, int input) | |||
1023 | static void | 1023 | static void |
1024 | i2c_vidiocschan(struct bttv *btv) | 1024 | i2c_vidiocschan(struct bttv *btv) |
1025 | { | 1025 | { |
1026 | struct video_channel c; | 1026 | v4l2_std_id std = bttv_tvnorms[btv->tvnorm].v4l2_id; |
1027 | 1027 | ||
1028 | memset(&c,0,sizeof(c)); | 1028 | bttv_call_i2c_clients(btv, VIDIOC_S_INPUT, &btv->input); |
1029 | c.norm = btv->tvnorm; | 1029 | bttv_call_i2c_clients(btv, VIDIOC_S_STD, &std); |
1030 | c.channel = btv->input; | ||
1031 | bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c); | ||
1032 | if (btv->c.type == BTTV_BOARD_VOODOOTV_FM) | 1030 | if (btv->c.type == BTTV_BOARD_VOODOOTV_FM) |
1033 | bttv_tda9880_setnorm(btv,c.norm); | 1031 | bttv_tda9880_setnorm(btv,btv->tvnorm); |
1034 | } | 1032 | } |
1035 | 1033 | ||
1036 | static int | 1034 | static int |
@@ -1184,11 +1182,27 @@ static int get_control(struct bttv *btv, struct v4l2_control *c) | |||
1184 | break; | 1182 | break; |
1185 | if (i == BTTV_CTLS) | 1183 | if (i == BTTV_CTLS) |
1186 | return -EINVAL; | 1184 | return -EINVAL; |
1187 | if (i >= 4 && i <= 8) { | 1185 | if (btv->audio_hook && i >= 4 && i <= 8) { |
1188 | memset(&va,0,sizeof(va)); | 1186 | memset(&va,0,sizeof(va)); |
1189 | bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va); | 1187 | btv->audio_hook(btv,&va,0); |
1190 | if (btv->audio_hook) | 1188 | switch (c->id) { |
1191 | btv->audio_hook(btv,&va,0); | 1189 | case V4L2_CID_AUDIO_MUTE: |
1190 | c->value = (VIDEO_AUDIO_MUTE & va.flags) ? 1 : 0; | ||
1191 | break; | ||
1192 | case V4L2_CID_AUDIO_VOLUME: | ||
1193 | c->value = va.volume; | ||
1194 | break; | ||
1195 | case V4L2_CID_AUDIO_BALANCE: | ||
1196 | c->value = va.balance; | ||
1197 | break; | ||
1198 | case V4L2_CID_AUDIO_BASS: | ||
1199 | c->value = va.bass; | ||
1200 | break; | ||
1201 | case V4L2_CID_AUDIO_TREBLE: | ||
1202 | c->value = va.treble; | ||
1203 | break; | ||
1204 | } | ||
1205 | return 0; | ||
1192 | } | 1206 | } |
1193 | switch (c->id) { | 1207 | switch (c->id) { |
1194 | case V4L2_CID_BRIGHTNESS: | 1208 | case V4L2_CID_BRIGHTNESS: |
@@ -1205,19 +1219,11 @@ static int get_control(struct bttv *btv, struct v4l2_control *c) | |||
1205 | break; | 1219 | break; |
1206 | 1220 | ||
1207 | case V4L2_CID_AUDIO_MUTE: | 1221 | case V4L2_CID_AUDIO_MUTE: |
1208 | c->value = (VIDEO_AUDIO_MUTE & va.flags) ? 1 : 0; | ||
1209 | break; | ||
1210 | case V4L2_CID_AUDIO_VOLUME: | 1222 | case V4L2_CID_AUDIO_VOLUME: |
1211 | c->value = va.volume; | ||
1212 | break; | ||
1213 | case V4L2_CID_AUDIO_BALANCE: | 1223 | case V4L2_CID_AUDIO_BALANCE: |
1214 | c->value = va.balance; | ||
1215 | break; | ||
1216 | case V4L2_CID_AUDIO_BASS: | 1224 | case V4L2_CID_AUDIO_BASS: |
1217 | c->value = va.bass; | ||
1218 | break; | ||
1219 | case V4L2_CID_AUDIO_TREBLE: | 1225 | case V4L2_CID_AUDIO_TREBLE: |
1220 | c->value = va.treble; | 1226 | bttv_call_i2c_clients(btv,VIDIOC_G_CTRL,c); |
1221 | break; | 1227 | break; |
1222 | 1228 | ||
1223 | case V4L2_CID_PRIVATE_CHROMA_AGC: | 1229 | case V4L2_CID_PRIVATE_CHROMA_AGC: |
@@ -1269,11 +1275,35 @@ static int set_control(struct bttv *btv, struct v4l2_control *c) | |||
1269 | break; | 1275 | break; |
1270 | if (i == BTTV_CTLS) | 1276 | if (i == BTTV_CTLS) |
1271 | return -EINVAL; | 1277 | return -EINVAL; |
1272 | if (i >= 4 && i <= 8) { | 1278 | if (btv->audio_hook && i >= 4 && i <= 8) { |
1273 | memset(&va,0,sizeof(va)); | 1279 | memset(&va,0,sizeof(va)); |
1274 | bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va); | 1280 | btv->audio_hook(btv,&va,0); |
1275 | if (btv->audio_hook) | 1281 | switch (c->id) { |
1276 | btv->audio_hook(btv,&va,0); | 1282 | case V4L2_CID_AUDIO_MUTE: |
1283 | if (c->value) { | ||
1284 | va.flags |= VIDEO_AUDIO_MUTE; | ||
1285 | audio_mute(btv, 1); | ||
1286 | } else { | ||
1287 | va.flags &= ~VIDEO_AUDIO_MUTE; | ||
1288 | audio_mute(btv, 0); | ||
1289 | } | ||
1290 | break; | ||
1291 | |||
1292 | case V4L2_CID_AUDIO_VOLUME: | ||
1293 | va.volume = c->value; | ||
1294 | break; | ||
1295 | case V4L2_CID_AUDIO_BALANCE: | ||
1296 | va.balance = c->value; | ||
1297 | break; | ||
1298 | case V4L2_CID_AUDIO_BASS: | ||
1299 | va.bass = c->value; | ||
1300 | break; | ||
1301 | case V4L2_CID_AUDIO_TREBLE: | ||
1302 | va.treble = c->value; | ||
1303 | break; | ||
1304 | } | ||
1305 | btv->audio_hook(btv,&va,1); | ||
1306 | return 0; | ||
1277 | } | 1307 | } |
1278 | switch (c->id) { | 1308 | switch (c->id) { |
1279 | case V4L2_CID_BRIGHTNESS: | 1309 | case V4L2_CID_BRIGHTNESS: |
@@ -1289,26 +1319,13 @@ static int set_control(struct bttv *btv, struct v4l2_control *c) | |||
1289 | bt848_sat(btv,c->value); | 1319 | bt848_sat(btv,c->value); |
1290 | break; | 1320 | break; |
1291 | case V4L2_CID_AUDIO_MUTE: | 1321 | case V4L2_CID_AUDIO_MUTE: |
1292 | if (c->value) { | 1322 | audio_mute(btv, c->value); |
1293 | va.flags |= VIDEO_AUDIO_MUTE; | 1323 | /* fall through */ |
1294 | audio_mute(btv, 1); | ||
1295 | } else { | ||
1296 | va.flags &= ~VIDEO_AUDIO_MUTE; | ||
1297 | audio_mute(btv, 0); | ||
1298 | } | ||
1299 | break; | ||
1300 | |||
1301 | case V4L2_CID_AUDIO_VOLUME: | 1324 | case V4L2_CID_AUDIO_VOLUME: |
1302 | va.volume = c->value; | ||
1303 | break; | ||
1304 | case V4L2_CID_AUDIO_BALANCE: | 1325 | case V4L2_CID_AUDIO_BALANCE: |
1305 | va.balance = c->value; | ||
1306 | break; | ||
1307 | case V4L2_CID_AUDIO_BASS: | 1326 | case V4L2_CID_AUDIO_BASS: |
1308 | va.bass = c->value; | ||
1309 | break; | ||
1310 | case V4L2_CID_AUDIO_TREBLE: | 1327 | case V4L2_CID_AUDIO_TREBLE: |
1311 | va.treble = c->value; | 1328 | bttv_call_i2c_clients(btv,VIDIOC_S_CTRL,c); |
1312 | break; | 1329 | break; |
1313 | 1330 | ||
1314 | case V4L2_CID_PRIVATE_CHROMA_AGC: | 1331 | case V4L2_CID_PRIVATE_CHROMA_AGC: |
@@ -1364,11 +1381,6 @@ static int set_control(struct bttv *btv, struct v4l2_control *c) | |||
1364 | default: | 1381 | default: |
1365 | return -EINVAL; | 1382 | return -EINVAL; |
1366 | } | 1383 | } |
1367 | if (i >= 4 && i <= 8) { | ||
1368 | bttv_call_i2c_clients(btv, VIDIOCSAUDIO, &va); | ||
1369 | if (btv->audio_hook) | ||
1370 | btv->audio_hook(btv,&va,1); | ||
1371 | } | ||
1372 | return 0; | 1384 | return 0; |
1373 | } | 1385 | } |
1374 | 1386 | ||
@@ -1827,33 +1839,26 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) | |||
1827 | return -EINVAL; | 1839 | return -EINVAL; |
1828 | mutex_lock(&btv->lock); | 1840 | mutex_lock(&btv->lock); |
1829 | memset(t,0,sizeof(*t)); | 1841 | memset(t,0,sizeof(*t)); |
1842 | t->rxsubchans = V4L2_TUNER_SUB_MONO; | ||
1843 | bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t); | ||
1830 | strcpy(t->name, "Television"); | 1844 | strcpy(t->name, "Television"); |
1831 | t->type = V4L2_TUNER_ANALOG_TV; | ||
1832 | t->capability = V4L2_TUNER_CAP_NORM; | 1845 | t->capability = V4L2_TUNER_CAP_NORM; |
1833 | t->rxsubchans = V4L2_TUNER_SUB_MONO; | 1846 | t->type = V4L2_TUNER_ANALOG_TV; |
1834 | if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) | 1847 | if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) |
1835 | t->signal = 0xffff; | 1848 | t->signal = 0xffff; |
1836 | { | 1849 | |
1837 | struct video_tuner tuner; | 1850 | if (btv->audio_hook) { |
1838 | |||
1839 | memset(&tuner, 0, sizeof (tuner)); | ||
1840 | tuner.rangehigh = 0xffffffffUL; | ||
1841 | bttv_call_i2c_clients(btv, VIDIOCGTUNER, &tuner); | ||
1842 | t->rangelow = tuner.rangelow; | ||
1843 | t->rangehigh = tuner.rangehigh; | ||
1844 | } | ||
1845 | { | ||
1846 | /* Hmmm ... */ | 1851 | /* Hmmm ... */ |
1847 | struct video_audio va; | 1852 | struct video_audio va; |
1848 | memset(&va, 0, sizeof(struct video_audio)); | 1853 | memset(&va, 0, sizeof(struct video_audio)); |
1849 | bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va); | 1854 | btv->audio_hook(btv,&va,0); |
1850 | if (btv->audio_hook) | 1855 | t->audmode = V4L2_TUNER_MODE_MONO; |
1851 | btv->audio_hook(btv,&va,0); | 1856 | t->rxsubchans = V4L2_TUNER_SUB_MONO; |
1852 | if(va.mode & VIDEO_SOUND_STEREO) { | 1857 | if(va.mode & VIDEO_SOUND_STEREO) { |
1853 | t->audmode = V4L2_TUNER_MODE_STEREO; | 1858 | t->audmode = V4L2_TUNER_MODE_STEREO; |
1854 | t->rxsubchans |= V4L2_TUNER_SUB_STEREO; | 1859 | t->rxsubchans = V4L2_TUNER_SUB_STEREO; |
1855 | } | 1860 | } |
1856 | if(va.mode & VIDEO_SOUND_LANG1) { | 1861 | if(va.mode & VIDEO_SOUND_LANG2) { |
1857 | t->audmode = V4L2_TUNER_MODE_LANG1; | 1862 | t->audmode = V4L2_TUNER_MODE_LANG1; |
1858 | t->rxsubchans = V4L2_TUNER_SUB_LANG1 | 1863 | t->rxsubchans = V4L2_TUNER_SUB_LANG1 |
1859 | | V4L2_TUNER_SUB_LANG2; | 1864 | | V4L2_TUNER_SUB_LANG2; |
@@ -1872,10 +1877,10 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) | |||
1872 | if (0 != t->index) | 1877 | if (0 != t->index) |
1873 | return -EINVAL; | 1878 | return -EINVAL; |
1874 | mutex_lock(&btv->lock); | 1879 | mutex_lock(&btv->lock); |
1875 | { | 1880 | bttv_call_i2c_clients(btv, VIDIOC_S_TUNER, t); |
1881 | if (btv->audio_hook) { | ||
1876 | struct video_audio va; | 1882 | struct video_audio va; |
1877 | memset(&va, 0, sizeof(struct video_audio)); | 1883 | memset(&va, 0, sizeof(struct video_audio)); |
1878 | bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va); | ||
1879 | if (t->audmode == V4L2_TUNER_MODE_MONO) | 1884 | if (t->audmode == V4L2_TUNER_MODE_MONO) |
1880 | va.mode = VIDEO_SOUND_MONO; | 1885 | va.mode = VIDEO_SOUND_MONO; |
1881 | else if (t->audmode == V4L2_TUNER_MODE_STEREO || | 1886 | else if (t->audmode == V4L2_TUNER_MODE_STEREO || |
@@ -1885,9 +1890,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) | |||
1885 | va.mode = VIDEO_SOUND_LANG1; | 1890 | va.mode = VIDEO_SOUND_LANG1; |
1886 | else if (t->audmode == V4L2_TUNER_MODE_LANG2) | 1891 | else if (t->audmode == V4L2_TUNER_MODE_LANG2) |
1887 | va.mode = VIDEO_SOUND_LANG2; | 1892 | va.mode = VIDEO_SOUND_LANG2; |
1888 | bttv_call_i2c_clients(btv, VIDIOCSAUDIO, &va); | 1893 | btv->audio_hook(btv,&va,1); |
1889 | if (btv->audio_hook) | ||
1890 | btv->audio_hook(btv,&va,1); | ||
1891 | } | 1894 | } |
1892 | mutex_unlock(&btv->lock); | 1895 | mutex_unlock(&btv->lock); |
1893 | return 0; | 1896 | return 0; |
@@ -1912,7 +1915,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) | |||
1912 | return -EINVAL; | 1915 | return -EINVAL; |
1913 | mutex_lock(&btv->lock); | 1916 | mutex_lock(&btv->lock); |
1914 | btv->freq = f->frequency; | 1917 | btv->freq = f->frequency; |
1915 | bttv_call_i2c_clients(btv,VIDIOCSFREQ,&btv->freq); | 1918 | bttv_call_i2c_clients(btv,VIDIOC_S_FREQUENCY,f); |
1916 | if (btv->has_matchbox && btv->radio_user) | 1919 | if (btv->has_matchbox && btv->radio_user) |
1917 | tea5757_set_freq(btv,btv->freq); | 1920 | tea5757_set_freq(btv,btv->freq); |
1918 | mutex_unlock(&btv->lock); | 1921 | mutex_unlock(&btv->lock); |
@@ -1920,7 +1923,9 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) | |||
1920 | } | 1923 | } |
1921 | case VIDIOC_LOG_STATUS: | 1924 | case VIDIOC_LOG_STATUS: |
1922 | { | 1925 | { |
1926 | printk(KERN_INFO "bttv%d: ================= START STATUS CARD #%d =================\n", btv->c.nr, btv->c.nr); | ||
1923 | bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, NULL); | 1927 | bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, NULL); |
1928 | printk(KERN_INFO "bttv%d: ================== END STATUS CARD #%d ==================\n", btv->c.nr, btv->c.nr); | ||
1924 | return 0; | 1929 | return 0; |
1925 | } | 1930 | } |
1926 | 1931 | ||
@@ -2870,12 +2875,10 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2870 | return 0; | 2875 | return 0; |
2871 | } | 2876 | } |
2872 | *c = bttv_ctls[i]; | 2877 | *c = bttv_ctls[i]; |
2873 | if (i >= 4 && i <= 8) { | 2878 | if (btv->audio_hook && i >= 4 && i <= 8) { |
2874 | struct video_audio va; | 2879 | struct video_audio va; |
2875 | memset(&va,0,sizeof(va)); | 2880 | memset(&va,0,sizeof(va)); |
2876 | bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va); | 2881 | btv->audio_hook(btv,&va,0); |
2877 | if (btv->audio_hook) | ||
2878 | btv->audio_hook(btv,&va,0); | ||
2879 | switch (bttv_ctls[i].id) { | 2882 | switch (bttv_ctls[i].id) { |
2880 | case V4L2_CID_AUDIO_VOLUME: | 2883 | case V4L2_CID_AUDIO_VOLUME: |
2881 | if (!(va.flags & VIDEO_AUDIO_VOLUME)) | 2884 | if (!(va.flags & VIDEO_AUDIO_VOLUME)) |