diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2008-09-06 06:00:24 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-10-12 07:36:59 -0400 |
commit | ff5f26b40ab43a6c263834665bfa10d6114a27cd (patch) | |
tree | 562154355b077c4454e38178da9036c5a06acc00 /drivers/media/video/saa7134/saa6752hs.c | |
parent | 9afb7377ef16a73d1ae7b089aa853e00a3facea8 (diff) |
V4L/DVB (8918): saa6752hs: simplify writing to registers
Add some utility functions to set registers.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/saa7134/saa6752hs.c')
-rw-r--r-- | drivers/media/video/saa7134/saa6752hs.c | 127 |
1 files changed, 49 insertions, 78 deletions
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index f40cb0b479b1..1fb6eccdade3 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c | |||
@@ -224,7 +224,7 @@ static struct saa6752hs_mpeg_params param_defaults = | |||
224 | 224 | ||
225 | /* ---------------------------------------------------------------------- */ | 225 | /* ---------------------------------------------------------------------- */ |
226 | 226 | ||
227 | static int saa6752hs_chip_command(struct i2c_client* client, | 227 | static int saa6752hs_chip_command(struct i2c_client *client, |
228 | enum saa6752hs_command command) | 228 | enum saa6752hs_command command) |
229 | { | 229 | { |
230 | unsigned char buf[3]; | 230 | unsigned char buf[3]; |
@@ -291,54 +291,61 @@ static int saa6752hs_chip_command(struct i2c_client* client, | |||
291 | } | 291 | } |
292 | 292 | ||
293 | 293 | ||
294 | static int saa6752hs_set_bitrate(struct i2c_client* client, | 294 | static inline void set_reg8(struct i2c_client *client, uint8_t reg, uint8_t val) |
295 | { | ||
296 | u8 buf[2]; | ||
297 | |||
298 | buf[0] = reg; | ||
299 | buf[1] = val; | ||
300 | i2c_master_send(client, buf, 2); | ||
301 | } | ||
302 | |||
303 | static inline void set_reg16(struct i2c_client *client, uint8_t reg, uint16_t val) | ||
304 | { | ||
305 | u8 buf[3]; | ||
306 | |||
307 | buf[0] = reg; | ||
308 | buf[1] = val >> 8; | ||
309 | buf[2] = val & 0xff; | ||
310 | i2c_master_send(client, buf, 3); | ||
311 | } | ||
312 | |||
313 | static int saa6752hs_set_bitrate(struct i2c_client *client, | ||
295 | struct saa6752hs_state *h) | 314 | struct saa6752hs_state *h) |
296 | { | 315 | { |
297 | struct saa6752hs_mpeg_params *params = &h->params; | 316 | struct saa6752hs_mpeg_params *params = &h->params; |
298 | u8 buf[3]; | ||
299 | int tot_bitrate; | 317 | int tot_bitrate; |
318 | int is_384k; | ||
300 | 319 | ||
301 | /* set the bitrate mode */ | 320 | /* set the bitrate mode */ |
302 | buf[0] = 0x71; | 321 | set_reg8(client, 0x71, |
303 | buf[1] = (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) ? 0 : 1; | 322 | params->vi_bitrate_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); |
304 | i2c_master_send(client, buf, 2); | ||
305 | 323 | ||
306 | /* set the video bitrate */ | 324 | /* set the video bitrate */ |
307 | if (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) { | 325 | if (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) { |
308 | /* set the target bitrate */ | 326 | /* set the target bitrate */ |
309 | buf[0] = 0x80; | 327 | set_reg16(client, 0x80, params->vi_bitrate); |
310 | buf[1] = params->vi_bitrate >> 8; | ||
311 | buf[2] = params->vi_bitrate & 0xff; | ||
312 | i2c_master_send(client, buf, 3); | ||
313 | 328 | ||
314 | /* set the max bitrate */ | 329 | /* set the max bitrate */ |
315 | buf[0] = 0x81; | 330 | set_reg16(client, 0x81, params->vi_bitrate_peak); |
316 | buf[1] = params->vi_bitrate_peak >> 8; | ||
317 | buf[2] = params->vi_bitrate_peak & 0xff; | ||
318 | i2c_master_send(client, buf, 3); | ||
319 | tot_bitrate = params->vi_bitrate_peak; | 331 | tot_bitrate = params->vi_bitrate_peak; |
320 | } else { | 332 | } else { |
321 | /* set the target bitrate (no max bitrate for CBR) */ | 333 | /* set the target bitrate (no max bitrate for CBR) */ |
322 | buf[0] = 0x81; | 334 | set_reg16(client, 0x81, params->vi_bitrate); |
323 | buf[1] = params->vi_bitrate >> 8; | ||
324 | buf[2] = params->vi_bitrate & 0xff; | ||
325 | i2c_master_send(client, buf, 3); | ||
326 | tot_bitrate = params->vi_bitrate; | 335 | tot_bitrate = params->vi_bitrate; |
327 | } | 336 | } |
328 | 337 | ||
329 | /* set the audio encoding */ | 338 | /* set the audio encoding */ |
330 | buf[0] = 0x93; | 339 | set_reg8(client, 0x93, |
331 | buf[1] = (params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3); | 340 | params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3); |
332 | i2c_master_send(client, buf, 2); | ||
333 | 341 | ||
334 | /* set the audio bitrate */ | 342 | /* set the audio bitrate */ |
335 | buf[0] = 0x94; | ||
336 | if (params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) | 343 | if (params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) |
337 | buf[1] = V4L2_MPEG_AUDIO_AC3_BITRATE_384K == params->au_ac3_bitrate; | 344 | is_384k = V4L2_MPEG_AUDIO_AC3_BITRATE_384K == params->au_ac3_bitrate; |
338 | else | 345 | else |
339 | buf[1] = V4L2_MPEG_AUDIO_L2_BITRATE_384K == params->au_l2_bitrate; | 346 | is_384k = V4L2_MPEG_AUDIO_L2_BITRATE_384K == params->au_l2_bitrate; |
340 | tot_bitrate += buf[1] ? 384 : 256; | 347 | set_reg8(client, 0x94, is_384k); |
341 | i2c_master_send(client, buf, 2); | 348 | tot_bitrate += is_384k ? 384 : 256; |
342 | 349 | ||
343 | /* Note: the total max bitrate is determined by adding the video and audio | 350 | /* Note: the total max bitrate is determined by adding the video and audio |
344 | bitrates together and also adding an extra 768kbit/s to stay on the | 351 | bitrates together and also adding an extra 768kbit/s to stay on the |
@@ -349,16 +356,12 @@ static int saa6752hs_set_bitrate(struct i2c_client* client, | |||
349 | tot_bitrate = MPEG_TOTAL_TARGET_BITRATE_MAX; | 356 | tot_bitrate = MPEG_TOTAL_TARGET_BITRATE_MAX; |
350 | 357 | ||
351 | /* set the total bitrate */ | 358 | /* set the total bitrate */ |
352 | buf[0] = 0xb1; | 359 | set_reg16(client, 0xb1, tot_bitrate); |
353 | buf[1] = tot_bitrate >> 8; | ||
354 | buf[2] = tot_bitrate & 0xff; | ||
355 | i2c_master_send(client, buf, 3); | ||
356 | |||
357 | return 0; | 360 | return 0; |
358 | } | 361 | } |
359 | 362 | ||
360 | static void saa6752hs_set_subsampling(struct i2c_client* client, | 363 | static void saa6752hs_set_subsampling(struct i2c_client *client, |
361 | struct v4l2_format* f) | 364 | struct v4l2_format *f) |
362 | { | 365 | { |
363 | struct saa6752hs_state *h = i2c_get_clientdata(client); | 366 | struct saa6752hs_state *h = i2c_get_clientdata(client); |
364 | int dist_352, dist_480, dist_720; | 367 | int dist_352, dist_480, dist_720; |
@@ -665,51 +668,31 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes) | |||
665 | h = i2c_get_clientdata(client); | 668 | h = i2c_get_clientdata(client); |
666 | 669 | ||
667 | /* Set video format - must be done first as it resets other settings */ | 670 | /* Set video format - must be done first as it resets other settings */ |
668 | buf[0] = 0x41; | 671 | set_reg8(client, 0x41, h->video_format); |
669 | buf[1] = h->video_format; | ||
670 | i2c_master_send(client, buf, 2); | ||
671 | 672 | ||
672 | /* Set number of lines in input signal */ | 673 | /* Set number of lines in input signal */ |
673 | buf[0] = 0x40; | 674 | set_reg8(client, 0x40, (h->standard & V4L2_STD_525_60) ? 1 : 0); |
674 | buf[1] = 0x00; | ||
675 | if (h->standard & V4L2_STD_525_60) | ||
676 | buf[1] = 0x01; | ||
677 | i2c_master_send(client, buf, 2); | ||
678 | 675 | ||
679 | /* set bitrate */ | 676 | /* set bitrate */ |
680 | saa6752hs_set_bitrate(client, h); | 677 | saa6752hs_set_bitrate(client, h); |
681 | 678 | ||
682 | /* Set GOP structure {3, 13} */ | 679 | /* Set GOP structure {3, 13} */ |
683 | buf[0] = 0x72; | 680 | set_reg16(client, 0x72, 0x030d); |
684 | buf[1] = 0x03; | ||
685 | buf[2] = 0x0D; | ||
686 | i2c_master_send(client,buf,3); | ||
687 | 681 | ||
688 | /* Set minimum Q-scale {4} */ | 682 | /* Set minimum Q-scale {4} */ |
689 | buf[0] = 0x82; | 683 | set_reg8(client, 0x82, 0x04); |
690 | buf[1] = 0x04; | ||
691 | i2c_master_send(client,buf,2); | ||
692 | 684 | ||
693 | /* Set maximum Q-scale {12} */ | 685 | /* Set maximum Q-scale {12} */ |
694 | buf[0] = 0x83; | 686 | set_reg8(client, 0x83, 0x0c); |
695 | buf[1] = 0x0C; | ||
696 | i2c_master_send(client,buf,2); | ||
697 | 687 | ||
698 | /* Set Output Protocol */ | 688 | /* Set Output Protocol */ |
699 | buf[0] = 0xD0; | 689 | set_reg8(client, 0xd0, 0x81); |
700 | buf[1] = 0x81; | ||
701 | i2c_master_send(client,buf,2); | ||
702 | 690 | ||
703 | /* Set video output stream format {TS} */ | 691 | /* Set video output stream format {TS} */ |
704 | buf[0] = 0xB0; | 692 | set_reg8(client, 0xb0, 0x05); |
705 | buf[1] = 0x05; | ||
706 | i2c_master_send(client,buf,2); | ||
707 | 693 | ||
708 | /* Set leading null byte for TS */ | 694 | /* Set leading null byte for TS */ |
709 | buf[0] = 0xF6; | 695 | set_reg16(client, 0xf6, leading_null_bytes); |
710 | buf[1] = (leading_null_bytes >> 8) & 0xff; | ||
711 | buf[2] = leading_null_bytes & 0xff; | ||
712 | i2c_master_send(client, buf, 3); | ||
713 | 696 | ||
714 | /* compute PAT */ | 697 | /* compute PAT */ |
715 | memcpy(localPAT, PAT, sizeof(PAT)); | 698 | memcpy(localPAT, PAT, sizeof(PAT)); |
@@ -744,33 +727,21 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes) | |||
744 | localPMT[size - 1] = crc & 0xFF; | 727 | localPMT[size - 1] = crc & 0xFF; |
745 | 728 | ||
746 | /* Set Audio PID */ | 729 | /* Set Audio PID */ |
747 | buf[0] = 0xC1; | 730 | set_reg16(client, 0xc1, h->params.ts_pid_audio); |
748 | buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF; | ||
749 | buf[2] = h->params.ts_pid_audio & 0xFF; | ||
750 | i2c_master_send(client,buf,3); | ||
751 | 731 | ||
752 | /* Set Video PID */ | 732 | /* Set Video PID */ |
753 | buf[0] = 0xC0; | 733 | set_reg16(client, 0xc0, h->params.ts_pid_video); |
754 | buf[1] = (h->params.ts_pid_video >> 8) & 0xFF; | ||
755 | buf[2] = h->params.ts_pid_video & 0xFF; | ||
756 | i2c_master_send(client,buf,3); | ||
757 | 734 | ||
758 | /* Set PCR PID */ | 735 | /* Set PCR PID */ |
759 | buf[0] = 0xC4; | 736 | set_reg16(client, 0xc4, h->params.ts_pid_pcr); |
760 | buf[1] = (h->params.ts_pid_pcr >> 8) & 0xFF; | ||
761 | buf[2] = h->params.ts_pid_pcr & 0xFF; | ||
762 | i2c_master_send(client,buf,3); | ||
763 | 737 | ||
764 | /* Send SI tables */ | 738 | /* Send SI tables */ |
765 | i2c_master_send(client, localPAT, sizeof(PAT)); | 739 | i2c_master_send(client, localPAT, sizeof(PAT)); |
766 | i2c_master_send(client, localPMT, size); | 740 | i2c_master_send(client, localPMT, size); |
767 | 741 | ||
768 | /* mute then unmute audio. This removes buzzing artefacts */ | 742 | /* mute then unmute audio. This removes buzzing artefacts */ |
769 | buf[0] = 0xa4; | 743 | set_reg8(client, 0xa4, 1); |
770 | buf[1] = 1; | 744 | set_reg8(client, 0xa4, 0); |
771 | i2c_master_send(client, buf, 2); | ||
772 | buf[1] = 0; | ||
773 | i2c_master_send(client, buf, 2); | ||
774 | 745 | ||
775 | /* start it going */ | 746 | /* start it going */ |
776 | saa6752hs_chip_command(client, SAA6752HS_COMMAND_START); | 747 | saa6752hs_chip_command(client, SAA6752HS_COMMAND_START); |