Path: blob/master/drivers/media/video/ivtv/ivtv-fileops.c
17768 views
/*1file operation functions2Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>3Copyright (C) 2004 Chris Kennedy <[email protected]>4Copyright (C) 2005-2007 Hans Verkuil <[email protected]>56This program is free software; you can redistribute it and/or modify7it under the terms of the GNU General Public License as published by8the Free Software Foundation; either version 2 of the License, or9(at your option) any later version.1011This program is distributed in the hope that it will be useful,12but WITHOUT ANY WARRANTY; without even the implied warranty of13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14GNU General Public License for more details.1516You should have received a copy of the GNU General Public License17along with this program; if not, write to the Free Software18Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA19*/2021#include "ivtv-driver.h"22#include "ivtv-fileops.h"23#include "ivtv-i2c.h"24#include "ivtv-queue.h"25#include "ivtv-udma.h"26#include "ivtv-irq.h"27#include "ivtv-vbi.h"28#include "ivtv-mailbox.h"29#include "ivtv-routing.h"30#include "ivtv-streams.h"31#include "ivtv-yuv.h"32#include "ivtv-ioctl.h"33#include "ivtv-cards.h"34#include "ivtv-firmware.h"35#include <media/v4l2-event.h>36#include <media/saa7115.h>3738/* This function tries to claim the stream for a specific file descriptor.39If no one else is using this stream then the stream is claimed and40associated VBI streams are also automatically claimed.41Possible error returns: -EBUSY if someone else has claimed42the stream or 0 on success. */43static int ivtv_claim_stream(struct ivtv_open_id *id, int type)44{45struct ivtv *itv = id->itv;46struct ivtv_stream *s = &itv->streams[type];47struct ivtv_stream *s_vbi;48int vbi_type;4950if (test_and_set_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {51/* someone already claimed this stream */52if (s->id == id->open_id) {53/* yes, this file descriptor did. So that's OK. */54return 0;55}56if (s->id == -1 && (type == IVTV_DEC_STREAM_TYPE_VBI ||57type == IVTV_ENC_STREAM_TYPE_VBI)) {58/* VBI is handled already internally, now also assign59the file descriptor to this stream for external60reading of the stream. */61s->id = id->open_id;62IVTV_DEBUG_INFO("Start Read VBI\n");63return 0;64}65/* someone else is using this stream already */66IVTV_DEBUG_INFO("Stream %d is busy\n", type);67return -EBUSY;68}69s->id = id->open_id;70if (type == IVTV_DEC_STREAM_TYPE_VBI) {71/* Enable reinsertion interrupt */72ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);73}7475/* IVTV_DEC_STREAM_TYPE_MPG needs to claim IVTV_DEC_STREAM_TYPE_VBI,76IVTV_ENC_STREAM_TYPE_MPG needs to claim IVTV_ENC_STREAM_TYPE_VBI77(provided VBI insertion is on and sliced VBI is selected), for all78other streams we're done */79if (type == IVTV_DEC_STREAM_TYPE_MPG) {80vbi_type = IVTV_DEC_STREAM_TYPE_VBI;81} else if (type == IVTV_ENC_STREAM_TYPE_MPG &&82itv->vbi.insert_mpeg && !ivtv_raw_vbi(itv)) {83vbi_type = IVTV_ENC_STREAM_TYPE_VBI;84} else {85return 0;86}87s_vbi = &itv->streams[vbi_type];8889if (!test_and_set_bit(IVTV_F_S_CLAIMED, &s_vbi->s_flags)) {90/* Enable reinsertion interrupt */91if (vbi_type == IVTV_DEC_STREAM_TYPE_VBI)92ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);93}94/* mark that it is used internally */95set_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags);96return 0;97}9899/* This function releases a previously claimed stream. It will take into100account associated VBI streams. */101void ivtv_release_stream(struct ivtv_stream *s)102{103struct ivtv *itv = s->itv;104struct ivtv_stream *s_vbi;105106s->id = -1;107if ((s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type == IVTV_ENC_STREAM_TYPE_VBI) &&108test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {109/* this stream is still in use internally */110return;111}112if (!test_and_clear_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {113IVTV_DEBUG_WARN("Release stream %s not in use!\n", s->name);114return;115}116117ivtv_flush_queues(s);118119/* disable reinsertion interrupt */120if (s->type == IVTV_DEC_STREAM_TYPE_VBI)121ivtv_set_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);122123/* IVTV_DEC_STREAM_TYPE_MPG needs to release IVTV_DEC_STREAM_TYPE_VBI,124IVTV_ENC_STREAM_TYPE_MPG needs to release IVTV_ENC_STREAM_TYPE_VBI,125for all other streams we're done */126if (s->type == IVTV_DEC_STREAM_TYPE_MPG)127s_vbi = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI];128else if (s->type == IVTV_ENC_STREAM_TYPE_MPG)129s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];130else131return;132133/* clear internal use flag */134if (!test_and_clear_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags)) {135/* was already cleared */136return;137}138if (s_vbi->id != -1) {139/* VBI stream still claimed by a file descriptor */140return;141}142/* disable reinsertion interrupt */143if (s_vbi->type == IVTV_DEC_STREAM_TYPE_VBI)144ivtv_set_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);145clear_bit(IVTV_F_S_CLAIMED, &s_vbi->s_flags);146ivtv_flush_queues(s_vbi);147}148149static void ivtv_dualwatch(struct ivtv *itv)150{151struct v4l2_tuner vt;152u32 new_stereo_mode;153const u32 dual = 0x02;154155new_stereo_mode = v4l2_ctrl_g_ctrl(itv->cxhdl.audio_mode);156memset(&vt, 0, sizeof(vt));157ivtv_call_all(itv, tuner, g_tuner, &vt);158if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 && (vt.rxsubchans & V4L2_TUNER_SUB_LANG2))159new_stereo_mode = dual;160161if (new_stereo_mode == itv->dualwatch_stereo_mode)162return;163164IVTV_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x.\n",165itv->dualwatch_stereo_mode, new_stereo_mode);166if (v4l2_ctrl_s_ctrl(itv->cxhdl.audio_mode, new_stereo_mode))167IVTV_DEBUG_INFO("dualwatch: changing stereo flag failed\n");168}169170static void ivtv_update_pgm_info(struct ivtv *itv)171{172u32 wr_idx = (read_enc(itv->pgm_info_offset) - itv->pgm_info_offset - 4) / 24;173int cnt;174int i = 0;175176if (wr_idx >= itv->pgm_info_num) {177IVTV_DEBUG_WARN("Invalid PGM index %d (>= %d)\n", wr_idx, itv->pgm_info_num);178return;179}180cnt = (wr_idx + itv->pgm_info_num - itv->pgm_info_write_idx) % itv->pgm_info_num;181while (i < cnt) {182int idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num;183struct v4l2_enc_idx_entry *e = itv->pgm_info + idx;184u32 addr = itv->pgm_info_offset + 4 + idx * 24;185const int mapping[8] = { -1, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_P, -1,186V4L2_ENC_IDX_FRAME_B, -1, -1, -1 };187// 1=I, 2=P, 4=B188189e->offset = read_enc(addr + 4) + ((u64)read_enc(addr + 8) << 32);190if (e->offset > itv->mpg_data_received) {191break;192}193e->offset += itv->vbi_data_inserted;194e->length = read_enc(addr);195e->pts = read_enc(addr + 16) + ((u64)(read_enc(addr + 20) & 1) << 32);196e->flags = mapping[read_enc(addr + 12) & 7];197i++;198}199itv->pgm_info_write_idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num;200}201202static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block, int *err)203{204struct ivtv *itv = s->itv;205struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];206struct ivtv_buffer *buf;207DEFINE_WAIT(wait);208209*err = 0;210while (1) {211if (s->type == IVTV_ENC_STREAM_TYPE_MPG) {212/* Process pending program info updates and pending VBI data */213ivtv_update_pgm_info(itv);214215if (time_after(jiffies,216itv->dualwatch_jiffies +217msecs_to_jiffies(1000))) {218itv->dualwatch_jiffies = jiffies;219ivtv_dualwatch(itv);220}221222if (test_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags) &&223!test_bit(IVTV_F_S_APPL_IO, &s_vbi->s_flags)) {224while ((buf = ivtv_dequeue(s_vbi, &s_vbi->q_full))) {225/* byteswap and process VBI data */226ivtv_process_vbi_data(itv, buf, s_vbi->dma_pts, s_vbi->type);227ivtv_enqueue(s_vbi, buf, &s_vbi->q_free);228}229}230buf = &itv->vbi.sliced_mpeg_buf;231if (buf->readpos != buf->bytesused) {232return buf;233}234}235236/* do we have leftover data? */237buf = ivtv_dequeue(s, &s->q_io);238if (buf)239return buf;240241/* do we have new data? */242buf = ivtv_dequeue(s, &s->q_full);243if (buf) {244if ((buf->b_flags & IVTV_F_B_NEED_BUF_SWAP) == 0)245return buf;246buf->b_flags &= ~IVTV_F_B_NEED_BUF_SWAP;247if (s->type == IVTV_ENC_STREAM_TYPE_MPG)248/* byteswap MPG data */249ivtv_buf_swap(buf);250else if (s->type != IVTV_DEC_STREAM_TYPE_VBI) {251/* byteswap and process VBI data */252ivtv_process_vbi_data(itv, buf, s->dma_pts, s->type);253}254return buf;255}256257/* return if end of stream */258if (s->type != IVTV_DEC_STREAM_TYPE_VBI && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {259IVTV_DEBUG_INFO("EOS %s\n", s->name);260return NULL;261}262263/* return if file was opened with O_NONBLOCK */264if (non_block) {265*err = -EAGAIN;266return NULL;267}268269/* wait for more data to arrive */270prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);271/* New buffers might have become available before we were added to the waitqueue */272if (!s->q_full.buffers)273schedule();274finish_wait(&s->waitq, &wait);275if (signal_pending(current)) {276/* return if a signal was received */277IVTV_DEBUG_INFO("User stopped %s\n", s->name);278*err = -EINTR;279return NULL;280}281}282}283284static void ivtv_setup_sliced_vbi_buf(struct ivtv *itv)285{286int idx = itv->vbi.inserted_frame % IVTV_VBI_FRAMES;287288itv->vbi.sliced_mpeg_buf.buf = itv->vbi.sliced_mpeg_data[idx];289itv->vbi.sliced_mpeg_buf.bytesused = itv->vbi.sliced_mpeg_size[idx];290itv->vbi.sliced_mpeg_buf.readpos = 0;291}292293static size_t ivtv_copy_buf_to_user(struct ivtv_stream *s, struct ivtv_buffer *buf,294char __user *ubuf, size_t ucount)295{296struct ivtv *itv = s->itv;297size_t len = buf->bytesused - buf->readpos;298299if (len > ucount) len = ucount;300if (itv->vbi.insert_mpeg && s->type == IVTV_ENC_STREAM_TYPE_MPG &&301!ivtv_raw_vbi(itv) && buf != &itv->vbi.sliced_mpeg_buf) {302const char *start = buf->buf + buf->readpos;303const char *p = start + 1;304const u8 *q;305u8 ch = itv->search_pack_header ? 0xba : 0xe0;306int stuffing, i;307308while (start + len > p && (q = memchr(p, 0, start + len - p))) {309p = q + 1;310if ((char *)q + 15 >= buf->buf + buf->bytesused ||311q[1] != 0 || q[2] != 1 || q[3] != ch) {312continue;313}314if (!itv->search_pack_header) {315if ((q[6] & 0xc0) != 0x80)316continue;317if (((q[7] & 0xc0) == 0x80 && (q[9] & 0xf0) == 0x20) ||318((q[7] & 0xc0) == 0xc0 && (q[9] & 0xf0) == 0x30)) {319ch = 0xba;320itv->search_pack_header = 1;321p = q + 9;322}323continue;324}325stuffing = q[13] & 7;326/* all stuffing bytes must be 0xff */327for (i = 0; i < stuffing; i++)328if (q[14 + i] != 0xff)329break;330if (i == stuffing && (q[4] & 0xc4) == 0x44 && (q[12] & 3) == 3 &&331q[14 + stuffing] == 0 && q[15 + stuffing] == 0 &&332q[16 + stuffing] == 1) {333itv->search_pack_header = 0;334len = (char *)q - start;335ivtv_setup_sliced_vbi_buf(itv);336break;337}338}339}340if (copy_to_user(ubuf, (u8 *)buf->buf + buf->readpos, len)) {341IVTV_DEBUG_WARN("copy %zd bytes to user failed for %s\n", len, s->name);342return -EFAULT;343}344/*IVTV_INFO("copied %lld %d %d %d %d %d vbi %d\n", itv->mpg_data_received, len, ucount,345buf->readpos, buf->bytesused, buf->bytesused - buf->readpos - len,346buf == &itv->vbi.sliced_mpeg_buf); */347buf->readpos += len;348if (s->type == IVTV_ENC_STREAM_TYPE_MPG && buf != &itv->vbi.sliced_mpeg_buf)349itv->mpg_data_received += len;350return len;351}352353static ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_count, int non_block)354{355struct ivtv *itv = s->itv;356size_t tot_written = 0;357int single_frame = 0;358359if (atomic_read(&itv->capturing) == 0 && s->id == -1) {360/* shouldn't happen */361IVTV_DEBUG_WARN("Stream %s not initialized before read\n", s->name);362return -EIO;363}364365/* Each VBI buffer is one frame, the v4l2 API says that for VBI the frames should366arrive one-by-one, so make sure we never output more than one VBI frame at a time */367if (s->type == IVTV_DEC_STREAM_TYPE_VBI ||368(s->type == IVTV_ENC_STREAM_TYPE_VBI && !ivtv_raw_vbi(itv)))369single_frame = 1;370371for (;;) {372struct ivtv_buffer *buf;373int rc;374375buf = ivtv_get_buffer(s, non_block, &rc);376/* if there is no data available... */377if (buf == NULL) {378/* if we got data, then return that regardless */379if (tot_written)380break;381/* EOS condition */382if (rc == 0) {383clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);384clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);385ivtv_release_stream(s);386}387/* set errno */388return rc;389}390rc = ivtv_copy_buf_to_user(s, buf, ubuf + tot_written, tot_count - tot_written);391if (buf != &itv->vbi.sliced_mpeg_buf) {392ivtv_enqueue(s, buf, (buf->readpos == buf->bytesused) ? &s->q_free : &s->q_io);393}394else if (buf->readpos == buf->bytesused) {395int idx = itv->vbi.inserted_frame % IVTV_VBI_FRAMES;396itv->vbi.sliced_mpeg_size[idx] = 0;397itv->vbi.inserted_frame++;398itv->vbi_data_inserted += buf->bytesused;399}400if (rc < 0)401return rc;402tot_written += rc;403404if (tot_written == tot_count || single_frame)405break;406}407return tot_written;408}409410static ssize_t ivtv_read_pos(struct ivtv_stream *s, char __user *ubuf, size_t count,411loff_t *pos, int non_block)412{413ssize_t rc = count ? ivtv_read(s, ubuf, count, non_block) : 0;414struct ivtv *itv = s->itv;415416IVTV_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc);417if (rc > 0)418pos += rc;419return rc;420}421422int ivtv_start_capture(struct ivtv_open_id *id)423{424struct ivtv *itv = id->itv;425struct ivtv_stream *s = &itv->streams[id->type];426struct ivtv_stream *s_vbi;427428if (s->type == IVTV_ENC_STREAM_TYPE_RAD ||429s->type == IVTV_DEC_STREAM_TYPE_MPG ||430s->type == IVTV_DEC_STREAM_TYPE_YUV ||431s->type == IVTV_DEC_STREAM_TYPE_VOUT) {432/* you cannot read from these stream types. */433return -EPERM;434}435436/* Try to claim this stream. */437if (ivtv_claim_stream(id, s->type))438return -EBUSY;439440/* This stream does not need to start capturing */441if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {442set_bit(IVTV_F_S_APPL_IO, &s->s_flags);443return 0;444}445446/* If capture is already in progress, then we also have to447do nothing extra. */448if (test_bit(IVTV_F_S_STREAMOFF, &s->s_flags) || test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags)) {449set_bit(IVTV_F_S_APPL_IO, &s->s_flags);450return 0;451}452453/* Start VBI capture if required */454s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];455if (s->type == IVTV_ENC_STREAM_TYPE_MPG &&456test_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags) &&457!test_and_set_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags)) {458/* Note: the IVTV_ENC_STREAM_TYPE_VBI is claimed459automatically when the MPG stream is claimed.460We only need to start the VBI capturing. */461if (ivtv_start_v4l2_encode_stream(s_vbi)) {462IVTV_DEBUG_WARN("VBI capture start failed\n");463464/* Failure, clean up and return an error */465clear_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags);466clear_bit(IVTV_F_S_STREAMING, &s->s_flags);467/* also releases the associated VBI stream */468ivtv_release_stream(s);469return -EIO;470}471IVTV_DEBUG_INFO("VBI insertion started\n");472}473474/* Tell the card to start capturing */475if (!ivtv_start_v4l2_encode_stream(s)) {476/* We're done */477set_bit(IVTV_F_S_APPL_IO, &s->s_flags);478/* Resume a possibly paused encoder */479if (test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))480ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);481return 0;482}483484/* failure, clean up */485IVTV_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);486487/* Note: the IVTV_ENC_STREAM_TYPE_VBI is released488automatically when the MPG stream is released.489We only need to stop the VBI capturing. */490if (s->type == IVTV_ENC_STREAM_TYPE_MPG &&491test_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags)) {492ivtv_stop_v4l2_encode_stream(s_vbi, 0);493clear_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags);494}495clear_bit(IVTV_F_S_STREAMING, &s->s_flags);496ivtv_release_stream(s);497return -EIO;498}499500ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_t * pos)501{502struct ivtv_open_id *id = fh2id(filp->private_data);503struct ivtv *itv = id->itv;504struct ivtv_stream *s = &itv->streams[id->type];505int rc;506507IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name);508509mutex_lock(&itv->serialize_lock);510rc = ivtv_start_capture(id);511mutex_unlock(&itv->serialize_lock);512if (rc)513return rc;514return ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);515}516517int ivtv_start_decoding(struct ivtv_open_id *id, int speed)518{519struct ivtv *itv = id->itv;520struct ivtv_stream *s = &itv->streams[id->type];521int rc;522523if (atomic_read(&itv->decoding) == 0) {524if (ivtv_claim_stream(id, s->type)) {525/* someone else is using this stream already */526IVTV_DEBUG_WARN("start decode, stream already claimed\n");527return -EBUSY;528}529rc = ivtv_start_v4l2_decode_stream(s, 0);530if (rc < 0) {531if (rc == -EAGAIN)532rc = ivtv_start_v4l2_decode_stream(s, 0);533if (rc < 0)534return rc;535}536}537if (s->type == IVTV_DEC_STREAM_TYPE_MPG)538return ivtv_set_speed(itv, speed);539return 0;540}541542ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos)543{544struct ivtv_open_id *id = fh2id(filp->private_data);545struct ivtv *itv = id->itv;546struct ivtv_stream *s = &itv->streams[id->type];547struct yuv_playback_info *yi = &itv->yuv_info;548struct ivtv_buffer *buf;549struct ivtv_queue q;550int bytes_written = 0;551int mode;552int rc;553DEFINE_WAIT(wait);554555IVTV_DEBUG_HI_FILE("write %zd bytes to %s\n", count, s->name);556557if (s->type != IVTV_DEC_STREAM_TYPE_MPG &&558s->type != IVTV_DEC_STREAM_TYPE_YUV &&559s->type != IVTV_DEC_STREAM_TYPE_VOUT)560/* not decoder streams */561return -EPERM;562563/* Try to claim this stream */564if (ivtv_claim_stream(id, s->type))565return -EBUSY;566567/* This stream does not need to start any decoding */568if (s->type == IVTV_DEC_STREAM_TYPE_VOUT) {569int elems = count / sizeof(struct v4l2_sliced_vbi_data);570571set_bit(IVTV_F_S_APPL_IO, &s->s_flags);572return ivtv_write_vbi_from_user(itv,573(const struct v4l2_sliced_vbi_data __user *)user_buf, elems);574}575576mode = s->type == IVTV_DEC_STREAM_TYPE_MPG ? OUT_MPG : OUT_YUV;577578if (ivtv_set_output_mode(itv, mode) != mode) {579ivtv_release_stream(s);580return -EBUSY;581}582ivtv_queue_init(&q);583set_bit(IVTV_F_S_APPL_IO, &s->s_flags);584585/* Start decoder (returns 0 if already started) */586mutex_lock(&itv->serialize_lock);587rc = ivtv_start_decoding(id, itv->speed);588mutex_unlock(&itv->serialize_lock);589if (rc) {590IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name);591592/* failure, clean up */593clear_bit(IVTV_F_S_STREAMING, &s->s_flags);594clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);595return rc;596}597598retry:599/* If possible, just DMA the entire frame - Check the data transfer size600since we may get here before the stream has been fully set-up */601if (mode == OUT_YUV && s->q_full.length == 0 && itv->dma_data_req_size) {602while (count >= itv->dma_data_req_size) {603rc = ivtv_yuv_udma_stream_frame(itv, (void __user *)user_buf);604605if (rc < 0)606return rc;607608bytes_written += itv->dma_data_req_size;609user_buf += itv->dma_data_req_size;610count -= itv->dma_data_req_size;611}612if (count == 0) {613IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused);614return bytes_written;615}616}617618for (;;) {619/* Gather buffers */620while (q.length - q.bytesused < count && (buf = ivtv_dequeue(s, &s->q_io)))621ivtv_enqueue(s, buf, &q);622while (q.length - q.bytesused < count && (buf = ivtv_dequeue(s, &s->q_free))) {623ivtv_enqueue(s, buf, &q);624}625if (q.buffers)626break;627if (filp->f_flags & O_NONBLOCK)628return -EAGAIN;629prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);630/* New buffers might have become free before we were added to the waitqueue */631if (!s->q_free.buffers)632schedule();633finish_wait(&s->waitq, &wait);634if (signal_pending(current)) {635IVTV_DEBUG_INFO("User stopped %s\n", s->name);636return -EINTR;637}638}639640/* copy user data into buffers */641while ((buf = ivtv_dequeue(s, &q))) {642/* yuv is a pain. Don't copy more data than needed for a single643frame, otherwise we lose sync with the incoming stream */644if (s->type == IVTV_DEC_STREAM_TYPE_YUV &&645yi->stream_size + count > itv->dma_data_req_size)646rc = ivtv_buf_copy_from_user(s, buf, user_buf,647itv->dma_data_req_size - yi->stream_size);648else649rc = ivtv_buf_copy_from_user(s, buf, user_buf, count);650651/* Make sure we really got all the user data */652if (rc < 0) {653ivtv_queue_move(s, &q, NULL, &s->q_free, 0);654return rc;655}656user_buf += rc;657count -= rc;658bytes_written += rc;659660if (s->type == IVTV_DEC_STREAM_TYPE_YUV) {661yi->stream_size += rc;662/* If we have a complete yuv frame, break loop now */663if (yi->stream_size == itv->dma_data_req_size) {664ivtv_enqueue(s, buf, &s->q_full);665yi->stream_size = 0;666break;667}668}669670if (buf->bytesused != s->buf_size) {671/* incomplete, leave in q_io for next time */672ivtv_enqueue(s, buf, &s->q_io);673break;674}675/* Byteswap MPEG buffer */676if (s->type == IVTV_DEC_STREAM_TYPE_MPG)677ivtv_buf_swap(buf);678ivtv_enqueue(s, buf, &s->q_full);679}680681if (test_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags)) {682if (s->q_full.length >= itv->dma_data_req_size) {683int got_sig;684685if (mode == OUT_YUV)686ivtv_yuv_setup_stream_frame(itv);687688prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);689while (!(got_sig = signal_pending(current)) &&690test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) {691schedule();692}693finish_wait(&itv->dma_waitq, &wait);694if (got_sig) {695IVTV_DEBUG_INFO("User interrupted %s\n", s->name);696return -EINTR;697}698699clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);700ivtv_queue_move(s, &s->q_full, NULL, &s->q_predma, itv->dma_data_req_size);701ivtv_dma_stream_dec_prepare(s, itv->dma_data_req_offset + IVTV_DECODER_OFFSET, 1);702}703}704/* more user data is available, wait until buffers become free705to transfer the rest. */706if (count && !(filp->f_flags & O_NONBLOCK))707goto retry;708IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused);709return bytes_written;710}711712unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait)713{714struct ivtv_open_id *id = fh2id(filp->private_data);715struct ivtv *itv = id->itv;716struct ivtv_stream *s = &itv->streams[id->type];717int res = 0;718719/* add stream's waitq to the poll list */720IVTV_DEBUG_HI_FILE("Decoder poll\n");721722/* If there are subscribed events, then only use the new event723API instead of the old video.h based API. */724if (!list_empty(&id->fh.events->subscribed)) {725poll_wait(filp, &id->fh.events->wait, wait);726/* Turn off the old-style vsync events */727clear_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);728if (v4l2_event_pending(&id->fh))729res = POLLPRI;730} else {731/* This is the old-style API which is here only for backwards732compatibility. */733poll_wait(filp, &s->waitq, wait);734set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);735if (test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags) ||736test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))737res = POLLPRI;738}739740/* Allow write if buffers are available for writing */741if (s->q_free.buffers)742res |= POLLOUT | POLLWRNORM;743return res;744}745746unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait)747{748struct ivtv_open_id *id = fh2id(filp->private_data);749struct ivtv *itv = id->itv;750struct ivtv_stream *s = &itv->streams[id->type];751int eof = test_bit(IVTV_F_S_STREAMOFF, &s->s_flags);752753/* Start a capture if there is none */754if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {755int rc;756757mutex_lock(&itv->serialize_lock);758rc = ivtv_start_capture(id);759mutex_unlock(&itv->serialize_lock);760if (rc) {761IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n",762s->name, rc);763return POLLERR;764}765IVTV_DEBUG_FILE("Encoder poll started capture\n");766}767768/* add stream's waitq to the poll list */769IVTV_DEBUG_HI_FILE("Encoder poll\n");770poll_wait(filp, &s->waitq, wait);771772if (s->q_full.length || s->q_io.length)773return POLLIN | POLLRDNORM;774if (eof)775return POLLHUP;776return 0;777}778779void ivtv_stop_capture(struct ivtv_open_id *id, int gop_end)780{781struct ivtv *itv = id->itv;782struct ivtv_stream *s = &itv->streams[id->type];783784IVTV_DEBUG_FILE("close() of %s\n", s->name);785786/* 'Unclaim' this stream */787788/* Stop capturing */789if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {790struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];791792IVTV_DEBUG_INFO("close stopping capture\n");793/* Special case: a running VBI capture for VBI insertion794in the mpeg stream. Need to stop that too. */795if (id->type == IVTV_ENC_STREAM_TYPE_MPG &&796test_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags) &&797!test_bit(IVTV_F_S_APPL_IO, &s_vbi->s_flags)) {798IVTV_DEBUG_INFO("close stopping embedded VBI capture\n");799ivtv_stop_v4l2_encode_stream(s_vbi, 0);800}801if ((id->type == IVTV_DEC_STREAM_TYPE_VBI ||802id->type == IVTV_ENC_STREAM_TYPE_VBI) &&803test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {804/* Also used internally, don't stop capturing */805s->id = -1;806}807else {808ivtv_stop_v4l2_encode_stream(s, gop_end);809}810}811if (!gop_end) {812clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);813clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);814ivtv_release_stream(s);815}816}817818static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)819{820struct ivtv *itv = id->itv;821struct ivtv_stream *s = &itv->streams[id->type];822823IVTV_DEBUG_FILE("close() of %s\n", s->name);824825if (id->type == IVTV_DEC_STREAM_TYPE_YUV &&826test_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags)) {827/* Restore registers we've changed & clean up any mess */828ivtv_yuv_close(itv);829}830831/* Stop decoding */832if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {833IVTV_DEBUG_INFO("close stopping decode\n");834835ivtv_stop_v4l2_decode_stream(s, flags, pts);836itv->output_mode = OUT_NONE;837}838clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);839clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);840841if (itv->output_mode == OUT_UDMA_YUV && id->yuv_frames)842itv->output_mode = OUT_NONE;843844itv->speed = 0;845clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);846ivtv_release_stream(s);847}848849int ivtv_v4l2_close(struct file *filp)850{851struct v4l2_fh *fh = filp->private_data;852struct ivtv_open_id *id = fh2id(fh);853struct ivtv *itv = id->itv;854struct ivtv_stream *s = &itv->streams[id->type];855856IVTV_DEBUG_FILE("close %s\n", s->name);857858v4l2_fh_del(fh);859v4l2_fh_exit(fh);860861/* Easy case first: this stream was never claimed by us */862if (s->id != id->open_id) {863kfree(id);864return 0;865}866867/* 'Unclaim' this stream */868869/* Stop radio */870mutex_lock(&itv->serialize_lock);871if (id->type == IVTV_ENC_STREAM_TYPE_RAD) {872/* Closing radio device, return to TV mode */873ivtv_mute(itv);874/* Mark that the radio is no longer in use */875clear_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);876/* Switch tuner to TV */877ivtv_call_all(itv, core, s_std, itv->std);878/* Select correct audio input (i.e. TV tuner or Line in) */879ivtv_audio_set_io(itv);880if (itv->hw_flags & IVTV_HW_SAA711X) {881ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq,882SAA7115_FREQ_32_11_MHZ, 0);883}884if (atomic_read(&itv->capturing) > 0) {885/* Undo video mute */886ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1,887v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute) |888(v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8));889}890/* Done! Unmute and continue. */891ivtv_unmute(itv);892ivtv_release_stream(s);893} else if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) {894struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT];895896ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0);897898/* If all output streams are closed, and if the user doesn't have899IVTV_DEC_STREAM_TYPE_VOUT open, then disable CC on TV-out. */900if (itv->output_mode == OUT_NONE && !test_bit(IVTV_F_S_APPL_IO, &s_vout->s_flags)) {901/* disable CC on TV-out */902ivtv_disable_cc(itv);903}904} else {905ivtv_stop_capture(id, 0);906}907kfree(id);908mutex_unlock(&itv->serialize_lock);909return 0;910}911912static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)913{914#ifdef CONFIG_VIDEO_ADV_DEBUG915struct video_device *vdev = video_devdata(filp);916#endif917struct ivtv *itv = s->itv;918struct ivtv_open_id *item;919int res = 0;920921IVTV_DEBUG_FILE("open %s\n", s->name);922923#ifdef CONFIG_VIDEO_ADV_DEBUG924/* Unless ivtv_fw_debug is set, error out if firmware dead. */925if (ivtv_fw_debug) {926IVTV_WARN("Opening %s with dead firmware lockout disabled\n",927video_device_node_name(vdev));928IVTV_WARN("Selected firmware errors will be ignored\n");929} else {930#else931if (1) {932#endif933res = ivtv_firmware_check(itv, "ivtv_serialized_open");934if (res == -EAGAIN)935res = ivtv_firmware_check(itv, "ivtv_serialized_open");936if (res < 0)937return -EIO;938}939940if (s->type == IVTV_DEC_STREAM_TYPE_MPG &&941test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags))942return -EBUSY;943944if (s->type == IVTV_DEC_STREAM_TYPE_YUV &&945test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_MPG].s_flags))946return -EBUSY;947948if (s->type == IVTV_DEC_STREAM_TYPE_YUV) {949if (read_reg(0x82c) == 0) {950IVTV_ERR("Tried to open YUV output device but need to send data to mpeg decoder before it can be used\n");951/* return -ENODEV; */952}953ivtv_udma_alloc(itv);954}955956/* Allocate memory */957item = kzalloc(sizeof(struct ivtv_open_id), GFP_KERNEL);958if (NULL == item) {959IVTV_DEBUG_WARN("nomem on v4l2 open\n");960return -ENOMEM;961}962v4l2_fh_init(&item->fh, s->vdev);963if (s->type == IVTV_DEC_STREAM_TYPE_YUV ||964s->type == IVTV_DEC_STREAM_TYPE_MPG) {965res = v4l2_event_alloc(&item->fh, 60);966}967if (res < 0) {968v4l2_fh_exit(&item->fh);969kfree(item);970return res;971}972item->itv = itv;973item->type = s->type;974975item->open_id = itv->open_id++;976filp->private_data = &item->fh;977978if (item->type == IVTV_ENC_STREAM_TYPE_RAD) {979/* Try to claim this stream */980if (ivtv_claim_stream(item, item->type)) {981/* No, it's already in use */982v4l2_fh_exit(&item->fh);983kfree(item);984return -EBUSY;985}986987if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {988if (atomic_read(&itv->capturing) > 0) {989/* switching to radio while capture is990in progress is not polite */991ivtv_release_stream(s);992v4l2_fh_exit(&item->fh);993kfree(item);994return -EBUSY;995}996}997/* Mark that the radio is being used. */998set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);999/* We have the radio */1000ivtv_mute(itv);1001/* Switch tuner to radio */1002ivtv_call_all(itv, tuner, s_radio);1003/* Select the correct audio input (i.e. radio tuner) */1004ivtv_audio_set_io(itv);1005if (itv->hw_flags & IVTV_HW_SAA711X) {1006ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq,1007SAA7115_FREQ_32_11_MHZ, SAA7115_FREQ_FL_APLL);1008}1009/* Done! Unmute and continue. */1010ivtv_unmute(itv);1011}10121013/* YUV or MPG Decoding Mode? */1014if (s->type == IVTV_DEC_STREAM_TYPE_MPG) {1015clear_bit(IVTV_F_I_DEC_YUV, &itv->i_flags);1016} else if (s->type == IVTV_DEC_STREAM_TYPE_YUV) {1017set_bit(IVTV_F_I_DEC_YUV, &itv->i_flags);1018/* For yuv, we need to know the dma size before we start */1019itv->dma_data_req_size =10201080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31);1021itv->yuv_info.stream_size = 0;1022}1023v4l2_fh_add(&item->fh);1024return 0;1025}10261027int ivtv_v4l2_open(struct file *filp)1028{1029int res;1030struct ivtv *itv = NULL;1031struct ivtv_stream *s = NULL;1032struct video_device *vdev = video_devdata(filp);10331034s = video_get_drvdata(vdev);1035itv = s->itv;10361037mutex_lock(&itv->serialize_lock);1038if (ivtv_init_on_first_open(itv)) {1039IVTV_ERR("Failed to initialize on device %s\n",1040video_device_node_name(vdev));1041mutex_unlock(&itv->serialize_lock);1042return -ENXIO;1043}1044res = ivtv_serialized_open(s, filp);1045mutex_unlock(&itv->serialize_lock);1046return res;1047}10481049void ivtv_mute(struct ivtv *itv)1050{1051if (atomic_read(&itv->capturing))1052ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 1);1053IVTV_DEBUG_INFO("Mute\n");1054}10551056void ivtv_unmute(struct ivtv *itv)1057{1058if (atomic_read(&itv->capturing)) {1059ivtv_msleep_timeout(100, 0);1060ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12);1061ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 0);1062}1063IVTV_DEBUG_INFO("Unmute\n");1064}106510661067