blob: d7d2fe009ff97e380301cff531e9c6a7d2f2919d [file] [log] [blame]
Steven Toth9b8b0192010-07-31 14:39:44 -03001/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
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.
20 */
21
22#include "saa7164.h"
23
Steven Toth7615e432010-07-31 14:44:53 -030024#define ENCODER_MAX_BITRATE 6500000
25#define ENCODER_MIN_BITRATE 1000000
26#define ENCODER_DEF_BITRATE 5000000
27
28static struct saa7164_tvnorm saa7164_tvnorms[] = {
29 {
30 .name = "NTSC-M",
31 .id = V4L2_STD_NTSC_M,
32 }, {
33 .name = "NTSC-JP",
34 .id = V4L2_STD_NTSC_M_JP,
35 }
36};
37
38static const u32 saa7164_v4l2_ctrls[] = {
39 V4L2_CID_BRIGHTNESS,
40 V4L2_CID_CONTRAST,
41 V4L2_CID_SATURATION,
42 V4L2_CID_HUE,
43 V4L2_CID_AUDIO_VOLUME,
44 V4L2_CID_SHARPNESS,
45 V4L2_CID_MPEG_VIDEO_ASPECT,
46 V4L2_CID_MPEG_STREAM_TYPE,
47 V4L2_CID_MPEG_AUDIO_MUTE,
Steven Toth2600d712010-07-31 14:51:30 -030048 V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
Steven Toth7615e432010-07-31 14:44:53 -030049 V4L2_CID_MPEG_VIDEO_BITRATE,
50 0
51};
52
53/* Take the encoder configuration form the port struct and
54 * flush it to the hardware.
55 */
56static void saa7164_encoder_configure(struct saa7164_port *port)
57{
58 struct saa7164_dev *dev = port->dev;
59 dprintk(DBGLVL_ENC, "%s()\n", __func__);
60
61 port->encoder_params.width = port->width;
62 port->encoder_params.height = port->height;
63 port->encoder_params.is_50hz =
64 (port->encodernorm.id & V4L2_STD_625_50) != 0;
65
66 /* Set up the DIF (enable it) for analog mode by default */
67 saa7164_api_initialize_dif(port);
68
69 /* Configure the correct video standard */
70 saa7164_api_configure_dif(port, port->encodernorm.id);
71
72 /* Ensure the audio decoder is correct configured */
73 saa7164_api_set_audio_std(port);
74}
75
76/* One time configuration at registration time */
77static int saa7164_encoder_initialize(struct saa7164_port *port)
78{
79 struct saa7164_dev *dev = port->dev;
80
81 dprintk(DBGLVL_ENC, "%s()\n", __func__);
82
83 saa7164_encoder_configure(port);
84
85 return 0;
86}
87
88/* -- V4L2 --------------------------------------------------------- */
89static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
90{
91 struct saa7164_fh *fh = file->private_data;
92 struct saa7164_port *port = fh->port;
93 struct saa7164_dev *dev = port->dev;
94 unsigned int i;
95
96 dprintk(DBGLVL_ENC, "%s(id=0x%x)\n", __func__, (u32)*id);
97
98 for (i = 0; i < ARRAY_SIZE(saa7164_tvnorms); i++) {
99 if (*id & saa7164_tvnorms[i].id)
100 break;
101 }
102 if (i == ARRAY_SIZE(saa7164_tvnorms))
103 return -EINVAL;
104
105 port->encodernorm = saa7164_tvnorms[i];
106
107 /* Update the audio decoder while is not running in
108 * auto detect mode.
109 */
110 saa7164_api_set_audio_std(port);
111
112 dprintk(DBGLVL_ENC, "%s(id=0x%x) OK\n", __func__, (u32)*id);
113
114 return 0;
115}
116
117static int vidioc_enum_input(struct file *file, void *priv,
118 struct v4l2_input *i)
119{
120 int n;
121
122 char *inputs[] = { "tuner", "composite", "svideo", "aux",
123 "composite", "svideo", "aux" };
124
125 if (i->index >= 7)
126 return -EINVAL;
127
128 strcpy(i->name, inputs[ i->index ]);
129
130 if (i->index == 0)
131 i->type = V4L2_INPUT_TYPE_TUNER;
132 else
133 i->type = V4L2_INPUT_TYPE_CAMERA;
134
135 for (n = 0; n < ARRAY_SIZE(saa7164_tvnorms); n++)
136 i->std |= saa7164_tvnorms[n].id;
137
138 return 0;
139}
140
141static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
142{
143 struct saa7164_fh *fh = file->private_data;
144 struct saa7164_port *port = fh->port;
145 struct saa7164_dev *dev = port->dev;
146
147 if (saa7164_api_get_videomux(port) != SAA_OK)
148 return -EIO;
149
150 *i = (port->mux_input - 1);
151
152 dprintk(DBGLVL_ENC, "%s() input=%d\n", __func__, *i);
153
154 return 0;
155}
156
157static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
158{
159 struct saa7164_fh *fh = file->private_data;
160 struct saa7164_port *port = fh->port;
161 struct saa7164_dev *dev = port->dev;
162
163 dprintk(DBGLVL_ENC, "%s() input=%d\n", __func__, i);
164
165 if (i >= 7)
166 return -EINVAL;
167
168 port->mux_input = i + 1;
169
170 if (saa7164_api_set_videomux(port) != SAA_OK)
171 return -EIO;
172
173 return 0;
174}
175
176static int vidioc_g_tuner(struct file *file, void *priv,
177 struct v4l2_tuner *t)
178{
179 struct saa7164_fh *fh = file->private_data;
180 struct saa7164_port *port = fh->port;
181 struct saa7164_dev *dev = port->dev;
182
183 if (0 != t->index)
184 return -EINVAL;
185
186 strcpy(t->name, "tuner");
187 t->type = V4L2_TUNER_ANALOG_TV;
188 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO;
189
190 dprintk(DBGLVL_ENC, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
191
192 return 0;
193}
194
195static int vidioc_s_tuner(struct file *file, void *priv,
196 struct v4l2_tuner *t)
197{
198
199 /* Update the A/V core */
200
201 return 0;
202}
203
204static int vidioc_g_frequency(struct file *file, void *priv,
205 struct v4l2_frequency *f)
206{
207 struct saa7164_fh *fh = file->private_data;
208 struct saa7164_port *port = fh->port;
209
210 f->type = V4L2_TUNER_ANALOG_TV;
211 f->frequency = port->freq;
212
213 return 0;
214}
215
216static int vidioc_s_frequency(struct file *file, void *priv,
217 struct v4l2_frequency *f)
218{
219 struct saa7164_fh *fh = file->private_data;
220 struct saa7164_port *port = fh->port;
221 struct saa7164_dev *dev = port->dev;
222 struct saa7164_port *tsport;
223 struct dvb_frontend *fe;
224
225 /* TODO: Pull this for the std */
226 struct analog_parameters params = {
227 .mode = V4L2_TUNER_ANALOG_TV,
228 .audmode = V4L2_TUNER_MODE_STEREO,
229 .std = port->encodernorm.id,
230 .frequency = f->frequency
231 };
232
233 /* Stop the encoder */
234 dprintk(DBGLVL_ENC, "%s() frequency=%d tuner=%d\n", __func__,
235 f->frequency, f->tuner);
236
237 if (f->tuner != 0)
238 return -EINVAL;
239
240 if (f->type != V4L2_TUNER_ANALOG_TV)
241 return -EINVAL;
242
243 port->freq = f->frequency;
244
245 /* Update the hardware */
246 if (port->nr == SAA7164_PORT_ENC1)
247 tsport = &dev->ports[ SAA7164_PORT_TS1 ];
248 else
249 if (port->nr == SAA7164_PORT_ENC2)
250 tsport = &dev->ports[ SAA7164_PORT_TS2 ];
251 else
252 BUG();
253
254 fe = tsport->dvb.frontend;
255
256 if (fe && fe->ops.tuner_ops.set_analog_params)
257 fe->ops.tuner_ops.set_analog_params(fe, &params);
258 else
259 printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__);
260
261 saa7164_encoder_initialize(port);
262
263 return 0;
264}
265
266static int vidioc_g_ctrl(struct file *file, void *priv,
267 struct v4l2_control *ctl)
268{
269 struct saa7164_fh *fh = file->private_data;
270 struct saa7164_port *port = fh->port;
271 struct saa7164_dev *dev = port->dev;
272
273 dprintk(DBGLVL_ENC, "%s(id=%d, value=%d)\n", __func__,
274 ctl->id, ctl->value);
275
276 switch (ctl->id) {
277 case V4L2_CID_BRIGHTNESS:
278 ctl->value = port->ctl_brightness;
279 break;
280 case V4L2_CID_CONTRAST:
281 ctl->value = port->ctl_contrast;
282 break;
283 case V4L2_CID_SATURATION:
284 ctl->value = port->ctl_saturation;
285 break;
286 case V4L2_CID_HUE:
287 ctl->value = port->ctl_hue;
288 break;
289 case V4L2_CID_SHARPNESS:
290 ctl->value = port->ctl_sharpness;
291 break;
292 case V4L2_CID_AUDIO_VOLUME:
293 ctl->value = port->ctl_volume;
294 break;
295 default:
296 return -EINVAL;
297 }
298
299 return 0;
300}
301
302static int vidioc_s_ctrl(struct file *file, void *priv,
303 struct v4l2_control *ctl)
304{
305 struct saa7164_fh *fh = file->private_data;
306 struct saa7164_port *port = fh->port;
307 struct saa7164_dev *dev = port->dev;
308 int ret = 0;
309
310 dprintk(DBGLVL_ENC, "%s(id=%d, value=%d)\n", __func__,
311 ctl->id, ctl->value);
312
313 switch (ctl->id) {
314 case V4L2_CID_BRIGHTNESS:
315 if ((ctl->value >= 0) && (ctl->value <= 255)) {
316 port->ctl_brightness = ctl->value;
317 saa7164_api_set_usercontrol(port,
318 PU_BRIGHTNESS_CONTROL);
319 } else
320 ret = -EINVAL;
321 break;
322 case V4L2_CID_CONTRAST:
323 if ((ctl->value >= 0) && (ctl->value <= 255)) {
324 port->ctl_contrast = ctl->value;
325 saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL);
326 } else
327 ret = -EINVAL;
328 break;
329 case V4L2_CID_SATURATION:
330 if ((ctl->value >= 0) && (ctl->value <= 255)) {
331 port->ctl_saturation = ctl->value;
332 saa7164_api_set_usercontrol(port,
333 PU_SATURATION_CONTROL);
334 } else
335 ret = -EINVAL;
336 break;
337 case V4L2_CID_HUE:
338 if ((ctl->value >= 0) && (ctl->value <= 255)) {
339 port->ctl_hue = ctl->value;
340 saa7164_api_set_usercontrol(port, PU_HUE_CONTROL);
341 } else
342 ret = -EINVAL;
343 break;
344 case V4L2_CID_SHARPNESS:
345 if ((ctl->value >= 0) && (ctl->value <= 255)) {
346 port->ctl_sharpness = ctl->value;
347 saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL);
348 } else
349 ret = -EINVAL;
350 break;
351 case V4L2_CID_AUDIO_VOLUME:
352 if ((ctl->value >= -83) && (ctl->value <= 24)) {
353 port->ctl_volume = ctl->value;
354 saa7164_api_set_audio_volume(port, port->ctl_volume);
355 } else
356 ret = -EINVAL;
357 break;
358 default:
359 ret = -EINVAL;
360 }
361
362 return ret;
363}
364
365static int saa7164_get_ctrl(struct saa7164_port *port,
366 struct v4l2_ext_control *ctrl)
367{
368 struct saa7164_encoder_params *params = &port->encoder_params;
369
370 switch (ctrl->id) {
371 case V4L2_CID_MPEG_VIDEO_BITRATE:
372 ctrl->value = params->bitrate;
373 break;
374 case V4L2_CID_MPEG_STREAM_TYPE:
375 ctrl->value = params->stream_type;
376 break;
377 case V4L2_CID_MPEG_AUDIO_MUTE:
378 ctrl->value = params->ctl_mute;
379 break;
380 case V4L2_CID_MPEG_VIDEO_ASPECT:
381 ctrl->value = params->ctl_aspect;
382 break;
Steven Toth2600d712010-07-31 14:51:30 -0300383 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
384 ctrl->value = params->bitrate_mode;
385 break;
Steven Toth7615e432010-07-31 14:44:53 -0300386 default:
387 return -EINVAL;
388 }
389 return 0;
390}
391
392static int vidioc_g_ext_ctrls(struct file *file, void *priv,
393 struct v4l2_ext_controls *ctrls)
394{
395 struct saa7164_fh *fh = file->private_data;
396 struct saa7164_port *port = fh->port;
397 int i, err = 0;
398
399 if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
400 for (i = 0; i < ctrls->count; i++) {
401 struct v4l2_ext_control *ctrl = ctrls->controls + i;
402
403 err = saa7164_get_ctrl(port, ctrl);
404 if (err) {
405 ctrls->error_idx = i;
406 break;
407 }
408 }
409 return err;
410
411 }
412
413 return -EINVAL;
414}
415
416static int saa7164_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
417{
418 int ret = -EINVAL;
419
420 switch (ctrl->id) {
421 case V4L2_CID_MPEG_VIDEO_BITRATE:
422 if ((ctrl->value >= ENCODER_MIN_BITRATE) &&
423 (ctrl->value <= ENCODER_MAX_BITRATE))
424 ret = 0;
425 break;
426 case V4L2_CID_MPEG_STREAM_TYPE:
427 if (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_PS)
428 ret = 0;
429 break;
430 case V4L2_CID_MPEG_AUDIO_MUTE:
431 if ((ctrl->value >= 0) &&
432 (ctrl->value <= 1))
433 ret = 0;
434 break;
435 case V4L2_CID_MPEG_VIDEO_ASPECT:
436 if ((ctrl->value >= V4L2_MPEG_VIDEO_ASPECT_1x1) &&
437 (ctrl->value <= V4L2_MPEG_VIDEO_ASPECT_221x100))
438 ret = 0;
439 break;
440 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
441 if ((ctrl->value >= 0) &&
442 (ctrl->value <= 255))
443 ret = 0;
444 break;
Steven Toth2600d712010-07-31 14:51:30 -0300445 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
446 if ((ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) ||
447 (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR))
448 ret = 0;
449 break;
Steven Toth7615e432010-07-31 14:44:53 -0300450 default:
451 ret = -EINVAL;
452 }
453
454 return ret;
455}
456
457static int vidioc_try_ext_ctrls(struct file *file, void *priv,
458 struct v4l2_ext_controls *ctrls)
459{
460 int i, err = 0;
461
462 if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
463 for (i = 0; i < ctrls->count; i++) {
464 struct v4l2_ext_control *ctrl = ctrls->controls + i;
465
466 err = saa7164_try_ctrl(ctrl, 0);
467 if (err) {
468 ctrls->error_idx = i;
469 break;
470 }
471 }
472 return err;
473 }
474
475 return -EINVAL;
476}
477
478static int saa7164_set_ctrl(struct saa7164_port *port,
479 struct v4l2_ext_control *ctrl)
480{
481 struct saa7164_encoder_params *params = &port->encoder_params;
482 int ret = 0;
483
484 switch (ctrl->id) {
485 case V4L2_CID_MPEG_VIDEO_BITRATE:
486 params->bitrate = ctrl->value;
487 break;
488 case V4L2_CID_MPEG_STREAM_TYPE:
489 params->stream_type = ctrl->value;
490 break;
491 case V4L2_CID_MPEG_AUDIO_MUTE:
492 params->ctl_mute = ctrl->value;
493 ret = saa7164_api_audio_mute(port, params->ctl_mute);
494 if (ret != SAA_OK) {
495 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
496 ret);
497 ret = -EIO;
498 }
499 break;
500 case V4L2_CID_MPEG_VIDEO_ASPECT:
501 params->ctl_aspect = ctrl->value;
502 ret = saa7164_api_set_aspect_ratio(port);
503 if (ret != SAA_OK) {
504 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
505 ret);
506 ret = -EIO;
507 }
508 break;
Steven Toth2600d712010-07-31 14:51:30 -0300509 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
510 params->bitrate_mode = ctrl->value;
511 break;
Steven Toth7615e432010-07-31 14:44:53 -0300512 default:
513 return -EINVAL;
514 }
515
516 /* TODO: Update the hardware */
517
518 return ret;
519}
520
521static int vidioc_s_ext_ctrls(struct file *file, void *priv,
522 struct v4l2_ext_controls *ctrls)
523{
524 struct saa7164_fh *fh = file->private_data;
525 struct saa7164_port *port = fh->port;
526 int i, err = 0;
527
528 if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
529 for (i = 0; i < ctrls->count; i++) {
530 struct v4l2_ext_control *ctrl = ctrls->controls + i;
531
532 err = saa7164_try_ctrl(ctrl, 0);
533 if (err) {
534 ctrls->error_idx = i;
535 break;
536 }
537 err = saa7164_set_ctrl(port, ctrl);
538 if (err) {
539 ctrls->error_idx = i;
540 break;
541 }
542 }
543 return err;
544
545 }
546
547 return -EINVAL;
548}
549
550static int vidioc_querycap(struct file *file, void *priv,
551 struct v4l2_capability *cap)
552{
553 struct saa7164_fh *fh = file->private_data;
554 struct saa7164_port *port = fh->port;
555 struct saa7164_dev *dev = port->dev;
556
557 strcpy(cap->driver, dev->name);
558 strlcpy(cap->card, saa7164_boards[dev->board].name,
559 sizeof(cap->card));
560 sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
561
562 cap->capabilities =
563 V4L2_CAP_VIDEO_CAPTURE |
564 V4L2_CAP_READWRITE |
565 V4L2_CAP_STREAMING |
566 0;
567
568 cap->capabilities |= V4L2_CAP_TUNER;
569 cap->version = 0;
570
571 return 0;
572}
573
574static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
575 struct v4l2_fmtdesc *f)
576{
577 if (f->index != 0)
578 return -EINVAL;
579
580 strlcpy(f->description, "MPEG", sizeof(f->description));
581 f->pixelformat = V4L2_PIX_FMT_MPEG;
582
583 return 0;
584}
585
586static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
587 struct v4l2_format *f)
588{
589 struct saa7164_fh *fh = file->private_data;
590 struct saa7164_port *port = fh->port;
591 struct saa7164_dev *dev = port->dev;
592
593 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
594 f->fmt.pix.bytesperline = 0;
595 f->fmt.pix.sizeimage =
596 port->ts_packet_size * port->ts_packet_count;
597 f->fmt.pix.colorspace = 0;
598 f->fmt.pix.width = port->width;
599 f->fmt.pix.height = port->height;
600
601 dprintk(DBGLVL_ENC, "VIDIOC_G_FMT: w: %d, h: %d\n",
602 port->width, port->height);
603
604 return 0;
605}
606
607static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
608 struct v4l2_format *f)
609{
610 struct saa7164_fh *fh = file->private_data;
611 struct saa7164_port *port = fh->port;
612 struct saa7164_dev *dev = port->dev;
613
614 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
615 f->fmt.pix.bytesperline = 0;
616 f->fmt.pix.sizeimage =
617 port->ts_packet_size * port->ts_packet_count;
618 f->fmt.pix.colorspace = 0;
619 dprintk(DBGLVL_ENC, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
620 port->width, port->height);
621 return 0;
622}
623
624static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
625 struct v4l2_format *f)
626{
627 struct saa7164_fh *fh = file->private_data;
628 struct saa7164_port *port = fh->port;
629 struct saa7164_dev *dev = port->dev;
630
631 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
632 f->fmt.pix.bytesperline = 0;
633 f->fmt.pix.sizeimage =
634 port->ts_packet_size * port->ts_packet_count;
635 f->fmt.pix.colorspace = 0;
636
637 dprintk(DBGLVL_ENC, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
638 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
639
640 return 0;
641}
642
643static int vidioc_log_status(struct file *file, void *priv)
644{
645 return 0;
646}
647
648static int fill_queryctrl(struct saa7164_encoder_params *params,
649 struct v4l2_queryctrl *c)
650{
651 switch (c->id) {
652 case V4L2_CID_BRIGHTNESS:
653 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 127);
654 case V4L2_CID_CONTRAST:
655 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 66);
656 case V4L2_CID_SATURATION:
657 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 62);
658 case V4L2_CID_HUE:
659 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 128);
660 case V4L2_CID_SHARPNESS:
661 return v4l2_ctrl_query_fill(c, 0x0, 0x0f, 1, 8);
662 case V4L2_CID_MPEG_AUDIO_MUTE:
663 return v4l2_ctrl_query_fill(c, 0x0, 0x01, 1, 0);
664 case V4L2_CID_AUDIO_VOLUME:
665 return v4l2_ctrl_query_fill(c, -83, 24, 1, 20);
666 case V4L2_CID_MPEG_VIDEO_BITRATE:
667 return v4l2_ctrl_query_fill(c,
668 ENCODER_MIN_BITRATE, ENCODER_MAX_BITRATE,
669 100000, ENCODER_DEF_BITRATE);
670 case V4L2_CID_MPEG_STREAM_TYPE:
671 return v4l2_ctrl_query_fill(c,
672 V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
673 V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
674 0, V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
675 case V4L2_CID_MPEG_VIDEO_ASPECT:
676 return v4l2_ctrl_query_fill(c,
677 V4L2_MPEG_VIDEO_ASPECT_1x1,
678 V4L2_MPEG_VIDEO_ASPECT_221x100,
679 1, V4L2_MPEG_VIDEO_ASPECT_4x3);
680 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
681 return v4l2_ctrl_query_fill(c, 1, 255, 1, 15);
Steven Toth2600d712010-07-31 14:51:30 -0300682 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
683 return v4l2_ctrl_query_fill(c,
684 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
685 1, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
Steven Toth7615e432010-07-31 14:44:53 -0300686 default:
687 return -EINVAL;
688 }
689}
690
691static int vidioc_queryctrl(struct file *file, void *priv,
692 struct v4l2_queryctrl *c)
693{
694 struct saa7164_fh *fh = priv;
695 struct saa7164_port *port = fh->port;
696 int i, next;
697 u32 id = c->id;
698
699 memset(c, 0, sizeof(*c));
700
701 next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL);
702 c->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
703
704 for (i = 0; i < ARRAY_SIZE(saa7164_v4l2_ctrls); i++) {
705 if (next) {
706 if (c->id < saa7164_v4l2_ctrls[i])
707 c->id = saa7164_v4l2_ctrls[i];
708 else
709 continue;
710 }
711
712 if (c->id == saa7164_v4l2_ctrls[i])
713 return fill_queryctrl(&port->encoder_params, c);
714
715 if (c->id < saa7164_v4l2_ctrls[i])
716 break;
717 }
718
719 return -EINVAL;
720}
721
722static int saa7164_encoder_stop_port(struct saa7164_port *port)
723{
724 struct saa7164_dev *dev = port->dev;
725 int ret;
726
727 ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
728 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
729 printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n",
730 __func__, ret);
731 ret = -EIO;
732 } else {
733 dprintk(DBGLVL_ENC, "%s() Stopped\n", __func__);
734 ret = 0;
735 }
736
737 return ret;
738}
739
740static int saa7164_encoder_acquire_port(struct saa7164_port *port)
741{
742 struct saa7164_dev *dev = port->dev;
743 int ret;
744
745 ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
746 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
747 printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n",
748 __func__, ret);
749 ret = -EIO;
750 } else {
751 dprintk(DBGLVL_ENC, "%s() Acquired\n", __func__);
752 ret = 0;
753 }
754
755 return ret;
756}
757
758static int saa7164_encoder_pause_port(struct saa7164_port *port)
759{
760 struct saa7164_dev *dev = port->dev;
761 int ret;
762
763 ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
764 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
765 printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n",
766 __func__, ret);
767 ret = -EIO;
768 } else {
769 dprintk(DBGLVL_ENC, "%s() Paused\n", __func__);
770 ret = 0;
771 }
772
773 return ret;
774}
775
776/* Firmware is very windows centric, meaning you have to transition
777 * the part through AVStream / KS Windows stages, forwards or backwards.
778 * States are: stopped, acquired (h/w), paused, started.
779 * We have to leave here will all of the soft buffers on the free list,
780 * else the cfg_post() func won't have soft buffers to correctly configure.
781 */
782static int saa7164_encoder_stop_streaming(struct saa7164_port *port)
783{
784 struct saa7164_dev *dev = port->dev;
785 struct saa7164_buffer *buf;
786 struct saa7164_user_buffer *ubuf;
787 struct list_head *c, *n;
788 int ret;
789
790 dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr);
791
792 ret = saa7164_encoder_pause_port(port);
793 ret = saa7164_encoder_acquire_port(port);
794 ret = saa7164_encoder_stop_port(port);
795
796 dprintk(DBGLVL_ENC, "%s(port=%d) Hardware stopped\n", __func__,
797 port->nr);
798
799 mutex_lock(&port->dmaqueue_lock);
800
801 /* Reset the hard and soft buffer state */
802 list_for_each_safe(c, n, &port->dmaqueue.list) {
803 buf = list_entry(c, struct saa7164_buffer, list);
804 buf->flags = SAA7164_BUFFER_FREE;
805 buf->pos = 0;
806 }
807
808 list_for_each_safe(c, n, &port->list_buf_used.list) {
809 ubuf = list_entry(c, struct saa7164_user_buffer, list);
810 ubuf->pos = 0;
811 list_move_tail(&ubuf->list, &port->list_buf_free.list);
812 }
813
814 mutex_unlock(&port->dmaqueue_lock);
815 dprintk(DBGLVL_ENC, "%s(port=%d) Released\n", __func__, port->nr);
816
817 return ret;
818}
819
820static int saa7164_encoder_start_streaming(struct saa7164_port *port)
821{
822 struct saa7164_dev *dev = port->dev;
823 int result, ret = 0;
824
825 dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr);
826
827 /* Configure the encoder with any cache values */
828 saa7164_api_set_encoder(port);
829
830 saa7164_buffer_cfg_port(port);
831
832 /* Acquire the hardware */
833 result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
834 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
835 printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n",
836 __func__, result);
837
838 /* Stop the hardware, regardless */
839 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
840 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
841 printk(KERN_ERR "%s() acquire/forced stop transition "
842 "failed, res = 0x%x\n", __func__, result);
843 }
844 ret = -EIO;
845 goto out;
846 } else
847 dprintk(DBGLVL_ENC, "%s() Acquired\n", __func__);
848
849 /* Pause the hardware */
850 result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
851 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
852 printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n",
853 __func__, result);
854
855 /* Stop the hardware, regardless */
856 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
857 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
858 printk(KERN_ERR "%s() pause/forced stop transition "
859 "failed, res = 0x%x\n", __func__, result);
860 }
861
862 ret = -EIO;
863 goto out;
864 } else
865 dprintk(DBGLVL_ENC, "%s() Paused\n", __func__);
866
867 /* Start the hardware */
868 result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN);
869 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
870 printk(KERN_ERR "%s() run transition failed, result = 0x%x\n",
871 __func__, result);
872
873 /* Stop the hardware, regardless */
874 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
875 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
876 printk(KERN_ERR "%s() run/forced stop transition "
877 "failed, res = 0x%x\n", __func__, result);
878 }
879
880 ret = -EIO;
881 } else
882 dprintk(DBGLVL_ENC, "%s() Running\n", __func__);
883
884out:
885 return ret;
886}
887
888static int fops_open(struct file *file)
889{
890 struct saa7164_dev *h, *dev = NULL;
891 struct saa7164_port *port = NULL;
892 struct saa7164_port *portc = NULL;
893 struct saa7164_port *portd = NULL;
894 struct saa7164_fh *fh;
895 struct list_head *list;
896 int minor = video_devdata(file)->minor;
897
898 dprintk(DBGLVL_ENC, "%s()\n", __func__);
899
900 /* TODO: Really, the BKL? - remove this */
901 lock_kernel();
902 list_for_each(list, &saa7164_devlist) {
903 h = list_entry(list, struct saa7164_dev, devlist);
904
905 portc = &h->ports[ SAA7164_PORT_ENC1 ];
906 portd = &h->ports[ SAA7164_PORT_ENC2 ];
907
908 if (portc->v4l_device &&
909 portc->v4l_device->minor == minor) {
910 dev = h;
911 port = portc;
912 break;
913 }
914
915 if (portd->v4l_device &&
916 portd->v4l_device->minor == minor) {
917 dev = h;
918 port = portd;
919 break;
920 }
921
922 }
923
924 if (port == NULL) {
925 unlock_kernel();
926 return -ENODEV;
927 }
928
929 /* allocate + initialize per filehandle data */
930 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
931 if (NULL == fh) {
932 unlock_kernel();
933 return -ENOMEM;
934 }
935
936 file->private_data = fh;
937 fh->port = port;
938
939 unlock_kernel();
940
941 return 0;
942}
943
944static int fops_release(struct file *file)
945{
946 struct saa7164_fh *fh = file->private_data;
947 struct saa7164_port *port = fh->port;
948 struct saa7164_dev *dev = port->dev;
949
950 dprintk(DBGLVL_ENC, "%s()\n", __func__);
951
952 /* Shut device down on last close */
953 if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) {
954 if (atomic_dec_return(&port->v4l_reader_count) == 0) {
955 /* stop mpeg capture then cancel buffers */
956 saa7164_encoder_stop_streaming(port);
957 }
958 }
959
960 file->private_data = NULL;
961 kfree(fh);
962
963 return 0;
964}
965
966struct saa7164_user_buffer *saa7164_enc_next_buf(struct saa7164_port *port)
967{
968 struct saa7164_user_buffer *buf = 0;
969 struct saa7164_dev *dev = port->dev;
970
971 mutex_lock(&port->dmaqueue_lock);
972 if (!list_empty(&port->list_buf_used.list)) {
973 buf = list_first_entry(&port->list_buf_used.list,
974 struct saa7164_user_buffer, list);
975 }
976 mutex_unlock(&port->dmaqueue_lock);
977
978 dprintk(DBGLVL_ENC, "%s() returns %p\n", __func__, buf);
979
980 return buf;
981}
982
983static ssize_t fops_read(struct file *file, char __user *buffer,
984 size_t count, loff_t *pos)
985{
986 struct saa7164_fh *fh = file->private_data;
987 struct saa7164_port *port = fh->port;
988 struct saa7164_user_buffer *ubuf = NULL;
989 struct saa7164_dev *dev = port->dev;
990 unsigned int ret = 0;
991 int rem, cnt;
992 u8 *p;
993
994 if (*pos)
995 return -ESPIPE;
996
997 if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
998 if (atomic_inc_return(&port->v4l_reader_count) == 1) {
999
1000 if (saa7164_encoder_initialize(port) < 0)
1001 return -EINVAL;
1002
1003 saa7164_encoder_start_streaming(port);
1004 msleep(200);
1005 }
1006 }
1007
1008 /* blocking wait for buffer */
1009 if ((file->f_flags & O_NONBLOCK) == 0) {
1010 if (wait_event_interruptible(port->wait_read,
1011 saa7164_enc_next_buf(port))) {
1012 return -ERESTARTSYS;
1013 }
1014 }
1015
1016 /* Pull the first buffer from the used list */
1017 ubuf = saa7164_enc_next_buf(port);
1018
1019 while ((count > 0) && ubuf) {
1020
1021 /* set remaining bytes to copy */
1022 rem = ubuf->actual_size - ubuf->pos;
1023 cnt = rem > count ? count : rem;
1024
1025 p = ubuf->data + ubuf->pos;
1026
1027 dprintk(DBGLVL_ENC,
1028 "%s() count=%d cnt=%d rem=%d buf=%p buf->pos=%d\n",
1029 __func__, (int)count, cnt, rem, ubuf, ubuf->pos);
1030
1031 if (copy_to_user(buffer, p, cnt)) {
1032 printk(KERN_ERR "%s() copy_to_user failed\n", __func__);
1033 if (!ret)
1034 ret = -EFAULT;
1035 goto err;
1036 }
1037
1038 ubuf->pos += cnt;
1039 count -= cnt;
1040 buffer += cnt;
1041 ret += cnt;
1042
1043 if (ubuf->pos == ubuf->actual_size) {
1044
1045 /* finished with current buffer, take next buffer */
1046
1047 /* Requeue the buffer on the free list */
1048 ubuf->pos = 0;
1049
1050 mutex_lock(&port->dmaqueue_lock);
1051 list_move_tail(&ubuf->list, &port->list_buf_free.list);
1052 mutex_unlock(&port->dmaqueue_lock);
1053
1054 /* Dequeue next */
1055 if ((file->f_flags & O_NONBLOCK) == 0) {
1056 if (wait_event_interruptible(port->wait_read,
1057 saa7164_enc_next_buf(port))) {
1058 break;
1059 }
1060 }
1061 ubuf = saa7164_enc_next_buf(port);
1062 }
1063 }
1064err:
1065 if (!ret && !ubuf)
1066 ret = -EAGAIN;
1067
1068 return ret;
1069}
1070
1071static unsigned int fops_poll(struct file *file, poll_table *wait)
1072{
1073 struct saa7164_fh *fh = (struct saa7164_fh *)file->private_data;
1074 struct saa7164_port *port = fh->port;
1075 struct saa7164_user_buffer *ubuf;
1076 unsigned int mask = 0;
1077
1078 if (!video_is_registered(port->v4l_device)) {
1079 return -EIO;
1080 }
1081
1082 if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
1083 if (atomic_inc_return(&port->v4l_reader_count) == 1) {
1084 if (saa7164_encoder_initialize(port) < 0)
1085 return -EINVAL;
1086 saa7164_encoder_start_streaming(port);
1087 msleep(200);
1088 }
1089 }
1090
1091 /* blocking wait for buffer */
1092 if ((file->f_flags & O_NONBLOCK) == 0) {
1093 if (wait_event_interruptible(port->wait_read,
1094 saa7164_enc_next_buf(port))) {
1095 return -ERESTARTSYS;
1096 }
1097 }
1098
1099 /* Pull the first buffer from the used list */
1100 ubuf = list_first_entry(&port->list_buf_used.list,
1101 struct saa7164_user_buffer, list);
1102
1103 if (ubuf)
1104 mask |= POLLIN | POLLRDNORM;
1105
1106 return mask;
1107}
1108
1109static const struct v4l2_file_operations mpeg_fops = {
1110 .owner = THIS_MODULE,
1111 .open = fops_open,
1112 .release = fops_release,
1113 .read = fops_read,
1114 .poll = fops_poll,
1115 .unlocked_ioctl = video_ioctl2,
1116};
1117
1118int saa7164_g_chip_ident(struct file *file, void *fh,
1119 struct v4l2_dbg_chip_ident *chip)
1120{
1121 struct saa7164_port *port = ((struct saa7164_fh *)fh)->port;
1122 struct saa7164_dev *dev = port->dev;
1123 dprintk(DBGLVL_ENC, "%s()\n", __func__);
1124
1125 return 0;
1126}
1127
1128int saa7164_g_register(struct file *file, void *fh,
1129 struct v4l2_dbg_register *reg)
1130{
1131 struct saa7164_port *port = ((struct saa7164_fh *)fh)->port;
1132 struct saa7164_dev *dev = port->dev;
1133 dprintk(DBGLVL_ENC, "%s()\n", __func__);
1134
1135 if (!capable(CAP_SYS_ADMIN))
1136 return -EPERM;
1137
1138 return 0;
1139}
1140
1141int saa7164_s_register(struct file *file, void *fh,
1142 struct v4l2_dbg_register *reg)
1143{
1144 struct saa7164_port *port = ((struct saa7164_fh *)fh)->port;
1145 struct saa7164_dev *dev = port->dev;
1146 dprintk(DBGLVL_ENC, "%s()\n", __func__);
1147
1148 if (!capable(CAP_SYS_ADMIN))
1149 return -EPERM;
1150
1151 return 0;
1152}
1153
1154static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
1155 .vidioc_s_std = vidioc_s_std,
1156 .vidioc_enum_input = vidioc_enum_input,
1157 .vidioc_g_input = vidioc_g_input,
1158 .vidioc_s_input = vidioc_s_input,
1159 .vidioc_g_tuner = vidioc_g_tuner,
1160 .vidioc_s_tuner = vidioc_s_tuner,
1161 .vidioc_g_frequency = vidioc_g_frequency,
1162 .vidioc_s_frequency = vidioc_s_frequency,
1163 .vidioc_s_ctrl = vidioc_s_ctrl,
1164 .vidioc_g_ctrl = vidioc_g_ctrl,
1165 .vidioc_querycap = vidioc_querycap,
1166 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1167 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1168 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1169 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1170 .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
1171 .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
1172 .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
1173 .vidioc_log_status = vidioc_log_status,
1174 .vidioc_queryctrl = vidioc_queryctrl,
1175 .vidioc_g_chip_ident = saa7164_g_chip_ident,
1176#ifdef CONFIG_VIDEO_ADV_DEBUG
1177 .vidioc_g_register = saa7164_g_register,
1178 .vidioc_s_register = saa7164_s_register,
1179#endif
1180};
1181
1182static struct video_device saa7164_mpeg_template = {
1183 .name = "saa7164",
1184 .fops = &mpeg_fops,
1185 .ioctl_ops = &mpeg_ioctl_ops,
1186 .minor = -1,
1187 .tvnorms = SAA7164_NORMS,
1188 .current_norm = V4L2_STD_NTSC_M,
1189};
1190
1191static struct video_device *saa7164_encoder_alloc(
1192 struct saa7164_port *port,
1193 struct pci_dev *pci,
1194 struct video_device *template,
1195 char *type)
1196{
1197 struct video_device *vfd;
1198 struct saa7164_dev *dev = port->dev;
1199
1200 dprintk(DBGLVL_ENC, "%s()\n", __func__);
1201
1202 vfd = video_device_alloc();
1203 if (NULL == vfd)
1204 return NULL;
1205
1206 *vfd = *template;
1207 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
1208 type, saa7164_boards[dev->board].name);
1209
1210 vfd->parent = &pci->dev;
1211 vfd->release = video_device_release;
1212 return vfd;
1213}
1214
1215int saa7164_encoder_register(struct saa7164_port *port)
1216{
1217 struct saa7164_dev *dev = port->dev;
1218 struct saa7164_buffer *buf;
1219 struct saa7164_user_buffer *ubuf;
1220 int result = -ENODEV, i;
1221 int len = 0;
1222
1223 dprintk(DBGLVL_ENC, "%s()\n", __func__);
1224
1225 if (port->type != SAA7164_MPEG_ENCODER)
1226 BUG();
1227
1228 /* Sanity check that the PCI configuration space is active */
1229 if (port->hwcfg.BARLocation == 0) {
1230 printk(KERN_ERR "%s() failed "
1231 "(errno = %d), NO PCI configuration\n",
1232 __func__, result);
1233 result = -ENOMEM;
1234 goto failed;
1235 }
1236
1237 /* Init and establish defaults */
1238 /* TODO: Check the umber of lines for PS */
1239 port->hw_streamingparams.bitspersample = 8;
1240 port->hw_streamingparams.samplesperline = 188;
1241 port->hw_streamingparams.numberoflines =
1242 (SAA7164_TS_NUMBER_OF_LINES * 188) / 188;
1243
1244 port->hw_streamingparams.pitch = 188;
1245 port->hw_streamingparams.linethreshold = 0;
1246 port->hw_streamingparams.pagetablelistvirt = 0;
1247 port->hw_streamingparams.pagetablelistphys = 0;
1248 port->hw_streamingparams.numpagetables = 2 +
1249 ((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE);
1250
1251 port->hw_streamingparams.numpagetableentries = port->hwcfg.buffercount;
1252
1253 /* Allocate the PCI resources, buffers (hard) */
1254 for (i = 0; i < port->hwcfg.buffercount; i++) {
1255 buf = saa7164_buffer_alloc(port,
1256 port->hw_streamingparams.numberoflines *
1257 port->hw_streamingparams.pitch);
1258
1259 if (!buf) {
1260 printk(KERN_ERR "%s() failed "
1261 "(errno = %d), unable to allocate buffer\n",
1262 __func__, result);
1263 result = -ENOMEM;
1264 goto failed;
1265 } else {
1266
1267 mutex_lock(&port->dmaqueue_lock);
1268 list_add_tail(&buf->list, &port->dmaqueue.list);
1269 mutex_unlock(&port->dmaqueue_lock);
1270
1271 }
1272 }
1273
1274 /* Allocate some kenrel kernel buffers for copying
1275 * to userpsace.
1276 */
1277 len = port->hw_streamingparams.numberoflines *
1278 port->hw_streamingparams.pitch;
1279
1280 for (i = 0; i < SAA7164_MAX_ENCODER_BUFFERS; i++) {
1281
1282 ubuf = saa7164_buffer_alloc_user(dev, len);
1283 if (ubuf) {
1284 mutex_lock(&port->dmaqueue_lock);
1285 list_add_tail(&ubuf->list, &port->list_buf_free.list);
1286 mutex_unlock(&port->dmaqueue_lock);
1287 }
1288
1289 }
1290
1291 /* Establish encoder defaults here */
1292 /* Set default TV standard */
1293 port->encodernorm = saa7164_tvnorms[0];
1294 port->width = 720;
1295 port->mux_input = 1; /* Composite */
1296 port->encoder_profile = EU_PROFILE_PS_DVD;
1297 port->video_format = EU_VIDEO_FORMAT_MPEG_2;
1298 port->audio_format = 0;
1299 port->video_resolution = 0;
1300 port->ctl_brightness = 127;
1301 port->ctl_contrast = 66;
1302 port->ctl_hue = 128;
1303 port->ctl_saturation = 62;
1304 port->ctl_sharpness = 8;
1305 port->encoder_params.bitrate = ENCODER_DEF_BITRATE;
Steven Toth2600d712010-07-31 14:51:30 -03001306 port->encoder_params.bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR;
Steven Toth7615e432010-07-31 14:44:53 -03001307 port->encoder_params.stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS;
1308 port->encoder_params.ctl_mute = 0;
1309 port->encoder_params.ctl_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3;
1310
1311 if (port->encodernorm.id & V4L2_STD_525_60)
1312 port->height = 480;
1313 else
1314 port->height = 576;
1315
1316 /* Allocate and register the video device node */
1317 port->v4l_device = saa7164_encoder_alloc(port,
1318 dev->pci, &saa7164_mpeg_template, "mpeg");
1319
1320 if (port->v4l_device == NULL) {
1321 printk(KERN_INFO "%s: can't allocate mpeg device\n",
1322 dev->name);
1323 result = -ENOMEM;
1324 goto failed;
1325 }
1326
1327 result = video_register_device(port->v4l_device,
1328 VFL_TYPE_GRABBER, -1);
1329 if (result < 0) {
1330 printk(KERN_INFO "%s: can't register mpeg device\n",
1331 dev->name);
1332 /* TODO: We're going to leak here if we don't dealloc
1333 The buffers above. The unreg function can't deal wit it.
1334 */
1335 goto failed;
1336 }
1337
1338 printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
1339 dev->name, port->v4l_device->num);
1340
1341 /* Configure the hardware defaults */
1342 saa7164_api_set_videomux(port);
1343 saa7164_api_set_usercontrol(port, PU_BRIGHTNESS_CONTROL);
1344 saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL);
1345 saa7164_api_set_usercontrol(port, PU_HUE_CONTROL);
1346 saa7164_api_set_usercontrol(port, PU_SATURATION_CONTROL);
1347 saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL);
1348 saa7164_api_audio_mute(port, 0);
1349 saa7164_api_set_audio_volume(port, 20);
1350 saa7164_api_set_aspect_ratio(port);
1351
1352 /* Disable audio standard detection, it's buggy */
1353 saa7164_api_set_audio_detection(port, 0);
1354
1355 saa7164_api_set_encoder(port);
1356 saa7164_api_get_encoder(port);
1357
1358 result = 0;
1359failed:
1360 return result;
1361}
1362
1363void saa7164_encoder_unregister(struct saa7164_port *port)
1364{
1365 struct saa7164_dev *dev = port->dev;
1366 struct saa7164_buffer *buf;
1367 struct saa7164_user_buffer *ubuf;
1368 struct list_head *c, *n, *p, *q, *l, *v;
1369
1370 dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr);
1371
1372 if (port->type != SAA7164_MPEG_ENCODER)
1373 BUG();
1374
1375 if (port->v4l_device) {
1376 if (port->v4l_device->minor != -1)
1377 video_unregister_device(port->v4l_device);
1378 else
1379 video_device_release(port->v4l_device);
1380
1381 port->v4l_device = NULL;
1382 }
1383
1384 /* Remove any allocated buffers */
1385 mutex_lock(&port->dmaqueue_lock);
1386
1387 dprintk(DBGLVL_ENC, "%s(port=%d) dmaqueue\n", __func__, port->nr);
1388 list_for_each_safe(c, n, &port->dmaqueue.list) {
1389 buf = list_entry(c, struct saa7164_buffer, list);
1390 list_del(c);
1391 saa7164_buffer_dealloc(buf);
1392 }
1393
1394 dprintk(DBGLVL_ENC, "%s(port=%d) used\n", __func__, port->nr);
1395 list_for_each_safe(p, q, &port->list_buf_used.list) {
1396 ubuf = list_entry(p, struct saa7164_user_buffer, list);
1397 list_del(p);
1398 saa7164_buffer_dealloc_user(ubuf);
1399 }
1400
1401 dprintk(DBGLVL_ENC, "%s(port=%d) free\n", __func__, port->nr);
1402 list_for_each_safe(l, v, &port->list_buf_free.list) {
1403 ubuf = list_entry(l, struct saa7164_user_buffer, list);
1404 list_del(l);
1405 saa7164_buffer_dealloc_user(ubuf);
1406 }
1407
1408 mutex_unlock(&port->dmaqueue_lock);
1409 dprintk(DBGLVL_ENC, "%s(port=%d) done\n", __func__, port->nr);
1410}
1411