diff options
author | Dmitri Belimov <d.belimov@gmail.com> | 2009-05-28 00:58:57 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-06-16 18:07:27 -0400 |
commit | 6b6b75432caf87b8b7834ad8eb9acd75e383e20f (patch) | |
tree | 541ff9c0210b7fe90e23dd72cf05a3d4526f6e14 /drivers/media/video/saa7134 | |
parent | 028bbfedcc00225d4a1d700e75658d773523005d (diff) |
V4L/DVB (11938): big rework of TS for saa7134
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.
Tested-by: Hermann Pitton <hermann-pitton@arcor.de>
Tested-by: Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com>
Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com>
Signed-off-by: Alexey Osipov <lion-simba@pridelands.ru>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/saa7134')
-rw-r--r-- | drivers/media/video/saa7134/saa7134-cards.c | 2 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-core.c | 17 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-empress.c | 11 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-ts.c | 120 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134.h | 12 |
5 files changed, 100 insertions, 62 deletions
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 73482eb8d388..229ba93bcc9f 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -4458,6 +4458,7 @@ struct saa7134_board saa7134_boards[] = { | |||
4458 | /* Igor Kuznetsov <igk@igk.ru> */ | 4458 | /* Igor Kuznetsov <igk@igk.ru> */ |
4459 | /* Andrey Melnikoff <temnota@kmv.ru> */ | 4459 | /* Andrey Melnikoff <temnota@kmv.ru> */ |
4460 | /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */ | 4460 | /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */ |
4461 | /* Alexey Osipov <lion-simba@pridelands.ru> */ | ||
4461 | .name = "Beholder BeholdTV M6", | 4462 | .name = "Beholder BeholdTV M6", |
4462 | .audio_clock = 0x00187de7, | 4463 | .audio_clock = 0x00187de7, |
4463 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 4464 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
@@ -4532,6 +4533,7 @@ struct saa7134_board saa7134_boards[] = { | |||
4532 | /* Igor Kuznetsov <igk@igk.ru> */ | 4533 | /* Igor Kuznetsov <igk@igk.ru> */ |
4533 | /* Andrey Melnikoff <temnota@kmv.ru> */ | 4534 | /* Andrey Melnikoff <temnota@kmv.ru> */ |
4534 | /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */ | 4535 | /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */ |
4536 | /* Alexey Osipov <lion-simba@pridelands.ru> */ | ||
4535 | .name = "Beholder BeholdTV M6 Extra", | 4537 | .name = "Beholder BeholdTV M6 Extra", |
4536 | .audio_clock = 0x00187de7, | 4538 | .audio_clock = 0x00187de7, |
4537 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ | 4539 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ |
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 37b14526a093..94a023a14bbc 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
@@ -331,6 +331,10 @@ void saa7134_buffer_next(struct saa7134_dev *dev, | |||
331 | dprintk("buffer_next %p\n",NULL); | 331 | dprintk("buffer_next %p\n",NULL); |
332 | saa7134_set_dmabits(dev); | 332 | saa7134_set_dmabits(dev); |
333 | del_timer(&q->timeout); | 333 | del_timer(&q->timeout); |
334 | |||
335 | if (card_has_mpeg(dev)) | ||
336 | if (dev->ts_started) | ||
337 | saa7134_ts_stop(dev); | ||
334 | } | 338 | } |
335 | } | 339 | } |
336 | 340 | ||
@@ -416,6 +420,19 @@ int saa7134_set_dmabits(struct saa7134_dev *dev) | |||
416 | ctrl |= SAA7134_MAIN_CTRL_TE5; | 420 | ctrl |= SAA7134_MAIN_CTRL_TE5; |
417 | irq |= SAA7134_IRQ1_INTE_RA2_1 | | 421 | irq |= SAA7134_IRQ1_INTE_RA2_1 | |
418 | SAA7134_IRQ1_INTE_RA2_0; | 422 | SAA7134_IRQ1_INTE_RA2_0; |
423 | |||
424 | /* dma: setup channel 5 (= TS) */ | ||
425 | |||
426 | saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff); | ||
427 | saa_writeb(SAA7134_TS_DMA1, | ||
428 | ((dev->ts.nr_packets - 1) >> 8) & 0xff); | ||
429 | /* TSNOPIT=0, TSCOLAP=0 */ | ||
430 | saa_writeb(SAA7134_TS_DMA2, | ||
431 | (((dev->ts.nr_packets - 1) >> 16) & 0x3f) | 0x00); | ||
432 | saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE); | ||
433 | saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 | | ||
434 | SAA7134_RS_CONTROL_ME | | ||
435 | (dev->ts.pt_ts.dma >> 12)); | ||
419 | } | 436 | } |
420 | 437 | ||
421 | /* set task conditions + field handling */ | 438 | /* set task conditions + field handling */ |
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 097c2dfebd2c..add1757f8930 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c | |||
@@ -255,6 +255,16 @@ static int empress_s_fmt_vid_cap(struct file *file, void *priv, | |||
255 | return 0; | 255 | return 0; |
256 | } | 256 | } |
257 | 257 | ||
258 | static int empress_try_fmt_vid_cap(struct file *file, void *priv, | ||
259 | struct v4l2_format *f) | ||
260 | { | ||
261 | struct saa7134_dev *dev = file->private_data; | ||
262 | |||
263 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
264 | f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; | ||
265 | |||
266 | return 0; | ||
267 | } | ||
258 | 268 | ||
259 | static int empress_reqbufs(struct file *file, void *priv, | 269 | static int empress_reqbufs(struct file *file, void *priv, |
260 | struct v4l2_requestbuffers *p) | 270 | struct v4l2_requestbuffers *p) |
@@ -450,6 +460,7 @@ static const struct v4l2_file_operations ts_fops = | |||
450 | static const struct v4l2_ioctl_ops ts_ioctl_ops = { | 460 | static const struct v4l2_ioctl_ops ts_ioctl_ops = { |
451 | .vidioc_querycap = empress_querycap, | 461 | .vidioc_querycap = empress_querycap, |
452 | .vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap, | 462 | .vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap, |
463 | .vidioc_try_fmt_vid_cap = empress_try_fmt_vid_cap, | ||
453 | .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap, | 464 | .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap, |
454 | .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap, | 465 | .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap, |
455 | .vidioc_reqbufs = empress_reqbufs, | 466 | .vidioc_reqbufs = empress_reqbufs, |
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c index b8ff459d0d30..3fa652279ac0 100644 --- a/drivers/media/video/saa7134/saa7134-ts.c +++ b/drivers/media/video/saa7134/saa7134-ts.c | |||
@@ -67,33 +67,8 @@ static int buffer_activate(struct saa7134_dev *dev, | |||
67 | 67 | ||
68 | mod_timer(&dev->ts_q.timeout, jiffies+TS_BUFFER_TIMEOUT); | 68 | mod_timer(&dev->ts_q.timeout, jiffies+TS_BUFFER_TIMEOUT); |
69 | 69 | ||
70 | if (dev->ts_state == SAA7134_TS_BUFF_DONE) { | 70 | if (!dev->ts_started) |
71 | /* Clear TS cache */ | 71 | saa7134_ts_start(dev); |
72 | dev->buff_cnt = 0; | ||
73 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | ||
74 | saa_writeb(SAA7134_TS_SERIAL1, 0x03); | ||
75 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | ||
76 | saa_writeb(SAA7134_TS_SERIAL1, 0x01); | ||
77 | |||
78 | /* TS clock non-inverted */ | ||
79 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | ||
80 | |||
81 | /* Start TS stream */ | ||
82 | switch (saa7134_boards[dev->board].ts_type) { | ||
83 | case SAA7134_MPEG_TS_PARALLEL: | ||
84 | saa_writeb(SAA7134_TS_SERIAL0, 0x40); | ||
85 | saa_writeb(SAA7134_TS_PARALLEL, 0xec); | ||
86 | break; | ||
87 | case SAA7134_MPEG_TS_SERIAL: | ||
88 | saa_writeb(SAA7134_TS_SERIAL0, 0xd8); | ||
89 | saa_writeb(SAA7134_TS_PARALLEL, 0x6c); | ||
90 | saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc); | ||
91 | saa_writeb(SAA7134_TS_SERIAL1, 0x02); | ||
92 | break; | ||
93 | } | ||
94 | |||
95 | dev->ts_state = SAA7134_TS_STARTED; | ||
96 | } | ||
97 | 72 | ||
98 | return 0; | 73 | return 0; |
99 | } | 74 | } |
@@ -104,7 +79,6 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | |||
104 | struct saa7134_dev *dev = q->priv_data; | 79 | struct saa7134_dev *dev = q->priv_data; |
105 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); | 80 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); |
106 | unsigned int lines, llength, size; | 81 | unsigned int lines, llength, size; |
107 | u32 control; | ||
108 | int err; | 82 | int err; |
109 | 83 | ||
110 | dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]); | 84 | dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]); |
@@ -121,8 +95,11 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | |||
121 | } | 95 | } |
122 | 96 | ||
123 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | 97 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { |
98 | |||
124 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); | 99 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); |
125 | 100 | ||
101 | dprintk("buffer_prepare: needs_init\n"); | ||
102 | |||
126 | buf->vb.width = llength; | 103 | buf->vb.width = llength; |
127 | buf->vb.height = lines; | 104 | buf->vb.height = lines; |
128 | buf->vb.size = size; | 105 | buf->vb.size = size; |
@@ -139,23 +116,6 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | |||
139 | goto oops; | 116 | goto oops; |
140 | } | 117 | } |
141 | 118 | ||
142 | dev->buff_cnt++; | ||
143 | |||
144 | if (dev->buff_cnt == dev->ts.nr_bufs) { | ||
145 | dev->ts_state = SAA7134_TS_BUFF_DONE; | ||
146 | /* dma: setup channel 5 (= TS) */ | ||
147 | control = SAA7134_RS_CONTROL_BURST_16 | | ||
148 | SAA7134_RS_CONTROL_ME | | ||
149 | (buf->pt->dma >> 12); | ||
150 | |||
151 | saa_writeb(SAA7134_TS_DMA0, (lines - 1) & 0xff); | ||
152 | saa_writeb(SAA7134_TS_DMA1, ((lines - 1) >> 8) & 0xff); | ||
153 | /* TSNOPIT=0, TSCOLAP=0 */ | ||
154 | saa_writeb(SAA7134_TS_DMA2, (((lines - 1) >> 16) & 0x3f) | 0x00); | ||
155 | saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE); | ||
156 | saa_writel(SAA7134_RS_CONTROL(5), control); | ||
157 | } | ||
158 | |||
159 | buf->vb.state = VIDEOBUF_PREPARED; | 119 | buf->vb.state = VIDEOBUF_PREPARED; |
160 | buf->activate = buffer_activate; | 120 | buf->activate = buffer_activate; |
161 | buf->vb.field = field; | 121 | buf->vb.field = field; |
@@ -175,8 +135,7 @@ buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) | |||
175 | if (0 == *count) | 135 | if (0 == *count) |
176 | *count = dev->ts.nr_bufs; | 136 | *count = dev->ts.nr_bufs; |
177 | *count = saa7134_buffer_count(*size,*count); | 137 | *count = saa7134_buffer_count(*size,*count); |
178 | dev->buff_cnt = 0; | 138 | |
179 | dev->ts_state = SAA7134_TS_STOPPED; | ||
180 | return 0; | 139 | return 0; |
181 | } | 140 | } |
182 | 141 | ||
@@ -193,11 +152,9 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | |||
193 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); | 152 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); |
194 | struct saa7134_dev *dev = q->priv_data; | 153 | struct saa7134_dev *dev = q->priv_data; |
195 | 154 | ||
196 | if (dev->ts_state == SAA7134_TS_STARTED) { | 155 | if (dev->ts_started) |
197 | /* Stop TS transport */ | 156 | saa7134_ts_stop(dev); |
198 | saa_writeb(SAA7134_TS_PARALLEL, 0x6c); | 157 | |
199 | dev->ts_state = SAA7134_TS_STOPPED; | ||
200 | } | ||
201 | saa7134_dma_free(q,buf); | 158 | saa7134_dma_free(q,buf); |
202 | } | 159 | } |
203 | 160 | ||
@@ -214,7 +171,7 @@ EXPORT_SYMBOL_GPL(saa7134_ts_qops); | |||
214 | 171 | ||
215 | static unsigned int tsbufs = 8; | 172 | static unsigned int tsbufs = 8; |
216 | module_param(tsbufs, int, 0444); | 173 | module_param(tsbufs, int, 0444); |
217 | MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32"); | 174 | MODULE_PARM_DESC(tsbufs, "number of ts buffers for read/write IO, range 2-32"); |
218 | 175 | ||
219 | static unsigned int ts_nr_packets = 64; | 176 | static unsigned int ts_nr_packets = 64; |
220 | module_param(ts_nr_packets, int, 0444); | 177 | module_param(ts_nr_packets, int, 0444); |
@@ -256,6 +213,7 @@ int saa7134_ts_init1(struct saa7134_dev *dev) | |||
256 | dev->ts_q.timeout.data = (unsigned long)(&dev->ts_q); | 213 | dev->ts_q.timeout.data = (unsigned long)(&dev->ts_q); |
257 | dev->ts_q.dev = dev; | 214 | dev->ts_q.dev = dev; |
258 | dev->ts_q.need_two = 1; | 215 | dev->ts_q.need_two = 1; |
216 | dev->ts_started = 0; | ||
259 | saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts); | 217 | saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts); |
260 | 218 | ||
261 | /* init TS hw */ | 219 | /* init TS hw */ |
@@ -264,13 +222,67 @@ int saa7134_ts_init1(struct saa7134_dev *dev) | |||
264 | return 0; | 222 | return 0; |
265 | } | 223 | } |
266 | 224 | ||
225 | /* Function for stop TS */ | ||
226 | int saa7134_ts_stop(struct saa7134_dev *dev) | ||
227 | { | ||
228 | dprintk("TS stop\n"); | ||
229 | |||
230 | BUG_ON(!dev->ts_started); | ||
231 | |||
232 | /* Stop TS stream */ | ||
233 | switch (saa7134_boards[dev->board].ts_type) { | ||
234 | case SAA7134_MPEG_TS_PARALLEL: | ||
235 | saa_writeb(SAA7134_TS_PARALLEL, 0x6c); | ||
236 | dev->ts_started = 0; | ||
237 | break; | ||
238 | case SAA7134_MPEG_TS_SERIAL: | ||
239 | saa_writeb(SAA7134_TS_SERIAL0, 0x40); | ||
240 | dev->ts_started = 0; | ||
241 | break; | ||
242 | } | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | /* Function for start TS */ | ||
247 | int saa7134_ts_start(struct saa7134_dev *dev) | ||
248 | { | ||
249 | dprintk("TS start\n"); | ||
250 | |||
251 | BUG_ON(dev->ts_started); | ||
252 | |||
253 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | ||
254 | saa_writeb(SAA7134_TS_SERIAL1, 0x03); | ||
255 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | ||
256 | saa_writeb(SAA7134_TS_SERIAL1, 0x01); | ||
257 | |||
258 | /* TS clock non-inverted */ | ||
259 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | ||
260 | |||
261 | /* Start TS stream */ | ||
262 | switch (saa7134_boards[dev->board].ts_type) { | ||
263 | case SAA7134_MPEG_TS_PARALLEL: | ||
264 | saa_writeb(SAA7134_TS_SERIAL0, 0x40); | ||
265 | saa_writeb(SAA7134_TS_PARALLEL, 0xec); | ||
266 | break; | ||
267 | case SAA7134_MPEG_TS_SERIAL: | ||
268 | saa_writeb(SAA7134_TS_SERIAL0, 0xd8); | ||
269 | saa_writeb(SAA7134_TS_PARALLEL, 0x6c); | ||
270 | saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc); | ||
271 | saa_writeb(SAA7134_TS_SERIAL1, 0x02); | ||
272 | break; | ||
273 | } | ||
274 | |||
275 | dev->ts_started = 1; | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
267 | int saa7134_ts_fini(struct saa7134_dev *dev) | 280 | int saa7134_ts_fini(struct saa7134_dev *dev) |
268 | { | 281 | { |
269 | saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts); | 282 | saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts); |
270 | return 0; | 283 | return 0; |
271 | } | 284 | } |
272 | 285 | ||
273 | |||
274 | void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status) | 286 | void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status) |
275 | { | 287 | { |
276 | enum v4l2_field field; | 288 | enum v4l2_field field; |
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index ae7602d343c1..82268848f26a 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
@@ -493,12 +493,6 @@ struct saa7134_mpeg_ops { | |||
493 | void (*signal_change)(struct saa7134_dev *dev); | 493 | void (*signal_change)(struct saa7134_dev *dev); |
494 | }; | 494 | }; |
495 | 495 | ||
496 | enum saa7134_ts_status { | ||
497 | SAA7134_TS_STOPPED, | ||
498 | SAA7134_TS_BUFF_DONE, | ||
499 | SAA7134_TS_STARTED, | ||
500 | }; | ||
501 | |||
502 | /* global device status */ | 496 | /* global device status */ |
503 | struct saa7134_dev { | 497 | struct saa7134_dev { |
504 | struct list_head devlist; | 498 | struct list_head devlist; |
@@ -593,8 +587,7 @@ struct saa7134_dev { | |||
593 | /* SAA7134_MPEG_* */ | 587 | /* SAA7134_MPEG_* */ |
594 | struct saa7134_ts ts; | 588 | struct saa7134_ts ts; |
595 | struct saa7134_dmaqueue ts_q; | 589 | struct saa7134_dmaqueue ts_q; |
596 | enum saa7134_ts_status ts_state; | 590 | int ts_started; |
597 | unsigned int buff_cnt; | ||
598 | struct saa7134_mpeg_ops *mops; | 591 | struct saa7134_mpeg_ops *mops; |
599 | 592 | ||
600 | /* SAA7134_MPEG_EMPRESS only */ | 593 | /* SAA7134_MPEG_EMPRESS only */ |
@@ -752,6 +745,9 @@ void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops); | |||
752 | 745 | ||
753 | int saa7134_ts_init_hw(struct saa7134_dev *dev); | 746 | int saa7134_ts_init_hw(struct saa7134_dev *dev); |
754 | 747 | ||
748 | int saa7134_ts_start(struct saa7134_dev *dev); | ||
749 | int saa7134_ts_stop(struct saa7134_dev *dev); | ||
750 | |||
755 | /* ----------------------------------------------------------- */ | 751 | /* ----------------------------------------------------------- */ |
756 | /* saa7134-vbi.c */ | 752 | /* saa7134-vbi.c */ |
757 | 753 | ||