V4L/DVB (9593): cx18: Add outgoing mailbox mutexes and check for ack via waitq vs...
[safe/jmp/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         u8 v;
219
220         /* stop microcontroller */
221         v = cx18_av_read(cx, 0x803) & ~0x10;
222         cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
223
224         /* assert soft reset */
225         v = cx18_av_read(cx, 0x810) | 0x01;
226         cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
227
228         /* Mute everything to prevent the PFFT! */
229         cx18_av_write(cx, 0x8d3, 0x1f);
230
231         if (state->aud_input <= CX18_AV_AUDIO_SERIAL2) {
232                 /* Set Path1 to Serial Audio Input */
233                 cx18_av_write4(cx, 0x8d0, 0x01011012);
234
235                 /* The microcontroller should not be started for the
236                  * non-tuner inputs: autodetection is specific for
237                  * TV audio. */
238         } else {
239                 /* Set Path1 to Analog Demod Main Channel */
240                 cx18_av_write4(cx, 0x8d0, 0x1f063870);
241         }
242
243         set_audclk_freq(cx, state->audclk_freq);
244
245         /* deassert soft reset */
246         v = cx18_av_read(cx, 0x810) & ~0x01;
247         cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
248
249         if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
250                 /* When the microcontroller detects the
251                  * audio format, it will unmute the lines */
252                 v = cx18_av_read(cx, 0x803) | 0x10;
253                 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
254         }
255 }
256
257 static int get_volume(struct cx18 *cx)
258 {
259         /* Volume runs +18dB to -96dB in 1/2dB steps
260          * change to fit the msp3400 -114dB to +12dB range */
261
262         /* check PATH1_VOLUME */
263         int vol = 228 - cx18_av_read(cx, 0x8d4);
264         vol = (vol / 2) + 23;
265         return vol << 9;
266 }
267
268 static void set_volume(struct cx18 *cx, int volume)
269 {
270         /* First convert the volume to msp3400 values (0-127) */
271         int vol = volume >> 9;
272         /* now scale it up to cx18_av values
273          * -114dB to -96dB maps to 0
274          * this should be 19, but in my testing that was 4dB too loud */
275         if (vol <= 23)
276                 vol = 0;
277         else
278                 vol -= 23;
279
280         /* PATH1_VOLUME */
281         cx18_av_write(cx, 0x8d4, 228 - (vol * 2));
282 }
283
284 static int get_bass(struct cx18 *cx)
285 {
286         /* bass is 49 steps +12dB to -12dB */
287
288         /* check PATH1_EQ_BASS_VOL */
289         int bass = cx18_av_read(cx, 0x8d9) & 0x3f;
290         bass = (((48 - bass) * 0xffff) + 47) / 48;
291         return bass;
292 }
293
294 static void set_bass(struct cx18 *cx, int bass)
295 {
296         /* PATH1_EQ_BASS_VOL */
297         cx18_av_and_or(cx, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff));
298 }
299
300 static int get_treble(struct cx18 *cx)
301 {
302         /* treble is 49 steps +12dB to -12dB */
303
304         /* check PATH1_EQ_TREBLE_VOL */
305         int treble = cx18_av_read(cx, 0x8db) & 0x3f;
306         treble = (((48 - treble) * 0xffff) + 47) / 48;
307         return treble;
308 }
309
310 static void set_treble(struct cx18 *cx, int treble)
311 {
312         /* PATH1_EQ_TREBLE_VOL */
313         cx18_av_and_or(cx, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff));
314 }
315
316 static int get_balance(struct cx18 *cx)
317 {
318         /* balance is 7 bit, 0 to -96dB */
319
320         /* check PATH1_BAL_LEVEL */
321         int balance = cx18_av_read(cx, 0x8d5) & 0x7f;
322         /* check PATH1_BAL_LEFT */
323         if ((cx18_av_read(cx, 0x8d5) & 0x80) == 0)
324                 balance = 0x80 - balance;
325         else
326                 balance = 0x80 + balance;
327         return balance << 8;
328 }
329
330 static void set_balance(struct cx18 *cx, int balance)
331 {
332         int bal = balance >> 8;
333         if (bal > 0x80) {
334                 /* PATH1_BAL_LEFT */
335                 cx18_av_and_or(cx, 0x8d5, 0x7f, 0x80);
336                 /* PATH1_BAL_LEVEL */
337                 cx18_av_and_or(cx, 0x8d5, ~0x7f, bal & 0x7f);
338         } else {
339                 /* PATH1_BAL_LEFT */
340                 cx18_av_and_or(cx, 0x8d5, 0x7f, 0x00);
341                 /* PATH1_BAL_LEVEL */
342                 cx18_av_and_or(cx, 0x8d5, ~0x7f, 0x80 - bal);
343         }
344 }
345
346 static int get_mute(struct cx18 *cx)
347 {
348         /* check SRC1_MUTE_EN */
349         return cx18_av_read(cx, 0x8d3) & 0x2 ? 1 : 0;
350 }
351
352 static void set_mute(struct cx18 *cx, int mute)
353 {
354         struct cx18_av_state *state = &cx->av_state;
355         u8 v;
356
357         if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
358                 /* Must turn off microcontroller in order to mute sound.
359                  * Not sure if this is the best method, but it does work.
360                  * If the microcontroller is running, then it will undo any
361                  * changes to the mute register. */
362                 v = cx18_av_read(cx, 0x803);
363                 if (mute) {
364                         /* disable microcontroller */
365                         v &= ~0x10;
366                         cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
367                         cx18_av_write(cx, 0x8d3, 0x1f);
368                 } else {
369                         /* enable microcontroller */
370                         v |= 0x10;
371                         cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
372                 }
373         } else {
374                 /* SRC1_MUTE_EN */
375                 cx18_av_and_or(cx, 0x8d3, ~0x2, mute ? 0x02 : 0x00);
376         }
377 }
378
379 int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg)
380 {
381         struct cx18_av_state *state = &cx->av_state;
382         struct v4l2_control *ctrl = arg;
383         int retval;
384
385         switch (cmd) {
386         case VIDIOC_INT_AUDIO_CLOCK_FREQ:
387         {
388                 u8 v;
389                 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
390                         v = cx18_av_read(cx, 0x803) & ~0x10;
391                         cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
392                         cx18_av_write(cx, 0x8d3, 0x1f);
393                 }
394                 v = cx18_av_read(cx, 0x810) | 0x1;
395                 cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
396
397                 retval = set_audclk_freq(cx, *(u32 *)arg);
398
399                 v = cx18_av_read(cx, 0x810) & ~0x1;
400                 cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
401                 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
402                         v = cx18_av_read(cx, 0x803) | 0x10;
403                         cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
404                 }
405                 return retval;
406         }
407
408         case VIDIOC_G_CTRL:
409                 switch (ctrl->id) {
410                 case V4L2_CID_AUDIO_VOLUME:
411                         ctrl->value = get_volume(cx);
412                         break;
413                 case V4L2_CID_AUDIO_BASS:
414                         ctrl->value = get_bass(cx);
415                         break;
416                 case V4L2_CID_AUDIO_TREBLE:
417                         ctrl->value = get_treble(cx);
418                         break;
419                 case V4L2_CID_AUDIO_BALANCE:
420                         ctrl->value = get_balance(cx);
421                         break;
422                 case V4L2_CID_AUDIO_MUTE:
423                         ctrl->value = get_mute(cx);
424                         break;
425                 default:
426                         return -EINVAL;
427                 }
428                 break;
429
430         case VIDIOC_S_CTRL:
431                 switch (ctrl->id) {
432                 case V4L2_CID_AUDIO_VOLUME:
433                         set_volume(cx, ctrl->value);
434                         break;
435                 case V4L2_CID_AUDIO_BASS:
436                         set_bass(cx, ctrl->value);
437                         break;
438                 case V4L2_CID_AUDIO_TREBLE:
439                         set_treble(cx, ctrl->value);
440                         break;
441                 case V4L2_CID_AUDIO_BALANCE:
442                         set_balance(cx, ctrl->value);
443                         break;
444                 case V4L2_CID_AUDIO_MUTE:
445                         set_mute(cx, ctrl->value);
446                         break;
447                 default:
448                         return -EINVAL;
449                 }
450                 break;
451
452         default:
453                 return -EINVAL;
454         }
455
456         return 0;
457 }