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