11a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* 21a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil file operation functions 31a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> 41a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil Copyright (C) 2004 Chris Kennedy <c@groovy.org> 51a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> 61a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 71a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil This program is free software; you can redistribute it and/or modify 81a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil it under the terms of the GNU General Public License as published by 91a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil the Free Software Foundation; either version 2 of the License, or 101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil (at your option) any later version. 111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil This program is distributed in the hope that it will be useful, 131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil but WITHOUT ANY WARRANTY; without even the implied warranty of 141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil GNU General Public License for more details. 161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil You should have received a copy of the GNU General Public License 181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil along with this program; if not, write to the Free Software 191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil */ 211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-driver.h" 231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-fileops.h" 241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-i2c.h" 251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-queue.h" 261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-udma.h" 271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-irq.h" 281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-vbi.h" 291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-mailbox.h" 3033c0fcad2160bc211272295e862c6f708118d006Hans Verkuil#include "ivtv-routing.h" 311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-streams.h" 321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-yuv.h" 331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-ioctl.h" 34f2100d82b858815848b661d57d7e166341c02e20Hans Verkuil#include "ivtv-cards.h" 35914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong#include "ivtv-firmware.h" 36092501936fc128992456a086193746cf34642815Hans Verkuil#include <media/v4l2-event.h> 37f2100d82b858815848b661d57d7e166341c02e20Hans Verkuil#include <media/saa7115.h> 381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* This function tries to claim the stream for a specific file descriptor. 401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil If no one else is using this stream then the stream is claimed and 411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil associated VBI streams are also automatically claimed. 421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil Possible error returns: -EBUSY if someone else has claimed 431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil the stream or 0 on success. */ 4495f73c5b57990c97047c200b8746ab62a360c5bcAdrian Bunkstatic int ivtv_claim_stream(struct ivtv_open_id *id, int type) 451a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = id->itv; 471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_stream *s = &itv->streams[type]; 481a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_stream *s_vbi; 491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int vbi_type; 501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (test_and_set_bit(IVTV_F_S_CLAIMED, &s->s_flags)) { 521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* someone already claimed this stream */ 5361bb725ef5a646d3fc8a64e41b020a65542cdae1Hans Verkuil if (s->fh == &id->fh) { 541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* yes, this file descriptor did. So that's OK. */ 551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return 0; 561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 5761bb725ef5a646d3fc8a64e41b020a65542cdae1Hans Verkuil if (s->fh == NULL && (type == IVTV_DEC_STREAM_TYPE_VBI || 581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil type == IVTV_ENC_STREAM_TYPE_VBI)) { 591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* VBI is handled already internally, now also assign 601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil the file descriptor to this stream for external 611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil reading of the stream. */ 6261bb725ef5a646d3fc8a64e41b020a65542cdae1Hans Verkuil s->fh = &id->fh; 631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_INFO("Start Read VBI\n"); 641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return 0; 651a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 661a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* someone else is using this stream already */ 671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_INFO("Stream %d is busy\n", type); 681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EBUSY; 691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 7061bb725ef5a646d3fc8a64e41b020a65542cdae1Hans Verkuil s->fh = &id->fh; 711a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (type == IVTV_DEC_STREAM_TYPE_VBI) { 721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Enable reinsertion interrupt */ 731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT); 741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* IVTV_DEC_STREAM_TYPE_MPG needs to claim IVTV_DEC_STREAM_TYPE_VBI, 771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_ENC_STREAM_TYPE_MPG needs to claim IVTV_ENC_STREAM_TYPE_VBI 781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil (provided VBI insertion is on and sliced VBI is selected), for all 791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil other streams we're done */ 801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (type == IVTV_DEC_STREAM_TYPE_MPG) { 811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil vbi_type = IVTV_DEC_STREAM_TYPE_VBI; 821a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } else if (type == IVTV_ENC_STREAM_TYPE_MPG && 83a8b864354e060dda1000e62d1fea7c1274581cafHans Verkuil itv->vbi.insert_mpeg && !ivtv_raw_vbi(itv)) { 841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil vbi_type = IVTV_ENC_STREAM_TYPE_VBI; 851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } else { 861a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return 0; 871a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 881a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil s_vbi = &itv->streams[vbi_type]; 891a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 901a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!test_and_set_bit(IVTV_F_S_CLAIMED, &s_vbi->s_flags)) { 911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Enable reinsertion interrupt */ 921a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (vbi_type == IVTV_DEC_STREAM_TYPE_VBI) 931a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT); 941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* mark that it is used internally */ 961a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil set_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags); 971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return 0; 981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1001a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* This function releases a previously claimed stream. It will take into 1011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil account associated VBI streams. */ 1021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilvoid ivtv_release_stream(struct ivtv_stream *s) 1031a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 1041a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = s->itv; 1051a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_stream *s_vbi; 1061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 10761bb725ef5a646d3fc8a64e41b020a65542cdae1Hans Verkuil s->fh = NULL; 1081a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if ((s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type == IVTV_ENC_STREAM_TYPE_VBI) && 1091a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) { 1101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* this stream is still in use internally */ 1111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return; 1121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 1131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!test_and_clear_bit(IVTV_F_S_CLAIMED, &s->s_flags)) { 1141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_WARN("Release stream %s not in use!\n", s->name); 1151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return; 1161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 1171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_flush_queues(s); 1191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* disable reinsertion interrupt */ 1211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s->type == IVTV_DEC_STREAM_TYPE_VBI) 1221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_set_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT); 1231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* IVTV_DEC_STREAM_TYPE_MPG needs to release IVTV_DEC_STREAM_TYPE_VBI, 1251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_ENC_STREAM_TYPE_MPG needs to release IVTV_ENC_STREAM_TYPE_VBI, 1261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil for all other streams we're done */ 1271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s->type == IVTV_DEC_STREAM_TYPE_MPG) 1281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil s_vbi = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI]; 1291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil else if (s->type == IVTV_ENC_STREAM_TYPE_MPG) 1301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; 1311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil else 1321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return; 1331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1341a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* clear internal use flag */ 1351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!test_and_clear_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags)) { 1361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* was already cleared */ 1371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return; 1381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 13961bb725ef5a646d3fc8a64e41b020a65542cdae1Hans Verkuil if (s_vbi->fh) { 1401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* VBI stream still claimed by a file descriptor */ 1411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return; 1421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 1431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* disable reinsertion interrupt */ 1441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s_vbi->type == IVTV_DEC_STREAM_TYPE_VBI) 1451a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_set_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT); 1461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil clear_bit(IVTV_F_S_CLAIMED, &s_vbi->s_flags); 1471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_flush_queues(s_vbi); 1481a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 1491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic void ivtv_dualwatch(struct ivtv *itv) 1511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 1521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct v4l2_tuner vt; 1530d82fe801d7c6d8cb8987e66b570f6decde9e235Andy Walls u32 new_stereo_mode; 154f7b80e6919df812b4bed99a927325312a904111bHans Verkuil const u32 dual = 0x02; 1551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 156f7b80e6919df812b4bed99a927325312a904111bHans Verkuil new_stereo_mode = v4l2_ctrl_g_ctrl(itv->cxhdl.audio_mode); 1571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil memset(&vt, 0, sizeof(vt)); 15867ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil ivtv_call_all(itv, tuner, g_tuner, &vt); 1591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 && (vt.rxsubchans & V4L2_TUNER_SUB_LANG2)) 1601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil new_stereo_mode = dual; 1611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1621a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (new_stereo_mode == itv->dualwatch_stereo_mode) 1631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return; 1641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 165f7b80e6919df812b4bed99a927325312a904111bHans Verkuil IVTV_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x.\n", 166f7b80e6919df812b4bed99a927325312a904111bHans Verkuil itv->dualwatch_stereo_mode, new_stereo_mode); 167f7b80e6919df812b4bed99a927325312a904111bHans Verkuil if (v4l2_ctrl_s_ctrl(itv->cxhdl.audio_mode, new_stereo_mode)) 168f7b80e6919df812b4bed99a927325312a904111bHans Verkuil IVTV_DEBUG_INFO("dualwatch: changing stereo flag failed\n"); 1691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 1701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1711a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic void ivtv_update_pgm_info(struct ivtv *itv) 1721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 1731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil u32 wr_idx = (read_enc(itv->pgm_info_offset) - itv->pgm_info_offset - 4) / 24; 1741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int cnt; 1751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int i = 0; 1761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (wr_idx >= itv->pgm_info_num) { 1781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_WARN("Invalid PGM index %d (>= %d)\n", wr_idx, itv->pgm_info_num); 1791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return; 1801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 1811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil cnt = (wr_idx + itv->pgm_info_num - itv->pgm_info_write_idx) % itv->pgm_info_num; 1821a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil while (i < cnt) { 1831a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num; 1841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct v4l2_enc_idx_entry *e = itv->pgm_info + idx; 1851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil u32 addr = itv->pgm_info_offset + 4 + idx * 24; 1865614b02143171a99e0e6eb6c7d1d2f8750d2957fHans Verkuil const int mapping[8] = { -1, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_P, -1, 1875614b02143171a99e0e6eb6c7d1d2f8750d2957fHans Verkuil V4L2_ENC_IDX_FRAME_B, -1, -1, -1 }; 1885614b02143171a99e0e6eb6c7d1d2f8750d2957fHans Verkuil // 1=I, 2=P, 4=B 1891a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 1901a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil e->offset = read_enc(addr + 4) + ((u64)read_enc(addr + 8) << 32); 1911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (e->offset > itv->mpg_data_received) { 1921a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil break; 1931a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 1941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil e->offset += itv->vbi_data_inserted; 1951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil e->length = read_enc(addr); 1961a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil e->pts = read_enc(addr + 16) + ((u64)(read_enc(addr + 20) & 1) << 32); 1975614b02143171a99e0e6eb6c7d1d2f8750d2957fHans Verkuil e->flags = mapping[read_enc(addr + 12) & 7]; 1981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil i++; 1991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 2001a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil itv->pgm_info_write_idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num; 2011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 2021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 2031a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block, int *err) 2041a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 2051a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = s->itv; 2061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; 2071a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_buffer *buf; 2081a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil DEFINE_WAIT(wait); 2091a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 2101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil *err = 0; 2111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil while (1) { 2121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s->type == IVTV_ENC_STREAM_TYPE_MPG) { 2131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Process pending program info updates and pending VBI data */ 2141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_update_pgm_info(itv); 2151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 216168c626cb8f85df17585af99e14403904641c7acJulia Lawall if (time_after(jiffies, 217168c626cb8f85df17585af99e14403904641c7acJulia Lawall itv->dualwatch_jiffies + 218168c626cb8f85df17585af99e14403904641c7acJulia Lawall msecs_to_jiffies(1000))) { 2191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil itv->dualwatch_jiffies = jiffies; 2201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_dualwatch(itv); 2211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 2221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 2231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (test_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags) && 2241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil !test_bit(IVTV_F_S_APPL_IO, &s_vbi->s_flags)) { 2251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil while ((buf = ivtv_dequeue(s_vbi, &s_vbi->q_full))) { 2261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* byteswap and process VBI data */ 2271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_process_vbi_data(itv, buf, s_vbi->dma_pts, s_vbi->type); 2281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_enqueue(s_vbi, buf, &s_vbi->q_free); 2291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 2301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 2311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil buf = &itv->vbi.sliced_mpeg_buf; 2321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (buf->readpos != buf->bytesused) { 2331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return buf; 2341a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 2351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 2361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 2371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* do we have leftover data? */ 2381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil buf = ivtv_dequeue(s, &s->q_io); 2391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (buf) 2401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return buf; 2411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 2421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* do we have new data? */ 2431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil buf = ivtv_dequeue(s, &s->q_full); 2441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (buf) { 245f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil if ((buf->b_flags & IVTV_F_B_NEED_BUF_SWAP) == 0) 2461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return buf; 247f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil buf->b_flags &= ~IVTV_F_B_NEED_BUF_SWAP; 2481a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s->type == IVTV_ENC_STREAM_TYPE_MPG) 2491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* byteswap MPG data */ 2501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_buf_swap(buf); 2511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil else if (s->type != IVTV_DEC_STREAM_TYPE_VBI) { 2521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* byteswap and process VBI data */ 2531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_process_vbi_data(itv, buf, s->dma_pts, s->type); 2541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 2551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return buf; 2561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 2571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 2581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* return if end of stream */ 2591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s->type != IVTV_DEC_STREAM_TYPE_VBI && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { 2601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_INFO("EOS %s\n", s->name); 2611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return NULL; 2621a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 2631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 264559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil /* return if file was opened with O_NONBLOCK */ 265559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil if (non_block) { 266559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil *err = -EAGAIN; 267559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil return NULL; 268559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil } 269559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil 2701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* wait for more data to arrive */ 271cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil mutex_unlock(&itv->serialize_lock); 2721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); 2731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* New buffers might have become available before we were added to the waitqueue */ 2741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!s->q_full.buffers) 2751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil schedule(); 2761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil finish_wait(&s->waitq, &wait); 277cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil mutex_lock(&itv->serialize_lock); 2781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (signal_pending(current)) { 2791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* return if a signal was received */ 2801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_INFO("User stopped %s\n", s->name); 2811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil *err = -EINTR; 2821a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return NULL; 2831a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 2841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 2851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 2861a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 2871a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic void ivtv_setup_sliced_vbi_buf(struct ivtv *itv) 2881a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 2891a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int idx = itv->vbi.inserted_frame % IVTV_VBI_FRAMES; 2901a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 2911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil itv->vbi.sliced_mpeg_buf.buf = itv->vbi.sliced_mpeg_data[idx]; 2921a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil itv->vbi.sliced_mpeg_buf.bytesused = itv->vbi.sliced_mpeg_size[idx]; 2931a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil itv->vbi.sliced_mpeg_buf.readpos = 0; 2941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 2951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 2961a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic size_t ivtv_copy_buf_to_user(struct ivtv_stream *s, struct ivtv_buffer *buf, 2971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil char __user *ubuf, size_t ucount) 2981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 2991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = s->itv; 3001a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil size_t len = buf->bytesused - buf->readpos; 3011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 3021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (len > ucount) len = ucount; 3031a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (itv->vbi.insert_mpeg && s->type == IVTV_ENC_STREAM_TYPE_MPG && 304a8b864354e060dda1000e62d1fea7c1274581cafHans Verkuil !ivtv_raw_vbi(itv) && buf != &itv->vbi.sliced_mpeg_buf) { 3051a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil const char *start = buf->buf + buf->readpos; 3061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil const char *p = start + 1; 3071a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil const u8 *q; 3081a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil u8 ch = itv->search_pack_header ? 0xba : 0xe0; 3091a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int stuffing, i; 3101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 3111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil while (start + len > p && (q = memchr(p, 0, start + len - p))) { 3121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil p = q + 1; 3131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if ((char *)q + 15 >= buf->buf + buf->bytesused || 3141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil q[1] != 0 || q[2] != 1 || q[3] != ch) { 3151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil continue; 3161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 3171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!itv->search_pack_header) { 3181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if ((q[6] & 0xc0) != 0x80) 3191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil continue; 3201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (((q[7] & 0xc0) == 0x80 && (q[9] & 0xf0) == 0x20) || 3211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ((q[7] & 0xc0) == 0xc0 && (q[9] & 0xf0) == 0x30)) { 3221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ch = 0xba; 3231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil itv->search_pack_header = 1; 3241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil p = q + 9; 3251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 3261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil continue; 3271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 3281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil stuffing = q[13] & 7; 3291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* all stuffing bytes must be 0xff */ 3301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil for (i = 0; i < stuffing; i++) 3311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (q[14 + i] != 0xff) 3321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil break; 3331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (i == stuffing && (q[4] & 0xc4) == 0x44 && (q[12] & 3) == 3 && 3341a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil q[14 + stuffing] == 0 && q[15 + stuffing] == 0 && 3351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil q[16 + stuffing] == 1) { 3361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil itv->search_pack_header = 0; 3371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil len = (char *)q - start; 3381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setup_sliced_vbi_buf(itv); 3391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil break; 3401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 3411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 3421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 3431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (copy_to_user(ubuf, (u8 *)buf->buf + buf->readpos, len)) { 3441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_WARN("copy %zd bytes to user failed for %s\n", len, s->name); 3451a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EFAULT; 3461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 3471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /*IVTV_INFO("copied %lld %d %d %d %d %d vbi %d\n", itv->mpg_data_received, len, ucount, 3481a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil buf->readpos, buf->bytesused, buf->bytesused - buf->readpos - len, 3491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil buf == &itv->vbi.sliced_mpeg_buf); */ 3501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil buf->readpos += len; 3511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s->type == IVTV_ENC_STREAM_TYPE_MPG && buf != &itv->vbi.sliced_mpeg_buf) 3521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil itv->mpg_data_received += len; 3531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return len; 3541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 3551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 3561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_count, int non_block) 3571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 3581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = s->itv; 3591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil size_t tot_written = 0; 3601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int single_frame = 0; 3611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 36261bb725ef5a646d3fc8a64e41b020a65542cdae1Hans Verkuil if (atomic_read(&itv->capturing) == 0 && s->fh == NULL) { 3631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* shouldn't happen */ 3641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_WARN("Stream %s not initialized before read\n", s->name); 3651a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EIO; 3661a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 3671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 3681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Each VBI buffer is one frame, the v4l2 API says that for VBI the frames should 3691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil arrive one-by-one, so make sure we never output more than one VBI frame at a time */ 3701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s->type == IVTV_DEC_STREAM_TYPE_VBI || 371a8b864354e060dda1000e62d1fea7c1274581cafHans Verkuil (s->type == IVTV_ENC_STREAM_TYPE_VBI && !ivtv_raw_vbi(itv))) 3721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil single_frame = 1; 3731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 3741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil for (;;) { 3751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_buffer *buf; 3761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int rc; 3771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 3781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil buf = ivtv_get_buffer(s, non_block, &rc); 379559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil /* if there is no data available... */ 380559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil if (buf == NULL) { 381559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil /* if we got data, then return that regardless */ 382559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil if (tot_written) 383559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil break; 384559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil /* EOS condition */ 385559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil if (rc == 0) { 386559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); 387559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil clear_bit(IVTV_F_S_APPL_IO, &s->s_flags); 388559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil ivtv_release_stream(s); 389559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil } 390559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil /* set errno */ 3911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return rc; 392559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil } 3931a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil rc = ivtv_copy_buf_to_user(s, buf, ubuf + tot_written, tot_count - tot_written); 3941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (buf != &itv->vbi.sliced_mpeg_buf) { 3951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_enqueue(s, buf, (buf->readpos == buf->bytesused) ? &s->q_free : &s->q_io); 3961a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 3971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil else if (buf->readpos == buf->bytesused) { 3981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int idx = itv->vbi.inserted_frame % IVTV_VBI_FRAMES; 3991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil itv->vbi.sliced_mpeg_size[idx] = 0; 4001a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil itv->vbi.inserted_frame++; 4011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil itv->vbi_data_inserted += buf->bytesused; 4021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4031a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (rc < 0) 4041a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return rc; 4051a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil tot_written += rc; 4061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4071a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (tot_written == tot_count || single_frame) 4081a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil break; 4091a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return tot_written; 4111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 4121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic ssize_t ivtv_read_pos(struct ivtv_stream *s, char __user *ubuf, size_t count, 4141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil loff_t *pos, int non_block) 4151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 4161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ssize_t rc = count ? ivtv_read(s, ubuf, count, non_block) : 0; 4171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = s->itv; 4181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4191aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil IVTV_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc); 4201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (rc > 0) 4211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil pos += rc; 4221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return rc; 4231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 4241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilint ivtv_start_capture(struct ivtv_open_id *id) 4261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 4271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = id->itv; 4281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_stream *s = &itv->streams[id->type]; 4291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_stream *s_vbi; 4301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s->type == IVTV_ENC_STREAM_TYPE_RAD || 4321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil s->type == IVTV_DEC_STREAM_TYPE_MPG || 4331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil s->type == IVTV_DEC_STREAM_TYPE_YUV || 4341a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil s->type == IVTV_DEC_STREAM_TYPE_VOUT) { 4351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* you cannot read from these stream types. */ 4361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EPERM; 4371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Try to claim this stream. */ 4401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (ivtv_claim_stream(id, s->type)) 4411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EBUSY; 4421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* This stream does not need to start capturing */ 4441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s->type == IVTV_DEC_STREAM_TYPE_VBI) { 4451a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil set_bit(IVTV_F_S_APPL_IO, &s->s_flags); 4461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return 0; 4471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4481a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* If capture is already in progress, then we also have to 4501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil do nothing extra. */ 4511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (test_bit(IVTV_F_S_STREAMOFF, &s->s_flags) || test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags)) { 4521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil set_bit(IVTV_F_S_APPL_IO, &s->s_flags); 4531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return 0; 4541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Start VBI capture if required */ 4571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; 4581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s->type == IVTV_ENC_STREAM_TYPE_MPG && 4591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil test_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags) && 4601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil !test_and_set_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags)) { 4611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Note: the IVTV_ENC_STREAM_TYPE_VBI is claimed 4621a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil automatically when the MPG stream is claimed. 4631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil We only need to start the VBI capturing. */ 4641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (ivtv_start_v4l2_encode_stream(s_vbi)) { 4651a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_WARN("VBI capture start failed\n"); 4661a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Failure, clean up and return an error */ 4681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil clear_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags); 4691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil clear_bit(IVTV_F_S_STREAMING, &s->s_flags); 4701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* also releases the associated VBI stream */ 4711a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_release_stream(s); 4721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EIO; 4731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_INFO("VBI insertion started\n"); 4751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Tell the card to start capturing */ 4781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!ivtv_start_v4l2_encode_stream(s)) { 4791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* We're done */ 4801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil set_bit(IVTV_F_S_APPL_IO, &s->s_flags); 4811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Resume a possibly paused encoder */ 4821a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags)) 4831a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1); 4841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return 0; 4851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4861a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4871a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* failure, clean up */ 4881a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name); 4891a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4901a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Note: the IVTV_ENC_STREAM_TYPE_VBI is released 4911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil automatically when the MPG stream is released. 4921a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil We only need to stop the VBI capturing. */ 4931a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s->type == IVTV_ENC_STREAM_TYPE_MPG && 4941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil test_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags)) { 4951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_stop_v4l2_encode_stream(s_vbi, 0); 4961a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil clear_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags); 4971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil clear_bit(IVTV_F_S_STREAMING, &s->s_flags); 4991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_release_stream(s); 5001a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EIO; 5011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 5021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5031a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_t * pos) 5041a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 505092501936fc128992456a086193746cf34642815Hans Verkuil struct ivtv_open_id *id = fh2id(filp->private_data); 5061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = id->itv; 5071a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_stream *s = &itv->streams[id->type]; 5081a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int rc; 5091a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5101aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name); 5111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil rc = ivtv_start_capture(id); 5131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (rc) 5141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return rc; 5151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK); 5161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 5171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilint ivtv_start_decoding(struct ivtv_open_id *id, int speed) 5191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 5201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = id->itv; 5211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_stream *s = &itv->streams[id->type]; 522914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong int rc; 5231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (atomic_read(&itv->decoding) == 0) { 5251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (ivtv_claim_stream(id, s->type)) { 5261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* someone else is using this stream already */ 5271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_WARN("start decode, stream already claimed\n"); 5281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EBUSY; 5291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 530914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong rc = ivtv_start_v4l2_decode_stream(s, 0); 531215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong if (rc < 0) { 532215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong if (rc == -EAGAIN) 533215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong rc = ivtv_start_v4l2_decode_stream(s, 0); 534215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong if (rc < 0) 535215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong return rc; 536215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong } 5371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 5381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s->type == IVTV_DEC_STREAM_TYPE_MPG) 5391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return ivtv_set_speed(itv, speed); 5401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return 0; 5411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 5421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos) 5441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 545092501936fc128992456a086193746cf34642815Hans Verkuil struct ivtv_open_id *id = fh2id(filp->private_data); 5461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = id->itv; 5471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_stream *s = &itv->streams[id->type]; 548c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong struct yuv_playback_info *yi = &itv->yuv_info; 5491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_buffer *buf; 5501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_queue q; 5511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int bytes_written = 0; 5521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int mode; 5531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int rc; 5541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil DEFINE_WAIT(wait); 5551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5561aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil IVTV_DEBUG_HI_FILE("write %zd bytes to %s\n", count, s->name); 5571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s->type != IVTV_DEC_STREAM_TYPE_MPG && 5591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil s->type != IVTV_DEC_STREAM_TYPE_YUV && 5601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil s->type != IVTV_DEC_STREAM_TYPE_VOUT) 5611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* not decoder streams */ 5621a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EPERM; 5631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Try to claim this stream */ 5651a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (ivtv_claim_stream(id, s->type)) 5661a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EBUSY; 5671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* This stream does not need to start any decoding */ 5691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s->type == IVTV_DEC_STREAM_TYPE_VOUT) { 5702f3a98931f51be6093df7c6cc2633bf238778b7dHans Verkuil int elems = count / sizeof(struct v4l2_sliced_vbi_data); 5712f3a98931f51be6093df7c6cc2633bf238778b7dHans Verkuil 5721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil set_bit(IVTV_F_S_APPL_IO, &s->s_flags); 573ddda424999817fbc17adf9013feb066903382edeAndy Walls return ivtv_write_vbi_from_user(itv, 574b0c45686c8e8aecc7b0cd04d9b6af48d74418d53Andy Walls (const struct v4l2_sliced_vbi_data __user *)user_buf, elems); 5751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 5761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil mode = s->type == IVTV_DEC_STREAM_TYPE_MPG ? OUT_MPG : OUT_YUV; 5781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (ivtv_set_output_mode(itv, mode) != mode) { 5801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_release_stream(s); 5811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EBUSY; 5821a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 5831a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_queue_init(&q); 5841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil set_bit(IVTV_F_S_APPL_IO, &s->s_flags); 5851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 586464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong /* Start decoder (returns 0 if already started) */ 587464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong rc = ivtv_start_decoding(id, itv->speed); 588464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong if (rc) { 589464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name); 590464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong 591464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong /* failure, clean up */ 592464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong clear_bit(IVTV_F_S_STREAMING, &s->s_flags); 593464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong clear_bit(IVTV_F_S_APPL_IO, &s->s_flags); 594464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong return rc; 595464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong } 596464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong 5971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilretry: 59877aded6ba51f01335840ce8e18b413067810b68eIan Armstrong /* If possible, just DMA the entire frame - Check the data transfer size 59977aded6ba51f01335840ce8e18b413067810b68eIan Armstrong since we may get here before the stream has been fully set-up */ 60077aded6ba51f01335840ce8e18b413067810b68eIan Armstrong if (mode == OUT_YUV && s->q_full.length == 0 && itv->dma_data_req_size) { 60177aded6ba51f01335840ce8e18b413067810b68eIan Armstrong while (count >= itv->dma_data_req_size) { 6022e668962a54b64f3daffb8eef3ca538e25324d1aIan Armstrong rc = ivtv_yuv_udma_stream_frame(itv, (void __user *)user_buf); 6032e668962a54b64f3daffb8eef3ca538e25324d1aIan Armstrong 6042e668962a54b64f3daffb8eef3ca538e25324d1aIan Armstrong if (rc < 0) 6052e668962a54b64f3daffb8eef3ca538e25324d1aIan Armstrong return rc; 6062e668962a54b64f3daffb8eef3ca538e25324d1aIan Armstrong 6072e668962a54b64f3daffb8eef3ca538e25324d1aIan Armstrong bytes_written += itv->dma_data_req_size; 6082e668962a54b64f3daffb8eef3ca538e25324d1aIan Armstrong user_buf += itv->dma_data_req_size; 6092e668962a54b64f3daffb8eef3ca538e25324d1aIan Armstrong count -= itv->dma_data_req_size; 61077aded6ba51f01335840ce8e18b413067810b68eIan Armstrong } 61177aded6ba51f01335840ce8e18b413067810b68eIan Armstrong if (count == 0) { 61277aded6ba51f01335840ce8e18b413067810b68eIan Armstrong IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused); 61377aded6ba51f01335840ce8e18b413067810b68eIan Armstrong return bytes_written; 61477aded6ba51f01335840ce8e18b413067810b68eIan Armstrong } 61577aded6ba51f01335840ce8e18b413067810b68eIan Armstrong } 61677aded6ba51f01335840ce8e18b413067810b68eIan Armstrong 6171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil for (;;) { 6181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Gather buffers */ 6191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil while (q.length - q.bytesused < count && (buf = ivtv_dequeue(s, &s->q_io))) 6201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_enqueue(s, buf, &q); 6211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil while (q.length - q.bytesused < count && (buf = ivtv_dequeue(s, &s->q_free))) { 6221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_enqueue(s, buf, &q); 6231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 6241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (q.buffers) 6251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil break; 6261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (filp->f_flags & O_NONBLOCK) 6271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EAGAIN; 628cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil mutex_unlock(&itv->serialize_lock); 6291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); 6301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* New buffers might have become free before we were added to the waitqueue */ 6311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!s->q_free.buffers) 6321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil schedule(); 6331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil finish_wait(&s->waitq, &wait); 634cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil mutex_lock(&itv->serialize_lock); 6351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (signal_pending(current)) { 6361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_INFO("User stopped %s\n", s->name); 6371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EINTR; 6381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 6391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 6401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 6411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* copy user data into buffers */ 6421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil while ((buf = ivtv_dequeue(s, &q))) { 643c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong /* yuv is a pain. Don't copy more data than needed for a single 644c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong frame, otherwise we lose sync with the incoming stream */ 645c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong if (s->type == IVTV_DEC_STREAM_TYPE_YUV && 646c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong yi->stream_size + count > itv->dma_data_req_size) 647c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong rc = ivtv_buf_copy_from_user(s, buf, user_buf, 648c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong itv->dma_data_req_size - yi->stream_size); 649c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong else 650c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong rc = ivtv_buf_copy_from_user(s, buf, user_buf, count); 6511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 652c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong /* Make sure we really got all the user data */ 6531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (rc < 0) { 6541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_queue_move(s, &q, NULL, &s->q_free, 0); 6551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return rc; 6561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 6571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil user_buf += rc; 6581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil count -= rc; 6591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil bytes_written += rc; 6601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 661c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong if (s->type == IVTV_DEC_STREAM_TYPE_YUV) { 662c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong yi->stream_size += rc; 663c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong /* If we have a complete yuv frame, break loop now */ 664c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong if (yi->stream_size == itv->dma_data_req_size) { 665c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong ivtv_enqueue(s, buf, &s->q_full); 666c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong yi->stream_size = 0; 667c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong break; 668c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong } 669c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong } 670c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong 6711a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (buf->bytesused != s->buf_size) { 6721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* incomplete, leave in q_io for next time */ 6731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_enqueue(s, buf, &s->q_io); 6741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil break; 6751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 6761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Byteswap MPEG buffer */ 6771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s->type == IVTV_DEC_STREAM_TYPE_MPG) 6781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_buf_swap(buf); 6791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_enqueue(s, buf, &s->q_full); 6801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 6811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 6821a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (test_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags)) { 6831a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s->q_full.length >= itv->dma_data_req_size) { 6841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int got_sig; 6851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 68677aded6ba51f01335840ce8e18b413067810b68eIan Armstrong if (mode == OUT_YUV) 68777aded6ba51f01335840ce8e18b413067810b68eIan Armstrong ivtv_yuv_setup_stream_frame(itv); 68877aded6ba51f01335840ce8e18b413067810b68eIan Armstrong 689cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil mutex_unlock(&itv->serialize_lock); 6901a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); 6911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil while (!(got_sig = signal_pending(current)) && 6921a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) { 6931a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil schedule(); 6941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 6951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil finish_wait(&itv->dma_waitq, &wait); 696cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil mutex_lock(&itv->serialize_lock); 6971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (got_sig) { 6981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_INFO("User interrupted %s\n", s->name); 6991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EINTR; 7001a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 7011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 7021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags); 7031a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_queue_move(s, &s->q_full, NULL, &s->q_predma, itv->dma_data_req_size); 7041a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_dma_stream_dec_prepare(s, itv->dma_data_req_offset + IVTV_DECODER_OFFSET, 1); 7051a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 7061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 7071a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* more user data is available, wait until buffers become free 7081a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil to transfer the rest. */ 7091a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (count && !(filp->f_flags & O_NONBLOCK)) 7101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil goto retry; 7111aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused); 7121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return bytes_written; 7131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 7141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 7151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilunsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait) 7161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 717092501936fc128992456a086193746cf34642815Hans Verkuil struct ivtv_open_id *id = fh2id(filp->private_data); 7181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = id->itv; 7191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_stream *s = &itv->streams[id->type]; 7201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int res = 0; 7211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 7221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* add stream's waitq to the poll list */ 7231aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil IVTV_DEBUG_HI_FILE("Decoder poll\n"); 7241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 725092501936fc128992456a086193746cf34642815Hans Verkuil /* If there are subscribed events, then only use the new event 726092501936fc128992456a086193746cf34642815Hans Verkuil API instead of the old video.h based API. */ 727523f46d6aba9dcb0a2d0fc474ca884e93a7cf198Hans Verkuil if (!list_empty(&id->fh.subscribed)) { 728523f46d6aba9dcb0a2d0fc474ca884e93a7cf198Hans Verkuil poll_wait(filp, &id->fh.wait, wait); 729092501936fc128992456a086193746cf34642815Hans Verkuil /* Turn off the old-style vsync events */ 730092501936fc128992456a086193746cf34642815Hans Verkuil clear_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags); 731092501936fc128992456a086193746cf34642815Hans Verkuil if (v4l2_event_pending(&id->fh)) 732092501936fc128992456a086193746cf34642815Hans Verkuil res = POLLPRI; 733092501936fc128992456a086193746cf34642815Hans Verkuil } else { 734092501936fc128992456a086193746cf34642815Hans Verkuil /* This is the old-style API which is here only for backwards 735092501936fc128992456a086193746cf34642815Hans Verkuil compatibility. */ 736092501936fc128992456a086193746cf34642815Hans Verkuil poll_wait(filp, &s->waitq, wait); 737092501936fc128992456a086193746cf34642815Hans Verkuil set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags); 738092501936fc128992456a086193746cf34642815Hans Verkuil if (test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags) || 739092501936fc128992456a086193746cf34642815Hans Verkuil test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags)) 740092501936fc128992456a086193746cf34642815Hans Verkuil res = POLLPRI; 741092501936fc128992456a086193746cf34642815Hans Verkuil } 7421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 7431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Allow write if buffers are available for writing */ 7441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (s->q_free.buffers) 7451a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil res |= POLLOUT | POLLWRNORM; 7461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return res; 7471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 7481a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 7491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilunsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait) 7501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 751092501936fc128992456a086193746cf34642815Hans Verkuil struct ivtv_open_id *id = fh2id(filp->private_data); 7521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = id->itv; 7531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_stream *s = &itv->streams[id->type]; 7541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int eof = test_bit(IVTV_F_S_STREAMOFF, &s->s_flags); 7555138870d68ffbf6fcdf019af5b2ce78bc5a1f837Hans Verkuil unsigned res = 0; 7561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 7571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Start a capture if there is none */ 7581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { 759baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil int rc; 7601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 761baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil rc = ivtv_start_capture(id); 7621a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (rc) { 7631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n", 7641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil s->name, rc); 7651a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return POLLERR; 7661a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 7671aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil IVTV_DEBUG_FILE("Encoder poll started capture\n"); 7681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 7691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 7701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* add stream's waitq to the poll list */ 7711aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil IVTV_DEBUG_HI_FILE("Encoder poll\n"); 7721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil poll_wait(filp, &s->waitq, wait); 7735138870d68ffbf6fcdf019af5b2ce78bc5a1f837Hans Verkuil if (v4l2_event_pending(&id->fh)) 7745138870d68ffbf6fcdf019af5b2ce78bc5a1f837Hans Verkuil res |= POLLPRI; 7755138870d68ffbf6fcdf019af5b2ce78bc5a1f837Hans Verkuil else 776523f46d6aba9dcb0a2d0fc474ca884e93a7cf198Hans Verkuil poll_wait(filp, &id->fh.wait, wait); 7771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 77816928be301b0881f7b7afcf95e0ee7dc3214de8dHans Verkuil if (s->q_full.length || s->q_io.length) 7795138870d68ffbf6fcdf019af5b2ce78bc5a1f837Hans Verkuil return res | POLLIN | POLLRDNORM; 78016928be301b0881f7b7afcf95e0ee7dc3214de8dHans Verkuil if (eof) 7815138870d68ffbf6fcdf019af5b2ce78bc5a1f837Hans Verkuil return res | POLLHUP; 7825138870d68ffbf6fcdf019af5b2ce78bc5a1f837Hans Verkuil return res; 7831a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 7841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 7851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilvoid ivtv_stop_capture(struct ivtv_open_id *id, int gop_end) 7861a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 7871a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = id->itv; 7881a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_stream *s = &itv->streams[id->type]; 7891a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 7901aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil IVTV_DEBUG_FILE("close() of %s\n", s->name); 7911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 7921a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* 'Unclaim' this stream */ 7931a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 7941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Stop capturing */ 7951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { 7961a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; 7971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 7981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_INFO("close stopping capture\n"); 7991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Special case: a running VBI capture for VBI insertion 8001a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil in the mpeg stream. Need to stop that too. */ 8011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (id->type == IVTV_ENC_STREAM_TYPE_MPG && 8021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil test_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags) && 8031a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil !test_bit(IVTV_F_S_APPL_IO, &s_vbi->s_flags)) { 8041a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_INFO("close stopping embedded VBI capture\n"); 8051a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_stop_v4l2_encode_stream(s_vbi, 0); 8061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 8071a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if ((id->type == IVTV_DEC_STREAM_TYPE_VBI || 8081a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil id->type == IVTV_ENC_STREAM_TYPE_VBI) && 8091a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) { 8101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Also used internally, don't stop capturing */ 81161bb725ef5a646d3fc8a64e41b020a65542cdae1Hans Verkuil s->fh = NULL; 8121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 8131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil else { 8141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_stop_v4l2_encode_stream(s, gop_end); 8151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 8161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 817559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil if (!gop_end) { 818559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil clear_bit(IVTV_F_S_APPL_IO, &s->s_flags); 819559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); 820559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil ivtv_release_stream(s); 821559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil } 8221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 8231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 82431ec13561060b748221f4e0404bcc5bf8078ccd0Hans Verkuilstatic void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts) 8251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 8261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = id->itv; 8271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_stream *s = &itv->streams[id->type]; 8281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 8291aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil IVTV_DEBUG_FILE("close() of %s\n", s->name); 8301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 831666092c679f7d9eb9f5230087f960a487fda721cIan Armstrong if (id->type == IVTV_DEC_STREAM_TYPE_YUV && 832666092c679f7d9eb9f5230087f960a487fda721cIan Armstrong test_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags)) { 833666092c679f7d9eb9f5230087f960a487fda721cIan Armstrong /* Restore registers we've changed & clean up any mess */ 834666092c679f7d9eb9f5230087f960a487fda721cIan Armstrong ivtv_yuv_close(itv); 835666092c679f7d9eb9f5230087f960a487fda721cIan Armstrong } 836666092c679f7d9eb9f5230087f960a487fda721cIan Armstrong 8371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Stop decoding */ 8381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { 8391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_INFO("close stopping decode\n"); 8401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 8411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_stop_v4l2_decode_stream(s, flags, pts); 842ad8ff0f10b489562012e433acdac92498fe8bdc9Hans Verkuil itv->output_mode = OUT_NONE; 8431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 8441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil clear_bit(IVTV_F_S_APPL_IO, &s->s_flags); 8451a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); 846666092c679f7d9eb9f5230087f960a487fda721cIan Armstrong 847ad8ff0f10b489562012e433acdac92498fe8bdc9Hans Verkuil if (itv->output_mode == OUT_UDMA_YUV && id->yuv_frames) 848cb50f548c0ee9b2aac39743fc4021a7188825a98Ian Armstrong itv->output_mode = OUT_NONE; 8491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 8501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil itv->speed = 0; 851ac4251445d7302697814351f1d9f548f5aa49342Hans Verkuil clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags); 8521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_release_stream(s); 8531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 8541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 855bec43661b1dc0075b7445223ba775674133b164dHans Verkuilint ivtv_v4l2_close(struct file *filp) 8561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 857092501936fc128992456a086193746cf34642815Hans Verkuil struct v4l2_fh *fh = filp->private_data; 858092501936fc128992456a086193746cf34642815Hans Verkuil struct ivtv_open_id *id = fh2id(fh); 8591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = id->itv; 8601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_stream *s = &itv->streams[id->type]; 8611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 8621aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil IVTV_DEBUG_FILE("close %s\n", s->name); 8631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 8643f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil /* Stop radio */ 8653f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil if (id->type == IVTV_ENC_STREAM_TYPE_RAD && 8663f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil v4l2_fh_is_singular_file(filp)) { 8671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Closing radio device, return to TV mode */ 8681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_mute(itv); 8691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Mark that the radio is no longer in use */ 8701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil clear_bit(IVTV_F_I_RADIO_USER, &itv->i_flags); 8711a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Switch tuner to TV */ 872f41737ece472cd803ffb24ac9f5d6fdd1d871341Hans Verkuil ivtv_call_all(itv, core, s_std, itv->std); 8731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Select correct audio input (i.e. TV tuner or Line in) */ 8741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_audio_set_io(itv); 8753ff4ad815c5824ab35375d72ea8fe14fb3230daaHans Verkuil if (itv->hw_flags & IVTV_HW_SAA711X) { 8763ff4ad815c5824ab35375d72ea8fe14fb3230daaHans Verkuil ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq, 8773ff4ad815c5824ab35375d72ea8fe14fb3230daaHans Verkuil SAA7115_FREQ_32_11_MHZ, 0); 878f2100d82b858815848b661d57d7e166341c02e20Hans Verkuil } 8792f7362ef9bc9c41436c7f44212a2dcf12dddffbfHans Verkuil if (atomic_read(&itv->capturing) > 0) { 8802f7362ef9bc9c41436c7f44212a2dcf12dddffbfHans Verkuil /* Undo video mute */ 8812f7362ef9bc9c41436c7f44212a2dcf12dddffbfHans Verkuil ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1, 8823f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute) | 8833f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil (v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8)); 8842f7362ef9bc9c41436c7f44212a2dcf12dddffbfHans Verkuil } 8851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Done! Unmute and continue. */ 8861a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_unmute(itv); 8873f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil } 8883f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil 8893f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil v4l2_fh_del(fh); 8903f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil v4l2_fh_exit(fh); 8913f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil 8923f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil /* Easy case first: this stream was never claimed by us */ 89361bb725ef5a646d3fc8a64e41b020a65542cdae1Hans Verkuil if (s->fh != &id->fh) { 8943f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil kfree(id); 8953f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil return 0; 8963f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil } 8973f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil 8983f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil /* 'Unclaim' this stream */ 8993f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil 9003f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) { 9015a338c38ced1569a2e67e3c163505cc95429d508Hans Verkuil struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT]; 9025a338c38ced1569a2e67e3c163505cc95429d508Hans Verkuil 903da8ec560e3b4e25d73c64a9e08f9f90ebfbfbf7cHans Verkuil ivtv_stop_decoding(id, V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY, 0); 9045a338c38ced1569a2e67e3c163505cc95429d508Hans Verkuil 9055a338c38ced1569a2e67e3c163505cc95429d508Hans Verkuil /* If all output streams are closed, and if the user doesn't have 9062f3a98931f51be6093df7c6cc2633bf238778b7dHans Verkuil IVTV_DEC_STREAM_TYPE_VOUT open, then disable CC on TV-out. */ 9075a338c38ced1569a2e67e3c163505cc95429d508Hans Verkuil if (itv->output_mode == OUT_NONE && !test_bit(IVTV_F_S_APPL_IO, &s_vout->s_flags)) { 9082f3a98931f51be6093df7c6cc2633bf238778b7dHans Verkuil /* disable CC on TV-out */ 9092f3a98931f51be6093df7c6cc2633bf238778b7dHans Verkuil ivtv_disable_cc(itv); 9105a338c38ced1569a2e67e3c163505cc95429d508Hans Verkuil } 9111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } else { 9121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_stop_capture(id, 0); 9131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 9141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil kfree(id); 9151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return 0; 9161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 9171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 918cdc037817cc15caf931cd3476970860d62f1985cHans Verkuilint ivtv_v4l2_open(struct file *filp) 9191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 920914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong struct video_device *vdev = video_devdata(filp); 921cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil struct ivtv_stream *s = video_get_drvdata(vdev); 922baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil struct ivtv *itv = s->itv; 9231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv_open_id *item; 924092501936fc128992456a086193746cf34642815Hans Verkuil int res = 0; 9251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 9261aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil IVTV_DEBUG_FILE("open %s\n", s->name); 927c976bc82339437e840f7dbf0b8c89c09d3fcd75eHans Verkuil 928cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil if (ivtv_init_on_first_open(itv)) { 929cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil IVTV_ERR("Failed to initialize on device %s\n", 930cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil video_device_node_name(vdev)); 931cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil return -ENXIO; 932cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil } 933cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil 934914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong#ifdef CONFIG_VIDEO_ADV_DEBUG 935215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong /* Unless ivtv_fw_debug is set, error out if firmware dead. */ 936914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong if (ivtv_fw_debug) { 937914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong IVTV_WARN("Opening %s with dead firmware lockout disabled\n", 938914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong video_device_node_name(vdev)); 939914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong IVTV_WARN("Selected firmware errors will be ignored\n"); 940215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong } else { 941914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong#else 942215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong if (1) { 943914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong#endif 944215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong res = ivtv_firmware_check(itv, "ivtv_serialized_open"); 945215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong if (res == -EAGAIN) 946215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong res = ivtv_firmware_check(itv, "ivtv_serialized_open"); 947215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong if (res < 0) 948215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong return -EIO; 949215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong } 950914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong 951baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil if (s->type == IVTV_DEC_STREAM_TYPE_MPG && 9521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags)) 9531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EBUSY; 9541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 955baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil if (s->type == IVTV_DEC_STREAM_TYPE_YUV && 9561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_MPG].s_flags)) 9571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EBUSY; 9581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 959baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil if (s->type == IVTV_DEC_STREAM_TYPE_YUV) { 9601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (read_reg(0x82c) == 0) { 9611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_ERR("Tried to open YUV output device but need to send data to mpeg decoder before it can be used\n"); 9621a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* return -ENODEV; */ 9631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 9641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_udma_alloc(itv); 9651a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 9661a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 9671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Allocate memory */ 968092501936fc128992456a086193746cf34642815Hans Verkuil item = kzalloc(sizeof(struct ivtv_open_id), GFP_KERNEL); 9691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (NULL == item) { 9701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_WARN("nomem on v4l2 open\n"); 9711a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -ENOMEM; 9721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 973092501936fc128992456a086193746cf34642815Hans Verkuil v4l2_fh_init(&item->fh, s->vdev); 9741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil item->itv = itv; 975baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil item->type = s->type; 9761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 977092501936fc128992456a086193746cf34642815Hans Verkuil filp->private_data = &item->fh; 9783f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil v4l2_fh_add(&item->fh); 9791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 9803f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil if (item->type == IVTV_ENC_STREAM_TYPE_RAD && 9813f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil v4l2_fh_is_singular_file(filp)) { 9823562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { 9833562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil if (atomic_read(&itv->capturing) > 0) { 9843562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil /* switching to radio while capture is 9853562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil in progress is not polite */ 9863f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil v4l2_fh_del(&item->fh); 987092501936fc128992456a086193746cf34642815Hans Verkuil v4l2_fh_exit(&item->fh); 9883562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil kfree(item); 9893562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil return -EBUSY; 9903562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil } 9913562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil } 9923562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil /* Mark that the radio is being used. */ 9933562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags); 9941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* We have the radio */ 9951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_mute(itv); 9961a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Switch tuner to radio */ 99767ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil ivtv_call_all(itv, tuner, s_radio); 9981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Select the correct audio input (i.e. radio tuner) */ 9991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_audio_set_io(itv); 100067ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil if (itv->hw_flags & IVTV_HW_SAA711X) { 10013ff4ad815c5824ab35375d72ea8fe14fb3230daaHans Verkuil ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq, 10023ff4ad815c5824ab35375d72ea8fe14fb3230daaHans Verkuil SAA7115_FREQ_32_11_MHZ, SAA7115_FREQ_FL_APLL); 1003f2100d82b858815848b661d57d7e166341c02e20Hans Verkuil } 10041a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* Done! Unmute and continue. */ 10051a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_unmute(itv); 10061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 10071a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 10081a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* YUV or MPG Decoding Mode? */ 1009c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong if (s->type == IVTV_DEC_STREAM_TYPE_MPG) { 10101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil clear_bit(IVTV_F_I_DEC_YUV, &itv->i_flags); 1011c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong } else if (s->type == IVTV_DEC_STREAM_TYPE_YUV) { 10121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil set_bit(IVTV_F_I_DEC_YUV, &itv->i_flags); 1013c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong /* For yuv, we need to know the dma size before we start */ 1014c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong itv->dma_data_req_size = 101577aded6ba51f01335840ce8e18b413067810b68eIan Armstrong 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31); 1016c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong itv->yuv_info.stream_size = 0; 1017c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong } 1018baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil return 0; 1019baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil} 1020baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil 10211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilvoid ivtv_mute(struct ivtv *itv) 10221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 10231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (atomic_read(&itv->capturing)) 10241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 1); 10251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_INFO("Mute\n"); 10261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 10271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 10281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilvoid ivtv_unmute(struct ivtv *itv) 10291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 10301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (atomic_read(&itv->capturing)) { 10313562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil ivtv_msleep_timeout(100, 0); 10321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12); 10331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 0); 10341a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 10351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_INFO("Unmute\n"); 10361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 1037