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