V4L/DVB (9936): cx18: Disable locking of Video and Audio PLL for analog captures
[linux-2.6] / drivers / media / video / cx18 / cx18-av-audio.c
1 /*
2  *  cx18 ADEC audio functions
3  *
4  *  Derived from cx25840-audio.c
5  *
6  *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
7  *  Copyright (C) 2008  Andy Walls <awalls@radix.net>
8  *
9  *  This program is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU General Public License
11  *  as published by the Free Software Foundation; either version 2
12  *  of the License, or (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  *  02110-1301, USA.
23  */
24
25 #include "cx18-driver.h"
26
27 static int set_audclk_freq(struct cx18 *cx, u32 freq)
28 {
29         struct cx18_av_state *state = &cx->av_state;
30
31         if (freq != 32000 && freq != 44100 && freq != 48000)
32                 return -EINVAL;
33
34         /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
35         cx18_av_write(cx, 0x127, 0x50);
36
37         if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
38                 switch (freq) {
39                 case 32000:
40                         /* VID_PLL and AUX_PLL */
41                         cx18_av_write4(cx, 0x108, 0x1408040f);
42
43                         /* AUX_PLL_FRAC */
44                         /* 0x8.9504318a * 28,636,363.636 / 0x14 = 32000 * 384 */
45                         cx18_av_write4(cx, 0x110, 0x012a0863);
46
47                         /* src3/4/6_ctl */
48                         /* 0x1.f77f = (4 * 15734.26) / 32000 */
49                         cx18_av_write4(cx, 0x900, 0x0801f77f);
50                         cx18_av_write4(cx, 0x904, 0x0801f77f);
51                         cx18_av_write4(cx, 0x90c, 0x0801f77f);
52
53                         /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
54                         cx18_av_write(cx, 0x127, 0x54);
55
56                         /* AUD_COUNT = 0x2fff = 8 samples * 4 * 384 - 1 */
57                         cx18_av_write4(cx, 0x12c, 0x11202fff);
58
59                         /*
60                          * EN_AV_LOCK = 0
61                          * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 =
62                          *  ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8
63                          */
64                         cx18_av_write4(cx, 0x128, 0xa00d2ef8);
65                         break;
66
67                 case 44100:
68                         /* VID_PLL and AUX_PLL */
69                         cx18_av_write4(cx, 0x108, 0x1009040f);
70
71                         /* AUX_PLL_FRAC */
72                         /* 0x9.7635e7 * 28,636,363.63 / 0x10 = 44100 * 384 */
73                         cx18_av_write4(cx, 0x110, 0x00ec6bce);
74
75                         /* src3/4/6_ctl */
76                         /* 0x1.6d59 = (4 * 15734.26) / 44100 */
77                         cx18_av_write4(cx, 0x900, 0x08016d59);
78                         cx18_av_write4(cx, 0x904, 0x08016d59);
79                         cx18_av_write4(cx, 0x90c, 0x08016d59);
80
81                         /* AUD_COUNT = 0x92ff = 49 samples * 2 * 384 - 1 */
82                         cx18_av_write4(cx, 0x12c, 0x112092ff);
83
84                         /*
85                          * EN_AV_LOCK = 0
86                          * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 =
87                          *  ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8
88                          */
89                         cx18_av_write4(cx, 0x128, 0xa01d4bf8);
90                         break;
91
92                 case 48000:
93                         /* VID_PLL and AUX_PLL */
94                         cx18_av_write4(cx, 0x108, 0x100a040f);
95
96                         /* AUX_PLL_FRAC */
97                         /* 0xa.4c6b6ea * 28,636,363.63 / 0x10 = 48000 * 384 */
98                         cx18_av_write4(cx, 0x110, 0x0098d6dd);
99
100                         /* src3/4/6_ctl */
101                         /* 0x1.4faa = (4 * 15734.26) / 48000 */
102                         cx18_av_write4(cx, 0x900, 0x08014faa);
103                         cx18_av_write4(cx, 0x904, 0x08014faa);
104                         cx18_av_write4(cx, 0x90c, 0x08014faa);
105
106                         /* AUD_COUNT = 0x5fff = 4 samples * 16 * 384 - 1 */
107                         cx18_av_write4(cx, 0x12c, 0x11205fff);
108
109                         /*
110                          * EN_AV_LOCK = 0
111                          * VID_COUNT = 0x1193f8 = 143999.000 * 8 =
112                          *  ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8
113                          */
114                         cx18_av_write4(cx, 0x128, 0xa01193f8);
115                         break;
116                 }
117         } else {
118                 switch (freq) {
119                 case 32000:
120                         /* VID_PLL and AUX_PLL */
121                         cx18_av_write4(cx, 0x108, 0x1e08040f);
122
123                         /* AUX_PLL_FRAC */
124                         /* 0x8.9504318 * 28,636,363.63 / 0x1e = 32000 * 256 */
125                         cx18_av_write4(cx, 0x110, 0x012a0863);
126
127                         /* src1_ctl */
128                         /* 0x1.0000 = 32000/32000 */
129                         cx18_av_write4(cx, 0x8f8, 0x08010000);
130
131                         /* src3/4/6_ctl */
132                         /* 0x2.0000 = 2 * (32000/32000) */
133                         cx18_av_write4(cx, 0x900, 0x08020000);
134                         cx18_av_write4(cx, 0x904, 0x08020000);
135                         cx18_av_write4(cx, 0x90c, 0x08020000);
136
137                         /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
138                         cx18_av_write(cx, 0x127, 0x54);
139
140                         /* AUD_COUNT = 0x1fff = 8 samples * 4 * 256 - 1 */
141                         cx18_av_write4(cx, 0x12c, 0x11201fff);
142
143                         /*
144                          * EN_AV_LOCK = 0
145                          * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 =
146                          *  ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8
147                          */
148                         cx18_av_write4(cx, 0x128, 0xa00d2ef8);
149                         break;
150
151                 case 44100:
152                         /* VID_PLL and AUX_PLL */
153                         cx18_av_write4(cx, 0x108, 0x1809040f);
154
155                         /* AUX_PLL_FRAC */
156                         /* 0x9.7635e74 * 28,636,363.63 / 0x18 = 44100 * 256 */
157                         cx18_av_write4(cx, 0x110, 0x00ec6bce);
158
159                         /* src1_ctl */
160                         /* 0x1.60cd = 44100/32000 */
161                         cx18_av_write4(cx, 0x8f8, 0x080160cd);
162
163                         /* src3/4/6_ctl */
164                         /* 0x1.7385 = 2 * (32000/44100) */
165                         cx18_av_write4(cx, 0x900, 0x08017385);
166                         cx18_av_write4(cx, 0x904, 0x08017385);
167                         cx18_av_write4(cx, 0x90c, 0x08017385);
168
169                         /* AUD_COUNT = 0x61ff = 49 samples * 2 * 256 - 1 */
170                         cx18_av_write4(cx, 0x12c, 0x112061ff);
171
172                         /*
173                          * EN_AV_LOCK = 0
174                          * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 =
175                          *  ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8
176                          */
177                         cx18_av_write4(cx, 0x128, 0xa01d4bf8);
178                         break;
179
180                 case 48000:
181                         /* VID_PLL and AUX_PLL */
182                         cx18_av_write4(cx, 0x108, 0x180a040f);
183
184                         /* AUX_PLL_FRAC */
185                         /* 0xa.4c6b6ea * 28,636,363.63 / 0x18 = 48000 * 256 */
186                         cx18_av_write4(cx, 0x110, 0x0098d6dd);
187
188                         /* src1_ctl */
189                         /* 0x1.8000 = 48000/32000 */
190                         cx18_av_write4(cx, 0x8f8, 0x08018000);
191
192                         /* src3/4/6_ctl */
193                         /* 0x1.5555 = 2 * (32000/48000) */
194                         cx18_av_write4(cx, 0x900, 0x08015555);
195                         cx18_av_write4(cx, 0x904, 0x08015555);
196                         cx18_av_write4(cx, 0x90c, 0x08015555);
197
198                         /* AUD_COUNT = 0x3fff = 4 samples * 16 * 256 - 1 */
199                         cx18_av_write4(cx, 0x12c, 0x11203fff);
200
201                         /*
202                          * EN_AV_LOCK = 0
203                          * VID_COUNT = 0x1193f8 = 143999.000 * 8 =
204                          *  ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8
205                          */
206                         cx18_av_write4(cx, 0x128, 0xa01193f8);
207                         break;
208                 }
209         }
210
211         state->audclk_freq = freq;
212
213         return 0;
214 }
215
216 void cx18_av_audio_set_path(struct cx18 *cx)
217 {
218         struct cx18_av_state *state = &cx->av_state;
219         u8 v;
220
221         /* stop microcontroller */
222         v = cx18_av_read(cx, 0x803) & ~0x10;
223         cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
224
225         /* assert soft reset */
226         v = cx18_av_read(cx, 0x810) | 0x01;
227         cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
228
229         /* Mute everything to prevent the PFFT! */
230         cx18_av_write(cx, 0x8d3, 0x1f);
231
232         if (state->aud_input <= CX18_AV_AUDIO_SERIAL2) {
233                 /* Set Path1 to Serial Audio Input */
234                 cx18_av_write4(cx, 0x8d0, 0x01011012);
235
236                 /* The microcontroller should not be started for the
237                  * non-tuner inputs: autodetection is specific for
238                  * TV audio. */
239         } else {
240                 /* Set Path1 to Analog Demod Main Channel */
241                 cx18_av_write4(cx, 0x8d0, 0x1f063870);
242         }
243
244         set_audclk_freq(cx, state->audclk_freq);
245
246         /* deassert soft reset */
247         v = cx18_av_read(cx, 0x810) & ~0x01;
248         cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
249
250         if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
251                 /* When the microcontroller detects the
252                  * audio format, it will unmute the lines */
253                 v = cx18_av_read(cx, 0x803) | 0x10;
254                 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
255         }
256 }
257
258 static int get_volume(struct cx18 *cx)
259 {
260         /* Volume runs +18dB to -96dB in 1/2dB steps
261          * change to fit the msp3400 -114dB to +12dB range */
262
263         /* check PATH1_VOLUME */
264         int vol = 228 - cx18_av_read(cx, 0x8d4);
265         vol = (vol / 2) + 23;
266         return vol << 9;
267 }
268
269 static void set_volume(struct cx18 *cx, int volume)
270 {
271         /* First convert the volume to msp3400 values (0-127) */
272         int vol = volume >> 9;
273         /* now scale it up to cx18_av values
274          * -114dB to -96dB maps to 0
275          * this should be 19, but in my testing that was 4dB too loud */
276         if (vol <= 23)
277                 vol = 0;
278         else
279                 vol -= 23;
280
281         /* PATH1_VOLUME */
282         cx18_av_write(cx, 0x8d4, 228 - (vol * 2));
283 }
284
285 static int get_bass(struct cx18 *cx)
286 {
287         /* bass is 49 steps +12dB to -12dB */
288
289         /* check PATH1_EQ_BASS_VOL */
290         int bass = cx18_av_read(cx, 0x8d9) & 0x3f;
291         bass = (((48 - bass) * 0xffff) + 47) / 48;
292         return bass;
293 }
294
295 static void set_bass(struct cx18 *cx, int bass)
296 {
297         /* PATH1_EQ_BASS_VOL */
298         cx18_av_and_or(cx, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff));
299 }
300
301 static int get_treble(struct cx18 *cx)
302 {
303         /* treble is 49 steps +12dB to -12dB */
304
305         /* check PATH1_EQ_TREBLE_VOL */
306         int treble = cx18_av_read(cx, 0x8db) & 0x3f;
307         treble = (((48 - treble) * 0xffff) + 47) / 48;
308         return treble;
309 }
310
311 static void set_treble(struct cx18 *cx, int treble)
312 {
313         /* PATH1_EQ_TREBLE_VOL */
314         cx18_av_and_or(cx, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff));
315 }
316
317 static int get_balance(struct cx18 *cx)
318 {
319         /* balance is 7 bit, 0 to -96dB */
320
321         /* check PATH1_BAL_LEVEL */
322         int balance = cx18_av_read(cx, 0x8d5) & 0x7f;
323         /* check PATH1_BAL_LEFT */
324         if ((cx18_av_read(cx, 0x8d5) & 0x80) == 0)
325                 balance = 0x80 - balance;
326         else
327                 balance = 0x80 + balance;
328         return balance << 8;
329 }
330
331 static void set_balance(struct cx18 *cx, int balance)
332 {
333         int bal = balance >> 8;
334         if (bal > 0x80) {
335                 /* PATH1_BAL_LEFT */
336                 cx18_av_and_or(cx, 0x8d5, 0x7f, 0x80);
337                 /* PATH1_BAL_LEVEL */
338                 cx18_av_and_or(cx, 0x8d5, ~0x7f, bal & 0x7f);
339         } else {
340                 /* PATH1_BAL_LEFT */
341                 cx18_av_and_or(cx, 0x8d5, 0x7f, 0x00);
342                 /* PATH1_BAL_LEVEL */
343                 cx18_av_and_or(cx, 0x8d5, ~0x7f, 0x80 - bal);
344         }
345 }
346
347 static int get_mute(struct cx18 *cx)
348 {
349         /* check SRC1_MUTE_EN */
350         return cx18_av_read(cx, 0x8d3) & 0x2 ? 1 : 0;
351 }
352
353 static void set_mute(struct cx18 *cx, int mute)
354 {
355         struct cx18_av_state *state = &cx->av_state;
356         u8 v;
357
358         if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
359                 /* Must turn off microcontroller in order to mute sound.
360                  * Not sure if this is the best method, but it does work.
361                  * If the microcontroller is running, then it will undo any
362                  * changes to the mute register. */
363                 v = cx18_av_read(cx, 0x803);
364                 if (mute) {
365                         /* disable microcontroller */
366                         v &= ~0x10;
367                         cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
368                         cx18_av_write(cx, 0x8d3, 0x1f);
369                 } else {
370                         /* enable microcontroller */
371                         v |= 0x10;
372                         cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
373                 }
374         } else {
375                 /* SRC1_MUTE_EN */
376                 cx18_av_and_or(cx, 0x8d3, ~0x2, mute ? 0x02 : 0x00);
377         }
378 }
379
380 int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg)
381 {
382         struct cx18_av_state *state = &cx->av_state;
383         struct v4l2_control *ctrl = arg;
384         int retval;
385
386         switch (cmd) {
387         case VIDIOC_INT_AUDIO_CLOCK_FREQ:
388         {
389                 u8 v;
390                 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
391                         v = cx18_av_read(cx, 0x803) & ~0x10;
392                         cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
393                         cx18_av_write(cx, 0x8d3, 0x1f);
394                 }
395                 v = cx18_av_read(cx, 0x810) | 0x1;
396                 cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
397
398                 retval = set_audclk_freq(cx, *(u32 *)arg);
399
400                 v = cx18_av_read(cx, 0x810) & ~0x1;
401                 cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
402                 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
403                         v = cx18_av_read(cx, 0x803) | 0x10;
404                         cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
405                 }
406                 return retval;
407         }
408
409         case VIDIOC_G_CTRL:
410                 switch (ctrl->id) {
411                 case V4L2_CID_AUDIO_VOLUME:
412                         ctrl->value = get_volume(cx);
413                         break;
414                 case V4L2_CID_AUDIO_BASS:
415                         ctrl->value = get_bass(cx);
416                         break;
417                 case V4L2_CID_AUDIO_TREBLE:
418                         ctrl->value = get_treble(cx);
419                         break;
420                 case V4L2_CID_AUDIO_BALANCE:
421                         ctrl->value = get_balance(cx);
422                         break;
423                 case V4L2_CID_AUDIO_MUTE:
424                         ctrl->value = get_mute(cx);
425                         break;
426                 default:
427                         return -EINVAL;
428                 }
429                 break;
430
431         case VIDIOC_S_CTRL:
432                 switch (ctrl->id) {
433                 case V4L2_CID_AUDIO_VOLUME:
434                         set_volume(cx, ctrl->value);
435                         break;
436                 case V4L2_CID_AUDIO_BASS:
437                         set_bass(cx, ctrl->value);
438                         break;
439                 case V4L2_CID_AUDIO_TREBLE:
440                         set_treble(cx, ctrl->value);
441                         break;
442                 case V4L2_CID_AUDIO_BALANCE:
443                         set_balance(cx, ctrl->value);
444                         break;
445                 case V4L2_CID_AUDIO_MUTE:
446                         set_mute(cx, ctrl->value);
447                         break;
448                 default:
449                         return -EINVAL;
450                 }
451                 break;
452
453         default:
454                 return -EINVAL;
455         }
456
457         return 0;
458 }