diff options
Diffstat (limited to 'drivers/media/video/cx25840/cx25840-audio.c')
-rw-r--r-- | drivers/media/video/cx25840/cx25840-audio.c | 54 |
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 | ||
173 | static int get_volume(struct i2c_client *client) | 195 | static int get_volume(struct i2c_client *client) |
@@ -291,11 +313,25 @@ static void set_mute(struct i2c_client *client, int mute) | |||
291 | 313 | ||
292 | int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) | 314 | int 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) { |