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