Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cx25840-audio.c
Go to the documentation of this file.
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 /*
27  * Note: The PLL and SRC parameters are based on a reference frequency that
28  * would ideally be:
29  *
30  * NTSC Color subcarrier freq * 8 = 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
31  *
32  * However, it's not the exact reference frequency that matters, only that the
33  * firmware and modules that comprise the driver for a particular board all
34  * use the same value (close to the ideal value).
35  *
36  * Comments below will note which reference frequency is assumed for various
37  * parameters. They will usually be one of
38  *
39  * ref_freq = 28.636360 MHz
40  * or
41  * ref_freq = 28.636363 MHz
42  */
43 
44 static int cx25840_set_audclk_freq(struct i2c_client *client, u32 freq)
45 {
46  struct cx25840_state *state = to_state(i2c_get_clientdata(client));
47 
48  if (state->aud_input != CX25840_AUDIO_SERIAL) {
49  switch (freq) {
50  case 32000:
51  /*
52  * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
53  * AUX_PLL Integer = 0x06, AUX PLL Post Divider = 0x10
54  */
55  cx25840_write4(client, 0x108, 0x1006040f);
56 
57  /*
58  * VID_PLL Fraction (register 0x10c) = 0x2be2fe
59  * 28636360 * 0xf.15f17f0/4 = 108 MHz
60  * 432 MHz pre-postdivide
61  */
62 
63  /*
64  * AUX_PLL Fraction = 0x1bb39ee
65  * 28636363 * 0x6.dd9cf70/0x10 = 32000 * 384
66  * 196.6 MHz pre-postdivide
67  * FIXME < 200 MHz is out of specified valid range
68  * FIXME 28636363 ref_freq doesn't match VID PLL ref
69  */
70  cx25840_write4(client, 0x110, 0x01bb39ee);
71 
72  /*
73  * SA_MCLK_SEL = 1
74  * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider
75  */
76  cx25840_write(client, 0x127, 0x50);
77 
78  if (is_cx2583x(state))
79  break;
80 
81  /* src3/4/6_ctl */
82  /* 0x1.f77f = (4 * 28636360/8 * 2/455) / 32000 */
83  cx25840_write4(client, 0x900, 0x0801f77f);
84  cx25840_write4(client, 0x904, 0x0801f77f);
85  cx25840_write4(client, 0x90c, 0x0801f77f);
86  break;
87 
88  case 44100:
89  /*
90  * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
91  * AUX_PLL Integer = 0x09, AUX PLL Post Divider = 0x10
92  */
93  cx25840_write4(client, 0x108, 0x1009040f);
94 
95  /*
96  * VID_PLL Fraction (register 0x10c) = 0x2be2fe
97  * 28636360 * 0xf.15f17f0/4 = 108 MHz
98  * 432 MHz pre-postdivide
99  */
100 
101  /*
102  * AUX_PLL Fraction = 0x0ec6bd6
103  * 28636363 * 0x9.7635eb0/0x10 = 44100 * 384
104  * 271 MHz pre-postdivide
105  * FIXME 28636363 ref_freq doesn't match VID PLL ref
106  */
107  cx25840_write4(client, 0x110, 0x00ec6bd6);
108 
109  /*
110  * SA_MCLK_SEL = 1
111  * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider
112  */
113  cx25840_write(client, 0x127, 0x50);
114 
115  if (is_cx2583x(state))
116  break;
117 
118  /* src3/4/6_ctl */
119  /* 0x1.6d59 = (4 * 28636360/8 * 2/455) / 44100 */
120  cx25840_write4(client, 0x900, 0x08016d59);
121  cx25840_write4(client, 0x904, 0x08016d59);
122  cx25840_write4(client, 0x90c, 0x08016d59);
123  break;
124 
125  case 48000:
126  /*
127  * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
128  * AUX_PLL Integer = 0x0a, AUX PLL Post Divider = 0x10
129  */
130  cx25840_write4(client, 0x108, 0x100a040f);
131 
132  /*
133  * VID_PLL Fraction (register 0x10c) = 0x2be2fe
134  * 28636360 * 0xf.15f17f0/4 = 108 MHz
135  * 432 MHz pre-postdivide
136  */
137 
138  /*
139  * AUX_PLL Fraction = 0x098d6e5
140  * 28636363 * 0xa.4c6b728/0x10 = 48000 * 384
141  * 295 MHz pre-postdivide
142  * FIXME 28636363 ref_freq doesn't match VID PLL ref
143  */
144  cx25840_write4(client, 0x110, 0x0098d6e5);
145 
146  /*
147  * SA_MCLK_SEL = 1
148  * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider
149  */
150  cx25840_write(client, 0x127, 0x50);
151 
152  if (is_cx2583x(state))
153  break;
154 
155  /* src3/4/6_ctl */
156  /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
157  cx25840_write4(client, 0x900, 0x08014faa);
158  cx25840_write4(client, 0x904, 0x08014faa);
159  cx25840_write4(client, 0x90c, 0x08014faa);
160  break;
161  }
162  } else {
163  switch (freq) {
164  case 32000:
165  /*
166  * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
167  * AUX_PLL Integer = 0x08, AUX PLL Post Divider = 0x1e
168  */
169  cx25840_write4(client, 0x108, 0x1e08040f);
170 
171  /*
172  * VID_PLL Fraction (register 0x10c) = 0x2be2fe
173  * 28636360 * 0xf.15f17f0/4 = 108 MHz
174  * 432 MHz pre-postdivide
175  */
176 
177  /*
178  * AUX_PLL Fraction = 0x12a0869
179  * 28636363 * 0x8.9504348/0x1e = 32000 * 256
180  * 246 MHz pre-postdivide
181  * FIXME 28636363 ref_freq doesn't match VID PLL ref
182  */
183  cx25840_write4(client, 0x110, 0x012a0869);
184 
185  /*
186  * SA_MCLK_SEL = 1
187  * SA_MCLK_DIV = 0x14 = 256/384 * AUX_PLL post dvivider
188  */
189  cx25840_write(client, 0x127, 0x54);
190 
191  if (is_cx2583x(state))
192  break;
193 
194  /* src1_ctl */
195  /* 0x1.0000 = 32000/32000 */
196  cx25840_write4(client, 0x8f8, 0x08010000);
197 
198  /* src3/4/6_ctl */
199  /* 0x2.0000 = 2 * (32000/32000) */
200  cx25840_write4(client, 0x900, 0x08020000);
201  cx25840_write4(client, 0x904, 0x08020000);
202  cx25840_write4(client, 0x90c, 0x08020000);
203  break;
204 
205  case 44100:
206  /*
207  * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
208  * AUX_PLL Integer = 0x09, AUX PLL Post Divider = 0x18
209  */
210  cx25840_write4(client, 0x108, 0x1809040f);
211 
212  /*
213  * VID_PLL Fraction (register 0x10c) = 0x2be2fe
214  * 28636360 * 0xf.15f17f0/4 = 108 MHz
215  * 432 MHz pre-postdivide
216  */
217 
218  /*
219  * AUX_PLL Fraction = 0x0ec6bd6
220  * 28636363 * 0x9.7635eb0/0x18 = 44100 * 256
221  * 271 MHz pre-postdivide
222  * FIXME 28636363 ref_freq doesn't match VID PLL ref
223  */
224  cx25840_write4(client, 0x110, 0x00ec6bd6);
225 
226  /*
227  * SA_MCLK_SEL = 1
228  * SA_MCLK_DIV = 0x10 = 256/384 * AUX_PLL post dvivider
229  */
230  cx25840_write(client, 0x127, 0x50);
231 
232  if (is_cx2583x(state))
233  break;
234 
235  /* src1_ctl */
236  /* 0x1.60cd = 44100/32000 */
237  cx25840_write4(client, 0x8f8, 0x080160cd);
238 
239  /* src3/4/6_ctl */
240  /* 0x1.7385 = 2 * (32000/44100) */
241  cx25840_write4(client, 0x900, 0x08017385);
242  cx25840_write4(client, 0x904, 0x08017385);
243  cx25840_write4(client, 0x90c, 0x08017385);
244  break;
245 
246  case 48000:
247  /*
248  * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
249  * AUX_PLL Integer = 0x0a, AUX PLL Post Divider = 0x18
250  */
251  cx25840_write4(client, 0x108, 0x180a040f);
252 
253  /*
254  * VID_PLL Fraction (register 0x10c) = 0x2be2fe
255  * 28636360 * 0xf.15f17f0/4 = 108 MHz
256  * 432 MHz pre-postdivide
257  */
258 
259  /*
260  * AUX_PLL Fraction = 0x098d6e5
261  * 28636363 * 0xa.4c6b728/0x18 = 48000 * 256
262  * 295 MHz pre-postdivide
263  * FIXME 28636363 ref_freq doesn't match VID PLL ref
264  */
265  cx25840_write4(client, 0x110, 0x0098d6e5);
266 
267  /*
268  * SA_MCLK_SEL = 1
269  * SA_MCLK_DIV = 0x10 = 256/384 * AUX_PLL post dvivider
270  */
271  cx25840_write(client, 0x127, 0x50);
272 
273  if (is_cx2583x(state))
274  break;
275 
276  /* src1_ctl */
277  /* 0x1.8000 = 48000/32000 */
278  cx25840_write4(client, 0x8f8, 0x08018000);
279 
280  /* src3/4/6_ctl */
281  /* 0x1.5555 = 2 * (32000/48000) */
282  cx25840_write4(client, 0x900, 0x08015555);
283  cx25840_write4(client, 0x904, 0x08015555);
284  cx25840_write4(client, 0x90c, 0x08015555);
285  break;
286  }
287  }
288 
289  state->audclk_freq = freq;
290 
291  return 0;
292 }
293 
294 static inline int cx25836_set_audclk_freq(struct i2c_client *client, u32 freq)
295 {
296  return cx25840_set_audclk_freq(client, freq);
297 }
298 
299 static int cx23885_set_audclk_freq(struct i2c_client *client, u32 freq)
300 {
301  struct cx25840_state *state = to_state(i2c_get_clientdata(client));
302 
303  if (state->aud_input != CX25840_AUDIO_SERIAL) {
304  switch (freq) {
305  case 32000:
306  case 44100:
307  case 48000:
308  /* We don't have register values
309  * so avoid destroying registers. */
310  /* FIXME return -EINVAL; */
311  break;
312  }
313  } else {
314  switch (freq) {
315  case 32000:
316  case 44100:
317  /* We don't have register values
318  * so avoid destroying registers. */
319  /* FIXME return -EINVAL; */
320  break;
321 
322  case 48000:
323  /* src1_ctl */
324  /* 0x1.867c = 48000 / (2 * 28636360/8 * 2/455) */
325  cx25840_write4(client, 0x8f8, 0x0801867c);
326 
327  /* src3/4/6_ctl */
328  /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
329  cx25840_write4(client, 0x900, 0x08014faa);
330  cx25840_write4(client, 0x904, 0x08014faa);
331  cx25840_write4(client, 0x90c, 0x08014faa);
332  break;
333  }
334  }
335 
336  state->audclk_freq = freq;
337 
338  return 0;
339 }
340 
341 static int cx231xx_set_audclk_freq(struct i2c_client *client, u32 freq)
342 {
343  struct cx25840_state *state = to_state(i2c_get_clientdata(client));
344 
345  if (state->aud_input != CX25840_AUDIO_SERIAL) {
346  switch (freq) {
347  case 32000:
348  /* src3/4/6_ctl */
349  /* 0x1.f77f = (4 * 28636360/8 * 2/455) / 32000 */
350  cx25840_write4(client, 0x900, 0x0801f77f);
351  cx25840_write4(client, 0x904, 0x0801f77f);
352  cx25840_write4(client, 0x90c, 0x0801f77f);
353  break;
354 
355  case 44100:
356  /* src3/4/6_ctl */
357  /* 0x1.6d59 = (4 * 28636360/8 * 2/455) / 44100 */
358  cx25840_write4(client, 0x900, 0x08016d59);
359  cx25840_write4(client, 0x904, 0x08016d59);
360  cx25840_write4(client, 0x90c, 0x08016d59);
361  break;
362 
363  case 48000:
364  /* src3/4/6_ctl */
365  /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
366  cx25840_write4(client, 0x900, 0x08014faa);
367  cx25840_write4(client, 0x904, 0x08014faa);
368  cx25840_write4(client, 0x90c, 0x08014faa);
369  break;
370  }
371  } else {
372  switch (freq) {
373  /* FIXME These cases make different assumptions about audclk */
374  case 32000:
375  /* src1_ctl */
376  /* 0x1.0000 = 32000/32000 */
377  cx25840_write4(client, 0x8f8, 0x08010000);
378 
379  /* src3/4/6_ctl */
380  /* 0x2.0000 = 2 * (32000/32000) */
381  cx25840_write4(client, 0x900, 0x08020000);
382  cx25840_write4(client, 0x904, 0x08020000);
383  cx25840_write4(client, 0x90c, 0x08020000);
384  break;
385 
386  case 44100:
387  /* src1_ctl */
388  /* 0x1.60cd = 44100/32000 */
389  cx25840_write4(client, 0x8f8, 0x080160cd);
390 
391  /* src3/4/6_ctl */
392  /* 0x1.7385 = 2 * (32000/44100) */
393  cx25840_write4(client, 0x900, 0x08017385);
394  cx25840_write4(client, 0x904, 0x08017385);
395  cx25840_write4(client, 0x90c, 0x08017385);
396  break;
397 
398  case 48000:
399  /* src1_ctl */
400  /* 0x1.867c = 48000 / (2 * 28636360/8 * 2/455) */
401  cx25840_write4(client, 0x8f8, 0x0801867c);
402 
403  /* src3/4/6_ctl */
404  /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
405  cx25840_write4(client, 0x900, 0x08014faa);
406  cx25840_write4(client, 0x904, 0x08014faa);
407  cx25840_write4(client, 0x90c, 0x08014faa);
408  break;
409  }
410  }
411 
412  state->audclk_freq = freq;
413 
414  return 0;
415 }
416 
417 static int set_audclk_freq(struct i2c_client *client, u32 freq)
418 {
419  struct cx25840_state *state = to_state(i2c_get_clientdata(client));
420 
421  if (freq != 32000 && freq != 44100 && freq != 48000)
422  return -EINVAL;
423 
424  if (is_cx231xx(state))
425  return cx231xx_set_audclk_freq(client, freq);
426 
427  if (is_cx2388x(state))
428  return cx23885_set_audclk_freq(client, freq);
429 
430  if (is_cx2583x(state))
431  return cx25836_set_audclk_freq(client, freq);
432 
433  return cx25840_set_audclk_freq(client, freq);
434 }
435 
436 void cx25840_audio_set_path(struct i2c_client *client)
437 {
438  struct cx25840_state *state = to_state(i2c_get_clientdata(client));
439 
440  if (!is_cx2583x(state)) {
441  /* assert soft reset */
442  cx25840_and_or(client, 0x810, ~0x1, 0x01);
443 
444  /* stop microcontroller */
445  cx25840_and_or(client, 0x803, ~0x10, 0);
446 
447  /* Mute everything to prevent the PFFT! */
448  cx25840_write(client, 0x8d3, 0x1f);
449 
450  if (state->aud_input == CX25840_AUDIO_SERIAL) {
451  /* Set Path1 to Serial Audio Input */
452  cx25840_write4(client, 0x8d0, 0x01011012);
453 
454  /* The microcontroller should not be started for the
455  * non-tuner inputs: autodetection is specific for
456  * TV audio. */
457  } else {
458  /* Set Path1 to Analog Demod Main Channel */
459  cx25840_write4(client, 0x8d0, 0x1f063870);
460  }
461  }
462 
463  set_audclk_freq(client, state->audclk_freq);
464 
465  if (!is_cx2583x(state)) {
466  if (state->aud_input != CX25840_AUDIO_SERIAL) {
467  /* When the microcontroller detects the
468  * audio format, it will unmute the lines */
469  cx25840_and_or(client, 0x803, ~0x10, 0x10);
470  }
471 
472  /* deassert soft reset */
473  cx25840_and_or(client, 0x810, ~0x1, 0x00);
474 
475  /* Ensure the controller is running when we exit */
476  if (is_cx2388x(state) || is_cx231xx(state))
477  cx25840_and_or(client, 0x803, ~0x10, 0x10);
478  }
479 }
480 
481 static void set_volume(struct i2c_client *client, int volume)
482 {
483  int vol;
484 
485  /* Convert the volume to msp3400 values (0-127) */
486  vol = volume >> 9;
487 
488  /* now scale it up to cx25840 values
489  * -114dB to -96dB maps to 0
490  * this should be 19, but in my testing that was 4dB too loud */
491  if (vol <= 23) {
492  vol = 0;
493  } else {
494  vol -= 23;
495  }
496 
497  /* PATH1_VOLUME */
498  cx25840_write(client, 0x8d4, 228 - (vol * 2));
499 }
500 
501 static void set_balance(struct i2c_client *client, int balance)
502 {
503  int bal = balance >> 8;
504  if (bal > 0x80) {
505  /* PATH1_BAL_LEFT */
506  cx25840_and_or(client, 0x8d5, 0x7f, 0x80);
507  /* PATH1_BAL_LEVEL */
508  cx25840_and_or(client, 0x8d5, ~0x7f, bal & 0x7f);
509  } else {
510  /* PATH1_BAL_LEFT */
511  cx25840_and_or(client, 0x8d5, 0x7f, 0x00);
512  /* PATH1_BAL_LEVEL */
513  cx25840_and_or(client, 0x8d5, ~0x7f, 0x80 - bal);
514  }
515 }
516 
518 {
519  struct i2c_client *client = v4l2_get_subdevdata(sd);
520  struct cx25840_state *state = to_state(sd);
521  int retval;
522 
523  if (!is_cx2583x(state))
524  cx25840_and_or(client, 0x810, ~0x1, 1);
525  if (state->aud_input != CX25840_AUDIO_SERIAL) {
526  cx25840_and_or(client, 0x803, ~0x10, 0);
527  cx25840_write(client, 0x8d3, 0x1f);
528  }
529  retval = set_audclk_freq(client, freq);
530  if (state->aud_input != CX25840_AUDIO_SERIAL)
531  cx25840_and_or(client, 0x803, ~0x10, 0x10);
532  if (!is_cx2583x(state))
533  cx25840_and_or(client, 0x810, ~0x1, 0);
534  return retval;
535 }
536 
537 static int cx25840_audio_s_ctrl(struct v4l2_ctrl *ctrl)
538 {
539  struct v4l2_subdev *sd = to_sd(ctrl);
540  struct cx25840_state *state = to_state(sd);
541  struct i2c_client *client = v4l2_get_subdevdata(sd);
542 
543  switch (ctrl->id) {
545  if (state->mute->val)
546  set_volume(client, 0);
547  else
548  set_volume(client, state->volume->val);
549  break;
550  case V4L2_CID_AUDIO_BASS:
551  /* PATH1_EQ_BASS_VOL */
552  cx25840_and_or(client, 0x8d9, ~0x3f,
553  48 - (ctrl->val * 48 / 0xffff));
554  break;
556  /* PATH1_EQ_TREBLE_VOL */
557  cx25840_and_or(client, 0x8db, ~0x3f,
558  48 - (ctrl->val * 48 / 0xffff));
559  break;
561  set_balance(client, ctrl->val);
562  break;
563  default:
564  return -EINVAL;
565  }
566  return 0;
567 }
568 
570  .s_ctrl = cx25840_audio_s_ctrl,
571 };