diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-11-15 13:00:28 -0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-11-15 13:00:28 -0200 |
commit | 491d2fd7bd092c0938f38d7cef3b1d6e4cbcfbc9 (patch) | |
tree | e9d75ebe6bef813a17fbd62f25a8ca3dca1e0532 | |
parent | cc59b40aea72b8d3929a89f65fcabb3b9b5746c4 (diff) | |
parent | 52227110efbe3a7e7b28a0aa7185b126a6d3b9d7 (diff) | |
download | mediapointer-dvb-s2-491d2fd7bd092c0938f38d7cef3b1d6e4cbcfbc9.tar.gz mediapointer-dvb-s2-491d2fd7bd092c0938f38d7cef3b1d6e4cbcfbc9.tar.bz2 |
merge: http://linuxtv.org/hg/~mkrufky/oxford2
From: Mauro Carvalho Chehab <mchehab@infradead.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
30 files changed, 1212 insertions, 250 deletions
diff --git a/linux/drivers/media/common/saa7146_fops.c b/linux/drivers/media/common/saa7146_fops.c index 9b3d5e07f..b0bed2fbb 100644 --- a/linux/drivers/media/common/saa7146_fops.c +++ b/linux/drivers/media/common/saa7146_fops.c @@ -62,7 +62,7 @@ void saa7146_dma_free(struct saa7146_dev *dev,struct videobuf_queue *q, videobuf_waiton(&buf->vb,0,0); videobuf_dma_unmap(q, dma); videobuf_dma_free(dma); - buf->vb.state = STATE_NEEDS_INIT; + buf->vb.state = VIDEOBUF_NEEDS_INIT; } @@ -84,7 +84,7 @@ int saa7146_buffer_queue(struct saa7146_dev *dev, buf->activate(dev,buf,NULL); } else { list_add_tail(&buf->vb.queue,&q->queue); - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; DEB_D(("adding buffer %p to queue. (active buffer present)\n", buf)); } return 0; @@ -175,7 +175,7 @@ void saa7146_buffer_timeout(unsigned long data) spin_lock_irqsave(&dev->slock,flags); if (q->curr) { DEB_D(("timeout on %p\n", q->curr)); - saa7146_buffer_finish(dev,q,STATE_ERROR); + saa7146_buffer_finish(dev,q,VIDEOBUF_ERROR); } /* we don't restart the transfer here like other drivers do. when @@ -367,7 +367,7 @@ static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait) } poll_wait(file, &buf->done, wait); - if (buf->state == STATE_DONE || buf->state == STATE_ERROR) { + if (buf->state == VIDEOBUF_DONE || buf->state == VIDEOBUF_ERROR) { DEB_D(("poll succeeded!\n")); return POLLIN|POLLRDNORM; } diff --git a/linux/drivers/media/common/saa7146_vbi.c b/linux/drivers/media/common/saa7146_vbi.c index 2efee9436..57e441ed3 100644 --- a/linux/drivers/media/common/saa7146_vbi.c +++ b/linux/drivers/media/common/saa7146_vbi.c @@ -206,7 +206,7 @@ static int buffer_activate(struct saa7146_dev *dev, struct saa7146_buf *next) { struct saa7146_vv *vv = dev->vv_data; - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; DEB_VBI(("dev:%p, buf:%p, next:%p\n",dev,buf,next)); saa7146_set_vbi_capture(dev,buf,next); @@ -239,7 +239,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e if (buf->vb.size != size) saa7146_dma_free(dev,q,buf); - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); buf->vb.width = llength; @@ -258,7 +258,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e if (0 != err) return err; } - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; buf->activate = buffer_activate; return 0; @@ -336,7 +336,7 @@ static void vbi_stop(struct saa7146_fh *fh, struct file *file) saa7146_write(dev, MC1, MASK_20); if (vv->vbi_q.curr) { - saa7146_buffer_finish(dev,&vv->vbi_q,STATE_DONE); + saa7146_buffer_finish(dev,&vv->vbi_q,VIDEOBUF_DONE); } videobuf_queue_cancel(&fh->vbi_q); @@ -459,7 +459,7 @@ static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status) /* this must be += 2, one count for each field */ vv->vbi_fieldcount+=2; vv->vbi_q.curr->vb.field_count = vv->vbi_fieldcount; - saa7146_buffer_finish(dev,&vv->vbi_q,STATE_DONE); + saa7146_buffer_finish(dev,&vv->vbi_q,VIDEOBUF_DONE); } else { DEB_VBI(("dev:%p\n",dev)); } diff --git a/linux/drivers/media/common/saa7146_video.c b/linux/drivers/media/common/saa7146_video.c index 67d79a081..afb1b9e7d 100644 --- a/linux/drivers/media/common/saa7146_video.c +++ b/linux/drivers/media/common/saa7146_video.c @@ -1240,7 +1240,7 @@ static int buffer_activate (struct saa7146_dev *dev, { struct saa7146_vv *vv = dev->vv_data; - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; saa7146_set_capture(dev,buf,next); mod_timer(&vv->video_q.timeout, jiffies+BUFFER_TIMEOUT); @@ -1286,7 +1286,7 @@ static int buffer_prepare(struct videobuf_queue *q, saa7146_dma_free(dev,q,buf); } - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { struct saa7146_format *sfmt; buf->vb.bytesperline = fh->video_fmt.bytesperline; @@ -1319,7 +1319,7 @@ static int buffer_prepare(struct videobuf_queue *q, if (err) goto oops; } - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; buf->activate = buffer_activate; return 0; @@ -1441,10 +1441,7 @@ static void video_close(struct saa7146_dev *dev, struct file *file) err = saa7146_stop_preview(fh); } - // release all capture buffers - mutex_lock(&q->lock); - videobuf_read_stop(q); - mutex_unlock(&q->lock); + videobuf_stop(q); /* hmm, why is this function declared void? */ /* return err */ @@ -1461,7 +1458,7 @@ static void video_irq_done(struct saa7146_dev *dev, unsigned long st) /* only finish the buffer if we have one... */ if( NULL != q->curr ) { - saa7146_buffer_finish(dev,q,STATE_DONE); + saa7146_buffer_finish(dev,q,VIDEOBUF_DONE); } saa7146_buffer_next(dev,q,0); diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index 2aaa88dd6..06695c09c 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -1679,7 +1679,7 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh, dprintk("switch_overlay: enter [new=%p]\n",new); if (new) - new->vb.state = STATE_DONE; + new->vb.state = VIDEOBUF_DONE; spin_lock_irqsave(&btv->s_lock,flags); old = btv->screen; btv->screen = new; @@ -1790,7 +1790,7 @@ static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv, } /* alloc risc memory */ - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { redo_dma_risc = 1; if (0 != (rc = videobuf_iolock(q,&buf->vb,&btv->fbuf))) goto fail; @@ -1800,7 +1800,7 @@ static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv, if (0 != (rc = bttv_buffer_risc(btv,buf))) goto fail; - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; return 0; fail: @@ -1839,7 +1839,7 @@ buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) struct bttv_fh *fh = q->priv_data; struct bttv *btv = fh->btv; - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; list_add_tail(&buf->vb.queue,&btv->capture); if (!btv->curr.frame_irq) { btv->loop_irq |= 1; @@ -3145,8 +3145,8 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) } poll_wait(file, &buf->vb.done, wait); - if (buf->vb.state == STATE_DONE || - buf->vb.state == STATE_ERROR) + if (buf->vb.state == VIDEOBUF_DONE || + buf->vb.state == VIDEOBUF_ERROR) return POLLIN|POLLRDNORM; return 0; } @@ -3251,10 +3251,7 @@ static int bttv_release(struct inode *inode, struct file *file) /* stop vbi capture */ if (check_btres(fh, RESOURCE_VBI)) { - if (fh->vbi.streaming) - videobuf_streamoff(&fh->vbi); - if (fh->vbi.reading) - videobuf_read_stop(&fh->vbi); + videobuf_stop(&fh->vbi); free_btres(btv,fh,RESOURCE_VBI); } @@ -3747,20 +3744,20 @@ static void bttv_irq_timeout(unsigned long data) bttv_set_dma(btv, 0); /* wake up */ - bttv_irq_wakeup_video(btv, &old, &new, STATE_ERROR); - bttv_irq_wakeup_vbi(btv, ovbi, STATE_ERROR); + bttv_irq_wakeup_video(btv, &old, &new, VIDEOBUF_ERROR); + bttv_irq_wakeup_vbi(btv, ovbi, VIDEOBUF_ERROR); /* cancel all outstanding capture / vbi requests */ while (!list_empty(&btv->capture)) { item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue); list_del(&item->vb.queue); - item->vb.state = STATE_ERROR; + item->vb.state = VIDEOBUF_ERROR; wake_up(&item->vb.done); } while (!list_empty(&btv->vcapture)) { item = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue); list_del(&item->vb.queue); - item->vb.state = STATE_ERROR; + item->vb.state = VIDEOBUF_ERROR; wake_up(&item->vb.done); } @@ -3783,7 +3780,7 @@ bttv_irq_wakeup_top(struct bttv *btv) do_gettimeofday(&wakeup->vb.ts); wakeup->vb.field_count = btv->field_count; - wakeup->vb.state = STATE_DONE; + wakeup->vb.state = VIDEOBUF_DONE; wake_up(&wakeup->vb.done); spin_unlock(&btv->s_lock); } @@ -3832,7 +3829,7 @@ bttv_irq_switch_video(struct bttv *btv) } /* wake up finished buffers */ - bttv_irq_wakeup_video(btv, &old, &new, STATE_DONE); + bttv_irq_wakeup_video(btv, &old, &new, VIDEOBUF_DONE); spin_unlock(&btv->s_lock); } @@ -3865,7 +3862,7 @@ bttv_irq_switch_vbi(struct bttv *btv) bttv_buffer_activate_vbi(btv, new); bttv_set_dma(btv, 0); - bttv_irq_wakeup_vbi(btv, old, STATE_DONE); + bttv_irq_wakeup_vbi(btv, old, VIDEOBUF_DONE); spin_unlock(&btv->s_lock); } diff --git a/linux/drivers/media/video/bt8xx/bttv-risc.c b/linux/drivers/media/video/bt8xx/bttv-risc.c index cc8b1bcf2..a064f4ee9 100644 --- a/linux/drivers/media/video/bt8xx/bttv-risc.c +++ b/linux/drivers/media/video/bt8xx/bttv-risc.c @@ -586,7 +586,7 @@ bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf videobuf_dma_free(dma); btcx_riscmem_free(btv->c.pci,&buf->bottom); btcx_riscmem_free(btv->c.pci,&buf->top); - buf->vb.state = STATE_NEEDS_INIT; + buf->vb.state = VIDEOBUF_NEEDS_INIT; } int @@ -606,7 +606,7 @@ bttv_buffer_activate_vbi(struct bttv *btv, if (vbi) { unsigned int crop, vdelay; - vbi->vb.state = STATE_ACTIVE; + vbi->vb.state = VIDEOBUF_ACTIVE; list_del(&vbi->vb.queue); /* VDELAY is start of video, end of VBI capturing. */ @@ -648,12 +648,12 @@ bttv_buffer_activate_video(struct bttv *btv, /* video capture */ if (NULL != set->top && NULL != set->bottom) { if (set->top == set->bottom) { - set->top->vb.state = STATE_ACTIVE; + set->top->vb.state = VIDEOBUF_ACTIVE; if (set->top->vb.queue.next) list_del(&set->top->vb.queue); } else { - set->top->vb.state = STATE_ACTIVE; - set->bottom->vb.state = STATE_ACTIVE; + set->top->vb.state = VIDEOBUF_ACTIVE; + set->bottom->vb.state = VIDEOBUF_ACTIVE; if (set->top->vb.queue.next) list_del(&set->top->vb.queue); if (set->bottom->vb.queue.next) @@ -670,7 +670,7 @@ bttv_buffer_activate_video(struct bttv *btv, btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05), ~0x0f, BT848_COLOR_CTL); } else if (NULL != set->top) { - set->top->vb.state = STATE_ACTIVE; + set->top->vb.state = VIDEOBUF_ACTIVE; if (set->top->vb.queue.next) list_del(&set->top->vb.queue); bttv_apply_geo(btv, &set->top->geo,1); @@ -681,7 +681,7 @@ bttv_buffer_activate_video(struct bttv *btv, btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT); btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL); } else if (NULL != set->bottom) { - set->bottom->vb.state = STATE_ACTIVE; + set->bottom->vb.state = VIDEOBUF_ACTIVE; if (set->bottom->vb.queue.next) list_del(&set->bottom->vb.queue); bttv_apply_geo(btv, &set->bottom->geo,1); diff --git a/linux/drivers/media/video/bt8xx/bttv-vbi.c b/linux/drivers/media/video/bt8xx/bttv-vbi.c index 346ce019b..b924f05e3 100644 --- a/linux/drivers/media/video/bt8xx/bttv-vbi.c +++ b/linux/drivers/media/video/bt8xx/bttv-vbi.c @@ -142,7 +142,7 @@ static int vbi_buffer_prepare(struct videobuf_queue *q, redo_dma_risc = 1; } - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { redo_dma_risc = 1; if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL))) goto fail; @@ -189,7 +189,7 @@ static int vbi_buffer_prepare(struct videobuf_queue *q, /* For bttv_buffer_activate_vbi(). */ buf->geo.vdelay = min_vdelay; - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; buf->vb.field = field; dprintk("buf prepare %p: top=%p bottom=%p field=%s\n", vb, &buf->top, &buf->bottom, @@ -209,7 +209,7 @@ vbi_buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); dprintk("queue %p\n",vb); - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; list_add_tail(&buf->vb.queue,&btv->vcapture); if (NULL == btv->cvbi) { fh->btv->loop_irq |= 4; diff --git a/linux/drivers/media/video/cx23885/cx23885-core.c b/linux/drivers/media/video/cx23885/cx23885-core.c index 5422482dc..205b7b594 100644 --- a/linux/drivers/media/video/cx23885/cx23885-core.c +++ b/linux/drivers/media/video/cx23885/cx23885-core.c @@ -379,7 +379,7 @@ static void cx23885_wakeup(struct cx23885_tsport *port, do_gettimeofday(&buf->vb.ts); dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.i, count, buf->count); - buf->vb.state = STATE_DONE; + buf->vb.state = VIDEOBUF_DONE; list_del(&buf->vb.queue); wake_up(&buf->vb.done); } @@ -1014,7 +1014,7 @@ void cx23885_free_buffer(struct videobuf_queue *q, struct cx23885_buffer *buf) videobuf_dma_unmap(q, dma); videobuf_dma_free(dma); btcx_riscmem_free((struct pci_dev *)q->dev, &buf->risc); - buf->vb.state = STATE_NEEDS_INIT; + buf->vb.state = VIDEOBUF_NEEDS_INIT; } static int cx23885_start_dma(struct cx23885_tsport *port, @@ -1117,7 +1117,7 @@ static int cx23885_restart_queue(struct cx23885_tsport *port, list_del(&buf->vb.queue); list_add_tail(&buf->vb.queue, &q->active); cx23885_start_dma(port, q, buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); dprintk(5, "[%p/%d] restart_queue - first active\n", @@ -1128,7 +1128,7 @@ static int cx23885_restart_queue(struct cx23885_tsport *port, prev->fmt == buf->fmt) { list_del(&buf->vb.queue); list_add_tail(&buf->vb.queue, &q->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */ @@ -1165,7 +1165,7 @@ int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port, if (0 != buf->vb.baddr && buf->vb.bsize < size) return -EINVAL; - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { buf->vb.width = port->ts_packet_size; buf->vb.height = port->ts_packet_count; buf->vb.size = size; @@ -1177,7 +1177,7 @@ int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port, videobuf_to_dma(&buf->vb)->sglist, buf->vb.width, buf->vb.height); } - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; return 0; fail: @@ -1200,7 +1200,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) dprintk( 1, "queue is empty - first active\n" ); list_add_tail(&buf->vb.queue, &cx88q->active); cx23885_start_dma(port, cx88q, buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = cx88q->count++; mod_timer(&cx88q->timeout, jiffies + BUFFER_TIMEOUT); dprintk(1, "[%p/%d] %s - first active\n", @@ -1210,7 +1210,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) prev = list_entry(cx88q->active.prev, struct cx23885_buffer, vb.queue); list_add_tail(&buf->vb.queue, &cx88q->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = cx88q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */ @@ -1234,7 +1234,7 @@ static void do_cancel_buffers(struct cx23885_tsport *port, char *reason, buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue); list_del(&buf->vb.queue); - buf->vb.state = STATE_ERROR; + buf->vb.state = VIDEOBUF_ERROR; wake_up(&buf->vb.done); dprintk(1, "[%p/%d] %s - dma=0x%08lx\n", buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); diff --git a/linux/drivers/media/video/cx88/cx88-alsa.c b/linux/drivers/media/video/cx88/cx88-alsa.c index 4275f26e3..f5d65f675 100644 --- a/linux/drivers/media/video/cx88/cx88-alsa.c +++ b/linux/drivers/media/video/cx88/cx88-alsa.c @@ -470,7 +470,7 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream, buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP|RISC_IRQ1|RISC_CNT_INC); buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; chip->buf = buf; chip->dma_risc = dma; diff --git a/linux/drivers/media/video/cx88/cx88-blackbird.c b/linux/drivers/media/video/cx88/cx88-blackbird.c index 1d729dbde..d9b49275c 100644 --- a/linux/drivers/media/video/cx88/cx88-blackbird.c +++ b/linux/drivers/media/video/cx88/cx88-blackbird.c @@ -1111,10 +1111,7 @@ static int mpeg_release(struct inode *inode, struct file *file) cx8802_cancel_buffers(fh->dev); /* stop mpeg capture */ - if (fh->mpegq.streaming) - videobuf_streamoff(&fh->mpegq); - if (fh->mpegq.reading) - videobuf_read_stop(&fh->mpegq); + videobuf_stop(&fh->mpegq); videobuf_mmap_free(&fh->mpegq); file->private_data = NULL; diff --git a/linux/drivers/media/video/cx88/cx88-core.c b/linux/drivers/media/video/cx88/cx88-core.c index e3885a4d1..b67aa65e5 100644 --- a/linux/drivers/media/video/cx88/cx88-core.c +++ b/linux/drivers/media/video/cx88/cx88-core.c @@ -223,7 +223,7 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf) videobuf_dma_unmap(q, dma); videobuf_dma_free(dma); btcx_riscmem_free((struct pci_dev *)q->dev, &buf->risc); - buf->vb.state = STATE_NEEDS_INIT; + buf->vb.state = VIDEOBUF_NEEDS_INIT; } /* ------------------------------------------------------------------ */ @@ -565,7 +565,7 @@ void cx88_wakeup(struct cx88_core *core, do_gettimeofday(&buf->vb.ts); dprintk(2,"[%p/%d] wakeup reg=%d buf=%d\n",buf,buf->vb.i, count, buf->count); - buf->vb.state = STATE_DONE; + buf->vb.state = VIDEOBUF_DONE; list_del(&buf->vb.queue); wake_up(&buf->vb.done); } diff --git a/linux/drivers/media/video/cx88/cx88-mpeg.c b/linux/drivers/media/video/cx88/cx88-mpeg.c index afc3b30b5..e03f15ea9 100644 --- a/linux/drivers/media/video/cx88/cx88-mpeg.c +++ b/linux/drivers/media/video/cx88/cx88-mpeg.c @@ -227,7 +227,7 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, list_del(&buf->vb.queue); list_add_tail(&buf->vb.queue,&q->active); cx8802_start_dma(dev, q, buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); dprintk(1,"[%p/%d] restart_queue - first active\n", @@ -238,7 +238,7 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, prev->fmt == buf->fmt) { list_del(&buf->vb.queue); list_add_tail(&buf->vb.queue,&q->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk(1,"[%p/%d] restart_queue - move to active\n", @@ -274,7 +274,7 @@ int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev, if (0 != buf->vb.baddr && buf->vb.bsize < size) return -EINVAL; - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { buf->vb.width = dev->ts_packet_size; buf->vb.height = dev->ts_packet_count; buf->vb.size = size; @@ -286,7 +286,7 @@ int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev, dma->sglist, buf->vb.width, buf->vb.height, 0); } - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; return 0; fail: @@ -308,7 +308,7 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) dprintk( 1, "queue is empty - first active\n" ); list_add_tail(&buf->vb.queue,&cx88q->active); cx8802_start_dma(dev, cx88q, buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = cx88q->count++; mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT); dprintk(1,"[%p/%d] %s - first active\n", @@ -321,7 +321,7 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) dprintk( 1, "queue is not empty - append to active\n" ); prev = list_entry(cx88q->active.prev, struct cx88_buffer, vb.queue); list_add_tail(&buf->vb.queue,&cx88q->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = cx88q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk( 1, "[%p/%d] %s - append to active\n", @@ -344,7 +344,7 @@ static void do_cancel_buffers(struct cx8802_dev *dev, char *reason, int restart) while (!list_empty(&q->active)) { buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); list_del(&buf->vb.queue); - buf->vb.state = STATE_ERROR; + buf->vb.state = VIDEOBUF_ERROR; wake_up(&buf->vb.done); dprintk(1,"[%p/%d] %s - dma=0x%08lx\n", buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); diff --git a/linux/drivers/media/video/cx88/cx88-vbi.c b/linux/drivers/media/video/cx88/cx88-vbi.c index babb08556..d96ecfcf3 100644 --- a/linux/drivers/media/video/cx88/cx88-vbi.c +++ b/linux/drivers/media/video/cx88/cx88-vbi.c @@ -130,7 +130,7 @@ void cx8800_vbi_timeout(unsigned long data) while (!list_empty(&q->active)) { buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); list_del(&buf->vb.queue); - buf->vb.state = STATE_ERROR; + buf->vb.state = VIDEOBUF_ERROR; wake_up(&buf->vb.done); printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", dev->core->name, buf, buf->vb.i, (unsigned long)buf->risc.dma); @@ -168,7 +168,7 @@ vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, if (0 != buf->vb.baddr && buf->vb.bsize < size) return -EINVAL; - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); buf->vb.width = VBI_LINE_LENGTH; buf->vb.height = VBI_LINE_COUNT; @@ -183,7 +183,7 @@ vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, buf->vb.width, 0, buf->vb.height); } - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; return 0; fail: @@ -207,7 +207,7 @@ vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) if (list_empty(&q->active)) { list_add_tail(&buf->vb.queue,&q->active); cx8800_start_vbi_dma(dev, q, buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); dprintk(2,"[%p/%d] vbi_queue - first active\n", @@ -216,7 +216,7 @@ vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) } else { prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue); list_add_tail(&buf->vb.queue,&q->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk(2,"[%p/%d] buffer_queue - append to active\n", diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c index dbbcb212f..14b026820 100644 --- a/linux/drivers/media/video/cx88/cx88-video.c +++ b/linux/drivers/media/video/cx88/cx88-video.c @@ -502,7 +502,7 @@ static int restart_video_queue(struct cx8800_dev *dev, if (NULL == prev) { list_move_tail(&buf->vb.queue, &q->active); start_video_dma(dev, q, buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); dprintk(2,"[%p/%d] restart_queue - first active\n", @@ -512,7 +512,7 @@ static int restart_video_queue(struct cx8800_dev *dev, prev->vb.height == buf->vb.height && prev->fmt == buf->fmt) { list_move_tail(&buf->vb.queue, &q->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk(2,"[%p/%d] restart_queue - move to active\n", @@ -569,7 +569,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, init_buffer = 1; } - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { init_buffer = 1; if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL))) goto fail; @@ -617,7 +617,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, fh->width, fh->height, fh->fmt->depth, fh->fmt->name, (unsigned long)buf->risc.dma); - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; return 0; fail: @@ -641,14 +641,14 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) if (!list_empty(&q->queued)) { list_add_tail(&buf->vb.queue,&q->queued); - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; dprintk(2,"[%p/%d] buffer_queue - append to queued\n", buf, buf->vb.i); } else if (list_empty(&q->active)) { list_add_tail(&buf->vb.queue,&q->active); start_video_dma(dev, q, buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); dprintk(2,"[%p/%d] buffer_queue - first active\n", @@ -660,7 +660,7 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) prev->vb.height == buf->vb.height && prev->fmt == buf->fmt) { list_add_tail(&buf->vb.queue,&q->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk(2,"[%p/%d] buffer_queue - append to active\n", @@ -668,7 +668,7 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) } else { list_add_tail(&buf->vb.queue,&q->queued); - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; dprintk(2,"[%p/%d] buffer_queue - first queued\n", buf, buf->vb.i); } @@ -1063,8 +1063,8 @@ video_poll(struct file *file, struct poll_table_struct *wait) return POLLERR; } poll_wait(file, &buf->vb.done, wait); - if (buf->vb.state == STATE_DONE || - buf->vb.state == STATE_ERROR) + if (buf->vb.state == VIDEOBUF_DONE || + buf->vb.state == VIDEOBUF_ERROR) return POLLIN|POLLRDNORM; return 0; } @@ -1092,10 +1092,7 @@ static int video_release(struct inode *inode, struct file *file) /* stop vbi capture */ if (res_check(fh, RESOURCE_VBI)) { - if (fh->vbiq.streaming) - videobuf_streamoff(&fh->vbiq); - if (fh->vbiq.reading) - videobuf_read_stop(&fh->vbiq); + videobuf_stop(&fh->vbiq); res_free(dev,fh,RESOURCE_VBI); } @@ -1780,7 +1777,7 @@ static void cx8800_vid_timeout(unsigned long data) while (!list_empty(&q->active)) { buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); list_del(&buf->vb.queue); - buf->vb.state = STATE_ERROR; + buf->vb.state = VIDEOBUF_ERROR; wake_up(&buf->vb.done); printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", core->name, buf, buf->vb.i, (unsigned long)buf->risc.dma); diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c index d39005392..b8b8977fe 100644 --- a/linux/drivers/media/video/saa7134/saa7134-core.c +++ b/linux/drivers/media/video/saa7134/saa7134-core.c @@ -376,7 +376,7 @@ void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf) videobuf_waiton(&buf->vb,0,0); videobuf_dma_unmap(q, dma); videobuf_dma_free(dma); - buf->vb.state = STATE_NEEDS_INIT; + buf->vb.state = VIDEOBUF_NEEDS_INIT; } /* ------------------------------------------------------------------ */ @@ -395,7 +395,7 @@ int saa7134_buffer_queue(struct saa7134_dev *dev, buf->activate(dev,buf,NULL); } else if (list_empty(&q->queue)) { list_add_tail(&buf->vb.queue,&q->queue); - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; } else { next = list_entry(q->queue.next,struct saa7134_buf, vb.queue); @@ -404,7 +404,7 @@ int saa7134_buffer_queue(struct saa7134_dev *dev, } } else { list_add_tail(&buf->vb.queue,&q->queue); - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; } return 0; } @@ -469,7 +469,7 @@ void saa7134_buffer_timeout(unsigned long data) try to start over with the next one. */ if (q->curr) { dprintk("timeout on %p\n",q->curr); - saa7134_buffer_finish(dev,q,STATE_ERROR); + saa7134_buffer_finish(dev,q,VIDEOBUF_ERROR); } saa7134_buffer_next(dev,q); spin_unlock_irqrestore(&dev->slock,flags); diff --git a/linux/drivers/media/video/saa7134/saa7134-empress.c b/linux/drivers/media/video/saa7134/saa7134-empress.c index 9cf861614..5fe8f5320 100644 --- a/linux/drivers/media/video/saa7134/saa7134-empress.c +++ b/linux/drivers/media/video/saa7134/saa7134-empress.c @@ -119,11 +119,8 @@ static int ts_release(struct inode *inode, struct file *file) { struct saa7134_dev *dev = file->private_data; - if (dev->empress_tsq.streaming) - videobuf_streamoff(&dev->empress_tsq); mutex_lock(&dev->empress_tsq.lock); - if (dev->empress_tsq.reading) - videobuf_read_stop(&dev->empress_tsq); + videobuf_stop(&dev->empress_tsq); videobuf_mmap_free(&dev->empress_tsq); dev->empress_users--; diff --git a/linux/drivers/media/video/saa7134/saa7134-ts.c b/linux/drivers/media/video/saa7134/saa7134-ts.c index 4b63ad3e8..f1b8fcaeb 100644 --- a/linux/drivers/media/video/saa7134/saa7134-ts.c +++ b/linux/drivers/media/video/saa7134/saa7134-ts.c @@ -47,7 +47,7 @@ static int buffer_activate(struct saa7134_dev *dev, { dprintk("buffer_activate [%p]",buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->top_seen = 0; if (NULL == next) @@ -91,7 +91,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, saa7134_dma_free(q,buf); } - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); buf->vb.width = llength; @@ -121,7 +121,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE); saa_writel(SAA7134_RS_CONTROL(5),control); - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; buf->activate = buffer_activate; buf->vb.field = field; return 0; @@ -242,7 +242,7 @@ void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status) if ((status & 0x100000) != 0x100000) goto done; } - saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE); + saa7134_buffer_finish(dev,&dev->ts_q,VIDEOBUF_DONE); } saa7134_buffer_next(dev,&dev->ts_q); diff --git a/linux/drivers/media/video/saa7134/saa7134-vbi.c b/linux/drivers/media/video/saa7134/saa7134-vbi.c index 52f1ce90e..6abaa70d2 100644 --- a/linux/drivers/media/video/saa7134/saa7134-vbi.c +++ b/linux/drivers/media/video/saa7134/saa7134-vbi.c @@ -85,7 +85,7 @@ static int buffer_activate(struct saa7134_dev *dev, unsigned long control,base; dprintk("buffer_activate [%p]\n",buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->top_seen = 0; task_init(dev,buf,TASK_A); @@ -142,7 +142,7 @@ static int buffer_prepare(struct videobuf_queue *q, if (buf->vb.size != size) saa7134_dma_free(q,buf); - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); buf->vb.width = llength; @@ -160,7 +160,7 @@ static int buffer_prepare(struct videobuf_queue *q, if (err) goto oops; } - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; buf->activate = buffer_activate; buf->vb.field = field; return 0; @@ -252,7 +252,7 @@ void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status) goto done; dev->vbi_q.curr->vb.field_count = dev->vbi_fieldcount; - saa7134_buffer_finish(dev,&dev->vbi_q,STATE_DONE); + saa7134_buffer_finish(dev,&dev->vbi_q,VIDEOBUF_DONE); } saa7134_buffer_next(dev,&dev->vbi_q); diff --git a/linux/drivers/media/video/saa7134/saa7134-video.c b/linux/drivers/media/video/saa7134/saa7134-video.c index 82fd1c7ac..b8523aa91 100644 --- a/linux/drivers/media/video/saa7134/saa7134-video.c +++ b/linux/drivers/media/video/saa7134/saa7134-video.c @@ -945,7 +945,7 @@ static int buffer_activate(struct saa7134_dev *dev, unsigned long bpl_uv,lines_uv,base2,base3,tmp; /* planar */ dprintk("buffer_activate buf=%p\n",buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->top_seen = 0; set_size(dev,TASK_A,buf->vb.width,buf->vb.height, @@ -1054,7 +1054,7 @@ static int buffer_prepare(struct videobuf_queue *q, saa7134_dma_free(q,buf); } - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); buf->vb.width = fh->width; @@ -1074,7 +1074,7 @@ static int buffer_prepare(struct videobuf_queue *q, if (err) goto oops; } - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; buf->activate = buffer_activate; return 0; @@ -1421,8 +1421,8 @@ video_poll(struct file *file, struct poll_table_struct *wait) return POLLERR; poll_wait(file, &buf->done, wait); - if (buf->state == STATE_DONE || - buf->state == STATE_ERROR) + if (buf->state == VIDEOBUF_DONE || + buf->state == VIDEOBUF_ERROR) return POLLIN|POLLRDNORM; return 0; } @@ -1453,10 +1453,7 @@ static int video_release(struct inode *inode, struct file *file) /* stop vbi capture */ if (res_check(fh, RESOURCE_VBI)) { - if (fh->vbi.streaming) - videobuf_streamoff(&fh->vbi); - if (fh->vbi.reading) - videobuf_read_stop(&fh->vbi); + videobuf_stop(&fh->vbi); res_free(dev,fh,RESOURCE_VBI); } @@ -2533,7 +2530,7 @@ void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status) goto done; } dev->video_q.curr->vb.field_count = dev->video_fieldcount; - saa7134_buffer_finish(dev,&dev->video_q,STATE_DONE); + saa7134_buffer_finish(dev,&dev->video_q,VIDEOBUF_DONE); } saa7134_buffer_next(dev,&dev->video_q); diff --git a/linux/drivers/media/video/tuner-xc2028-types.h b/linux/drivers/media/video/tuner-xc2028-types.h index f6695d413..388884491 100644 --- a/linux/drivers/media/video/tuner-xc2028-types.h +++ b/linux/drivers/media/video/tuner-xc2028-types.h @@ -88,7 +88,7 @@ #define V4L2_STD_NICAM_B (1L<<35) #define V4L2_STD_AM (1L<<36) #define V4L2_STD_BTSC (1L<<37) -#define V4L2_STD__EIAJ (1L<<38) +#define V4L2_STD_EIAJ (1L<<38) #define V4L2_STD_A2 (V4L2_STD_A2_A | V4L2_STD_A2_B) #define V4L2_STD_NICAM (V4L2_STD_NICAM_A | V4L2_STD_NICAM_B) diff --git a/linux/drivers/media/video/tuner-xc2028.c b/linux/drivers/media/video/tuner-xc2028.c index 3378c8d91..40f785bed 100644 --- a/linux/drivers/media/video/tuner-xc2028.c +++ b/linux/drivers/media/video/tuner-xc2028.c @@ -36,6 +36,20 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable verbose debug messages"); +static char audio_std[8]; +module_param_string(audio_std, audio_std, sizeof(audio_std), 0); +MODULE_PARM_DESC(audio_std, + "Audio standard. XC3028 audio decoder explicitly " + "needs to know what audio\n" + "standard is needed for some video standards with audio A2 or NICAM.\n" + "The valid values are:\n" + "A2\n" + "A2/A\n" + "A2/B\n" + "NICAM\n" + "NICAM/A\n" + "NICAM/B\n"); + static LIST_HEAD(xc2028_list); /* struct for storing firmware table */ struct firmware_description { @@ -192,6 +206,24 @@ void dump_firm_type(unsigned int type) printk("SCODE "); } +static v4l2_std_id parse_audio_std_option(void) +{ + if (strcasecmp(audio_std, "A2")) + return V4L2_STD_A2; + if (strcasecmp(audio_std, "A2/A")) + return V4L2_STD_A2_A; + if (strcasecmp(audio_std, "A2/B")) + return V4L2_STD_A2_B; + if (strcasecmp(audio_std, "NICAM")) + return V4L2_STD_NICAM; + if (strcasecmp(audio_std, "NICAM/A")) + return V4L2_STD_NICAM_A; + if (strcasecmp(audio_std, "NICAM/B")) + return V4L2_STD_NICAM_B; + + return 0; +} + static void free_firmware(struct xc2028_data *priv) { int i; @@ -625,6 +657,9 @@ static int check_firmware(struct dvb_frontend *fe, enum tuner_mode new_mode, return 0; } + /* Add audio hack to std mask */ + std |= parse_audio_std_option(); + rc = load_firmware(fe, type, &std); if (rc < 0) return rc; diff --git a/linux/drivers/media/video/videobuf-core.c b/linux/drivers/media/video/videobuf-core.c index e591e6ca9..ca316dc58 100644 --- a/linux/drivers/media/video/videobuf-core.c +++ b/linux/drivers/media/video/videobuf-core.c @@ -69,14 +69,14 @@ int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr) MAGIC_CHECK(vb->magic,MAGIC_BUFFER); add_wait_queue(&vb->done, &wait); - while (vb->state == STATE_ACTIVE || vb->state == STATE_QUEUED) { + while (vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) { if (non_blocking) { retval = -EAGAIN; break; } set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); - if (vb->state == STATE_ACTIVE || vb->state == STATE_QUEUED) + if (vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) schedule(); set_current_state(TASK_RUNNING); if (intr && signal_pending(current)) { @@ -142,6 +142,7 @@ void videobuf_queue_core_init(struct videobuf_queue* q, INIT_LIST_HEAD(&q->stream); } +/* Locking: Only usage in bttv unsafe find way to remove */ int videobuf_queue_is_busy(struct videobuf_queue *q) { int i; @@ -167,11 +168,11 @@ int videobuf_queue_is_busy(struct videobuf_queue *q) dprintk(1,"busy: buffer #%d mapped\n",i); return 1; } - if (q->bufs[i]->state == STATE_QUEUED) { + if (q->bufs[i]->state == VIDEOBUF_QUEUED) { dprintk(1,"busy: buffer #%d queued\n",i); return 1; } - if (q->bufs[i]->state == STATE_ACTIVE) { + if (q->bufs[i]->state == VIDEOBUF_ACTIVE) { dprintk(1,"busy: buffer #%d avtive\n",i); return 1; } @@ -179,6 +180,7 @@ int videobuf_queue_is_busy(struct videobuf_queue *q) return 0; } +/* Locking: Caller holds q->lock */ void videobuf_queue_cancel(struct videobuf_queue *q) { unsigned long flags=0; @@ -190,9 +192,9 @@ void videobuf_queue_cancel(struct videobuf_queue *q) for (i = 0; i < VIDEO_MAX_FRAME; i++) { if (NULL == q->bufs[i]) continue; - if (q->bufs[i]->state == STATE_QUEUED) { + if (q->bufs[i]->state == VIDEOBUF_QUEUED) { list_del(&q->bufs[i]->queue); - q->bufs[i]->state = STATE_ERROR; + q->bufs[i]->state = VIDEOBUF_ERROR; } } if (q->irqlock) @@ -209,6 +211,7 @@ void videobuf_queue_cancel(struct videobuf_queue *q) /* --------------------------------------------------------------------- */ +/* Locking: Caller holds q->lock */ enum v4l2_field videobuf_next_field(struct videobuf_queue *q) { enum v4l2_field field = q->field; @@ -227,6 +230,7 @@ enum v4l2_field videobuf_next_field(struct videobuf_queue *q) return field; } +/* Locking: Caller holds q->lock */ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, struct videobuf_buffer *vb, enum v4l2_buf_type type) { @@ -256,17 +260,17 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, b->flags |= V4L2_BUF_FLAG_MAPPED; switch (vb->state) { - case STATE_PREPARED: - case STATE_QUEUED: - case STATE_ACTIVE: + case VIDEOBUF_PREPARED: + case VIDEOBUF_QUEUED: + case VIDEOBUF_ACTIVE: b->flags |= V4L2_BUF_FLAG_QUEUED; break; - case STATE_DONE: - case STATE_ERROR: + case VIDEOBUF_DONE: + case VIDEOBUF_ERROR: b->flags |= V4L2_BUF_FLAG_DONE; break; - case STATE_NEEDS_INIT: - case STATE_IDLE: + case VIDEOBUF_NEEDS_INIT: + case VIDEOBUF_IDLE: /* nothing */ break; } @@ -282,20 +286,108 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, b->sequence = vb->field_count >> 1; } +/* Locking: Caller holds q->lock */ +static int __videobuf_mmap_free(struct videobuf_queue *q) +{ + int i; + int rc; + + if (!q) + return 0; + + MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS); + + rc = CALL(q,mmap_free,q); + if (rc<0) + return rc; + + for (i = 0; i < VIDEO_MAX_FRAME; i++) { + if (NULL == q->bufs[i]) + continue; + q->ops->buf_release(q,q->bufs[i]); + kfree(q->bufs[i]); + q->bufs[i] = NULL; + } + + return rc; +} + +int videobuf_mmap_free(struct videobuf_queue *q) +{ + int ret; + mutex_lock(&q->lock); + ret = __videobuf_mmap_free(q); + mutex_unlock(&q->lock); + return ret; +} + +/* Locking: Caller holds q->lock */ +static int __videobuf_mmap_setup(struct videobuf_queue *q, + unsigned int bcount, unsigned int bsize, + enum v4l2_memory memory) +{ + unsigned int i; + int err; + + MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS); + + err = __videobuf_mmap_free(q); + if (0 != err) + return err; + + /* Allocate and initialize buffers */ + for (i = 0; i < bcount; i++) { + q->bufs[i] = videobuf_alloc(q); + + if (q->bufs[i] == NULL) + break; + + q->bufs[i]->i = i; + q->bufs[i]->input = UNSET; + q->bufs[i]->memory = memory; + q->bufs[i]->bsize = bsize; + switch (memory) { + case V4L2_MEMORY_MMAP: + q->bufs[i]->boff = bsize * i; + break; + case V4L2_MEMORY_USERPTR: + case V4L2_MEMORY_OVERLAY: + /* nothing */ + break; + } + } + + if (!i) + return -ENOMEM; + + dprintk(1,"mmap setup: %d buffers, %d bytes each\n", + i, bsize); + + return i; +} + +int videobuf_mmap_setup(struct videobuf_queue *q, + unsigned int bcount, unsigned int bsize, + enum v4l2_memory memory) +{ + int ret; + mutex_lock(&q->lock); + ret = __videobuf_mmap_setup(q, bcount, bsize, memory); + mutex_unlock(&q->lock); + return ret; +} + int videobuf_reqbufs(struct videobuf_queue *q, struct v4l2_requestbuffers *req) { unsigned int size,count; int retval; - if (req->type != q->type) { - dprintk(1,"reqbufs: queue type invalid\n"); - return -EINVAL; - } if (req->count < 1) { dprintk(1,"reqbufs: count invalid (%d)\n",req->count); return -EINVAL; } + if (req->memory != V4L2_MEMORY_MMAP && req->memory != V4L2_MEMORY_USERPTR && req->memory != V4L2_MEMORY_OVERLAY) { @@ -304,6 +396,12 @@ int videobuf_reqbufs(struct videobuf_queue *q, } mutex_lock(&q->lock); + if (req->type != q->type) { + dprintk(1,"reqbufs: queue type invalid\n"); + retval = -EINVAL; + goto done; + } + if (q->streaming) { dprintk(1,"reqbufs: streaming already exists\n"); retval = -EBUSY; @@ -324,7 +422,7 @@ int videobuf_reqbufs(struct videobuf_queue *q, dprintk(1,"reqbufs: bufs=%d, size=0x%x [%d pages total]\n", count, size, (count*size)>>PAGE_SHIFT); - retval = videobuf_mmap_setup(q,count,size,req->memory); + retval = __videobuf_mmap_setup(q,count,size,req->memory); if (retval < 0) { dprintk(1,"reqbufs: mmap setup returned %d\n",retval); goto done; @@ -339,20 +437,28 @@ int videobuf_reqbufs(struct videobuf_queue *q, int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b) { + int ret = -EINVAL; + + mutex_lock(&q->lock); if (unlikely(b->type != q->type)) { dprintk(1,"querybuf: Wrong type.\n"); - return -EINVAL; + goto done; } if (unlikely(b->index < 0 || b->index >= VIDEO_MAX_FRAME)) { dprintk(1,"querybuf: index out of range.\n"); - return -EINVAL; + goto done; } if (unlikely(NULL == q->bufs[b->index])) { dprintk(1,"querybuf: buffer is null.\n"); - return -EINVAL; + goto done; } + videobuf_status(q,b,q->bufs[b->index],q->type); - return 0; + + ret = 0; +done: + mutex_unlock(&q->lock); + return ret; } int videobuf_qbuf(struct videobuf_queue *q, @@ -393,7 +499,7 @@ int videobuf_qbuf(struct videobuf_queue *q, dprintk(1,"qbuf: memory type is wrong.\n"); goto done; } - if (buf->state != STATE_NEEDS_INIT && buf->state != STATE_IDLE) { + if (buf->state != VIDEOBUF_NEEDS_INIT && buf->state != VIDEOBUF_IDLE) { dprintk(1,"qbuf: buffer is already queued or active.\n"); goto done; } @@ -420,7 +526,7 @@ int videobuf_qbuf(struct videobuf_queue *q, dprintk(1,"qbuf: buffer length is not enough\n"); goto done; } - if (STATE_NEEDS_INIT != buf->state && buf->baddr != b->m.userptr) + if (VIDEOBUF_NEEDS_INIT != buf->state && buf->baddr != b->m.userptr) q->ops->buf_release(q,buf); buf->baddr = b->m.userptr; break; @@ -490,16 +596,16 @@ int videobuf_dqbuf(struct videobuf_queue *q, goto done; } switch (buf->state) { - case STATE_ERROR: + case VIDEOBUF_ERROR: dprintk(1,"dqbuf: state is error\n"); retval = -EIO; CALL(q,sync,q, buf); - buf->state = STATE_IDLE; + buf->state = VIDEOBUF_IDLE; break; - case STATE_DONE: + case VIDEOBUF_DONE: dprintk(1,"dqbuf: state is done\n"); CALL(q,sync,q, buf); - buf->state = STATE_IDLE; + buf->state = VIDEOBUF_IDLE; break; default: dprintk(1,"dqbuf: state invalid\n"); @@ -532,7 +638,7 @@ int videobuf_streamon(struct videobuf_queue *q) if (q->irqlock) spin_lock_irqsave(q->irqlock,flags); list_for_each_entry(buf, &q->stream, stream) - if (buf->state == STATE_PREPARED) + if (buf->state == VIDEOBUF_PREPARED) q->ops->buf_queue(q,buf); if (q->irqlock) spin_unlock_irqrestore(q->irqlock,flags); @@ -542,22 +648,30 @@ int videobuf_streamon(struct videobuf_queue *q) return retval; } -int videobuf_streamoff(struct videobuf_queue *q) +/* Locking: Caller holds q->lock */ +static int __videobuf_streamoff(struct videobuf_queue *q) { - int retval = -EINVAL; - - mutex_lock(&q->lock); if (!q->streaming) - goto done; + return -EINVAL; + videobuf_queue_cancel(q); q->streaming = 0; - retval = 0; - done: + return 0; +} + +int videobuf_streamoff(struct videobuf_queue *q) +{ + int retval; + + mutex_lock(&q->lock); + retval = __videobuf_streamoff(q); mutex_unlock(&q->lock); + return retval; } +/* Locking: Caller holds q->lock */ static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data, size_t count, loff_t *ppos) @@ -591,7 +705,7 @@ static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q, retval = videobuf_waiton(q->read_buf,0,0); if (0 == retval) { CALL(q,sync,q,q->read_buf); - if (STATE_ERROR == q->read_buf->state) + if (VIDEOBUF_ERROR == q->read_buf->state) retval = -EIO; else retval = q->read_buf->size; @@ -665,7 +779,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, CALL(q,sync,q,q->read_buf); - if (STATE_ERROR == q->read_buf->state) { + if (VIDEOBUF_ERROR == q->read_buf->state) { /* catch I/O errors */ q->ops->buf_release(q,q->read_buf); kfree(q->read_buf); @@ -692,6 +806,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, return retval; } +/* Locking: Caller holds q->lock */ int videobuf_read_start(struct videobuf_queue *q) { enum v4l2_field field; @@ -706,7 +821,7 @@ int videobuf_read_start(struct videobuf_queue *q) count = VIDEO_MAX_FRAME; size = PAGE_ALIGN(size); - err = videobuf_mmap_setup(q, count, size, V4L2_MEMORY_USERPTR); + err = __videobuf_mmap_setup(q, count, size, V4L2_MEMORY_USERPTR); if (err < 0) return err; @@ -729,12 +844,13 @@ int videobuf_read_start(struct videobuf_queue *q) return 0; } -void videobuf_read_stop(struct videobuf_queue *q) +static void __videobuf_read_stop(struct videobuf_queue *q) { int i; + videobuf_queue_cancel(q); - videobuf_mmap_free(q); + __videobuf_mmap_free(q); INIT_LIST_HEAD(&q->stream); for (i = 0; i < VIDEO_MAX_FRAME; i++) { if (NULL == q->bufs[i]) @@ -744,8 +860,30 @@ void videobuf_read_stop(struct videobuf_queue *q) } q->read_buf = NULL; q->reading = 0; + +} + +void videobuf_read_stop(struct videobuf_queue *q) +{ + mutex_lock(&q->lock); + __videobuf_read_stop(q); + mutex_unlock(&q->lock); +} + +void videobuf_stop(struct videobuf_queue *q) +{ + mutex_lock(&q->lock); + + if (q->streaming) + __videobuf_streamoff(q); + + if (q->reading) + __videobuf_read_stop(q); + + mutex_unlock(&q->lock); } + ssize_t videobuf_read_stream(struct videobuf_queue *q, char __user *data, size_t count, loff_t *ppos, int vbihack, int nonblocking) @@ -783,7 +921,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q, break; } - if (q->read_buf->state == STATE_DONE) { + if (q->read_buf->state == VIDEOBUF_DONE) { rc = CALL (q,copy_stream, q, data + retval, count, retval, vbihack, nonblocking); if (rc < 0) { @@ -851,83 +989,14 @@ unsigned int videobuf_poll_stream(struct file *file, if (0 == rc) { poll_wait(file, &buf->done, wait); - if (buf->state == STATE_DONE || - buf->state == STATE_ERROR) + if (buf->state == VIDEOBUF_DONE || + buf->state == VIDEOBUF_ERROR) rc = POLLIN|POLLRDNORM; } mutex_unlock(&q->lock); return rc; } -int videobuf_mmap_setup(struct videobuf_queue *q, - unsigned int bcount, unsigned int bsize, - enum v4l2_memory memory) -{ - unsigned int i; - int err; - - MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS); - - err = videobuf_mmap_free(q); - if (0 != err) - return err; - - /* Allocate and initialize buffers */ - for (i = 0; i < bcount; i++) { - q->bufs[i] = videobuf_alloc(q); - - if (q->bufs[i] == NULL) - break; - - q->bufs[i]->i = i; - q->bufs[i]->input = UNSET; - q->bufs[i]->memory = memory; - q->bufs[i]->bsize = bsize; - switch (memory) { - case V4L2_MEMORY_MMAP: - q->bufs[i]->boff = bsize * i; - break; - case V4L2_MEMORY_USERPTR: - case V4L2_MEMORY_OVERLAY: - /* nothing */ - break; - } - } - - if (!i) - return -ENOMEM; - - dprintk(1,"mmap setup: %d buffers, %d bytes each\n", - i, bsize); - - return i; -} - -int videobuf_mmap_free(struct videobuf_queue *q) -{ - int i; - int rc; - - if (!q) - return 0; - - MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS); - - rc = CALL(q,mmap_free,q); - if (rc<0) - return rc; - - for (i = 0; i < VIDEO_MAX_FRAME; i++) { - if (NULL == q->bufs[i]) - continue; - q->ops->buf_release(q,q->bufs[i]); - kfree(q->bufs[i]); - q->bufs[i] = NULL; - } - - return rc; -} - int videobuf_mmap_mapper(struct videobuf_queue *q, struct vm_area_struct *vma) { @@ -990,8 +1059,8 @@ EXPORT_SYMBOL_GPL(videobuf_dqbuf); EXPORT_SYMBOL_GPL(videobuf_streamon); EXPORT_SYMBOL_GPL(videobuf_streamoff); -EXPORT_SYMBOL_GPL(videobuf_read_start); EXPORT_SYMBOL_GPL(videobuf_read_stop); +EXPORT_SYMBOL_GPL(videobuf_stop); EXPORT_SYMBOL_GPL(videobuf_read_stream); EXPORT_SYMBOL_GPL(videobuf_read_one); EXPORT_SYMBOL_GPL(videobuf_poll_stream); diff --git a/linux/drivers/media/video/videobuf-dvb.c b/linux/drivers/media/video/videobuf-dvb.c index 6bc82f25f..9255be2ae 100644 --- a/linux/drivers/media/video/videobuf-dvb.c +++ b/linux/drivers/media/video/videobuf-dvb.c @@ -73,7 +73,7 @@ static int videobuf_dvb_thread(void *data) /* feed buffer data to demux */ dma=videobuf_to_dma(buf); - if (buf->state == STATE_DONE) + if (buf->state == VIDEOBUF_DONE) dvb_dmx_swfilter(&dvb->demux, dma->vmalloc, buf->size); diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index 72ddc8353..63b0c7aeb 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -399,7 +399,7 @@ static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf) (unsigned long)tmpbuf,pos); /* Advice that buffer was filled */ - buf->vb.state = STATE_DONE; + buf->vb.state = VIDEOBUF_DONE; buf->vb.field_count++; do_gettimeofday(&ts); buf->vb.ts = ts; @@ -608,7 +608,7 @@ static int restart_video_queue(struct vivi_dmaqueue *dma_q) /* cancel all outstanding capture / vbi requests */ list_for_each_entry_safe(buf, prev, &dma_q->active, vb.queue) { list_del(&buf->vb.queue); - buf->vb.state = STATE_ERROR; + buf->vb.state = VIDEOBUF_ERROR; wake_up(&buf->vb.done); } mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); @@ -629,7 +629,7 @@ static int restart_video_queue(struct vivi_dmaqueue *dma_q) vivi_stop_thread(dma_q); vivi_start_thread(dma_q); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); dprintk(2,"[%p/%d] restart_queue - first active\n", buf,buf->vb.i); @@ -639,7 +639,7 @@ static int restart_video_queue(struct vivi_dmaqueue *dma_q) prev->fmt == buf->fmt) { list_del(&buf->vb.queue); list_add_tail(&buf->vb.queue,&dma_q->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; dprintk(2,"[%p/%d] restart_queue - move to active\n", buf,buf->vb.i); } else { @@ -658,7 +658,7 @@ static void vivi_vid_timeout(unsigned long data) while (!list_empty(&vidq->active)) { buf = list_entry(vidq->active.next, struct vivi_buffer, vb.queue); list_del(&buf->vb.queue); - buf->vb.state = STATE_ERROR; + buf->vb.state = VIDEOBUF_ERROR; wake_up(&buf->vb.done); printk("vivi/0: [%p/%d] timeout\n", buf, buf->vb.i); } @@ -696,7 +696,7 @@ static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf) videobuf_waiton(&buf->vb,0,0); videobuf_vmalloc_free(&buf->vb); - buf->vb.state = STATE_NEEDS_INIT; + buf->vb.state = VIDEOBUF_NEEDS_INIT; } #define norm_maxw() 1024 @@ -730,12 +730,12 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, init_buffer = 1; } - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { if (0 != (rc = videobuf_iolock(vq,&buf->vb,NULL))) goto fail; } - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; #ifdef CONFIG_VIVI_SCATTER if (NULL == (buf->to_addr = kmalloc(sizeof(*buf->to_addr) * vb->dma.nr_pages,GFP_KERNEL))) { @@ -762,13 +762,13 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) if (!list_empty(&vidq->queued)) { dprintk(1,"adding vb queue=0x%08lx\n",(unsigned long)&buf->vb.queue); list_add_tail(&buf->vb.queue,&vidq->queued); - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; dprintk(2,"[%p/%d] buffer_queue - append to queued\n", buf, buf->vb.i); } else if (list_empty(&vidq->active)) { list_add_tail(&buf->vb.queue,&vidq->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; mod_timer(&vidq->timeout, jiffies+BUFFER_TIMEOUT); dprintk(2,"[%p/%d] buffer_queue - first active\n", buf, buf->vb.i); @@ -780,13 +780,13 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) prev->vb.height == buf->vb.height && prev->fmt == buf->fmt) { list_add_tail(&buf->vb.queue,&vidq->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; dprintk(2,"[%p/%d] buffer_queue - append to active\n", buf, buf->vb.i); } else { list_add_tail(&buf->vb.queue,&vidq->queued); - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; dprintk(2,"[%p/%d] buffer_queue - first queued\n", buf, buf->vb.i); } @@ -1174,6 +1174,7 @@ static int vivi_release(struct inode *inode, struct file *file) int minor = iminor(inode); vivi_stop_thread(vidq); + videobuf_stop(&fh->vb_vidq); videobuf_mmap_free(&fh->vb_vidq); kfree (fh); diff --git a/linux/include/media/videobuf-core.h b/linux/include/media/videobuf-core.h index 4359823c3..dea9c53fe 100644 --- a/linux/include/media/videobuf-core.h +++ b/linux/include/media/videobuf-core.h @@ -56,13 +56,13 @@ struct videobuf_mapping { }; enum videobuf_state { - STATE_NEEDS_INIT = 0, - STATE_PREPARED = 1, - STATE_QUEUED = 2, - STATE_ACTIVE = 3, - STATE_DONE = 4, - STATE_ERROR = 5, - STATE_IDLE = 6, + VIDEOBUF_NEEDS_INIT = 0, + VIDEOBUF_PREPARED = 1, + VIDEOBUF_QUEUED = 2, + VIDEOBUF_ACTIVE = 3, + VIDEOBUF_DONE = 4, + VIDEOBUF_ERROR = 5, + VIDEOBUF_IDLE = 6, }; struct videobuf_buffer { @@ -166,12 +166,12 @@ struct videobuf_queue { struct videobuf_queue_ops *ops; struct videobuf_qtype_ops *int_ops; + unsigned int streaming:1; + unsigned int reading:1; /* capture via mmap() + ioctl(QBUF/DQBUF) */ - unsigned int streaming; struct list_head stream; /* capture via read() */ - unsigned int reading; unsigned int read_off; struct videobuf_buffer *read_buf; @@ -212,6 +212,8 @@ int videobuf_cgmbuf(struct videobuf_queue *q, int videobuf_streamon(struct videobuf_queue *q); int videobuf_streamoff(struct videobuf_queue *q); +void videobuf_stop(struct videobuf_queue *q); + int videobuf_read_start(struct videobuf_queue *q); void videobuf_read_stop(struct videobuf_queue *q); ssize_t videobuf_read_stream(struct videobuf_queue *q, diff --git a/v4l2-apps/util/Makefile b/v4l2-apps/util/Makefile index fcc193a09..34fc9a103 100644 --- a/v4l2-apps/util/Makefile +++ b/v4l2-apps/util/Makefile @@ -12,6 +12,7 @@ clean:: rm -f $(binaries) v4l2-driverids.cpp v4l2-chipids.cpp -if [ -f qv4l2/Makefile ]; then make -C qv4l2 $@; fi -rm -f qv4l2/qv4l2 qv4l2/Makefile + make -C xc3028-firmware $@ qv4l2: if [ ! -f qv4l2/Makefile ]; then (cd qv4l2; qmake); fi diff --git a/v4l2-apps/util/xc3028-firmware/Makefile b/v4l2-apps/util/xc3028-firmware/Makefile new file mode 100644 index 000000000..508575e16 --- /dev/null +++ b/v4l2-apps/util/xc3028-firmware/Makefile @@ -0,0 +1,19 @@ +# Makefile for linuxtv.org v4l2-apps/util/xc3028-firmware + +CPPFLAGS += -I../../../linux/include + +binaries = firmware-tool + +.PHONY: all clean install qv4l2 + +all: $(binaries) + +clean:: + rm -f $(binaries) + +firmware-tool: firmware-tool.o standards.o + $(CXX) $^ -o $@ + +install: + +include ../../Make.rules diff --git a/v4l2-apps/util/xc3028-firmware/README b/v4l2-apps/util/xc3028-firmware/README new file mode 100644 index 000000000..85df42a79 --- /dev/null +++ b/v4l2-apps/util/xc3028-firmware/README @@ -0,0 +1,3 @@ +Firmware dumps must be in ASCII format and each line corresponds to an I2C instruction sent to the chip. Each line +must either be a special instruction like RESET_CLK, RESET_TUNER (see standards.c) or be a sequence of bytes +represented in hexadecimal format xx separated by a space character ' '. diff --git a/v4l2-apps/util/xc3028-firmware/firmware-tool.c b/v4l2-apps/util/xc3028-firmware/firmware-tool.c new file mode 100644 index 000000000..feb804f11 --- /dev/null +++ b/v4l2-apps/util/xc3028-firmware/firmware-tool.c @@ -0,0 +1,673 @@ +/* + Xceive XC2028/3028 tuner module firmware manipulation tool + + Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation version 2 + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <sys/stat.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <getopt.h> +#include <string.h> +#include <unistd.h> + +#include <asm/byteorder.h> +#include <asm/types.h> + +#include "../../../linux/drivers/media/video/tuner-xc2028-types.h" +#include "../../../linux/include/linux/videodev2.h" + +#include "standards.h" + +#define LIST_ACTION (1<<0) +#define ADD_ACTION (1<<1) +#define DELETE_ACTION (1<<2) +#define SET_TYPE_ACTION (1<<3) +#define SET_ID_ACTION (1<<4) + +struct firmware_description { + __u32 type; + __u64 id; + unsigned char *data; + __u32 size; +}; + +struct firmware { + char* name; + struct firmware_description* desc; + __u16 version; + __u16 nr_desc; +}; + +struct firmware_description* alloc_firmware_description(void) { + struct firmware_description *d = malloc(sizeof(*d)); + d->type = 0; + d->id = 0; + d->data = NULL; + d->size = 0; + return d; +} + +void free_firmware_description(struct firmware_description *d) { + free(d->data); + free(d); +} + +struct firmware* alloc_firmware(void) { + struct firmware *f = malloc(sizeof(*f)); + f->name = NULL; + f->desc = NULL; + f->nr_desc = 0; + return f; +} + +void free_firmware(struct firmware *f) { + free(f->name); + free(f->desc); + if(f->desc) { + unsigned int i = 0; + for(i = 0; i < f->nr_desc; ++ i) { + free(f->desc[i].data); + } + } + free(f); +} + +void add_firmware_description(struct firmware *f, + struct firmware_description *d) { + struct firmware_description* new_desc; + + new_desc = malloc((f->nr_desc + 1) * sizeof(*new_desc)); + memcpy(new_desc, f->desc, f->nr_desc * sizeof(*new_desc)); + memcpy(new_desc + f->nr_desc, d, sizeof(*d)); + free(f->desc); + f->desc = new_desc; + ++f->nr_desc; +} + +void delete_firmware_description(struct firmware *f, __u16 i) { + struct firmware_description* new_desc; + + if(f->nr_desc == 0 || i >= f->nr_desc) { + return; + } + + new_desc = malloc((f->nr_desc - 1) * sizeof(*new_desc)); + memcpy(new_desc, f->desc, i * sizeof(*f->desc)); + memcpy(new_desc + i, f->desc + i + 1, (f->nr_desc - i - 1) * sizeof(*f->desc)); + free(f->desc); + f->desc = new_desc; + --f->nr_desc; +} + +/* name[32] + version[2] + nr_desc[2] */ +#define HEADER_LENGTH (32 + 2 + 2) +/* description header: 4 + 8 + 4.*/ +#define DESC_HEADER_LENGTH (4 + 8 + 4) + +int read_firmware(unsigned char* data, off_t size, struct firmware** f_res) { + char *name = malloc(33); + unsigned char *p = data; + struct firmware* f = alloc_firmware(); + unsigned int i; + + if(size < HEADER_LENGTH) { + printf("Invalid firmware header length.\n"); + free_firmware(f); + return -1; + } + name[32] = 0; + memcpy(name, data, 32); + f->name = name; + p += 32; + f->version = __le16_to_cpu(*(__u16*)p); + p += sizeof(f->version); + f->nr_desc = __le16_to_cpu(*(__u16*)p); + p += sizeof(f->nr_desc); + f->desc = malloc(f->nr_desc * sizeof(*(f->desc))); + + for(i = 0; i < f->nr_desc; ++i) { + if(p + DESC_HEADER_LENGTH > data + size) { + printf("Invalid description header length.\n"); + free_firmware(f); + return -1; + } + f->desc[i].type = __le32_to_cpu(*(__u32*) p); + p += sizeof(f->desc[i].type); + f->desc[i].id = __le64_to_cpu(*(__u64*) p); + p += sizeof(f->desc[i].id); + f->desc[i].size = __le32_to_cpu(*(__u32*) p); + p += sizeof(f->desc[i].size); + + if(p + f->desc[i].size > data + size) { + printf("Invalid firmware standard length.\n"); + f->nr_desc = (f->nr_desc == 0) ? 0 : f->nr_desc -1; + free_firmware(f); + return -1; + } + + f->desc[i].data = malloc(f->desc[i].size); + memcpy(f->desc[i].data, p, f->desc[i].size); + + p += f->desc[i].size; + } + + *f_res = f; + return 0; +} + +void write_firmware(struct firmware *f, unsigned char** r_data, off_t *r_size) { + off_t size; + unsigned int i = 0; + unsigned char* data; + unsigned char* p; + + size = HEADER_LENGTH + f->nr_desc * DESC_HEADER_LENGTH; + for(i = 0; i < f->nr_desc; ++i) { + size += f->desc[i].size; + } + + data = malloc(size); + p = data; + + memcpy(p, f->name, 32); + p += 32; + + *(__u16*)p = __cpu_to_le16(f->version); + p += sizeof(f->version); + + *(__u16*)p = __cpu_to_le16(f->nr_desc); + p += sizeof(f->nr_desc); + + for(i = 0; i < f->nr_desc; ++i) { + *(__u32*) p = __cpu_to_le32(f->desc[i].type); + p += sizeof(f->desc[i].type); + + *(__u64*) p = __cpu_to_le64(f->desc[i].id); + p += sizeof(f->desc[i].id); + + *(__u32*) p = __cpu_to_le32(f->desc[i].size); + p += sizeof(f->desc[i].size); + + memcpy(p, f->desc[i].data, f->desc[i].size); + p += f->desc[i].size; + } + + *r_data = data; + *r_size = size; +} + +struct firmware* read_firmware_file(const char* filename) { + struct stat buf; + unsigned char *ptr; + struct firmware *f; + int fd; + + if(stat(filename, &buf) < 0) { + perror("Error during stat"); + return NULL; + } + + fd = open(filename, O_RDONLY); + if(fd < 0) { + perror("Error while opening the firmware file"); + free_firmware(f); + return NULL; + } + + /* allocate firmware buffer*/ + ptr = malloc(buf.st_size); + + if(read(fd, ptr, buf.st_size) < 0) { + perror("Error while reading the firmware file"); + free(ptr); + close(fd); + return NULL; + } + + if(read_firmware(ptr, buf.st_size, &f) < 0) { + printf("Invalid firmware file!\n"); + free(ptr); + close(fd); + return NULL; + } + + close(fd); + free(ptr); + return f; +} + +void write_firmware_file(const char* filename, struct firmware *f) { + int fd; + unsigned char* data; + off_t size = 0; + + fd = open(filename, O_WRONLY | O_CREAT); + if(fd < 0) { + perror("Error while opening the firmware file"); + return; + } + + if(ftruncate(fd, 0) < 0) { + perror("Error while deleting the firmware file"); + close(fd); + return; + } + + write_firmware(f, &data, &size); + + if(write(fd, data, size) < 0) { + perror("Error while writing the firmware file"); + close(fd); + return; + } + + free(data); + close(fd); +} + +void dump_firm_type(unsigned int type) +{ + if (type & BASE) + printf("BASE "); + if (type & F8MHZ) + printf("F8MHZ "); + if (type & MTS) + printf("MTS "); + if (type & D2620) + printf("D2620 "); + if (type & D2633) + printf("D2633 "); + if (type & DTV6) + printf("DTV6 "); + if (type & QAM) + printf("QAM "); + if (type & DTV7) + printf("DTV7 "); + if (type & DTV78) + printf("DTV78 "); + if (type & DTV8) + printf("DTV8 "); + if (type & FM) + printf("FM "); + if (type & INPUT1) + printf("INPUT1 "); + if (type & LCD) + printf("LCD "); + if (type & NOGD) + printf("NOGD "); + if (type & MONO) + printf("MONO "); + if (type & ATSC) + printf("ATSC "); + if (type & IF) + printf("IF "); + if (type & LG60) + printf("LG60 "); + if (type & ATI638) + printf("ATI638 "); + if (type & OREN538) + printf("OREN538 "); + if (type & OREN36) + printf("OREN36 "); + if (type & TOYOTA388) + printf("TOYOTA388 "); + if (type & TOYOTA794) + printf("TOYOTA794 "); + if (type & DIBCOM52) + printf("DIBCOM52 "); + if (type & ZARLINK456) + printf("ZARLINK456 "); + if (type & CHINA) + printf("CHINA "); + if (type & F6MHZ) + printf("F6MHZ "); + if (type & INPUT2) + printf("INPUT2 "); + if (type & SCODE) + printf("SCODE "); +} + +void dump_firm_std(v4l2_std_id id) +{ + v4l2_std_id old=-1, curr_id; + + /* Dumps video standards */ + while (old!=id) { + old=id; + if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) { + printf ("PAL "); + curr_id = V4L2_STD_PAL; + } else if ( (id & V4L2_STD_MN) == V4L2_STD_MN) { + printf ("NTSC PAL/M PAL/N "); + curr_id = V4L2_STD_PAL; + } else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) { + printf ("PAL/BG "); + curr_id = V4L2_STD_PAL_BG; + } else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) { + printf ("PAL/DK "); + curr_id = V4L2_STD_PAL_DK; + } else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) { + printf ("PAL/B "); + curr_id = V4L2_STD_PAL_B; + } else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) { + printf ("PAL/B1 "); + curr_id = V4L2_STD_PAL_B1; + } else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) { + printf ("PAL/G "); + curr_id = V4L2_STD_PAL_G; + } else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) { + printf ("PAL/H "); + curr_id = V4L2_STD_PAL_H; + } else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) { + printf ("PAL/I "); + curr_id = V4L2_STD_PAL_I; + } else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) { + printf ("PAL/D "); + curr_id = V4L2_STD_PAL_D; + } else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) { + printf ("PAL/D1 "); + curr_id = V4L2_STD_PAL_D1; + } else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) { + printf ("PAL/K "); + curr_id = V4L2_STD_PAL_K; + } else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) { + printf ("PAL/M "); + curr_id = V4L2_STD_PAL_M; + } else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) { + printf ("PAL/N "); + curr_id = V4L2_STD_PAL_N; + } else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) { + printf ("PAL/Nc "); + curr_id = V4L2_STD_PAL_Nc; + } else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) { + printf ("PAL/60 "); + curr_id = V4L2_STD_PAL_60; + } else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) { + printf ("NTSC "); + curr_id = V4L2_STD_NTSC; + } else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) { + printf ("NTSC/M "); + curr_id = V4L2_STD_NTSC_M; + } else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) { + printf ("NTSC/M Jp "); + curr_id = V4L2_STD_NTSC_M_JP; + } else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) { + printf ("NTSC 443 "); + curr_id = V4L2_STD_NTSC_443; + } else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) { + printf ("NTSC/M Kr "); + curr_id = V4L2_STD_NTSC_M_KR; + } else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) { + printf ("SECAM "); + curr_id = V4L2_STD_SECAM; + } else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) { + printf ("SECAM/DK "); + curr_id = V4L2_STD_SECAM_DK; + } else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) { + printf ("SECAM/B "); + curr_id = V4L2_STD_SECAM_B; + } else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) { + printf ("SECAM/D "); + curr_id = V4L2_STD_SECAM_D; + } else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) { + printf ("SECAM/G "); + curr_id = V4L2_STD_SECAM_G; + } else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) { + printf ("SECAM/H "); + curr_id = V4L2_STD_SECAM_H; + } else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) { + printf ("SECAM/K "); + curr_id = V4L2_STD_SECAM_K; + } else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) { + printf ("SECAM/K1 "); + curr_id = V4L2_STD_SECAM_K1; + } else if ( (id & V4L2_STD_SECAM_K3) == V4L2_STD_SECAM_K3) { + printf ("SECAM/K3 "); + curr_id = V4L2_STD_SECAM_K3; + } else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) { + printf ("SECAM/L "); + curr_id = V4L2_STD_SECAM_L; + } else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) { + printf ("SECAM/Lc "); + curr_id = V4L2_STD_SECAM_LC; + } else if ( (id & V4L2_STD_A2) == V4L2_STD_A2) { + printf ("A2 "); + curr_id = V4L2_STD_A2; + } else if ( (id & V4L2_STD_A2_A) == V4L2_STD_A2_A) { + printf ("A2/A "); + curr_id = V4L2_STD_A2_A; + } else if ( (id & V4L2_STD_A2_B) == V4L2_STD_A2_B) { + printf ("A2/A "); + curr_id = V4L2_STD_A2_B; + } else if ( (id & V4L2_STD_NICAM) == V4L2_STD_NICAM) { + printf ("NICAM "); + curr_id = V4L2_STD_NICAM; + } else if ( (id & V4L2_STD_NICAM_A) == V4L2_STD_NICAM_A) { + printf ("NICAM/A "); + curr_id = V4L2_STD_NICAM_A; + } else if ( (id & V4L2_STD_NICAM_B) == V4L2_STD_NICAM_B) { + printf ("NICAM/B "); + curr_id = V4L2_STD_NICAM_B; + } else if ( (id & V4L2_STD_AM) == V4L2_STD_AM) { + printf ("AM "); + curr_id = V4L2_STD_AM; + } else if ( (id & V4L2_STD_BTSC) == V4L2_STD_BTSC) { + printf ("BTSC "); + curr_id = V4L2_STD_BTSC; + } else if ( (id & V4L2_STD_EIAJ) == V4L2_STD_EIAJ) { + printf ("EIAJ "); + curr_id = V4L2_STD_EIAJ; + } else { + curr_id = 0; + break; + } + id &= ~curr_id; + } +} + +void list_firmware(struct firmware *f) { + unsigned int i = 0; + + printf("firmware name:\t%s\n", f->name); + printf("version:\t%d.%d (%u)\n", f->version >> 8, f->version & 0xff, + f->version); + printf("standards:\t%u\n", f->nr_desc); + for(i = 0; i < f->nr_desc; ++i) { + printf("\n"); + printf("standard firmware %u\n", i); + printf("type:\t"); + dump_firm_type(f->desc[i].type); + printf("(0x%08x)\n", f->desc[i].type); + printf("id:\t"); + dump_firm_std(f->desc[i].id); + printf("(%016llx)\n", f->desc[i].id); + printf("size:\t%u\n", f->desc[i].size); + } +} + +void add_standard(struct firmware* f, char* firmware_file, char* standard_file) { + unsigned char* standard_data; + unsigned int len, i; + struct firmware_description desc; + + create_standard_data(standard_file, &standard_data, &len); + if(!standard_data) { + fprintf(stderr, "Couldn't create the firmware standard data.\n"); + return; + } + desc.id = 0; + desc.type = 0; + desc.size = len; + desc.data = standard_data; + add_firmware_description(f, &desc); + write_firmware_file(firmware_file, f); +} + +void delete_standard(struct firmware* f, char* firmware_file, __u16 i) { + delete_firmware_description(f, i); + write_firmware_file(firmware_file, f); +} + +void set_standard_type(struct firmware* f, char* firmware_file, __u16 i, __u32 type) { + if(i > f->nr_desc) { + return; + } + f->desc[i].type = type; + write_firmware_file(firmware_file, f); +} + +void set_standard_id(struct firmware* f, char* firmware_file, __u16 i, __u32 id) { + if(i > f->nr_desc) { + return; + } + f->desc[i].id = id; + write_firmware_file(firmware_file, f); +} + +void print_usage(void) +{ + printf("firmware-tool usage:\n"); + printf("\t firmware-tool --list <firmware-file>\n"); + printf("\t firmware-tool --add <firmware-dump> <firmware-file>\n"); + printf("\t firmware-tool --delete <index> <firmware-file>\n"); + printf("\t firmware-tool --type <type> --index <i> <firmware-file>\n"); + printf("\t firmware-tool --id <type> --index <i> <firmware-file>\n"); +} + +int main(int argc, char* argv[]) +{ + int c; + int nr_args; + unsigned int action = 0; + char* firmware_file, *file = NULL, *nr_str = NULL, *index_str = NULL; + struct firmware *f; + __u64 nr; + + while(1) { + static struct option long_options[] = { + {"list", no_argument, 0, 'l'}, + {"add", required_argument, 0, 'a'}, + {"delete", required_argument, 0, 'd'}, + {"type", required_argument, 0, 't'}, + {"id", required_argument, 0, 's'}, + {"index", required_argument, 0, 'i'}, + {0, 0, 0, 0} + }; + int option_index = 0; + + c = getopt_long(argc, argv, "", long_options, &option_index); + + if (c == -1) { + break; + } + + switch(c) { + case 'l': + puts("list action\n"); + if(action != 0) { + printf("Please specify only one action.\n"); + } + action |= LIST_ACTION; + break; + case 'a': + puts("add action\n"); + if(action != 0) { + printf("Please specify only one action.\n"); + } + action |= ADD_ACTION; + file = optarg; + break; + case 'd': + puts("delete action\n"); + if(action != 0) { + printf("Please specify only one action.\n"); + } + action |= DELETE_ACTION; + nr_str = optarg; + break; + case 't': + puts("set-type action\n"); + if(action != 0) { + printf("Please specify only one action.\n"); + } + action |= SET_TYPE_ACTION; + nr_str = optarg; + break; + case 's': + puts("set-id action\n"); + if(action != 0) { + printf("Please specify only one action.\n"); + } + action |= SET_ID_ACTION; + nr_str = optarg; + break; + case 'i': + index_str = optarg; + break; + default: + print_usage(); + return 0; + } + } + + nr_args = (action == LIST_ACTION) ? 1 : 1; + if(!(optind + nr_args == argc)) { + printf("Wrong number of arguments!\n\n"); + print_usage(); + return -1; + } + + if(!action) { + printf("Please specify an action!\n\n"); + print_usage(); + return -1; + } + + firmware_file = argv[optind]; + + printf("firmware file name: %s\n", firmware_file); + + f = read_firmware_file(firmware_file); + if(!f) { + printf("Couldn't read the firmware file!\n"); + return -1; + } + + switch(action) { + case LIST_ACTION: + list_firmware(f); + break; + + case ADD_ACTION: + add_standard(f, firmware_file, file); + break; + + case DELETE_ACTION: + delete_standard(f, firmware_file, strtoul(nr_str, NULL, 10)); + break; + + case SET_TYPE_ACTION: + set_standard_type(f, firmware_file, strtoul(index_str, NULL, 10), strtoul(nr_str, NULL, 10)); + break; + + case SET_ID_ACTION: + set_standard_id(f, firmware_file, strtoul(index_str, NULL, 10), strtoul(nr_str, NULL, 10)); + break; + } + return 0; +} diff --git a/v4l2-apps/util/xc3028-firmware/standards.c b/v4l2-apps/util/xc3028-firmware/standards.c new file mode 100644 index 000000000..38b2e625d --- /dev/null +++ b/v4l2-apps/util/xc3028-firmware/standards.c @@ -0,0 +1,152 @@ +/* + Xceive XC2028/3028 tuner module firmware manipulation tool + + Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation version 2 + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "standards.h" + +#define _GNU_SOURCE +#include <malloc.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <asm/byteorder.h> +#include <asm/types.h> + +#define MAX(a,b) ((a) >= (b) ? (a) : (b)) + +struct vector { + unsigned char* data; + unsigned int size; +}; + +struct vector* alloc_vector(unsigned int size) { + struct vector *v = malloc(sizeof(*v)); + v->data = malloc(size); + v->size = size; + return v; +} + +void free_vector(struct vector* v) { + free(v->data); + free(v); +} + +void enlarge_vector(struct vector* v, unsigned int new_size) { + unsigned char *n_data; + unsigned int old_size = v->size; + + v->size = MAX(v->size, new_size); + n_data = malloc(v->size); + memcpy(n_data, v->data, old_size); + free(v->data); + v->data = n_data; +} + +void copy_vector(struct vector *v, unsigned int i, + unsigned char* ptr, unsigned int len) { + if(i + len > v->size) { + enlarge_vector(v, MAX(2 * v->size, i + len)); + } + memcpy(v->data + i, ptr, len); +} + +void write_vector8(struct vector *v, unsigned int i, __u8 value) { + __u8 buf[1]; + + buf[0] = value; + copy_vector(v, i, buf, 1); +} + +void write_vector16(struct vector *v, unsigned int i, __u16 value) { + __u8 buf[2]; + + buf[0] = value & 0xff; + buf[1] = value >> 8; + copy_vector(v, i, buf, 2); +} + +static const const char reset_tuner_str[] = "RESET_TUNER"; +static const const char reset_clk_str[] = "RESET_CLK"; + +void create_standard_data(char* filename, unsigned char** data, unsigned int *r_len) { + FILE *file; + char* line = NULL; + ssize_t r = 0; + size_t len = 0; + struct vector *v = alloc_vector(1); + unsigned int v_i = 0; + + if (!(file = fopen(filename, "r"))) { + perror("Cannot open the firmware standard file.\n"); + *data = NULL; + } + + while ((r = getline(&line, &len, file)) != -1) { + unsigned int i = 0; + unsigned int val, count = 0; + unsigned int values[len]; + + printf("read line \"%s\"\n", line); + + if(len >= 9 && memcmp(reset_clk_str, line, strlen(reset_clk_str) - 1) == 0) { + printf("adding RESET_CLK\n"); + write_vector16(v, v_i, (__u16) 0xff00); + v_i += 2; + continue; + } + else if(len >= 11 && memcmp(reset_tuner_str, line, strlen(reset_tuner_str) - 1) == 0) { + printf("adding RESET_TUNER\n"); + write_vector16(v, v_i, (__u16) 0x0000); + v_i += 2; + continue; + } + + while(i < len && sscanf(line + i*sizeof(char), "%2x", &val) == 1) { + printf("%2x ", val); + values[count] = val; + ++count; + i += 2; + while(line[i] == ' ') { + ++i; + } + } + + write_vector16(v, v_i, __cpu_to_le16((__u16) count)); + v_i += 2; + + + for(i = 0; i < count; ++i) { + write_vector8(v, v_i, (__u8) values[i]); + ++v_i; + } + + printf("\n"); + } + write_vector16(v, v_i, 0xffff); + v_i += 2; + + free(line); + fclose(file); + *data = malloc(v_i); + memcpy(*data, v->data, v_i); + free_vector(v); + *r_len = v_i; +} + diff --git a/v4l2-apps/util/xc3028-firmware/standards.h b/v4l2-apps/util/xc3028-firmware/standards.h new file mode 100644 index 000000000..c9da02b5a --- /dev/null +++ b/v4l2-apps/util/xc3028-firmware/standards.h @@ -0,0 +1,25 @@ +/* + Xceive XC2028/3028 tuner module firmware manipulation tool + + Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation version 2 + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef STANDARDS_H +#define STANDARDS_H + +void create_standard_data(char* filename, unsigned char** data, unsigned int *len); + +#endif |