linux/drivers/media/pci/cx18/cx18-av-audio.c
<<
>>
Prefs
   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
  13static 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 minimize 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
 289void 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
 331static 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
 347static 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
 353static 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
 359static 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
 375static 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
 402int 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
 428static 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
 455const struct v4l2_ctrl_ops cx18_av_audio_ctrl_ops = {
 456        .s_ctrl = cx18_av_audio_s_ctrl,
 457};
 458