aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx25840/cx25840-audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx25840/cx25840-audio.c')
-rw-r--r--drivers/media/video/cx25840/cx25840-audio.c54
1 files changed, 45 insertions, 9 deletions
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c
index 9a4b813152e5..f897c1ebd5f3 100644
--- a/drivers/media/video/cx25840/cx25840-audio.c
+++ b/drivers/media/video/cx25840/cx25840-audio.c
@@ -30,9 +30,6 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
30 if (freq != 32000 && freq != 44100 && freq != 48000) 30 if (freq != 32000 && freq != 44100 && freq != 48000)
31 return -EINVAL; 31 return -EINVAL;
32 32
33 /* assert soft reset */
34 cx25840_and_or(client, 0x810, ~0x1, 0x01);
35
36 /* common for all inputs and rates */ 33 /* common for all inputs and rates */
37 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ 34 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
38 cx25840_write(client, 0x127, 0x50); 35 cx25840_write(client, 0x127, 0x50);
@@ -46,6 +43,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
46 /* AUX_PLL_FRAC */ 43 /* AUX_PLL_FRAC */
47 cx25840_write4(client, 0x110, 0xee39bb01); 44 cx25840_write4(client, 0x110, 0xee39bb01);
48 45
46 if (state->is_cx25836)
47 break;
48
49 /* src3/4/6_ctl = 0x0801f77f */ 49 /* src3/4/6_ctl = 0x0801f77f */
50 cx25840_write4(client, 0x900, 0x7ff70108); 50 cx25840_write4(client, 0x900, 0x7ff70108);
51 cx25840_write4(client, 0x904, 0x7ff70108); 51 cx25840_write4(client, 0x904, 0x7ff70108);
@@ -59,6 +59,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
59 /* AUX_PLL_FRAC */ 59 /* AUX_PLL_FRAC */
60 cx25840_write4(client, 0x110, 0xd66bec00); 60 cx25840_write4(client, 0x110, 0xd66bec00);
61 61
62 if (state->is_cx25836)
63 break;
64
62 /* src3/4/6_ctl = 0x08016d59 */ 65 /* src3/4/6_ctl = 0x08016d59 */
63 cx25840_write4(client, 0x900, 0x596d0108); 66 cx25840_write4(client, 0x900, 0x596d0108);
64 cx25840_write4(client, 0x904, 0x596d0108); 67 cx25840_write4(client, 0x904, 0x596d0108);
@@ -72,6 +75,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
72 /* AUX_PLL_FRAC */ 75 /* AUX_PLL_FRAC */
73 cx25840_write4(client, 0x110, 0xe5d69800); 76 cx25840_write4(client, 0x110, 0xe5d69800);
74 77
78 if (state->is_cx25836)
79 break;
80
75 /* src3/4/6_ctl = 0x08014faa */ 81 /* src3/4/6_ctl = 0x08014faa */
76 cx25840_write4(client, 0x900, 0xaa4f0108); 82 cx25840_write4(client, 0x900, 0xaa4f0108);
77 cx25840_write4(client, 0x904, 0xaa4f0108); 83 cx25840_write4(client, 0x904, 0xaa4f0108);
@@ -87,6 +93,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
87 /* AUX_PLL_FRAC */ 93 /* AUX_PLL_FRAC */
88 cx25840_write4(client, 0x110, 0x69082a01); 94 cx25840_write4(client, 0x110, 0x69082a01);
89 95
96 if (state->is_cx25836)
97 break;
98
90 /* src1_ctl = 0x08010000 */ 99 /* src1_ctl = 0x08010000 */
91 cx25840_write4(client, 0x8f8, 0x00000108); 100 cx25840_write4(client, 0x8f8, 0x00000108);
92 101
@@ -106,6 +115,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
106 /* AUX_PLL_FRAC */ 115 /* AUX_PLL_FRAC */
107 cx25840_write4(client, 0x110, 0xd66bec00); 116 cx25840_write4(client, 0x110, 0xd66bec00);
108 117
118 if (state->is_cx25836)
119 break;
120
109 /* src1_ctl = 0x08010000 */ 121 /* src1_ctl = 0x08010000 */
110 cx25840_write4(client, 0x8f8, 0xcd600108); 122 cx25840_write4(client, 0x8f8, 0xcd600108);
111 123
@@ -122,6 +134,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
122 /* AUX_PLL_FRAC */ 134 /* AUX_PLL_FRAC */
123 cx25840_write4(client, 0x110, 0xe5d69800); 135 cx25840_write4(client, 0x110, 0xe5d69800);
124 136
137 if (state->is_cx25836)
138 break;
139
125 /* src1_ctl = 0x08010000 */ 140 /* src1_ctl = 0x08010000 */
126 cx25840_write4(client, 0x8f8, 0x00800108); 141 cx25840_write4(client, 0x8f8, 0x00800108);
127 142
@@ -133,9 +148,6 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
133 } 148 }
134 } 149 }
135 150
136 /* deassert soft reset */
137 cx25840_and_or(client, 0x810, ~0x1, 0x00);
138
139 state->audclk_freq = freq; 151 state->audclk_freq = freq;
140 152
141 return 0; 153 return 0;
@@ -148,6 +160,10 @@ void cx25840_audio_set_path(struct i2c_client *client)
148 /* stop microcontroller */ 160 /* stop microcontroller */
149 cx25840_and_or(client, 0x803, ~0x10, 0); 161 cx25840_and_or(client, 0x803, ~0x10, 0);
150 162
163 /* assert soft reset */
164 if (!state->is_cx25836)
165 cx25840_and_or(client, 0x810, ~0x1, 0x01);
166
151 /* Mute everything to prevent the PFFT! */ 167 /* Mute everything to prevent the PFFT! */
152 cx25840_write(client, 0x8d3, 0x1f); 168 cx25840_write(client, 0x8d3, 0x1f);
153 169
@@ -161,13 +177,19 @@ void cx25840_audio_set_path(struct i2c_client *client)
161 } else { 177 } else {
162 /* Set Path1 to Analog Demod Main Channel */ 178 /* Set Path1 to Analog Demod Main Channel */
163 cx25840_write4(client, 0x8d0, 0x7038061f); 179 cx25840_write4(client, 0x8d0, 0x7038061f);
180 }
164 181
182 set_audclk_freq(client, state->audclk_freq);
183
184 /* deassert soft reset */
185 if (!state->is_cx25836)
186 cx25840_and_or(client, 0x810, ~0x1, 0x00);
187
188 if (state->aud_input != CX25840_AUDIO_SERIAL) {
165 /* When the microcontroller detects the 189 /* When the microcontroller detects the
166 * audio format, it will unmute the lines */ 190 * audio format, it will unmute the lines */
167 cx25840_and_or(client, 0x803, ~0x10, 0x10); 191 cx25840_and_or(client, 0x803, ~0x10, 0x10);
168 } 192 }
169
170 set_audclk_freq(client, state->audclk_freq);
171} 193}
172 194
173static int get_volume(struct i2c_client *client) 195static int get_volume(struct i2c_client *client)
@@ -291,11 +313,25 @@ static void set_mute(struct i2c_client *client, int mute)
291 313
292int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) 314int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
293{ 315{
316 struct cx25840_state *state = i2c_get_clientdata(client);
294 struct v4l2_control *ctrl = arg; 317 struct v4l2_control *ctrl = arg;
318 int retval;
295 319
296 switch (cmd) { 320 switch (cmd) {
297 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 321 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
298 return set_audclk_freq(client, *(u32 *)arg); 322 if (state->aud_input != CX25840_AUDIO_SERIAL) {
323 cx25840_and_or(client, 0x803, ~0x10, 0);
324 cx25840_write(client, 0x8d3, 0x1f);
325 }
326 if (!state->is_cx25836)
327 cx25840_and_or(client, 0x810, ~0x1, 1);
328 retval = set_audclk_freq(client, *(u32 *)arg);
329 if (!state->is_cx25836)
330 cx25840_and_or(client, 0x810, ~0x1, 0);
331 if (state->aud_input != CX25840_AUDIO_SERIAL) {
332 cx25840_and_or(client, 0x803, ~0x10, 0x10);
333 }
334 return retval;
299 335
300 case VIDIOC_G_CTRL: 336 case VIDIOC_G_CTRL:
301 switch (ctrl->id) { 337 switch (ctrl->id) {