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