xref: /linux/drivers/media/i2c/cx25840/cx25840-audio.c (revision b889fcf63cb62e7fdb7816565e28f44dbe4a76a5)
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 
517 int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
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) {
544 	case V4L2_CID_AUDIO_VOLUME:
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;
555 	case V4L2_CID_AUDIO_TREBLE:
556 		/* PATH1_EQ_TREBLE_VOL */
557 		cx25840_and_or(client, 0x8db, ~0x3f,
558 					48 - (ctrl->val * 48 / 0xffff));
559 		break;
560 	case V4L2_CID_AUDIO_BALANCE:
561 		set_balance(client, ctrl->val);
562 		break;
563 	default:
564 		return -EINVAL;
565 	}
566 	return 0;
567 }
568 
569 const struct v4l2_ctrl_ops cx25840_audio_ctrl_ops = {
570 	.s_ctrl = cx25840_audio_s_ctrl,
571 };
572