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