root/drivers/media/pci/cx18/cx18-av-audio.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. set_audclk_freq
  2. cx18_av_audio_set_path
  3. set_volume
  4. set_bass
  5. set_treble
  6. set_balance
  7. set_mute
  8. cx18_av_s_clock_freq
  9. cx18_av_audio_s_ctrl

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  cx18 ADEC audio functions
   4  *
   5  *  Derived from cx25840-audio.c
   6  *
   7  *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
   8  *  Copyright (C) 2008  Andy Walls <awalls@md.metrocast.net>
   9  */
  10 
  11 #include "cx18-driver.h"
  12 
  13 static int set_audclk_freq(struct cx18 *cx, u32 freq)
  14 {
  15         struct cx18_av_state *state = &cx->av_state;
  16 
  17         if (freq != 32000 && freq != 44100 && freq != 48000)
  18                 return -EINVAL;
  19 
  20         /*
  21          * The PLL parameters are based on the external crystal frequency that
  22          * would ideally be:
  23          *
  24          * NTSC Color subcarrier freq * 8 =
  25          *      4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
  26          *
  27          * The accidents of history and rationale that explain from where this
  28          * combination of magic numbers originate can be found in:
  29          *
  30          * [1] Abrahams, I. C., "Choice of Chrominance Subcarrier Frequency in
  31          * the NTSC Standards", Proceedings of the I-R-E, January 1954, pp 79-80
  32          *
  33          * [2] Abrahams, I. C., "The 'Frequency Interleaving' Principle in the
  34          * NTSC Standards", Proceedings of the I-R-E, January 1954, pp 81-83
  35          *
  36          * As Mike Bradley has rightly pointed out, it's not the exact crystal
  37          * frequency that matters, only that all parts of the driver and
  38          * firmware are using the same value (close to the ideal value).
  39          *
  40          * Since I have a strong suspicion that, if the firmware ever assumes a
  41          * crystal value at all, it will assume 28.636360 MHz, the crystal
  42          * freq used in calculations in this driver will be:
  43          *
  44          *      xtal_freq = 28.636360 MHz
  45          *
  46          * an error of less than 0.13 ppm which is way, way better than any off
  47          * the shelf crystal will have for accuracy anyway.
  48          *
  49          * Below I aim to run the PLLs' VCOs near 400 MHz to minimze error.
  50          *
  51          * Many thanks to Jeff Campbell and Mike Bradley for their extensive
  52          * investigation, experimentation, testing, and suggested solutions of
  53          * of audio/video sync problems with SVideo and CVBS captures.
  54          */
  55 
  56         if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
  57                 switch (freq) {
  58                 case 32000:
  59                         /*
  60                          * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
  61                          * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x20
  62                          */
  63                         cx18_av_write4(cx, 0x108, 0x200d040f);
  64 
  65                         /* VID_PLL Fraction = 0x2be2fe */
  66                         /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
  67                         cx18_av_write4(cx, 0x10c, 0x002be2fe);
  68 
  69                         /* AUX_PLL Fraction = 0x176740c */
  70                         /* xtal * 0xd.bb3a060/0x20 = 32000 * 384: 393 MHz p-pd*/
  71                         cx18_av_write4(cx, 0x110, 0x0176740c);
  72 
  73                         /* src3/4/6_ctl */
  74                         /* 0x1.f77f = (4 * xtal/8*2/455) / 32000 */
  75                         cx18_av_write4(cx, 0x900, 0x0801f77f);
  76                         cx18_av_write4(cx, 0x904, 0x0801f77f);
  77                         cx18_av_write4(cx, 0x90c, 0x0801f77f);
  78 
  79                         /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x20 */
  80                         cx18_av_write(cx, 0x127, 0x60);
  81 
  82                         /* AUD_COUNT = 0x2fff = 8 samples * 4 * 384 - 1 */
  83                         cx18_av_write4(cx, 0x12c, 0x11202fff);
  84 
  85                         /*
  86                          * EN_AV_LOCK = 0
  87                          * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 =
  88                          *  ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8
  89                          */
  90                         cx18_av_write4(cx, 0x128, 0xa00d2ef8);
  91                         break;
  92 
  93                 case 44100:
  94                         /*
  95                          * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
  96                          * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x18
  97                          */
  98                         cx18_av_write4(cx, 0x108, 0x180e040f);
  99 
 100                         /* VID_PLL Fraction = 0x2be2fe */
 101                         /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
 102                         cx18_av_write4(cx, 0x10c, 0x002be2fe);
 103 
 104                         /* AUX_PLL Fraction = 0x062a1f2 */
 105                         /* xtal * 0xe.3150f90/0x18 = 44100 * 384: 406 MHz p-pd*/
 106                         cx18_av_write4(cx, 0x110, 0x0062a1f2);
 107 
 108                         /* src3/4/6_ctl */
 109                         /* 0x1.6d59 = (4 * xtal/8*2/455) / 44100 */
 110                         cx18_av_write4(cx, 0x900, 0x08016d59);
 111                         cx18_av_write4(cx, 0x904, 0x08016d59);
 112                         cx18_av_write4(cx, 0x90c, 0x08016d59);
 113 
 114                         /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x18 */
 115                         cx18_av_write(cx, 0x127, 0x58);
 116 
 117                         /* AUD_COUNT = 0x92ff = 49 samples * 2 * 384 - 1 */
 118                         cx18_av_write4(cx, 0x12c, 0x112092ff);
 119 
 120                         /*
 121                          * EN_AV_LOCK = 0
 122                          * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 =
 123                          *  ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8
 124                          */
 125                         cx18_av_write4(cx, 0x128, 0xa01d4bf8);
 126                         break;
 127 
 128                 case 48000:
 129                         /*
 130                          * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
 131                          * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x16
 132                          */
 133                         cx18_av_write4(cx, 0x108, 0x160e040f);
 134 
 135                         /* VID_PLL Fraction = 0x2be2fe */
 136                         /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
 137                         cx18_av_write4(cx, 0x10c, 0x002be2fe);
 138 
 139                         /* AUX_PLL Fraction = 0x05227ad */
 140                         /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz p-pd*/
 141                         cx18_av_write4(cx, 0x110, 0x005227ad);
 142 
 143                         /* src3/4/6_ctl */
 144                         /* 0x1.4faa = (4 * xtal/8*2/455) / 48000 */
 145                         cx18_av_write4(cx, 0x900, 0x08014faa);
 146                         cx18_av_write4(cx, 0x904, 0x08014faa);
 147                         cx18_av_write4(cx, 0x90c, 0x08014faa);
 148 
 149                         /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
 150                         cx18_av_write(cx, 0x127, 0x56);
 151 
 152                         /* AUD_COUNT = 0x5fff = 4 samples * 16 * 384 - 1 */
 153                         cx18_av_write4(cx, 0x12c, 0x11205fff);
 154 
 155                         /*
 156                          * EN_AV_LOCK = 0
 157                          * VID_COUNT = 0x1193f8 = 143999.000 * 8 =
 158                          *  ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8
 159                          */
 160                         cx18_av_write4(cx, 0x128, 0xa01193f8);
 161                         break;
 162                 }
 163         } else {
 164                 switch (freq) {
 165                 case 32000:
 166                         /*
 167                          * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
 168                          * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x30
 169                          */
 170                         cx18_av_write4(cx, 0x108, 0x300d040f);
 171 
 172                         /* VID_PLL Fraction = 0x2be2fe */
 173                         /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
 174                         cx18_av_write4(cx, 0x10c, 0x002be2fe);
 175 
 176                         /* AUX_PLL Fraction = 0x176740c */
 177                         /* xtal * 0xd.bb3a060/0x30 = 32000 * 256: 393 MHz p-pd*/
 178                         cx18_av_write4(cx, 0x110, 0x0176740c);
 179 
 180                         /* src1_ctl */
 181                         /* 0x1.0000 = 32000/32000 */
 182                         cx18_av_write4(cx, 0x8f8, 0x08010000);
 183 
 184                         /* src3/4/6_ctl */
 185                         /* 0x2.0000 = 2 * (32000/32000) */
 186                         cx18_av_write4(cx, 0x900, 0x08020000);
 187                         cx18_av_write4(cx, 0x904, 0x08020000);
 188                         cx18_av_write4(cx, 0x90c, 0x08020000);
 189 
 190                         /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x30 */
 191                         cx18_av_write(cx, 0x127, 0x70);
 192 
 193                         /* AUD_COUNT = 0x1fff = 8 samples * 4 * 256 - 1 */
 194                         cx18_av_write4(cx, 0x12c, 0x11201fff);
 195 
 196                         /*
 197                          * EN_AV_LOCK = 0
 198                          * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 =
 199                          *  ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8
 200                          */
 201                         cx18_av_write4(cx, 0x128, 0xa00d2ef8);
 202                         break;
 203 
 204                 case 44100:
 205                         /*
 206                          * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
 207                          * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x24
 208                          */
 209                         cx18_av_write4(cx, 0x108, 0x240e040f);
 210 
 211                         /* VID_PLL Fraction = 0x2be2fe */
 212                         /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
 213                         cx18_av_write4(cx, 0x10c, 0x002be2fe);
 214 
 215                         /* AUX_PLL Fraction = 0x062a1f2 */
 216                         /* xtal * 0xe.3150f90/0x24 = 44100 * 256: 406 MHz p-pd*/
 217                         cx18_av_write4(cx, 0x110, 0x0062a1f2);
 218 
 219                         /* src1_ctl */
 220                         /* 0x1.60cd = 44100/32000 */
 221                         cx18_av_write4(cx, 0x8f8, 0x080160cd);
 222 
 223                         /* src3/4/6_ctl */
 224                         /* 0x1.7385 = 2 * (32000/44100) */
 225                         cx18_av_write4(cx, 0x900, 0x08017385);
 226                         cx18_av_write4(cx, 0x904, 0x08017385);
 227                         cx18_av_write4(cx, 0x90c, 0x08017385);
 228 
 229                         /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x24 */
 230                         cx18_av_write(cx, 0x127, 0x64);
 231 
 232                         /* AUD_COUNT = 0x61ff = 49 samples * 2 * 256 - 1 */
 233                         cx18_av_write4(cx, 0x12c, 0x112061ff);
 234 
 235                         /*
 236                          * EN_AV_LOCK = 0
 237                          * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 =
 238                          *  ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8
 239                          */
 240                         cx18_av_write4(cx, 0x128, 0xa01d4bf8);
 241                         break;
 242 
 243                 case 48000:
 244                         /*
 245                          * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
 246                          * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x20
 247                          */
 248                         cx18_av_write4(cx, 0x108, 0x200d040f);
 249 
 250                         /* VID_PLL Fraction = 0x2be2fe */
 251                         /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
 252                         cx18_av_write4(cx, 0x10c, 0x002be2fe);
 253 
 254                         /* AUX_PLL Fraction = 0x176740c */
 255                         /* xtal * 0xd.bb3a060/0x20 = 48000 * 256: 393 MHz p-pd*/
 256                         cx18_av_write4(cx, 0x110, 0x0176740c);
 257 
 258                         /* src1_ctl */
 259                         /* 0x1.8000 = 48000/32000 */
 260                         cx18_av_write4(cx, 0x8f8, 0x08018000);
 261 
 262                         /* src3/4/6_ctl */
 263                         /* 0x1.5555 = 2 * (32000/48000) */
 264                         cx18_av_write4(cx, 0x900, 0x08015555);
 265                         cx18_av_write4(cx, 0x904, 0x08015555);
 266                         cx18_av_write4(cx, 0x90c, 0x08015555);
 267 
 268                         /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x20 */
 269                         cx18_av_write(cx, 0x127, 0x60);
 270 
 271                         /* AUD_COUNT = 0x3fff = 4 samples * 16 * 256 - 1 */
 272                         cx18_av_write4(cx, 0x12c, 0x11203fff);
 273 
 274                         /*
 275                          * EN_AV_LOCK = 0
 276                          * VID_COUNT = 0x1193f8 = 143999.000 * 8 =
 277                          *  ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8
 278                          */
 279                         cx18_av_write4(cx, 0x128, 0xa01193f8);
 280                         break;
 281                 }
 282         }
 283 
 284         state->audclk_freq = freq;
 285 
 286         return 0;
 287 }
 288 
 289 void cx18_av_audio_set_path(struct cx18 *cx)
 290 {
 291         struct cx18_av_state *state = &cx->av_state;
 292         u8 v;
 293 
 294         /* stop microcontroller */
 295         v = cx18_av_read(cx, 0x803) & ~0x10;
 296         cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
 297 
 298         /* assert soft reset */
 299         v = cx18_av_read(cx, 0x810) | 0x01;
 300         cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
 301 
 302         /* Mute everything to prevent the PFFT! */
 303         cx18_av_write(cx, 0x8d3, 0x1f);
 304 
 305         if (state->aud_input <= CX18_AV_AUDIO_SERIAL2) {
 306                 /* Set Path1 to Serial Audio Input */
 307                 cx18_av_write4(cx, 0x8d0, 0x01011012);
 308 
 309                 /* The microcontroller should not be started for the
 310                  * non-tuner inputs: autodetection is specific for
 311                  * TV audio. */
 312         } else {
 313                 /* Set Path1 to Analog Demod Main Channel */
 314                 cx18_av_write4(cx, 0x8d0, 0x1f063870);
 315         }
 316 
 317         set_audclk_freq(cx, state->audclk_freq);
 318 
 319         /* deassert soft reset */
 320         v = cx18_av_read(cx, 0x810) & ~0x01;
 321         cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
 322 
 323         if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
 324                 /* When the microcontroller detects the
 325                  * audio format, it will unmute the lines */
 326                 v = cx18_av_read(cx, 0x803) | 0x10;
 327                 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
 328         }
 329 }
 330 
 331 static void set_volume(struct cx18 *cx, int volume)
 332 {
 333         /* First convert the volume to msp3400 values (0-127) */
 334         int vol = volume >> 9;
 335         /* now scale it up to cx18_av values
 336          * -114dB to -96dB maps to 0
 337          * this should be 19, but in my testing that was 4dB too loud */
 338         if (vol <= 23)
 339                 vol = 0;
 340         else
 341                 vol -= 23;
 342 
 343         /* PATH1_VOLUME */
 344         cx18_av_write(cx, 0x8d4, 228 - (vol * 2));
 345 }
 346 
 347 static void set_bass(struct cx18 *cx, int bass)
 348 {
 349         /* PATH1_EQ_BASS_VOL */
 350         cx18_av_and_or(cx, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff));
 351 }
 352 
 353 static void set_treble(struct cx18 *cx, int treble)
 354 {
 355         /* PATH1_EQ_TREBLE_VOL */
 356         cx18_av_and_or(cx, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff));
 357 }
 358 
 359 static void set_balance(struct cx18 *cx, int balance)
 360 {
 361         int bal = balance >> 8;
 362         if (bal > 0x80) {
 363                 /* PATH1_BAL_LEFT */
 364                 cx18_av_and_or(cx, 0x8d5, 0x7f, 0x80);
 365                 /* PATH1_BAL_LEVEL */
 366                 cx18_av_and_or(cx, 0x8d5, ~0x7f, bal & 0x7f);
 367         } else {
 368                 /* PATH1_BAL_LEFT */
 369                 cx18_av_and_or(cx, 0x8d5, 0x7f, 0x00);
 370                 /* PATH1_BAL_LEVEL */
 371                 cx18_av_and_or(cx, 0x8d5, ~0x7f, 0x80 - bal);
 372         }
 373 }
 374 
 375 static void set_mute(struct cx18 *cx, int mute)
 376 {
 377         struct cx18_av_state *state = &cx->av_state;
 378         u8 v;
 379 
 380         if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
 381                 /* Must turn off microcontroller in order to mute sound.
 382                  * Not sure if this is the best method, but it does work.
 383                  * If the microcontroller is running, then it will undo any
 384                  * changes to the mute register. */
 385                 v = cx18_av_read(cx, 0x803);
 386                 if (mute) {
 387                         /* disable microcontroller */
 388                         v &= ~0x10;
 389                         cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
 390                         cx18_av_write(cx, 0x8d3, 0x1f);
 391                 } else {
 392                         /* enable microcontroller */
 393                         v |= 0x10;
 394                         cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
 395                 }
 396         } else {
 397                 /* SRC1_MUTE_EN */
 398                 cx18_av_and_or(cx, 0x8d3, ~0x2, mute ? 0x02 : 0x00);
 399         }
 400 }
 401 
 402 int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
 403 {
 404         struct cx18 *cx = v4l2_get_subdevdata(sd);
 405         struct cx18_av_state *state = &cx->av_state;
 406         int retval;
 407         u8 v;
 408 
 409         if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
 410                 v = cx18_av_read(cx, 0x803) & ~0x10;
 411                 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
 412                 cx18_av_write(cx, 0x8d3, 0x1f);
 413         }
 414         v = cx18_av_read(cx, 0x810) | 0x1;
 415         cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
 416 
 417         retval = set_audclk_freq(cx, freq);
 418 
 419         v = cx18_av_read(cx, 0x810) & ~0x1;
 420         cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
 421         if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
 422                 v = cx18_av_read(cx, 0x803) | 0x10;
 423                 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
 424         }
 425         return retval;
 426 }
 427 
 428 static int cx18_av_audio_s_ctrl(struct v4l2_ctrl *ctrl)
 429 {
 430         struct v4l2_subdev *sd = to_sd(ctrl);
 431         struct cx18 *cx = v4l2_get_subdevdata(sd);
 432 
 433         switch (ctrl->id) {
 434         case V4L2_CID_AUDIO_VOLUME:
 435                 set_volume(cx, ctrl->val);
 436                 break;
 437         case V4L2_CID_AUDIO_BASS:
 438                 set_bass(cx, ctrl->val);
 439                 break;
 440         case V4L2_CID_AUDIO_TREBLE:
 441                 set_treble(cx, ctrl->val);
 442                 break;
 443         case V4L2_CID_AUDIO_BALANCE:
 444                 set_balance(cx, ctrl->val);
 445                 break;
 446         case V4L2_CID_AUDIO_MUTE:
 447                 set_mute(cx, ctrl->val);
 448                 break;
 449         default:
 450                 return -EINVAL;
 451         }
 452         return 0;
 453 }
 454 
 455 const struct v4l2_ctrl_ops cx18_av_audio_ctrl_ops = {
 456         .s_ctrl = cx18_av_audio_s_ctrl,
 457 };

/* [<][>][^][v][top][bottom][index][help] */