From patchwork Thu May 28 04:58:57 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitri Belimov X-Patchwork-Id: 1145 Return-path: Envelope-to: mchehab@infradead.org Delivery-date: Thu, 28 May 2009 04:58:13 +0000 Received: from bombadil.infradead.org [18.85.46.34] by pedra.chehab.org with IMAP (fetchmail-6.3.6) for (single-drop); Thu, 28 May 2009 01:58:43 -0300 (BRT) Received: from vger.kernel.org ([209.132.176.167]) by bombadil.infradead.org with esmtp (Exim 4.69 #1 (Red Hat Linux)) id 1M9Xgy-0008GH-FH; Thu, 28 May 2009 04:58:13 +0000 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751302AbZE1E6H (ORCPT + 1 other); Thu, 28 May 2009 00:58:07 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1751497AbZE1E6H (ORCPT ); Thu, 28 May 2009 00:58:07 -0400 Received: from mail-bw0-f222.google.com ([209.85.218.222]:36662 "EHLO mail-bw0-f222.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751302AbZE1E6G (ORCPT ); Thu, 28 May 2009 00:58:06 -0400 Received: by bwz22 with SMTP id 22so5170794bwz.37 for ; Wed, 27 May 2009 21:58:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:date:from:to:subject :message-id:x-mailer:mime-version:content-type; bh=m44K0iroYnQQRrxSKlEtbBYK9ve/pf5AU+IPbdCY0Yw=; b=F3AvDVP54px7W5KWoGZBZCvBUQsSlLHPyRHptyHpH9Mf7wq23bdqsr4DAf1MqIbTcH JzjGHScS1HGjBlVlv4rfADJN0UbjzwPzkDP4jArdgigwESkYnTqZYaaRpQm2DPHPvJJZ 9vv7br9HeVv8Iq5NLk6ECZbP9/Qq/39cFIiAg= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=date:from:to:subject:message-id:x-mailer:mime-version:content-type; b=PzCLgMmqyAHUvAuriQUVkVCiO5Plik8Cb254T3P4Uerf3VlmLG/GI6RgES1GZuixIR yDS+irsIvu6ocFmk7ymDJh9ank5joptqLnSKLKvCEE5E5QUFIvq5f5BFMcF8KmyR20kV Li/5ieXAgkvCMy+m5oJzOKd3gd2OvTuBul59g= Received: by 10.103.213.19 with SMTP id p19mr596416muq.9.1243486685014; Wed, 27 May 2009 21:58:05 -0700 (PDT) Received: from glory.loctelecom.ru (ns2.openhardware.ru [84.19.183.172]) by mx.google.com with ESMTPS id 23sm489015mun.46.2009.05.27.21.58.02 (version=SSLv3 cipher=RC4-MD5); Wed, 27 May 2009 21:58:03 -0700 (PDT) Date: Thu, 28 May 2009 14:58:57 +1000 From: Dmitri Belimov To: linux-media@vger.kernel.org, video4linux-list@redhat.com Subject: [RESEND PATCH 3/3 v2] big rework of TS for saa7134 Message-ID: <20090528145857.0c34edeb@glory.loctelecom.ru> X-Mailer: Claws Mail 3.5.0 (GTK+ 2.12.12; i486-pc-linux-gnu) Mime-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Hi all. 1. Add start/stop TS function. 2. Move setup DMA of TS to DMA function. 3. Write support cupture via MMAP 4. Rework startup and finish process, remove simple FSM. Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov Signed-off-by: Alexey Osipov Tested-by: Hermann Pitton Tested-by: Beholder Intl. Ltd. Dmitry Belimov With my best regards, Dmitry. diff -r 8d37e8505664 linux/drivers/media/video/saa7134/saa7134-cards.c --- a/linux/drivers/media/video/saa7134/saa7134-cards.c Mon May 11 09:37:41 2009 -0700 +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c Tue May 12 21:48:12 2009 +0200 @@ -4495,6 +4495,7 @@ /* Igor Kuznetsov */ /* Andrey Melnikoff */ /* Beholder Intl. Ltd. Dmitry Belimov */ + /* Alexey Osipov */ .name = "Beholder BeholdTV M6", .audio_clock = 0x00187de7, .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, @@ -4569,6 +4570,7 @@ /* Igor Kuznetsov */ /* Andrey Melnikoff */ /* Beholder Intl. Ltd. Dmitry Belimov */ + /* Alexey Osipov */ .name = "Beholder BeholdTV M6 Extra", .audio_clock = 0x00187de7, .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ diff -r 8d37e8505664 linux/drivers/media/video/saa7134/saa7134-core.c --- a/linux/drivers/media/video/saa7134/saa7134-core.c Mon May 11 09:37:41 2009 -0700 +++ b/linux/drivers/media/video/saa7134/saa7134-core.c Tue May 12 21:48:12 2009 +0200 @@ -380,6 +380,10 @@ dprintk("buffer_next %p\n",NULL); saa7134_set_dmabits(dev); del_timer(&q->timeout); + + if (card_has_mpeg(dev)) + if (dev->ts_started) + saa7134_ts_stop(dev); } } @@ -465,6 +469,19 @@ ctrl |= SAA7134_MAIN_CTRL_TE5; irq |= SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0; + + /* dma: setup channel 5 (= TS) */ + + saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff); + saa_writeb(SAA7134_TS_DMA1, + ((dev->ts.nr_packets - 1) >> 8) & 0xff); + /* TSNOPIT=0, TSCOLAP=0 */ + saa_writeb(SAA7134_TS_DMA2, + (((dev->ts.nr_packets - 1) >> 16) & 0x3f) | 0x00); + saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE); + saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 | + SAA7134_RS_CONTROL_ME | + (dev->ts.pt_ts.dma >> 12)); } /* set task conditions + field handling */ diff -r 8d37e8505664 linux/drivers/media/video/saa7134/saa7134-empress.c --- a/linux/drivers/media/video/saa7134/saa7134-empress.c Mon May 11 09:37:41 2009 -0700 +++ b/linux/drivers/media/video/saa7134/saa7134-empress.c Tue May 12 21:48:12 2009 +0200 @@ -255,6 +255,16 @@ return 0; } +static int empress_try_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct saa7134_dev *dev = file->private_data; + + f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; + f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; + + return 0; +} static int empress_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p) @@ -450,6 +460,7 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = { .vidioc_querycap = empress_querycap, .vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = empress_try_fmt_vid_cap, .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap, .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap, .vidioc_reqbufs = empress_reqbufs, diff -r 8d37e8505664 linux/drivers/media/video/saa7134/saa7134-ts.c --- a/linux/drivers/media/video/saa7134/saa7134-ts.c Mon May 11 09:37:41 2009 -0700 +++ b/linux/drivers/media/video/saa7134/saa7134-ts.c Tue May 12 21:48:12 2009 +0200 @@ -67,33 +67,8 @@ mod_timer(&dev->ts_q.timeout, jiffies+TS_BUFFER_TIMEOUT); - if (dev->ts_state == SAA7134_TS_BUFF_DONE) { - /* Clear TS cache */ - dev->buff_cnt = 0; - saa_writeb(SAA7134_TS_SERIAL1, 0x00); - saa_writeb(SAA7134_TS_SERIAL1, 0x03); - saa_writeb(SAA7134_TS_SERIAL1, 0x00); - saa_writeb(SAA7134_TS_SERIAL1, 0x01); - - /* TS clock non-inverted */ - saa_writeb(SAA7134_TS_SERIAL1, 0x00); - - /* Start TS stream */ - switch (saa7134_boards[dev->board].ts_type) { - case SAA7134_MPEG_TS_PARALLEL: - saa_writeb(SAA7134_TS_SERIAL0, 0x40); - saa_writeb(SAA7134_TS_PARALLEL, 0xec); - break; - case SAA7134_MPEG_TS_SERIAL: - saa_writeb(SAA7134_TS_SERIAL0, 0xd8); - saa_writeb(SAA7134_TS_PARALLEL, 0x6c); - saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc); - saa_writeb(SAA7134_TS_SERIAL1, 0x02); - break; - } - - dev->ts_state = SAA7134_TS_STARTED; - } + if (!dev->ts_started) + saa7134_ts_start(dev); return 0; } @@ -104,7 +79,6 @@ struct saa7134_dev *dev = q->priv_data; struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); unsigned int lines, llength, size; - u32 control; int err; dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]); @@ -121,8 +95,11 @@ } if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { + struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); + dprintk("buffer_prepare: needs_init\n"); + buf->vb.width = llength; buf->vb.height = lines; buf->vb.size = size; @@ -139,23 +116,6 @@ goto oops; } - dev->buff_cnt++; - - if (dev->buff_cnt == dev->ts.nr_bufs) { - dev->ts_state = SAA7134_TS_BUFF_DONE; - /* dma: setup channel 5 (= TS) */ - control = SAA7134_RS_CONTROL_BURST_16 | - SAA7134_RS_CONTROL_ME | - (buf->pt->dma >> 12); - - saa_writeb(SAA7134_TS_DMA0, (lines - 1) & 0xff); - saa_writeb(SAA7134_TS_DMA1, ((lines - 1) >> 8) & 0xff); - /* TSNOPIT=0, TSCOLAP=0 */ - saa_writeb(SAA7134_TS_DMA2, (((lines - 1) >> 16) & 0x3f) | 0x00); - saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE); - saa_writel(SAA7134_RS_CONTROL(5), control); - } - buf->vb.state = VIDEOBUF_PREPARED; buf->activate = buffer_activate; buf->vb.field = field; @@ -175,8 +135,7 @@ if (0 == *count) *count = dev->ts.nr_bufs; *count = saa7134_buffer_count(*size,*count); - dev->buff_cnt = 0; - dev->ts_state = SAA7134_TS_STOPPED; + return 0; } @@ -193,11 +152,9 @@ struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); struct saa7134_dev *dev = q->priv_data; - if (dev->ts_state == SAA7134_TS_STARTED) { - /* Stop TS transport */ - saa_writeb(SAA7134_TS_PARALLEL, 0x6c); - dev->ts_state = SAA7134_TS_STOPPED; - } + if (dev->ts_started) + saa7134_ts_stop(dev); + saa7134_dma_free(q,buf); } @@ -214,7 +171,7 @@ static unsigned int tsbufs = 8; module_param(tsbufs, int, 0444); -MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32"); +MODULE_PARM_DESC(tsbufs, "number of ts buffers for read/write IO, range 2-32"); static unsigned int ts_nr_packets = 64; module_param(ts_nr_packets, int, 0444); @@ -256,6 +213,7 @@ dev->ts_q.timeout.data = (unsigned long)(&dev->ts_q); dev->ts_q.dev = dev; dev->ts_q.need_two = 1; + dev->ts_started = 0; saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts); /* init TS hw */ @@ -264,13 +222,67 @@ return 0; } +/* Function for stop TS */ +int saa7134_ts_stop(struct saa7134_dev *dev) +{ + dprintk("TS stop\n"); + + BUG_ON(!dev->ts_started); + + /* Stop TS stream */ + switch (saa7134_boards[dev->board].ts_type) { + case SAA7134_MPEG_TS_PARALLEL: + saa_writeb(SAA7134_TS_PARALLEL, 0x6c); + dev->ts_started = 0; + break; + case SAA7134_MPEG_TS_SERIAL: + saa_writeb(SAA7134_TS_SERIAL0, 0x40); + dev->ts_started = 0; + break; + } + return 0; +} + +/* Function for start TS */ +int saa7134_ts_start(struct saa7134_dev *dev) +{ + dprintk("TS start\n"); + + BUG_ON(dev->ts_started); + + saa_writeb(SAA7134_TS_SERIAL1, 0x00); + saa_writeb(SAA7134_TS_SERIAL1, 0x03); + saa_writeb(SAA7134_TS_SERIAL1, 0x00); + saa_writeb(SAA7134_TS_SERIAL1, 0x01); + + /* TS clock non-inverted */ + saa_writeb(SAA7134_TS_SERIAL1, 0x00); + + /* Start TS stream */ + switch (saa7134_boards[dev->board].ts_type) { + case SAA7134_MPEG_TS_PARALLEL: + saa_writeb(SAA7134_TS_SERIAL0, 0x40); + saa_writeb(SAA7134_TS_PARALLEL, 0xec); + break; + case SAA7134_MPEG_TS_SERIAL: + saa_writeb(SAA7134_TS_SERIAL0, 0xd8); + saa_writeb(SAA7134_TS_PARALLEL, 0x6c); + saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc); + saa_writeb(SAA7134_TS_SERIAL1, 0x02); + break; + } + + dev->ts_started = 1; + + return 0; +} + int saa7134_ts_fini(struct saa7134_dev *dev) { saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts); return 0; } - void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status) { enum v4l2_field field; diff -r 8d37e8505664 linux/drivers/media/video/saa7134/saa7134.h --- a/linux/drivers/media/video/saa7134/saa7134.h Mon May 11 09:37:41 2009 -0700 +++ b/linux/drivers/media/video/saa7134/saa7134.h Tue May 12 21:48:12 2009 +0200 @@ -498,12 +498,6 @@ void (*signal_change)(struct saa7134_dev *dev); }; -enum saa7134_ts_status { - SAA7134_TS_STOPPED, - SAA7134_TS_BUFF_DONE, - SAA7134_TS_STARTED, -}; - /* global device status */ struct saa7134_dev { struct list_head devlist; @@ -598,8 +592,7 @@ /* SAA7134_MPEG_* */ struct saa7134_ts ts; struct saa7134_dmaqueue ts_q; - enum saa7134_ts_status ts_state; - unsigned int buff_cnt; + int ts_started; struct saa7134_mpeg_ops *mops; /* SAA7134_MPEG_EMPRESS only */ @@ -757,6 +750,9 @@ int saa7134_ts_init_hw(struct saa7134_dev *dev); +int saa7134_ts_start(struct saa7134_dev *dev); +int saa7134_ts_stop(struct saa7134_dev *dev); + /* ----------------------------------------------------------- */ /* saa7134-vbi.c */ Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov Signed-off-by: Alexey Osipov Tested-by: Hermann Pitton Tested-by: Beholder Intl. Ltd. Dmitry Belimov