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 }; 559