V4L/DVB (11475): gspca - m5602-po1030: Lower the default blue and gain balance
[linux-2.6] / drivers / media / video / cx25840 / cx25840-audio.c
1 /* cx25840 audio functions
2  *
3  * This program is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU General Public License
5  * as published by the Free Software Foundation; either version 2
6  * of the License, or (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16  */
17
18
19 #include <linux/videodev2.h>
20 #include <linux/i2c.h>
21 #include <media/v4l2-common.h>
22 #include <media/cx25840.h>
23
24 #include "cx25840-core.h"
25
26 static int set_audclk_freq(struct i2c_client *client, u32 freq)
27 {
28         struct cx25840_state *state = to_state(i2c_get_clientdata(client));
29
30         if (freq != 32000 && freq != 44100 && freq != 48000)
31                 return -EINVAL;
32
33         /* common for all inputs and rates */
34         /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
35         if (!state->is_cx23885 && !state->is_cx231xx)
36                 cx25840_write(client, 0x127, 0x50);
37
38         if (state->aud_input != CX25840_AUDIO_SERIAL) {
39                 switch (freq) {
40                 case 32000:
41                         if (state->is_cx23885) {
42                                 /* We don't have register values
43                                  * so avoid destroying registers. */
44                                 break;
45                         }
46
47                         if (!state->is_cx231xx) {
48                                 /* VID_PLL and AUX_PLL */
49                                 cx25840_write4(client, 0x108, 0x1006040f);
50
51                                 /* AUX_PLL_FRAC */
52                                 cx25840_write4(client, 0x110, 0x01bb39ee);
53                         }
54
55                         if (state->is_cx25836)
56                                 break;
57
58                         /* src3/4/6_ctl = 0x0801f77f */
59                         cx25840_write4(client, 0x900, 0x0801f77f);
60                         cx25840_write4(client, 0x904, 0x0801f77f);
61                         cx25840_write4(client, 0x90c, 0x0801f77f);
62                         break;
63
64                 case 44100:
65                         if (state->is_cx23885) {
66                                 /* We don't have register values
67                                  * so avoid destroying registers. */
68                                 break;
69                         }
70
71                         if (!state->is_cx231xx) {
72                                 /* VID_PLL and AUX_PLL */
73                                 cx25840_write4(client, 0x108, 0x1009040f);
74
75                                 /* AUX_PLL_FRAC */
76                                 cx25840_write4(client, 0x110, 0x00ec6bd6);
77                         }
78
79                         if (state->is_cx25836)
80                                 break;
81
82                         /* src3/4/6_ctl = 0x08016d59 */
83                         cx25840_write4(client, 0x900, 0x08016d59);
84                         cx25840_write4(client, 0x904, 0x08016d59);
85                         cx25840_write4(client, 0x90c, 0x08016d59);
86                         break;
87
88                 case 48000:
89                         if (state->is_cx23885) {
90                                 /* We don't have register values
91                                  * so avoid destroying registers. */
92                                 break;
93                         }
94
95                         if (!state->is_cx231xx) {
96                                 /* VID_PLL and AUX_PLL */
97                                 cx25840_write4(client, 0x108, 0x100a040f);
98
99                                 /* AUX_PLL_FRAC */
100                                 cx25840_write4(client, 0x110, 0x0098d6e5);
101                         }
102
103                         if (state->is_cx25836)
104                                 break;
105
106                         /* src3/4/6_ctl = 0x08014faa */
107                         cx25840_write4(client, 0x900, 0x08014faa);
108                         cx25840_write4(client, 0x904, 0x08014faa);
109                         cx25840_write4(client, 0x90c, 0x08014faa);
110                         break;
111                 }
112         } else {
113                 switch (freq) {
114                 case 32000:
115                         if (state->is_cx23885) {
116                                 /* We don't have register values
117                                  * so avoid destroying registers. */
118                                 break;
119                         }
120
121                         if (!state->is_cx231xx) {
122                                 /* VID_PLL and AUX_PLL */
123                                 cx25840_write4(client, 0x108, 0x1e08040f);
124
125                                 /* AUX_PLL_FRAC */
126                                 cx25840_write4(client, 0x110, 0x012a0869);
127                         }
128
129                         if (state->is_cx25836)
130                                 break;
131
132                         /* src1_ctl = 0x08010000 */
133                         cx25840_write4(client, 0x8f8, 0x08010000);
134
135                         /* src3/4/6_ctl = 0x08020000 */
136                         cx25840_write4(client, 0x900, 0x08020000);
137                         cx25840_write4(client, 0x904, 0x08020000);
138                         cx25840_write4(client, 0x90c, 0x08020000);
139
140                         /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
141                         cx25840_write(client, 0x127, 0x54);
142                         break;
143
144                 case 44100:
145                         if (state->is_cx23885) {
146                                 /* We don't have register values
147                                  * so avoid destroying registers. */
148                                 break;
149                         }
150
151
152                         if (!state->is_cx231xx) {
153                                 /* VID_PLL and AUX_PLL */
154                                 cx25840_write4(client, 0x108, 0x1809040f);
155
156                                 /* AUX_PLL_FRAC */
157                                 cx25840_write4(client, 0x110, 0x00ec6bd6);
158                         }
159
160                         if (state->is_cx25836)
161                                 break;
162
163                         /* src1_ctl = 0x08010000 */
164                         cx25840_write4(client, 0x8f8, 0x080160cd);
165
166                         /* src3/4/6_ctl = 0x08020000 */
167                         cx25840_write4(client, 0x900, 0x08017385);
168                         cx25840_write4(client, 0x904, 0x08017385);
169                         cx25840_write4(client, 0x90c, 0x08017385);
170                         break;
171
172                 case 48000:
173                         if (!state->is_cx23885 && !state->is_cx231xx) {
174                                 /* VID_PLL and AUX_PLL */
175                                 cx25840_write4(client, 0x108, 0x180a040f);
176
177                                 /* AUX_PLL_FRAC */
178                                 cx25840_write4(client, 0x110, 0x0098d6e5);
179                         }
180
181                         if (state->is_cx25836)
182                                 break;
183
184                         if (!state->is_cx23885 && !state->is_cx231xx) {
185                                 /* src1_ctl */
186                                 cx25840_write4(client, 0x8f8, 0x08018000);
187
188                                 /* src3/4/6_ctl */
189                                 cx25840_write4(client, 0x900, 0x08015555);
190                                 cx25840_write4(client, 0x904, 0x08015555);
191                                 cx25840_write4(client, 0x90c, 0x08015555);
192                         } else {
193
194                                 cx25840_write4(client, 0x8f8, 0x0801867c);
195
196                                 cx25840_write4(client, 0x900, 0x08014faa);
197                                 cx25840_write4(client, 0x904, 0x08014faa);
198                                 cx25840_write4(client, 0x90c, 0x08014faa);
199                         }
200                         break;
201                 }
202         }
203
204         state->audclk_freq = freq;
205
206         return 0;
207 }
208
209 void cx25840_audio_set_path(struct i2c_client *client)
210 {
211         struct cx25840_state *state = to_state(i2c_get_clientdata(client));
212
213         /* assert soft reset */
214         cx25840_and_or(client, 0x810, ~0x1, 0x01);
215
216         /* stop microcontroller */
217         cx25840_and_or(client, 0x803, ~0x10, 0);
218
219         /* Mute everything to prevent the PFFT! */
220         cx25840_write(client, 0x8d3, 0x1f);
221
222         if (state->aud_input == CX25840_AUDIO_SERIAL) {
223                 /* Set Path1 to Serial Audio Input */
224                 cx25840_write4(client, 0x8d0, 0x01011012);
225
226                 /* The microcontroller should not be started for the
227                  * non-tuner inputs: autodetection is specific for
228                  * TV audio. */
229         } else {
230                 /* Set Path1 to Analog Demod Main Channel */
231                 cx25840_write4(client, 0x8d0, 0x1f063870);
232         }
233
234         set_audclk_freq(client, state->audclk_freq);
235
236         if (state->aud_input != CX25840_AUDIO_SERIAL) {
237                 /* When the microcontroller detects the
238                  * audio format, it will unmute the lines */
239                 cx25840_and_or(client, 0x803, ~0x10, 0x10);
240         }
241
242         /* deassert soft reset */
243         cx25840_and_or(client, 0x810, ~0x1, 0x00);
244
245         /* Ensure the controller is running when we exit */
246         if (state->is_cx23885 || state->is_cx231xx)
247                 cx25840_and_or(client, 0x803, ~0x10, 0x10);
248 }
249
250 static int get_volume(struct i2c_client *client)
251 {
252         struct cx25840_state *state = to_state(i2c_get_clientdata(client));
253         int vol;
254
255         if (state->unmute_volume >= 0)
256                 return state->unmute_volume;
257
258         /* Volume runs +18dB to -96dB in 1/2dB steps
259          * change to fit the msp3400 -114dB to +12dB range */
260
261         /* check PATH1_VOLUME */
262         vol = 228 - cx25840_read(client, 0x8d4);
263         vol = (vol / 2) + 23;
264         return vol << 9;
265 }
266
267 static void set_volume(struct i2c_client *client, int volume)
268 {
269         struct cx25840_state *state = to_state(i2c_get_clientdata(client));
270         int vol;
271
272         if (state->unmute_volume >= 0) {
273                 state->unmute_volume = volume;
274                 return;
275         }
276
277         /* Convert the volume to msp3400 values (0-127) */
278         vol = volume >> 9;
279
280         /* now scale it up to cx25840 values
281          * -114dB to -96dB maps to 0
282          * this should be 19, but in my testing that was 4dB too loud */
283         if (vol <= 23) {
284                 vol = 0;
285         } else {
286                 vol -= 23;
287         }
288
289         /* PATH1_VOLUME */
290         cx25840_write(client, 0x8d4, 228 - (vol * 2));
291 }
292
293 static int get_bass(struct i2c_client *client)
294 {
295         /* bass is 49 steps +12dB to -12dB */
296
297         /* check PATH1_EQ_BASS_VOL */
298         int bass = cx25840_read(client, 0x8d9) & 0x3f;
299         bass = (((48 - bass) * 0xffff) + 47) / 48;
300         return bass;
301 }
302
303 static void set_bass(struct i2c_client *client, int bass)
304 {
305         /* PATH1_EQ_BASS_VOL */
306         cx25840_and_or(client, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff));
307 }
308
309 static int get_treble(struct i2c_client *client)
310 {
311         /* treble is 49 steps +12dB to -12dB */
312
313         /* check PATH1_EQ_TREBLE_VOL */
314         int treble = cx25840_read(client, 0x8db) & 0x3f;
315         treble = (((48 - treble) * 0xffff) + 47) / 48;
316         return treble;
317 }
318
319 static void set_treble(struct i2c_client *client, int treble)
320 {
321         /* PATH1_EQ_TREBLE_VOL */
322         cx25840_and_or(client, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff));
323 }
324
325 static int get_balance(struct i2c_client *client)
326 {
327         /* balance is 7 bit, 0 to -96dB */
328
329         /* check PATH1_BAL_LEVEL */
330         int balance = cx25840_read(client, 0x8d5) & 0x7f;
331         /* check PATH1_BAL_LEFT */
332         if ((cx25840_read(client, 0x8d5) & 0x80) == 0)
333                 balance = 0x80 - balance;
334         else
335                 balance = 0x80 + balance;
336         return balance << 8;
337 }
338
339 static void set_balance(struct i2c_client *client, int balance)
340 {
341         int bal = balance >> 8;
342         if (bal > 0x80) {
343                 /* PATH1_BAL_LEFT */
344                 cx25840_and_or(client, 0x8d5, 0x7f, 0x80);
345                 /* PATH1_BAL_LEVEL */
346                 cx25840_and_or(client, 0x8d5, ~0x7f, bal & 0x7f);
347         } else {
348                 /* PATH1_BAL_LEFT */
349                 cx25840_and_or(client, 0x8d5, 0x7f, 0x00);
350                 /* PATH1_BAL_LEVEL */
351                 cx25840_and_or(client, 0x8d5, ~0x7f, 0x80 - bal);
352         }
353 }
354
355 static int get_mute(struct i2c_client *client)
356 {
357         struct cx25840_state *state = to_state(i2c_get_clientdata(client));
358
359         return state->unmute_volume >= 0;
360 }
361
362 static void set_mute(struct i2c_client *client, int mute)
363 {
364         struct cx25840_state *state = to_state(i2c_get_clientdata(client));
365
366         if (mute && state->unmute_volume == -1) {
367                 int vol = get_volume(client);
368
369                 set_volume(client, 0);
370                 state->unmute_volume = vol;
371         }
372         else if (!mute && state->unmute_volume != -1) {
373                 int vol = state->unmute_volume;
374
375                 state->unmute_volume = -1;
376                 set_volume(client, vol);
377         }
378 }
379
380 int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
381 {
382         struct i2c_client *client = v4l2_get_subdevdata(sd);
383         struct cx25840_state *state = to_state(sd);
384         int retval;
385
386         if (!state->is_cx25836)
387                 cx25840_and_or(client, 0x810, ~0x1, 1);
388         if (state->aud_input != CX25840_AUDIO_SERIAL) {
389                 cx25840_and_or(client, 0x803, ~0x10, 0);
390                 cx25840_write(client, 0x8d3, 0x1f);
391         }
392         retval = set_audclk_freq(client, freq);
393         if (state->aud_input != CX25840_AUDIO_SERIAL)
394                 cx25840_and_or(client, 0x803, ~0x10, 0x10);
395         if (!state->is_cx25836)
396                 cx25840_and_or(client, 0x810, ~0x1, 0);
397         return retval;
398 }
399
400 int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
401 {
402         struct i2c_client *client = v4l2_get_subdevdata(sd);
403
404         switch (ctrl->id) {
405         case V4L2_CID_AUDIO_VOLUME:
406                 ctrl->value = get_volume(client);
407                 break;
408         case V4L2_CID_AUDIO_BASS:
409                 ctrl->value = get_bass(client);
410                 break;
411         case V4L2_CID_AUDIO_TREBLE:
412                 ctrl->value = get_treble(client);
413                 break;
414         case V4L2_CID_AUDIO_BALANCE:
415                 ctrl->value = get_balance(client);
416                 break;
417         case V4L2_CID_AUDIO_MUTE:
418                 ctrl->value = get_mute(client);
419                 break;
420         default:
421                 return -EINVAL;
422         }
423         return 0;
424 }
425
426 int cx25840_audio_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
427 {
428         struct i2c_client *client = v4l2_get_subdevdata(sd);
429
430         switch (ctrl->id) {
431         case V4L2_CID_AUDIO_VOLUME:
432                 set_volume(client, ctrl->value);
433                 break;
434         case V4L2_CID_AUDIO_BASS:
435                 set_bass(client, ctrl->value);
436                 break;
437         case V4L2_CID_AUDIO_TREBLE:
438                 set_treble(client, ctrl->value);
439                 break;
440         case V4L2_CID_AUDIO_BALANCE:
441                 set_balance(client, ctrl->value);
442                 break;
443         case V4L2_CID_AUDIO_MUTE:
444                 set_mute(client, ctrl->value);
445                 break;
446         default:
447                 return -EINVAL;
448         }
449         return 0;
450 }