diff options
Diffstat (limited to 'drivers/media/video/saa7134/saa6752hs.c')
-rw-r--r-- | drivers/media/video/saa7134/saa6752hs.c | 315 |
1 files changed, 262 insertions, 53 deletions
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index 0e0ba50946e..de7b9e6e932 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c | |||
@@ -39,6 +39,23 @@ enum saa6752hs_videoformat { | |||
39 | SAA6752HS_VF_UNKNOWN, | 39 | SAA6752HS_VF_UNKNOWN, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | struct saa6752hs_mpeg_params { | ||
43 | /* transport streams */ | ||
44 | __u16 ts_pid_pmt; | ||
45 | __u16 ts_pid_audio; | ||
46 | __u16 ts_pid_video; | ||
47 | __u16 ts_pid_pcr; | ||
48 | |||
49 | /* audio */ | ||
50 | enum v4l2_mpeg_audio_l2_bitrate au_l2_bitrate; | ||
51 | |||
52 | /* video */ | ||
53 | enum v4l2_mpeg_video_aspect vi_aspect; | ||
54 | enum v4l2_mpeg_video_bitrate_mode vi_bitrate_mode; | ||
55 | __u32 vi_bitrate; | ||
56 | __u32 vi_bitrate_peak; | ||
57 | }; | ||
58 | |||
42 | static const struct v4l2_format v4l2_format_table[] = | 59 | static const struct v4l2_format v4l2_format_table[] = |
43 | { | 60 | { |
44 | [SAA6752HS_VF_D1] = | 61 | [SAA6752HS_VF_D1] = |
@@ -55,18 +72,19 @@ static const struct v4l2_format v4l2_format_table[] = | |||
55 | 72 | ||
56 | struct saa6752hs_state { | 73 | struct saa6752hs_state { |
57 | struct i2c_client client; | 74 | struct i2c_client client; |
58 | struct v4l2_mpeg_compression params; | 75 | struct v4l2_mpeg_compression old_params; |
76 | struct saa6752hs_mpeg_params params; | ||
59 | enum saa6752hs_videoformat video_format; | 77 | enum saa6752hs_videoformat video_format; |
60 | v4l2_std_id standard; | 78 | v4l2_std_id standard; |
61 | }; | 79 | }; |
62 | 80 | ||
63 | enum saa6752hs_command { | 81 | enum saa6752hs_command { |
64 | SAA6752HS_COMMAND_RESET = 0, | 82 | SAA6752HS_COMMAND_RESET = 0, |
65 | SAA6752HS_COMMAND_STOP = 1, | 83 | SAA6752HS_COMMAND_STOP = 1, |
66 | SAA6752HS_COMMAND_START = 2, | 84 | SAA6752HS_COMMAND_START = 2, |
67 | SAA6752HS_COMMAND_PAUSE = 3, | 85 | SAA6752HS_COMMAND_PAUSE = 3, |
68 | SAA6752HS_COMMAND_RECONFIGURE = 4, | 86 | SAA6752HS_COMMAND_RECONFIGURE = 4, |
69 | SAA6752HS_COMMAND_SLEEP = 5, | 87 | SAA6752HS_COMMAND_SLEEP = 5, |
70 | SAA6752HS_COMMAND_RECONFIGURE_FORCE = 6, | 88 | SAA6752HS_COMMAND_RECONFIGURE_FORCE = 6, |
71 | 89 | ||
72 | SAA6752HS_COMMAND_MAX | 90 | SAA6752HS_COMMAND_MAX |
@@ -129,7 +147,22 @@ static u8 PMT[] = { | |||
129 | 0x00, 0x00, 0x00, 0x00 /* CRC32 */ | 147 | 0x00, 0x00, 0x00, 0x00 /* CRC32 */ |
130 | }; | 148 | }; |
131 | 149 | ||
132 | static struct v4l2_mpeg_compression param_defaults = | 150 | static struct saa6752hs_mpeg_params param_defaults = |
151 | { | ||
152 | .ts_pid_pmt = 16, | ||
153 | .ts_pid_video = 260, | ||
154 | .ts_pid_audio = 256, | ||
155 | .ts_pid_pcr = 259, | ||
156 | |||
157 | .vi_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3, | ||
158 | .vi_bitrate = 4000, | ||
159 | .vi_bitrate_peak = 6000, | ||
160 | .vi_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, | ||
161 | |||
162 | .au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K, | ||
163 | }; | ||
164 | |||
165 | static struct v4l2_mpeg_compression old_param_defaults = | ||
133 | { | 166 | { |
134 | .st_type = V4L2_MPEG_TS_2, | 167 | .st_type = V4L2_MPEG_TS_2, |
135 | .st_bitrate = { | 168 | .st_bitrate = { |
@@ -228,45 +261,57 @@ static int saa6752hs_chip_command(struct i2c_client* client, | |||
228 | 261 | ||
229 | 262 | ||
230 | static int saa6752hs_set_bitrate(struct i2c_client* client, | 263 | static int saa6752hs_set_bitrate(struct i2c_client* client, |
231 | struct v4l2_mpeg_compression* params) | 264 | struct saa6752hs_mpeg_params* params) |
232 | { | 265 | { |
233 | u8 buf[3]; | 266 | u8 buf[3]; |
267 | int tot_bitrate; | ||
234 | 268 | ||
235 | /* set the bitrate mode */ | 269 | /* set the bitrate mode */ |
236 | buf[0] = 0x71; | 270 | buf[0] = 0x71; |
237 | buf[1] = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? 0 : 1; | 271 | buf[1] = (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) ? 0 : 1; |
238 | i2c_master_send(client, buf, 2); | 272 | i2c_master_send(client, buf, 2); |
239 | 273 | ||
240 | /* set the video bitrate */ | 274 | /* set the video bitrate */ |
241 | if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) { | 275 | if (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) { |
242 | /* set the target bitrate */ | 276 | /* set the target bitrate */ |
243 | buf[0] = 0x80; | 277 | buf[0] = 0x80; |
244 | buf[1] = params->vi_bitrate.target >> 8; | 278 | buf[1] = params->vi_bitrate >> 8; |
245 | buf[2] = params->vi_bitrate.target & 0xff; | 279 | buf[2] = params->vi_bitrate & 0xff; |
246 | i2c_master_send(client, buf, 3); | 280 | i2c_master_send(client, buf, 3); |
247 | 281 | ||
248 | /* set the max bitrate */ | 282 | /* set the max bitrate */ |
249 | buf[0] = 0x81; | 283 | buf[0] = 0x81; |
250 | buf[1] = params->vi_bitrate.max >> 8; | 284 | buf[1] = params->vi_bitrate_peak >> 8; |
251 | buf[2] = params->vi_bitrate.max & 0xff; | 285 | buf[2] = params->vi_bitrate_peak & 0xff; |
252 | i2c_master_send(client, buf, 3); | 286 | i2c_master_send(client, buf, 3); |
287 | tot_bitrate = params->vi_bitrate_peak; | ||
253 | } else { | 288 | } else { |
254 | /* set the target bitrate (no max bitrate for CBR) */ | 289 | /* set the target bitrate (no max bitrate for CBR) */ |
255 | buf[0] = 0x81; | 290 | buf[0] = 0x81; |
256 | buf[1] = params->vi_bitrate.target >> 8; | 291 | buf[1] = params->vi_bitrate >> 8; |
257 | buf[2] = params->vi_bitrate.target & 0xff; | 292 | buf[2] = params->vi_bitrate & 0xff; |
258 | i2c_master_send(client, buf, 3); | 293 | i2c_master_send(client, buf, 3); |
294 | tot_bitrate = params->vi_bitrate; | ||
259 | } | 295 | } |
260 | 296 | ||
261 | /* set the audio bitrate */ | 297 | /* set the audio bitrate */ |
262 | buf[0] = 0x94; | 298 | buf[0] = 0x94; |
263 | buf[1] = (256 == params->au_bitrate.target) ? 0 : 1; | 299 | buf[1] = (V4L2_MPEG_AUDIO_L2_BITRATE_256K == params->au_l2_bitrate) ? 0 : 1; |
264 | i2c_master_send(client, buf, 2); | 300 | i2c_master_send(client, buf, 2); |
301 | tot_bitrate += (V4L2_MPEG_AUDIO_L2_BITRATE_256K == params->au_l2_bitrate) ? 256 : 384; | ||
302 | |||
303 | /* Note: the total max bitrate is determined by adding the video and audio | ||
304 | bitrates together and also adding an extra 768kbit/s to stay on the | ||
305 | safe side. If more control should be required, then an extra MPEG control | ||
306 | should be added. */ | ||
307 | tot_bitrate += 768; | ||
308 | if (tot_bitrate > MPEG_TOTAL_TARGET_BITRATE_MAX) | ||
309 | tot_bitrate = MPEG_TOTAL_TARGET_BITRATE_MAX; | ||
265 | 310 | ||
266 | /* set the total bitrate */ | 311 | /* set the total bitrate */ |
267 | buf[0] = 0xb1; | 312 | buf[0] = 0xb1; |
268 | buf[1] = params->st_bitrate.target >> 8; | 313 | buf[1] = tot_bitrate >> 8; |
269 | buf[2] = params->st_bitrate.target & 0xff; | 314 | buf[2] = tot_bitrate & 0xff; |
270 | i2c_master_send(client, buf, 3); | 315 | i2c_master_send(client, buf, 3); |
271 | 316 | ||
272 | return 0; | 317 | return 0; |
@@ -318,50 +363,188 @@ static void saa6752hs_set_subsampling(struct i2c_client* client, | |||
318 | } | 363 | } |
319 | 364 | ||
320 | 365 | ||
321 | static void saa6752hs_set_params(struct i2c_client* client, | 366 | static void saa6752hs_old_set_params(struct i2c_client* client, |
322 | struct v4l2_mpeg_compression* params) | 367 | struct v4l2_mpeg_compression* params) |
323 | { | 368 | { |
324 | struct saa6752hs_state *h = i2c_get_clientdata(client); | 369 | struct saa6752hs_state *h = i2c_get_clientdata(client); |
325 | 370 | ||
326 | /* check PIDs */ | 371 | /* check PIDs */ |
327 | if (params->ts_pid_pmt <= MPEG_PID_MAX) | 372 | if (params->ts_pid_pmt <= MPEG_PID_MAX) { |
373 | h->old_params.ts_pid_pmt = params->ts_pid_pmt; | ||
328 | h->params.ts_pid_pmt = params->ts_pid_pmt; | 374 | h->params.ts_pid_pmt = params->ts_pid_pmt; |
329 | if (params->ts_pid_pcr <= MPEG_PID_MAX) | 375 | } |
376 | if (params->ts_pid_pcr <= MPEG_PID_MAX) { | ||
377 | h->old_params.ts_pid_pcr = params->ts_pid_pcr; | ||
330 | h->params.ts_pid_pcr = params->ts_pid_pcr; | 378 | h->params.ts_pid_pcr = params->ts_pid_pcr; |
331 | if (params->ts_pid_video <= MPEG_PID_MAX) | 379 | } |
380 | if (params->ts_pid_video <= MPEG_PID_MAX) { | ||
381 | h->old_params.ts_pid_video = params->ts_pid_video; | ||
332 | h->params.ts_pid_video = params->ts_pid_video; | 382 | h->params.ts_pid_video = params->ts_pid_video; |
333 | if (params->ts_pid_audio <= MPEG_PID_MAX) | 383 | } |
384 | if (params->ts_pid_audio <= MPEG_PID_MAX) { | ||
385 | h->old_params.ts_pid_audio = params->ts_pid_audio; | ||
334 | h->params.ts_pid_audio = params->ts_pid_audio; | 386 | h->params.ts_pid_audio = params->ts_pid_audio; |
387 | } | ||
335 | 388 | ||
336 | /* check bitrate parameters */ | 389 | /* check bitrate parameters */ |
337 | if ((params->vi_bitrate.mode == V4L2_BITRATE_CBR) || | 390 | if ((params->vi_bitrate.mode == V4L2_BITRATE_CBR) || |
338 | (params->vi_bitrate.mode == V4L2_BITRATE_VBR)) | 391 | (params->vi_bitrate.mode == V4L2_BITRATE_VBR)) { |
339 | h->params.vi_bitrate.mode = params->vi_bitrate.mode; | 392 | h->old_params.vi_bitrate.mode = params->vi_bitrate.mode; |
393 | h->params.vi_bitrate_mode = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? | ||
394 | V4L2_MPEG_VIDEO_BITRATE_MODE_VBR : V4L2_MPEG_VIDEO_BITRATE_MODE_CBR; | ||
395 | } | ||
340 | if (params->vi_bitrate.mode != V4L2_BITRATE_NONE) | 396 | if (params->vi_bitrate.mode != V4L2_BITRATE_NONE) |
341 | h->params.st_bitrate.target = params->st_bitrate.target; | 397 | h->old_params.st_bitrate.target = params->st_bitrate.target; |
342 | if (params->vi_bitrate.mode != V4L2_BITRATE_NONE) | 398 | if (params->vi_bitrate.mode != V4L2_BITRATE_NONE) |
343 | h->params.vi_bitrate.target = params->vi_bitrate.target; | 399 | h->old_params.vi_bitrate.target = params->vi_bitrate.target; |
344 | if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) | 400 | if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) |
345 | h->params.vi_bitrate.max = params->vi_bitrate.max; | 401 | h->old_params.vi_bitrate.max = params->vi_bitrate.max; |
346 | if (params->au_bitrate.mode != V4L2_BITRATE_NONE) | 402 | if (params->au_bitrate.mode != V4L2_BITRATE_NONE) |
347 | h->params.au_bitrate.target = params->au_bitrate.target; | 403 | h->old_params.au_bitrate.target = params->au_bitrate.target; |
348 | 404 | ||
349 | /* aspect ratio */ | 405 | /* aspect ratio */ |
350 | if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3 || | 406 | if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3 || |
351 | params->vi_aspect_ratio == V4L2_MPEG_ASPECT_16_9) | 407 | params->vi_aspect_ratio == V4L2_MPEG_ASPECT_16_9) { |
352 | h->params.vi_aspect_ratio = params->vi_aspect_ratio; | 408 | h->old_params.vi_aspect_ratio = params->vi_aspect_ratio; |
409 | if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3) | ||
410 | h->params.vi_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3; | ||
411 | else | ||
412 | h->params.vi_aspect = V4L2_MPEG_VIDEO_ASPECT_16x9; | ||
413 | } | ||
353 | 414 | ||
354 | /* range checks */ | 415 | /* range checks */ |
355 | if (h->params.st_bitrate.target > MPEG_TOTAL_TARGET_BITRATE_MAX) | 416 | if (h->old_params.st_bitrate.target > MPEG_TOTAL_TARGET_BITRATE_MAX) |
356 | h->params.st_bitrate.target = MPEG_TOTAL_TARGET_BITRATE_MAX; | 417 | h->old_params.st_bitrate.target = MPEG_TOTAL_TARGET_BITRATE_MAX; |
357 | if (h->params.vi_bitrate.target > MPEG_VIDEO_TARGET_BITRATE_MAX) | 418 | if (h->old_params.vi_bitrate.target > MPEG_VIDEO_TARGET_BITRATE_MAX) |
358 | h->params.vi_bitrate.target = MPEG_VIDEO_TARGET_BITRATE_MAX; | 419 | h->old_params.vi_bitrate.target = MPEG_VIDEO_TARGET_BITRATE_MAX; |
359 | if (h->params.vi_bitrate.max > MPEG_VIDEO_MAX_BITRATE_MAX) | 420 | if (h->old_params.vi_bitrate.max > MPEG_VIDEO_MAX_BITRATE_MAX) |
360 | h->params.vi_bitrate.max = MPEG_VIDEO_MAX_BITRATE_MAX; | 421 | h->old_params.vi_bitrate.max = MPEG_VIDEO_MAX_BITRATE_MAX; |
361 | if (h->params.au_bitrate.target <= 256) | 422 | h->params.vi_bitrate = params->vi_bitrate.target; |
362 | h->params.au_bitrate.target = 256; | 423 | h->params.vi_bitrate_peak = params->vi_bitrate.max; |
424 | if (h->old_params.au_bitrate.target <= 256) { | ||
425 | h->old_params.au_bitrate.target = 256; | ||
426 | h->params.au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K; | ||
427 | } | ||
428 | else { | ||
429 | h->old_params.au_bitrate.target = 384; | ||
430 | h->params.au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_384K; | ||
431 | } | ||
432 | } | ||
433 | |||
434 | static int handle_ctrl(struct saa6752hs_mpeg_params *params, | ||
435 | struct v4l2_ext_control *ctrl, int cmd) | ||
436 | { | ||
437 | int old = 0, new; | ||
438 | int set = cmd == VIDIOC_S_EXT_CTRLS; | ||
439 | |||
440 | new = ctrl->value; | ||
441 | switch (ctrl->id) { | ||
442 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
443 | old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS; | ||
444 | if (set && new != old) | ||
445 | return -ERANGE; | ||
446 | new = old; | ||
447 | break; | ||
448 | case V4L2_CID_MPEG_STREAM_PID_PMT: | ||
449 | old = params->ts_pid_pmt; | ||
450 | if (set && new > MPEG_PID_MAX) | ||
451 | return -ERANGE; | ||
452 | if (new > MPEG_PID_MAX) | ||
453 | new = MPEG_PID_MAX; | ||
454 | params->ts_pid_pmt = new; | ||
455 | break; | ||
456 | case V4L2_CID_MPEG_STREAM_PID_AUDIO: | ||
457 | old = params->ts_pid_audio; | ||
458 | if (set && new > MPEG_PID_MAX) | ||
459 | return -ERANGE; | ||
460 | if (new > MPEG_PID_MAX) | ||
461 | new = MPEG_PID_MAX; | ||
462 | params->ts_pid_audio = new; | ||
463 | break; | ||
464 | case V4L2_CID_MPEG_STREAM_PID_VIDEO: | ||
465 | old = params->ts_pid_video; | ||
466 | if (set && new > MPEG_PID_MAX) | ||
467 | return -ERANGE; | ||
468 | if (new > MPEG_PID_MAX) | ||
469 | new = MPEG_PID_MAX; | ||
470 | params->ts_pid_video = new; | ||
471 | break; | ||
472 | case V4L2_CID_MPEG_STREAM_PID_PCR: | ||
473 | old = params->ts_pid_pcr; | ||
474 | if (set && new > MPEG_PID_MAX) | ||
475 | return -ERANGE; | ||
476 | if (new > MPEG_PID_MAX) | ||
477 | new = MPEG_PID_MAX; | ||
478 | params->ts_pid_pcr = new; | ||
479 | break; | ||
480 | case V4L2_CID_MPEG_AUDIO_ENCODING: | ||
481 | old = V4L2_MPEG_AUDIO_ENCODING_LAYER_2; | ||
482 | if (set && new != old) | ||
483 | return -ERANGE; | ||
484 | new = old; | ||
485 | break; | ||
486 | case V4L2_CID_MPEG_AUDIO_L2_BITRATE: | ||
487 | old = params->au_l2_bitrate; | ||
488 | if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K && | ||
489 | new != V4L2_MPEG_AUDIO_L2_BITRATE_384K) | ||
490 | return -ERANGE; | ||
491 | if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K) | ||
492 | new = V4L2_MPEG_AUDIO_L2_BITRATE_256K; | ||
493 | else | ||
494 | new = V4L2_MPEG_AUDIO_L2_BITRATE_384K; | ||
495 | params->au_l2_bitrate = new; | ||
496 | break; | ||
497 | case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: | ||
498 | old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000; | ||
499 | if (set && new != old) | ||
500 | return -ERANGE; | ||
501 | new = old; | ||
502 | break; | ||
503 | case V4L2_CID_MPEG_VIDEO_ENCODING: | ||
504 | old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2; | ||
505 | if (set && new != old) | ||
506 | return -ERANGE; | ||
507 | new = old; | ||
508 | break; | ||
509 | case V4L2_CID_MPEG_VIDEO_ASPECT: | ||
510 | old = params->vi_aspect; | ||
511 | if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 && | ||
512 | new != V4L2_MPEG_VIDEO_ASPECT_4x3) | ||
513 | return -ERANGE; | ||
514 | if (new != V4L2_MPEG_VIDEO_ASPECT_16x9) | ||
515 | new = V4L2_MPEG_VIDEO_ASPECT_4x3; | ||
516 | params->vi_aspect = new; | ||
517 | break; | ||
518 | case V4L2_CID_MPEG_VIDEO_BITRATE: | ||
519 | old = params->vi_bitrate * 1000; | ||
520 | new = 1000 * (new / 1000); | ||
521 | if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) | ||
522 | return -ERANGE; | ||
523 | if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) | ||
524 | new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000; | ||
525 | params->vi_bitrate = new / 1000; | ||
526 | break; | ||
527 | case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: | ||
528 | old = params->vi_bitrate_peak * 1000; | ||
529 | new = 1000 * (new / 1000); | ||
530 | if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) | ||
531 | return -ERANGE; | ||
532 | if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) | ||
533 | new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000; | ||
534 | params->vi_bitrate_peak = new / 1000; | ||
535 | break; | ||
536 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | ||
537 | old = params->vi_bitrate_mode; | ||
538 | params->vi_bitrate_mode = new; | ||
539 | break; | ||
540 | default: | ||
541 | return -EINVAL; | ||
542 | } | ||
543 | if (cmd == VIDIOC_G_EXT_CTRLS) | ||
544 | ctrl->value = old; | ||
363 | else | 545 | else |
364 | h->params.au_bitrate.target = 384; | 546 | ctrl->value = new; |
547 | return 0; | ||
365 | } | 548 | } |
366 | 549 | ||
367 | static int saa6752hs_init(struct i2c_client* client) | 550 | static int saa6752hs_init(struct i2c_client* client) |
@@ -395,22 +578,22 @@ static int saa6752hs_init(struct i2c_client* client) | |||
395 | buf[2] = 0x0D; | 578 | buf[2] = 0x0D; |
396 | i2c_master_send(client,buf,3); | 579 | i2c_master_send(client,buf,3); |
397 | 580 | ||
398 | /* Set minimum Q-scale {4} */ | 581 | /* Set minimum Q-scale {4} */ |
399 | buf[0] = 0x82; | 582 | buf[0] = 0x82; |
400 | buf[1] = 0x04; | 583 | buf[1] = 0x04; |
401 | i2c_master_send(client,buf,2); | 584 | i2c_master_send(client,buf,2); |
402 | 585 | ||
403 | /* Set maximum Q-scale {12} */ | 586 | /* Set maximum Q-scale {12} */ |
404 | buf[0] = 0x83; | 587 | buf[0] = 0x83; |
405 | buf[1] = 0x0C; | 588 | buf[1] = 0x0C; |
406 | i2c_master_send(client,buf,2); | 589 | i2c_master_send(client,buf,2); |
407 | 590 | ||
408 | /* Set Output Protocol */ | 591 | /* Set Output Protocol */ |
409 | buf[0] = 0xD0; | 592 | buf[0] = 0xD0; |
410 | buf[1] = 0x81; | 593 | buf[1] = 0x81; |
411 | i2c_master_send(client,buf,2); | 594 | i2c_master_send(client,buf,2); |
412 | 595 | ||
413 | /* Set video output stream format {TS} */ | 596 | /* Set video output stream format {TS} */ |
414 | buf[0] = 0xB0; | 597 | buf[0] = 0xB0; |
415 | buf[1] = 0x05; | 598 | buf[1] = 0x05; |
416 | i2c_master_send(client,buf,2); | 599 | i2c_master_send(client,buf,2); |
@@ -441,7 +624,7 @@ static int saa6752hs_init(struct i2c_client* client) | |||
441 | localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF; | 624 | localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF; |
442 | localPMT[sizeof(PMT) - 1] = crc & 0xFF; | 625 | localPMT[sizeof(PMT) - 1] = crc & 0xFF; |
443 | 626 | ||
444 | /* Set Audio PID */ | 627 | /* Set Audio PID */ |
445 | buf[0] = 0xC1; | 628 | buf[0] = 0xC1; |
446 | buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF; | 629 | buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF; |
447 | buf[2] = h->params.ts_pid_audio & 0xFF; | 630 | buf[2] = h->params.ts_pid_audio & 0xFF; |
@@ -489,11 +672,11 @@ static int saa6752hs_init(struct i2c_client* client) | |||
489 | buf[3] = 0x82; | 672 | buf[3] = 0x82; |
490 | buf[4] = 0xB0; | 673 | buf[4] = 0xB0; |
491 | buf[5] = buf2[0]; | 674 | buf[5] = buf2[0]; |
492 | switch(h->params.vi_aspect_ratio) { | 675 | switch(h->params.vi_aspect) { |
493 | case V4L2_MPEG_ASPECT_16_9: | 676 | case V4L2_MPEG_VIDEO_ASPECT_16x9: |
494 | buf[6] = buf2[1] | 0x40; | 677 | buf[6] = buf2[1] | 0x40; |
495 | break; | 678 | break; |
496 | case V4L2_MPEG_ASPECT_4_3: | 679 | case V4L2_MPEG_VIDEO_ASPECT_4x3: |
497 | default: | 680 | default: |
498 | buf[6] = buf2[1] & 0xBF; | 681 | buf[6] = buf2[1] & 0xBF; |
499 | break; | 682 | break; |
@@ -515,6 +698,7 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind) | |||
515 | return -ENOMEM; | 698 | return -ENOMEM; |
516 | h->client = client_template; | 699 | h->client = client_template; |
517 | h->params = param_defaults; | 700 | h->params = param_defaults; |
701 | h->old_params = old_param_defaults; | ||
518 | h->client.adapter = adap; | 702 | h->client.adapter = adap; |
519 | h->client.addr = addr; | 703 | h->client.addr = addr; |
520 | 704 | ||
@@ -550,20 +734,45 @@ static int | |||
550 | saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) | 734 | saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) |
551 | { | 735 | { |
552 | struct saa6752hs_state *h = i2c_get_clientdata(client); | 736 | struct saa6752hs_state *h = i2c_get_clientdata(client); |
553 | struct v4l2_mpeg_compression *params = arg; | 737 | struct v4l2_ext_controls *ctrls = arg; |
738 | struct v4l2_mpeg_compression *old_params = arg; | ||
739 | struct saa6752hs_mpeg_params params; | ||
554 | int err = 0; | 740 | int err = 0; |
741 | int i; | ||
555 | 742 | ||
556 | switch (cmd) { | 743 | switch (cmd) { |
557 | case VIDIOC_S_MPEGCOMP: | 744 | case VIDIOC_S_MPEGCOMP: |
558 | if (NULL == params) { | 745 | if (NULL == old_params) { |
559 | /* apply settings and start encoder */ | 746 | /* apply settings and start encoder */ |
560 | saa6752hs_init(client); | 747 | saa6752hs_init(client); |
561 | break; | 748 | break; |
562 | } | 749 | } |
563 | saa6752hs_set_params(client, params); | 750 | saa6752hs_old_set_params(client, old_params); |
564 | /* fall through */ | 751 | /* fall through */ |
565 | case VIDIOC_G_MPEGCOMP: | 752 | case VIDIOC_G_MPEGCOMP: |
566 | *params = h->params; | 753 | *old_params = h->old_params; |
754 | break; | ||
755 | case VIDIOC_S_EXT_CTRLS: | ||
756 | if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) | ||
757 | return -EINVAL; | ||
758 | if (ctrls->count == 0) { | ||
759 | /* apply settings and start encoder */ | ||
760 | saa6752hs_init(client); | ||
761 | break; | ||
762 | } | ||
763 | /* fall through */ | ||
764 | case VIDIOC_TRY_EXT_CTRLS: | ||
765 | case VIDIOC_G_EXT_CTRLS: | ||
766 | if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) | ||
767 | return -EINVAL; | ||
768 | params = h->params; | ||
769 | for (i = 0; i < ctrls->count; i++) { | ||
770 | if ((err = handle_ctrl(¶ms, ctrls->controls + i, cmd))) { | ||
771 | ctrls->error_idx = i; | ||
772 | return err; | ||
773 | } | ||
774 | } | ||
775 | h->params = params; | ||
567 | break; | 776 | break; |
568 | case VIDIOC_G_FMT: | 777 | case VIDIOC_G_FMT: |
569 | { | 778 | { |