2 * device driver for philips saa7134 based TV cards
3 * video4linux video interface
5 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <linux/init.h>
23 #include <linux/list.h>
24 #include <linux/module.h>
25 #include <linux/kernel.h>
26 #include <linux/slab.h>
27 #include <linux/delay.h>
29 #include "saa7134-reg.h"
32 #include <media/saa6752hs.h>
34 /* ------------------------------------------------------------------ */
36 #define TS_PACKET_SIZE 188 /* TS packets 188 bytes */
38 static unsigned int ts_debug
= 0;
39 MODULE_PARM(ts_debug
,"i");
40 MODULE_PARM_DESC(ts_debug
,"enable debug messages [ts]");
42 static unsigned int tsbufs
= 4;
43 MODULE_PARM(tsbufs
,"i");
44 MODULE_PARM_DESC(tsbufs
,"number of ts buffers, range 2-32");
46 static unsigned int ts_nr_packets
= 30;
47 MODULE_PARM(ts_nr_packets
,"i");
48 MODULE_PARM_DESC(ts_nr_packets
,"size of a ts buffers (in ts packets)");
50 #define dprintk(fmt, arg...) if (ts_debug) \
51 printk(KERN_DEBUG "%s/ts: " fmt, dev->name , ## arg)
53 /* ------------------------------------------------------------------ */
55 static int buffer_activate(struct saa7134_dev
*dev
,
56 struct saa7134_buf
*buf
,
57 struct saa7134_buf
*next
)
61 dprintk("buffer_activate [%p]",buf
);
62 buf
->vb
.state
= STATE_ACTIVE
;
65 /* dma: setup channel 5 (= TS) */
66 control
= SAA7134_RS_CONTROL_BURST_16
|
67 SAA7134_RS_CONTROL_ME
|
72 if (V4L2_FIELD_TOP
== buf
->vb
.field
) {
73 dprintk("- [top] buf=%p next=%p\n",buf
,next
);
74 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf
));
75 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next
));
77 dprintk("- [bottom] buf=%p next=%p\n",buf
,next
);
78 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next
));
79 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf
));
81 saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE
);
82 saa_writel(SAA7134_RS_CONTROL(5),control
);
85 saa7134_set_dmabits(dev
);
87 mod_timer(&dev
->ts_q
.timeout
, jiffies
+BUFFER_TIMEOUT
);
91 static int buffer_prepare(struct file
*file
, struct videobuf_buffer
*vb
,
92 enum v4l2_field field
)
94 struct saa7134_dev
*dev
= file
->private_data
;
95 struct saa7134_buf
*buf
= (struct saa7134_buf
*)vb
;
96 unsigned int lines
, llength
, size
;
99 dprintk("buffer_prepare [%p,%s]\n",buf
,v4l2_field_names
[field
]);
101 llength
= TS_PACKET_SIZE
;
102 lines
= ts_nr_packets
;
104 size
= lines
* llength
;
105 if (0 != buf
->vb
.baddr
&& buf
->vb
.bsize
< size
)
108 if (buf
->vb
.size
!= size
) {
109 saa7134_dma_free(dev
,buf
);
112 if (STATE_NEEDS_INIT
== buf
->vb
.state
) {
113 buf
->vb
.width
= llength
;
114 buf
->vb
.height
= lines
;
116 buf
->pt
= &dev
->ts
.pt_ts
;
118 err
= videobuf_iolock(dev
->pci
,&buf
->vb
,NULL
);
121 err
= saa7134_pgtable_build(dev
->pci
,buf
->pt
,
124 saa7134_buffer_startpage(buf
));
128 buf
->vb
.state
= STATE_PREPARED
;
129 buf
->activate
= buffer_activate
;
130 buf
->vb
.field
= field
;
134 saa7134_dma_free(dev
,buf
);
139 buffer_setup(struct file
*file
, unsigned int *count
, unsigned int *size
)
141 *size
= TS_PACKET_SIZE
* ts_nr_packets
;
144 *count
= saa7134_buffer_count(*size
,*count
);
148 static void buffer_queue(struct file
*file
, struct videobuf_buffer
*vb
)
150 struct saa7134_dev
*dev
= file
->private_data
;
151 struct saa7134_buf
*buf
= (struct saa7134_buf
*)vb
;
153 saa7134_buffer_queue(dev
,&dev
->ts_q
,buf
);
156 static void buffer_release(struct file
*file
, struct videobuf_buffer
*vb
)
158 struct saa7134_dev
*dev
= file
->private_data
;
159 struct saa7134_buf
*buf
= (struct saa7134_buf
*)vb
;
161 saa7134_dma_free(dev
,buf
);
164 static struct videobuf_queue_ops ts_qops
= {
165 .buf_setup
= buffer_setup
,
166 .buf_prepare
= buffer_prepare
,
167 .buf_queue
= buffer_queue
,
168 .buf_release
= buffer_release
,
172 /* ------------------------------------------------------------------ */
174 static void ts_reset_encoder(struct saa7134_dev
* dev
)
176 saa_writeb(SAA7134_SPECIAL_MODE
, 0x00);
178 saa_writeb(SAA7134_SPECIAL_MODE
, 0x01);
179 set_current_state(TASK_INTERRUPTIBLE
);
180 schedule_timeout(HZ
/10);
183 static int ts_init_encoder(struct saa7134_dev
* dev
, void* arg
)
185 ts_reset_encoder(dev
);
186 saa7134_i2c_call_clients(dev
, MPEG_SETPARAMS
, arg
);
191 /* ------------------------------------------------------------------ */
193 static int ts_open(struct inode
*inode
, struct file
*file
)
195 int minor
= iminor(inode
);
196 struct saa7134_dev
*h
,*dev
= NULL
;
197 struct list_head
*list
;
200 list_for_each(list
,&saa7134_devlist
) {
201 h
= list_entry(list
, struct saa7134_dev
, devlist
);
202 if (h
->ts_dev
&& h
->ts_dev
->minor
== minor
)
208 dprintk("open minor=%d\n",minor
);
209 down(&dev
->ts
.ts
.lock
);
216 file
->private_data
= dev
;
220 up(&dev
->ts
.ts
.lock
);
224 static int ts_release(struct inode
*inode
, struct file
*file
)
226 struct saa7134_dev
*dev
= file
->private_data
;
228 if (dev
->ts
.ts
.streaming
)
229 videobuf_streamoff(file
,&dev
->ts
.ts
);
230 down(&dev
->ts
.ts
.lock
);
231 if (dev
->ts
.ts
.reading
)
232 videobuf_read_stop(file
,&dev
->ts
.ts
);
235 /* stop the encoder */
237 ts_reset_encoder(dev
);
239 up(&dev
->ts
.ts
.lock
);
244 ts_read(struct file
*file
, char __user
*data
, size_t count
, loff_t
*ppos
)
246 struct saa7134_dev
*dev
= file
->private_data
;
248 if (!dev
->ts
.started
) {
249 ts_init_encoder(dev
, NULL
);
253 return videobuf_read_stream(file
, &dev
->ts
.ts
, data
, count
, ppos
, 0);
257 ts_poll(struct file
*file
, struct poll_table_struct
*wait
)
259 struct saa7134_dev
*dev
= file
->private_data
;
261 return videobuf_poll_stream(file
, &dev
->ts
.ts
, wait
);
266 ts_mmap(struct file
*file
, struct vm_area_struct
* vma
)
268 struct saa7134_dev
*dev
= file
->private_data
;
270 return videobuf_mmap_mapper(vma
, &dev
->ts
.ts
);
274 * This function is _not_ called directly, but from
275 * video_generic_ioctl (and maybe others). userspace
276 * copying is done already, arg is a kernel pointer.
278 static int ts_do_ioctl(struct inode
*inode
, struct file
*file
,
279 unsigned int cmd
, void *arg
)
281 struct saa7134_dev
*dev
= file
->private_data
;
284 saa7134_print_ioctl(dev
->name
,cmd
);
286 case VIDIOC_QUERYCAP
:
288 struct v4l2_capability
*cap
= arg
;
290 memset(cap
,0,sizeof(*cap
));
291 strcpy(cap
->driver
, "saa7134");
292 strlcpy(cap
->card
, saa7134_boards
[dev
->board
].name
,
294 sprintf(cap
->bus_info
,"PCI:%s",pci_name(dev
->pci
));
295 cap
->version
= SAA7134_VERSION_CODE
;
297 V4L2_CAP_VIDEO_CAPTURE
|
303 /* --- input switching --------------------------------------- */
304 case VIDIOC_ENUMINPUT
:
306 struct v4l2_input
*i
= arg
;
310 i
->type
= V4L2_INPUT_TYPE_CAMERA
;
311 strcpy(i
->name
,"CCIR656");
328 /* --- capture ioctls ---------------------------------------- */
330 case VIDIOC_ENUM_FMT
:
332 struct v4l2_fmtdesc
*f
= arg
;
339 memset(f
,0,sizeof(*f
));
341 strlcpy(f
->description
, "MPEG TS", sizeof(f
->description
));
342 f
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
343 f
->pixelformat
= V4L2_PIX_FMT_MPEG
;
349 struct v4l2_format
*f
= arg
;
351 memset(f
,0,sizeof(*f
));
352 f
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
354 /* FIXME: translate subsampling type EMPRESS into
356 f
->fmt
.pix
.width
= 720; /* D1 */
357 f
->fmt
.pix
.height
= 576;
358 f
->fmt
.pix
.pixelformat
= V4L2_PIX_FMT_MPEG
;
359 f
->fmt
.pix
.sizeimage
= TS_PACKET_SIZE
*ts_nr_packets
;
365 struct v4l2_format
*f
= arg
;
367 if (f
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
371 FIXME: translate and round width/height into EMPRESS
375 ---------------------------
376 SIF | 352x288 | 352x240
377 1/2 D1 | 352x576 | 352x480
378 2/3 D1 | 480x576 | 480x480
379 D1 | 720x576 | 720x480
382 f
->fmt
.pix
.width
= 720; /* D1 */
383 f
->fmt
.pix
.height
= 576;
384 f
->fmt
.pix
.pixelformat
= V4L2_PIX_FMT_MPEG
;
385 f
->fmt
.pix
.sizeimage
= TS_PACKET_SIZE
*ts_nr_packets
;
390 return videobuf_reqbufs(file
,&dev
->ts
.ts
,arg
);
392 case VIDIOC_QUERYBUF
:
393 return videobuf_querybuf(&dev
->ts
.ts
,arg
);
396 return videobuf_qbuf(file
,&dev
->ts
.ts
,arg
);
399 return videobuf_dqbuf(file
,&dev
->ts
.ts
,arg
);
401 case VIDIOC_STREAMON
:
402 return videobuf_streamon(file
,&dev
->ts
.ts
);
404 case VIDIOC_STREAMOFF
:
405 return videobuf_streamoff(file
,&dev
->ts
.ts
);
407 case VIDIOC_QUERYCTRL
:
410 return saa7134_common_ioctl(dev
, cmd
, arg
);
413 return ts_init_encoder(dev
, arg
);
421 static int ts_ioctl(struct inode
*inode
, struct file
*file
,
422 unsigned int cmd
, unsigned long arg
)
424 return video_usercopy(inode
, file
, cmd
, arg
, ts_do_ioctl
);
428 static struct file_operations ts_fops
=
430 .owner
= THIS_MODULE
,
432 .release
= ts_release
,
441 /* ----------------------------------------------------------- */
444 struct video_device saa7134_ts_template
=
446 .name
= "saa7134-ts",
447 .type
= 0 /* FIXME */,
448 .type2
= 0 /* FIXME */,
454 int saa7134_ts_init1(struct saa7134_dev
*dev
)
456 /* sanitycheck insmod options */
459 if (tsbufs
> VIDEO_MAX_FRAME
)
460 tsbufs
= VIDEO_MAX_FRAME
;
461 if (ts_nr_packets
< 4)
463 if (ts_nr_packets
> 312)
466 INIT_LIST_HEAD(&dev
->ts_q
.queue
);
467 init_timer(&dev
->ts_q
.timeout
);
468 dev
->ts_q
.timeout
.function
= saa7134_buffer_timeout
;
469 dev
->ts_q
.timeout
.data
= (unsigned long)(&dev
->ts_q
);
471 dev
->ts_q
.need_two
= 1;
472 videobuf_queue_init(&dev
->ts
.ts
, &ts_qops
, dev
->pci
, &dev
->slock
,
473 V4L2_BUF_TYPE_VIDEO_CAPTURE
,
474 V4L2_FIELD_ALTERNATE
,
475 sizeof(struct saa7134_buf
));
476 saa7134_pgtable_alloc(dev
->pci
,&dev
->ts
.pt_ts
);
479 saa_writeb(SAA7134_TS_SERIAL1
, 0x00); /* deactivate TS softreset */
480 saa_writeb(SAA7134_TS_PARALLEL
, 0xec); /* TSSOP high active, TSVAL high active, TSLOCK ignored */
481 saa_writeb(SAA7134_TS_PARALLEL_SERIAL
, (TS_PACKET_SIZE
-1));
482 saa_writeb(SAA7134_TS_DMA0
, ((ts_nr_packets
-1)&0xff));
483 saa_writeb(SAA7134_TS_DMA1
, (((ts_nr_packets
-1)>>8)&0xff));
484 saa_writeb(SAA7134_TS_DMA2
, ((((ts_nr_packets
-1)>>16)&0x3f) | 0x00)); /* TSNOPIT=0, TSCOLAP=0 */
489 int saa7134_ts_fini(struct saa7134_dev
*dev
)
492 saa7134_pgtable_free(dev
->pci
,&dev
->ts
.pt_ts
);
497 void saa7134_irq_ts_done(struct saa7134_dev
*dev
, unsigned long status
)
499 enum v4l2_field field
;
501 spin_lock(&dev
->slock
);
502 if (dev
->ts_q
.curr
) {
503 field
= dev
->ts_q
.curr
->vb
.field
;
504 if (field
== V4L2_FIELD_TOP
) {
505 if ((status
& 0x100000) != 0x100000)
508 if ((status
& 0x100000) != 0x000000)
511 saa7134_buffer_finish(dev
,&dev
->ts_q
,STATE_DONE
);
513 saa7134_buffer_next(dev
,&dev
->ts_q
);
516 spin_unlock(&dev
->slock
);
519 /* ----------------------------------------------------------- */