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