aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2006-01-09 12:25:41 -0500
committerMauro Carvalho Chehab <mchehab@brturbo.com.br>2006-01-09 12:25:41 -0500
commit3578d3dd0b1e468a44a76a83efe90476a854625d (patch)
tree2cd544f2aae9844821afdf90308048a800e961a1 /drivers
parent21fa715e67fe57e404d7f5f39b7f18016db9e4b6 (diff)
V4L/DVB (3214): Calculate the saa7115 AMCLK regs instead of using fixed values
- Calculate the audio master clock registers from the actual frequencies. This simplifies the code and it also prepares for adding CGC2 support. - VIDIOC_INT_AUDIO_CLOCK_FREQ now receives an u32 instead of an enum. It is more generic and actually easier to implement. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/cx25840/cx25840-audio.c20
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c10
-rw-r--r--drivers/media/video/cx25840/cx25840.h2
-rw-r--r--drivers/media/video/saa7115.c155
4 files changed, 50 insertions, 137 deletions
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c
index 740908f8027d..6c44bd9c1704 100644
--- a/drivers/media/video/cx25840/cx25840-audio.c
+++ b/drivers/media/video/cx25840/cx25840-audio.c
@@ -23,11 +23,13 @@
23 23
24#include "cx25840.h" 24#include "cx25840.h"
25 25
26inline static int set_audclk_freq(struct i2c_client *client, 26static int set_audclk_freq(struct i2c_client *client, u32 freq)
27 enum v4l2_audio_clock_freq freq)
28{ 27{
29 struct cx25840_state *state = i2c_get_clientdata(client); 28 struct cx25840_state *state = i2c_get_clientdata(client);
30 29
30 if (freq != 32000 && freq != 44100 && freq != 48000)
31 return -EINVAL;
32
31 /* assert soft reset */ 33 /* assert soft reset */
32 cx25840_and_or(client, 0x810, ~0x1, 0x01); 34 cx25840_and_or(client, 0x810, ~0x1, 0x01);
33 35
@@ -38,7 +40,7 @@ inline static int set_audclk_freq(struct i2c_client *client,
38 switch (state->audio_input) { 40 switch (state->audio_input) {
39 case AUDIO_TUNER: 41 case AUDIO_TUNER:
40 switch (freq) { 42 switch (freq) {
41 case V4L2_AUDCLK_32_KHZ: 43 case 32000:
42 /* VID_PLL and AUX_PLL */ 44 /* VID_PLL and AUX_PLL */
43 cx25840_write4(client, 0x108, 0x0f040610); 45 cx25840_write4(client, 0x108, 0x0f040610);
44 46
@@ -51,7 +53,7 @@ inline static int set_audclk_freq(struct i2c_client *client,
51 cx25840_write4(client, 0x90c, 0x7ff70108); 53 cx25840_write4(client, 0x90c, 0x7ff70108);
52 break; 54 break;
53 55
54 case V4L2_AUDCLK_441_KHZ: 56 case 44100:
55 /* VID_PLL and AUX_PLL */ 57 /* VID_PLL and AUX_PLL */
56 cx25840_write4(client, 0x108, 0x0f040910); 58 cx25840_write4(client, 0x108, 0x0f040910);
57 59
@@ -64,7 +66,7 @@ inline static int set_audclk_freq(struct i2c_client *client,
64 cx25840_write4(client, 0x90c, 0x596d0108); 66 cx25840_write4(client, 0x90c, 0x596d0108);
65 break; 67 break;
66 68
67 case V4L2_AUDCLK_48_KHZ: 69 case 48000:
68 /* VID_PLL and AUX_PLL */ 70 /* VID_PLL and AUX_PLL */
69 cx25840_write4(client, 0x108, 0x0f040a10); 71 cx25840_write4(client, 0x108, 0x0f040a10);
70 72
@@ -84,7 +86,7 @@ inline static int set_audclk_freq(struct i2c_client *client,
84 case AUDIO_INTERN: 86 case AUDIO_INTERN:
85 case AUDIO_RADIO: 87 case AUDIO_RADIO:
86 switch (freq) { 88 switch (freq) {
87 case V4L2_AUDCLK_32_KHZ: 89 case 32000:
88 /* VID_PLL and AUX_PLL */ 90 /* VID_PLL and AUX_PLL */
89 cx25840_write4(client, 0x108, 0x0f04081e); 91 cx25840_write4(client, 0x108, 0x0f04081e);
90 92
@@ -103,7 +105,7 @@ inline static int set_audclk_freq(struct i2c_client *client,
103 cx25840_write(client, 0x127, 0x54); 105 cx25840_write(client, 0x127, 0x54);
104 break; 106 break;
105 107
106 case V4L2_AUDCLK_441_KHZ: 108 case 44100:
107 /* VID_PLL and AUX_PLL */ 109 /* VID_PLL and AUX_PLL */
108 cx25840_write4(client, 0x108, 0x0f040918); 110 cx25840_write4(client, 0x108, 0x0f040918);
109 111
@@ -119,7 +121,7 @@ inline static int set_audclk_freq(struct i2c_client *client,
119 cx25840_write4(client, 0x90c, 0x85730108); 121 cx25840_write4(client, 0x90c, 0x85730108);
120 break; 122 break;
121 123
122 case V4L2_AUDCLK_48_KHZ: 124 case 48000:
123 /* VID_PLL and AUX_PLL */ 125 /* VID_PLL and AUX_PLL */
124 cx25840_write4(client, 0x108, 0x0f040a18); 126 cx25840_write4(client, 0x108, 0x0f040a18);
125 127
@@ -317,7 +319,7 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
317 case AUDC_SET_INPUT: 319 case AUDC_SET_INPUT:
318 return set_input(client, *(int *)arg); 320 return set_input(client, *(int *)arg);
319 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 321 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
320 return set_audclk_freq(client, *(enum v4l2_audio_clock_freq *)arg); 322 return set_audclk_freq(client, *(u32 *)arg);
321 case VIDIOC_G_CTRL: 323 case VIDIOC_G_CTRL:
322 switch (ctrl->id) { 324 switch (ctrl->id) {
323 case V4L2_CID_AUDIO_VOLUME: 325 case V4L2_CID_AUDIO_VOLUME:
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 54ffae686dc9..c2c1e856aa60 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -802,7 +802,7 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
802 i2c_set_clientdata(client, state); 802 i2c_set_clientdata(client, state);
803 memset(state, 0, sizeof(struct cx25840_state)); 803 memset(state, 0, sizeof(struct cx25840_state));
804 state->input = CX25840_TUNER; 804 state->input = CX25840_TUNER;
805 state->audclk_freq = V4L2_AUDCLK_48_KHZ; 805 state->audclk_freq = 48000;
806 state->audio_input = AUDIO_TUNER; 806 state->audio_input = AUDIO_TUNER;
807 state->cardtype = CARDTYPE_PVR150; 807 state->cardtype = CARDTYPE_PVR150;
808 808
@@ -1008,13 +1008,7 @@ static void log_status(struct i2c_client *client)
1008 cx25840_info("Specified audio input: %s\n", 1008 cx25840_info("Specified audio input: %s\n",
1009 state->audio_input == 0 ? "Tuner" : "External"); 1009 state->audio_input == 0 ? "Tuner" : "External");
1010 1010
1011 switch (state->audclk_freq) { 1011 cx25840_info("Specified audioclock freq: %d Hz\n", state->audclk_freq);
1012 case V4L2_AUDCLK_441_KHZ: p = "44.1 kHz"; break;
1013 case V4L2_AUDCLK_48_KHZ: p = "48 kHz"; break;
1014 case V4L2_AUDCLK_32_KHZ: p = "32 kHz"; break;
1015 default: p = "undefined";
1016 }
1017 cx25840_info("Specified audioclock freq: %s\n", p);
1018 1012
1019 switch (pref_mode & 0xf) { 1013 switch (pref_mode & 0xf) {
1020 case 0: p = "mono/language A"; break; 1014 case 0: p = "mono/language A"; break;
diff --git a/drivers/media/video/cx25840/cx25840.h b/drivers/media/video/cx25840/cx25840.h
index 40aa59f9c525..4731a19092a6 100644
--- a/drivers/media/video/cx25840/cx25840.h
+++ b/drivers/media/video/cx25840/cx25840.h
@@ -65,7 +65,7 @@ struct cx25840_state {
65 enum cx25840_cardtype cardtype; 65 enum cx25840_cardtype cardtype;
66 enum cx25840_input input; 66 enum cx25840_input input;
67 int audio_input; 67 int audio_input;
68 enum v4l2_audio_clock_freq audclk_freq; 68 u32 audclk_freq;
69}; 69};
70 70
71/* ----------------------------------------------------------------------- */ 71/* ----------------------------------------------------------------------- */
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index b175389d9f43..3e4e5584c5d0 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -39,6 +39,7 @@
39#include <linux/i2c.h> 39#include <linux/i2c.h>
40#include <linux/videodev2.h> 40#include <linux/videodev2.h>
41#include <media/v4l2-common.h> 41#include <media/v4l2-common.h>
42#include <asm/div64.h>
42 43
43MODULE_DESCRIPTION("Philips SAA7114/SAA7115 video decoder driver"); 44MODULE_DESCRIPTION("Philips SAA7114/SAA7115 video decoder driver");
44MODULE_AUTHOR("Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, Hans Verkuil"); 45MODULE_AUTHOR("Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, Hans Verkuil");
@@ -78,7 +79,7 @@ struct saa7115_state {
78 int hue; 79 int hue;
79 int sat; 80 int sat;
80 enum v4l2_chip_ident ident; 81 enum v4l2_chip_ident ident;
81 enum v4l2_audio_clock_freq audclk_freq; 82 u32 audclk_freq;
82}; 83};
83 84
84/* ----------------------------------------------------------------------- */ 85/* ----------------------------------------------------------------------- */
@@ -469,80 +470,6 @@ static const unsigned char saa7115_init_misc[] = {
469 0x00, 0x00 470 0x00, 0x00
470}; 471};
471 472
472/* ============== SAA7715 AUDIO settings ============= */
473
474/* 48.0 kHz */
475static const unsigned char saa7115_cfg_48_audio[] = {
476 0x34, 0xce,
477 0x35, 0xfb,
478 0x36, 0x30,
479 0x00, 0x00
480};
481
482/* 44.1 kHz */
483static const unsigned char saa7115_cfg_441_audio[] = {
484 0x34, 0xf2,
485 0x35, 0x00,
486 0x36, 0x2d,
487 0x00, 0x00
488};
489
490/* 32.0 kHz */
491static const unsigned char saa7115_cfg_32_audio[] = {
492 0x34, 0xdf,
493 0x35, 0xa7,
494 0x36, 0x20,
495 0x00, 0x00
496};
497
498/* 48.0 kHz 60hz */
499static const unsigned char saa7115_cfg_60hz_48_audio[] = {
500 0x30, 0xcd,
501 0x31, 0x20,
502 0x32, 0x03,
503 0x00, 0x00
504};
505
506/* 48.0 kHz 50hz */
507static const unsigned char saa7115_cfg_50hz_48_audio[] = {
508 0x30, 0x00,
509 0x31, 0xc0,
510 0x32, 0x03,
511 0x00, 0x00
512};
513
514/* 44.1 kHz 60hz */
515static const unsigned char saa7115_cfg_60hz_441_audio[] = {
516 0x30, 0xbc,
517 0x31, 0xdf,
518 0x32, 0x02,
519 0x00, 0x00
520};
521
522/* 44.1 kHz 50hz */
523static const unsigned char saa7115_cfg_50hz_441_audio[] = {
524 0x30, 0x00,
525 0x31, 0x72,
526 0x32, 0x03,
527 0x00, 0x00
528};
529
530/* 32.0 kHz 60hz */
531static const unsigned char saa7115_cfg_60hz_32_audio[] = {
532 0x30, 0xde,
533 0x31, 0x15,
534 0x32, 0x02,
535 0x00, 0x00
536};
537
538/* 32.0 kHz 50hz */
539static const unsigned char saa7115_cfg_50hz_32_audio[] = {
540 0x30, 0x00,
541 0x31, 0x80,
542 0x32, 0x02,
543 0x00, 0x00
544};
545
546static int saa7115_odd_parity(u8 c) 473static int saa7115_odd_parity(u8 c)
547{ 474{
548 c ^= (c >> 4); 475 c ^= (c >> 4);
@@ -627,40 +554,38 @@ static int saa7115_decode_wss(u8 * p)
627} 554}
628 555
629 556
630static int saa7115_set_audio_clock_freq(struct i2c_client *client, enum v4l2_audio_clock_freq freq) 557static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq)
631{ 558{
632 struct saa7115_state *state = i2c_get_clientdata(client); 559 struct saa7115_state *state = i2c_get_clientdata(client);
560 u32 acpf;
561 u32 acni;
562 u32 hz;
563 u64 f;
633 564
634 saa7115_dbg("set audio clock freq: %d\n", freq); 565 saa7115_dbg("set audio clock freq: %d\n", freq);
635 switch (freq) { 566
636 case V4L2_AUDCLK_32_KHZ: 567 /* sanity check */
637 saa7115_writeregs(client, saa7115_cfg_32_audio); 568 if (freq < 32000 || freq > 48000)
638 if (state->std & V4L2_STD_525_60) { 569 return -EINVAL;
639 saa7115_writeregs(client, saa7115_cfg_60hz_32_audio); 570
640 } else { 571 /* hz is the refresh rate times 100 */
641 saa7115_writeregs(client, saa7115_cfg_50hz_32_audio); 572 hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000;
642 } 573 /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */
643 break; 574 acpf = (25600 * freq) / hz;
644 case V4L2_AUDCLK_441_KHZ: 575 /* acni = (256 * freq * 2^23) / crystal_frequency =
645 saa7115_writeregs(client, saa7115_cfg_441_audio); 576 (freq * 2^(8+23)) / crystal_frequency =
646 if (state->std & V4L2_STD_525_60) { 577 (freq << 31) / 32.11 MHz */
647 saa7115_writeregs(client, saa7115_cfg_60hz_441_audio); 578 f = freq;
648 } else { 579 f = f << 31;
649 saa7115_writeregs(client, saa7115_cfg_50hz_441_audio); 580 do_div(f, 32110000);
650 } 581 acni = f;
651 break; 582
652 case V4L2_AUDCLK_48_KHZ: 583 saa7115_write(client, 0x30, acpf & 0xff);
653 saa7115_writeregs(client, saa7115_cfg_48_audio); 584 saa7115_write(client, 0x31, (acpf >> 8) & 0xff);
654 if (state->std & V4L2_STD_525_60) { 585 saa7115_write(client, 0x32, (acpf >> 16) & 0x03);
655 saa7115_writeregs(client, saa7115_cfg_60hz_48_audio); 586 saa7115_write(client, 0x34, acni & 0xff);
656 } else { 587 saa7115_write(client, 0x35, (acni >> 8) & 0xff);
657 saa7115_writeregs(client, saa7115_cfg_50hz_48_audio); 588 saa7115_write(client, 0x36, (acni >> 16) & 0x3f);
658 }
659 break;
660 default:
661 saa7115_dbg("invalid audio setting %d\n", freq);
662 return -EINVAL;
663 }
664 state->audclk_freq = freq; 589 state->audclk_freq = freq;
665 return 0; 590 return 0;
666} 591}
@@ -773,24 +698,17 @@ static v4l2_std_id saa7115_get_v4lstd(struct i2c_client *client)
773static void saa7115_log_status(struct i2c_client *client) 698static void saa7115_log_status(struct i2c_client *client)
774{ 699{
775 struct saa7115_state *state = i2c_get_clientdata(client); 700 struct saa7115_state *state = i2c_get_clientdata(client);
776 char *audfreq = "undefined";
777 int reg1e, reg1f; 701 int reg1e, reg1f;
778 int signalOk; 702 int signalOk;
779 int vcr; 703 int vcr;
780 704
781 switch (state->audclk_freq) { 705 saa7115_info("Audio frequency: %d Hz\n", state->audclk_freq);
782 case V4L2_AUDCLK_32_KHZ: audfreq = "32 kHz"; break;
783 case V4L2_AUDCLK_441_KHZ: audfreq = "44.1 kHz"; break;
784 case V4L2_AUDCLK_48_KHZ: audfreq = "48 kHz"; break;
785 }
786
787 saa7115_info("Audio frequency: %s\n", audfreq);
788 if (client->name[6] == '4') { 706 if (client->name[6] == '4') {
789 /* status for the saa7114 */ 707 /* status for the saa7114 */
790 reg1f = saa7115_read(client, 0x1f); 708 reg1f = saa7115_read(client, 0x1f);
791 signalOk = (reg1f & 0xc1) == 0x81; 709 signalOk = (reg1f & 0xc1) == 0x81;
792 saa7115_info("Video signal: %s\n", signalOk ? "ok" : "bad"); 710 saa7115_info("Video signal: %s\n", signalOk ? "ok" : "bad");
793 saa7115_info("Frequency: %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz"); 711 saa7115_info("Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
794 return; 712 return;
795 } 713 }
796 714
@@ -807,7 +725,7 @@ static void saa7115_log_status(struct i2c_client *client)
807 saa7115_info("Input: Composite %d\n", state->input); 725 saa7115_info("Input: Composite %d\n", state->input);
808 } 726 }
809 saa7115_info("Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad"); 727 saa7115_info("Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
810 saa7115_info("Frequency: %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz"); 728 saa7115_info("Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
811 729
812 switch (reg1e & 0x03) { 730 switch (reg1e & 0x03) {
813 case 1: 731 case 1:
@@ -1108,7 +1026,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1108 return saa7115_get_v4lfmt(client, (struct v4l2_format *)arg); 1026 return saa7115_get_v4lfmt(client, (struct v4l2_format *)arg);
1109 1027
1110 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 1028 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
1111 return saa7115_set_audio_clock_freq(client, *(enum v4l2_audio_clock_freq *)arg); 1029 return saa7115_set_audio_clock_freq(client, *(u32 *)arg);
1112 1030
1113 case VIDIOC_G_TUNER: 1031 case VIDIOC_G_TUNER:
1114 { 1032 {
@@ -1307,7 +1225,7 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
1307 state->hue = 0; 1225 state->hue = 0;
1308 state->sat = 64; 1226 state->sat = 64;
1309 state->ident = (chip_id == 4) ? V4L2_IDENT_SAA7114 : V4L2_IDENT_SAA7115; 1227 state->ident = (chip_id == 4) ? V4L2_IDENT_SAA7114 : V4L2_IDENT_SAA7115;
1310 state->audclk_freq = V4L2_AUDCLK_48_KHZ; 1228 state->audclk_freq = 48000;
1311 1229
1312 saa7115_dbg("writing init values\n"); 1230 saa7115_dbg("writing init values\n");
1313 1231
@@ -1317,8 +1235,7 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
1317 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); 1235 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
1318 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y); 1236 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
1319 saa7115_writeregs(client, saa7115_cfg_60hz_video); 1237 saa7115_writeregs(client, saa7115_cfg_60hz_video);
1320 saa7115_writeregs(client, saa7115_cfg_48_audio); 1238 saa7115_set_audio_clock_freq(client, state->audclk_freq);
1321 saa7115_writeregs(client, saa7115_cfg_60hz_48_audio);
1322 saa7115_writeregs(client, saa7115_cfg_reset_scaler); 1239 saa7115_writeregs(client, saa7115_cfg_reset_scaler);
1323 1240
1324 i2c_attach_client(client); 1241 i2c_attach_client(client);