cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cx18-av-audio.c (12791B)


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