saa7134-empress.c revision 718bde1aa9e03fd49d69816c4facea55d69a4737
1/*
2 *
3 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
4 *
5 *  This program is free software; you can redistribute it and/or modify
6 *  it under the terms of the GNU General Public License as published by
7 *  the Free Software Foundation; either version 2 of the License, or
8 *  (at your option) any later version.
9 *
10 *  This program is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 *  GNU General Public License for more details.
14 *
15 *  You should have received a copy of the GNU General Public License
16 *  along with this program; if not, write to the Free Software
17 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/init.h>
21#include <linux/list.h>
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/delay.h>
25
26#include "saa7134-reg.h"
27#include "saa7134.h"
28
29#include <media/saa6752hs.h>
30#include <media/v4l2-common.h>
31
32/* ------------------------------------------------------------------ */
33
34MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
35MODULE_LICENSE("GPL");
36
37static unsigned int empress_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
38
39module_param_array(empress_nr, int, NULL, 0444);
40MODULE_PARM_DESC(empress_nr,"ts device number");
41
42static unsigned int debug;
43module_param(debug, int, 0644);
44MODULE_PARM_DESC(debug,"enable debug messages");
45
46#define dprintk(fmt, arg...)	if (debug)			\
47	printk(KERN_DEBUG "%s/empress: " fmt, dev->name , ## arg)
48
49/* ------------------------------------------------------------------ */
50
51static void ts_reset_encoder(struct saa7134_dev* dev)
52{
53	if (!dev->empress_started)
54		return;
55
56	saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
57	msleep(10);
58	saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
59	msleep(100);
60	dev->empress_started = 0;
61}
62
63static int ts_init_encoder(struct saa7134_dev* dev)
64{
65	u32 leading_null_bytes = 0;
66
67	/* If more cards start to need this, then this
68	   should probably be added to the card definitions. */
69	switch (dev->board) {
70	case SAA7134_BOARD_BEHOLD_M6:
71	case SAA7134_BOARD_BEHOLD_M63:
72	case SAA7134_BOARD_BEHOLD_M6_EXTRA:
73		leading_null_bytes = 1;
74		break;
75	}
76	ts_reset_encoder(dev);
77	saa_call_all(dev, core, init, leading_null_bytes);
78	dev->empress_started = 1;
79	return 0;
80}
81
82/* ------------------------------------------------------------------ */
83
84static int ts_open(struct file *file)
85{
86	struct video_device *vdev = video_devdata(file);
87	struct saa7134_dev *dev = video_drvdata(file);
88	int err;
89
90	dprintk("open dev=%s\n", video_device_node_name(vdev));
91	err = -EBUSY;
92	if (!mutex_trylock(&dev->empress_tsq.vb_lock))
93		return err;
94	if (atomic_read(&dev->empress_users))
95		goto done;
96
97	/* Unmute audio */
98	saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
99		saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6));
100
101	atomic_inc(&dev->empress_users);
102	file->private_data = dev;
103	err = 0;
104
105done:
106	mutex_unlock(&dev->empress_tsq.vb_lock);
107	return err;
108}
109
110static int ts_release(struct file *file)
111{
112	struct saa7134_dev *dev = file->private_data;
113
114	videobuf_stop(&dev->empress_tsq);
115	videobuf_mmap_free(&dev->empress_tsq);
116
117	/* stop the encoder */
118	ts_reset_encoder(dev);
119
120	/* Mute audio */
121	saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
122		saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
123
124	atomic_dec(&dev->empress_users);
125
126	return 0;
127}
128
129static ssize_t
130ts_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
131{
132	struct saa7134_dev *dev = file->private_data;
133
134	if (!dev->empress_started)
135		ts_init_encoder(dev);
136
137	return videobuf_read_stream(&dev->empress_tsq,
138				    data, count, ppos, 0,
139				    file->f_flags & O_NONBLOCK);
140}
141
142static unsigned int
143ts_poll(struct file *file, struct poll_table_struct *wait)
144{
145	struct saa7134_dev *dev = file->private_data;
146
147	return videobuf_poll_stream(file, &dev->empress_tsq, wait);
148}
149
150
151static int
152ts_mmap(struct file *file, struct vm_area_struct * vma)
153{
154	struct saa7134_dev *dev = file->private_data;
155
156	return videobuf_mmap_mapper(&dev->empress_tsq, vma);
157}
158
159/*
160 * This function is _not_ called directly, but from
161 * video_generic_ioctl (and maybe others).  userspace
162 * copying is done already, arg is a kernel pointer.
163 */
164
165static int empress_querycap(struct file *file, void  *priv,
166					struct v4l2_capability *cap)
167{
168	struct saa7134_dev *dev = file->private_data;
169
170	strcpy(cap->driver, "saa7134");
171	strlcpy(cap->card, saa7134_boards[dev->board].name,
172		sizeof(cap->card));
173	sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
174	cap->capabilities =
175		V4L2_CAP_VIDEO_CAPTURE |
176		V4L2_CAP_READWRITE |
177		V4L2_CAP_STREAMING;
178	return 0;
179}
180
181static int empress_enum_input(struct file *file, void *priv,
182					struct v4l2_input *i)
183{
184	if (i->index != 0)
185		return -EINVAL;
186
187	i->type = V4L2_INPUT_TYPE_CAMERA;
188	strcpy(i->name, "CCIR656");
189
190	return 0;
191}
192
193static int empress_g_input(struct file *file, void *priv, unsigned int *i)
194{
195	*i = 0;
196	return 0;
197}
198
199static int empress_s_input(struct file *file, void *priv, unsigned int i)
200{
201	if (i != 0)
202		return -EINVAL;
203
204	return 0;
205}
206
207static int empress_enum_fmt_vid_cap(struct file *file, void  *priv,
208					struct v4l2_fmtdesc *f)
209{
210	if (f->index != 0)
211		return -EINVAL;
212
213	strlcpy(f->description, "MPEG TS", sizeof(f->description));
214	f->pixelformat = V4L2_PIX_FMT_MPEG;
215	f->flags = V4L2_FMT_FLAG_COMPRESSED;
216	return 0;
217}
218
219static int empress_g_fmt_vid_cap(struct file *file, void *priv,
220				struct v4l2_format *f)
221{
222	struct saa7134_dev *dev = file->private_data;
223	struct v4l2_mbus_framefmt mbus_fmt;
224
225	saa_call_all(dev, video, g_mbus_fmt, &mbus_fmt);
226
227	v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
228	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
229	f->fmt.pix.sizeimage    = TS_PACKET_SIZE * dev->ts.nr_packets;
230	f->fmt.pix.bytesperline = 0;
231	f->fmt.pix.priv = 0;
232
233	return 0;
234}
235
236static int empress_s_fmt_vid_cap(struct file *file, void *priv,
237				struct v4l2_format *f)
238{
239	struct saa7134_dev *dev = file->private_data;
240	struct v4l2_mbus_framefmt mbus_fmt;
241
242	v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
243	saa_call_all(dev, video, s_mbus_fmt, &mbus_fmt);
244	v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
245
246	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
247	f->fmt.pix.sizeimage    = TS_PACKET_SIZE * dev->ts.nr_packets;
248	f->fmt.pix.bytesperline = 0;
249	f->fmt.pix.priv = 0;
250
251	return 0;
252}
253
254static int empress_try_fmt_vid_cap(struct file *file, void *priv,
255				struct v4l2_format *f)
256{
257	struct saa7134_dev *dev = file->private_data;
258	struct v4l2_mbus_framefmt mbus_fmt;
259
260	v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
261	saa_call_all(dev, video, try_mbus_fmt, &mbus_fmt);
262	v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
263
264	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
265	f->fmt.pix.sizeimage    = TS_PACKET_SIZE * dev->ts.nr_packets;
266	f->fmt.pix.bytesperline = 0;
267	f->fmt.pix.priv = 0;
268
269	return 0;
270}
271
272static int empress_reqbufs(struct file *file, void *priv,
273					struct v4l2_requestbuffers *p)
274{
275	struct saa7134_dev *dev = file->private_data;
276
277	return videobuf_reqbufs(&dev->empress_tsq, p);
278}
279
280static int empress_querybuf(struct file *file, void *priv,
281					struct v4l2_buffer *b)
282{
283	struct saa7134_dev *dev = file->private_data;
284
285	return videobuf_querybuf(&dev->empress_tsq, b);
286}
287
288static int empress_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
289{
290	struct saa7134_dev *dev = file->private_data;
291
292	return videobuf_qbuf(&dev->empress_tsq, b);
293}
294
295static int empress_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
296{
297	struct saa7134_dev *dev = file->private_data;
298
299	return videobuf_dqbuf(&dev->empress_tsq, b,
300				file->f_flags & O_NONBLOCK);
301}
302
303static int empress_streamon(struct file *file, void *priv,
304					enum v4l2_buf_type type)
305{
306	struct saa7134_dev *dev = file->private_data;
307
308	return videobuf_streamon(&dev->empress_tsq);
309}
310
311static int empress_streamoff(struct file *file, void *priv,
312					enum v4l2_buf_type type)
313{
314	struct saa7134_dev *dev = file->private_data;
315
316	return videobuf_streamoff(&dev->empress_tsq);
317}
318
319static int empress_s_std(struct file *file, void *priv, v4l2_std_id id)
320{
321	struct saa7134_dev *dev = file->private_data;
322
323	return saa7134_s_std_internal(dev, NULL, id);
324}
325
326static int empress_g_std(struct file *file, void *priv, v4l2_std_id *id)
327{
328	struct saa7134_dev *dev = file->private_data;
329
330	*id = dev->tvnorm->id;
331	return 0;
332}
333
334static const struct v4l2_file_operations ts_fops =
335{
336	.owner	  = THIS_MODULE,
337	.open	  = ts_open,
338	.release  = ts_release,
339	.read	  = ts_read,
340	.poll	  = ts_poll,
341	.mmap	  = ts_mmap,
342	.ioctl	  = video_ioctl2,
343};
344
345static const struct v4l2_ioctl_ops ts_ioctl_ops = {
346	.vidioc_querycap		= empress_querycap,
347	.vidioc_enum_fmt_vid_cap	= empress_enum_fmt_vid_cap,
348	.vidioc_try_fmt_vid_cap		= empress_try_fmt_vid_cap,
349	.vidioc_s_fmt_vid_cap		= empress_s_fmt_vid_cap,
350	.vidioc_g_fmt_vid_cap		= empress_g_fmt_vid_cap,
351	.vidioc_reqbufs			= empress_reqbufs,
352	.vidioc_querybuf		= empress_querybuf,
353	.vidioc_qbuf			= empress_qbuf,
354	.vidioc_dqbuf			= empress_dqbuf,
355	.vidioc_streamon		= empress_streamon,
356	.vidioc_streamoff		= empress_streamoff,
357	.vidioc_enum_input		= empress_enum_input,
358	.vidioc_g_input			= empress_g_input,
359	.vidioc_s_input			= empress_s_input,
360	.vidioc_s_std			= empress_s_std,
361	.vidioc_g_std			= empress_g_std,
362};
363
364/* ----------------------------------------------------------- */
365
366static struct video_device saa7134_empress_template = {
367	.name          = "saa7134-empress",
368	.fops          = &ts_fops,
369	.ioctl_ops     = &ts_ioctl_ops,
370
371	.tvnorms			= SAA7134_NORMS,
372};
373
374static void empress_signal_update(struct work_struct *work)
375{
376	struct saa7134_dev* dev =
377		container_of(work, struct saa7134_dev, empress_workqueue);
378
379	if (dev->nosignal) {
380		dprintk("no video signal\n");
381	} else {
382		dprintk("video signal acquired\n");
383	}
384}
385
386static void empress_signal_change(struct saa7134_dev *dev)
387{
388	schedule_work(&dev->empress_workqueue);
389}
390
391static bool empress_ctrl_filter(const struct v4l2_ctrl *ctrl)
392{
393	switch (ctrl->id) {
394	case V4L2_CID_BRIGHTNESS:
395	case V4L2_CID_HUE:
396	case V4L2_CID_CONTRAST:
397	case V4L2_CID_SATURATION:
398	case V4L2_CID_AUDIO_MUTE:
399	case V4L2_CID_AUDIO_VOLUME:
400	case V4L2_CID_PRIVATE_INVERT:
401	case V4L2_CID_PRIVATE_AUTOMUTE:
402		return true;
403	default:
404		return false;
405	}
406}
407
408static int empress_init(struct saa7134_dev *dev)
409{
410	struct v4l2_ctrl_handler *hdl = &dev->empress_ctrl_handler;
411	int err;
412
413	dprintk("%s: %s\n",dev->name,__func__);
414	dev->empress_dev = video_device_alloc();
415	if (NULL == dev->empress_dev)
416		return -ENOMEM;
417	*(dev->empress_dev) = saa7134_empress_template;
418	dev->empress_dev->v4l2_dev  = &dev->v4l2_dev;
419	dev->empress_dev->release = video_device_release;
420	snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name),
421		 "%s empress (%s)", dev->name,
422		 saa7134_boards[dev->board].name);
423	v4l2_ctrl_handler_init(hdl, 21);
424	v4l2_ctrl_add_handler(hdl, &dev->ctrl_handler, empress_ctrl_filter);
425	if (dev->empress_sd)
426		v4l2_ctrl_add_handler(hdl, dev->empress_sd->ctrl_handler, NULL);
427	if (hdl->error) {
428		video_device_release(dev->empress_dev);
429		return hdl->error;
430	}
431	dev->empress_dev->ctrl_handler = hdl;
432
433	INIT_WORK(&dev->empress_workqueue, empress_signal_update);
434
435	video_set_drvdata(dev->empress_dev, dev);
436	err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER,
437				    empress_nr[dev->nr]);
438	if (err < 0) {
439		printk(KERN_INFO "%s: can't register video device\n",
440		       dev->name);
441		video_device_release(dev->empress_dev);
442		dev->empress_dev = NULL;
443		return err;
444	}
445	printk(KERN_INFO "%s: registered device %s [mpeg]\n",
446	       dev->name, video_device_node_name(dev->empress_dev));
447
448	videobuf_queue_sg_init(&dev->empress_tsq, &saa7134_ts_qops,
449			    &dev->pci->dev, &dev->slock,
450			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
451			    V4L2_FIELD_ALTERNATE,
452			    sizeof(struct saa7134_buf),
453			    dev, NULL);
454
455	empress_signal_update(&dev->empress_workqueue);
456	return 0;
457}
458
459static int empress_fini(struct saa7134_dev *dev)
460{
461	dprintk("%s: %s\n",dev->name,__func__);
462
463	if (NULL == dev->empress_dev)
464		return 0;
465	flush_work(&dev->empress_workqueue);
466	video_unregister_device(dev->empress_dev);
467	v4l2_ctrl_handler_free(&dev->empress_ctrl_handler);
468	dev->empress_dev = NULL;
469	return 0;
470}
471
472static struct saa7134_mpeg_ops empress_ops = {
473	.type          = SAA7134_MPEG_EMPRESS,
474	.init          = empress_init,
475	.fini          = empress_fini,
476	.signal_change = empress_signal_change,
477};
478
479static int __init empress_register(void)
480{
481	return saa7134_ts_register(&empress_ops);
482}
483
484static void __exit empress_unregister(void)
485{
486	saa7134_ts_unregister(&empress_ops);
487}
488
489module_init(empress_register);
490module_exit(empress_unregister);
491
492/* ----------------------------------------------------------- */
493/*
494 * Local variables:
495 * c-basic-offset: 8
496 * End:
497 */
498