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

echoaudio_3g.c (11239B)


      1/****************************************************************************
      2
      3   Copyright Echo Digital Audio Corporation (c) 1998 - 2004
      4   All rights reserved
      5   www.echoaudio.com
      6
      7   This file is part of Echo Digital Audio's generic driver library.
      8
      9   Echo Digital Audio's generic driver library is free software;
     10   you can redistribute it and/or modify it under the terms of
     11   the GNU General Public License as published by the Free Software
     12   Foundation.
     13
     14   This program is distributed in the hope that it will be useful,
     15   but WITHOUT ANY WARRANTY; without even the implied warranty of
     16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17   GNU General Public License for more details.
     18
     19   You should have received a copy of the GNU General Public License
     20   along with this program; if not, write to the Free Software
     21   Foundation, Inc., 59 Temple Place - Suite 330, Boston,
     22   MA  02111-1307, USA.
     23
     24   *************************************************************************
     25
     26 Translation from C++ and adaptation for use in ALSA-Driver
     27 were made by Giuliano Pochini <pochini@shiny.it>
     28
     29****************************************************************************/
     30
     31
     32
     33/* These functions are common for all "3G" cards */
     34
     35
     36static int check_asic_status(struct echoaudio *chip)
     37{
     38	u32 box_status;
     39
     40	if (wait_handshake(chip))
     41		return -EIO;
     42
     43	chip->comm_page->ext_box_status = cpu_to_le32(E3G_ASIC_NOT_LOADED);
     44	chip->asic_loaded = false;
     45	clear_handshake(chip);
     46	send_vector(chip, DSP_VC_TEST_ASIC);
     47
     48	if (wait_handshake(chip)) {
     49		chip->dsp_code = NULL;
     50		return -EIO;
     51	}
     52
     53	box_status = le32_to_cpu(chip->comm_page->ext_box_status);
     54	dev_dbg(chip->card->dev, "box_status=%x\n", box_status);
     55	if (box_status == E3G_ASIC_NOT_LOADED)
     56		return -ENODEV;
     57
     58	chip->asic_loaded = true;
     59	return box_status & E3G_BOX_TYPE_MASK;
     60}
     61
     62
     63
     64static inline u32 get_frq_reg(struct echoaudio *chip)
     65{
     66	return le32_to_cpu(chip->comm_page->e3g_frq_register);
     67}
     68
     69
     70
     71/* Most configuration of 3G cards is accomplished by writing the control
     72register. write_control_reg sends the new control register value to the DSP. */
     73static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq,
     74			     char force)
     75{
     76	__le32 ctl_reg, frq_reg;
     77
     78	if (wait_handshake(chip))
     79		return -EIO;
     80
     81	dev_dbg(chip->card->dev,
     82		"WriteControlReg: Setting 0x%x, 0x%x\n", ctl, frq);
     83
     84	ctl_reg = cpu_to_le32(ctl);
     85	frq_reg = cpu_to_le32(frq);
     86
     87	if (ctl_reg != chip->comm_page->control_register ||
     88	    frq_reg != chip->comm_page->e3g_frq_register || force) {
     89		chip->comm_page->e3g_frq_register = frq_reg;
     90		chip->comm_page->control_register = ctl_reg;
     91		clear_handshake(chip);
     92		return send_vector(chip, DSP_VC_WRITE_CONTROL_REG);
     93	}
     94
     95	dev_dbg(chip->card->dev, "WriteControlReg: not written, no change\n");
     96	return 0;
     97}
     98
     99
    100
    101/* Set the digital mode - currently for Gina24, Layla24, Mona, 3G */
    102static int set_digital_mode(struct echoaudio *chip, u8 mode)
    103{
    104	u8 previous_mode;
    105	int err, i, o;
    106
    107	/* All audio channels must be closed before changing the digital mode */
    108	if (snd_BUG_ON(chip->pipe_alloc_mask))
    109		return -EAGAIN;
    110
    111	if (snd_BUG_ON(!(chip->digital_modes & (1 << mode))))
    112		return -EINVAL;
    113
    114	previous_mode = chip->digital_mode;
    115	err = dsp_set_digital_mode(chip, mode);
    116
    117	/* If we successfully changed the digital mode from or to ADAT,
    118	 * then make sure all output, input and monitor levels are
    119	 * updated by the DSP comm object. */
    120	if (err >= 0 && previous_mode != mode &&
    121	    (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) {
    122		spin_lock_irq(&chip->lock);
    123		for (o = 0; o < num_busses_out(chip); o++)
    124			for (i = 0; i < num_busses_in(chip); i++)
    125				set_monitor_gain(chip, o, i,
    126						 chip->monitor_gain[o][i]);
    127
    128#ifdef ECHOCARD_HAS_INPUT_GAIN
    129		for (i = 0; i < num_busses_in(chip); i++)
    130			set_input_gain(chip, i, chip->input_gain[i]);
    131		update_input_line_level(chip);
    132#endif
    133
    134		for (o = 0; o < num_busses_out(chip); o++)
    135			set_output_gain(chip, o, chip->output_gain[o]);
    136		update_output_line_level(chip);
    137		spin_unlock_irq(&chip->lock);
    138	}
    139
    140	return err;
    141}
    142
    143
    144
    145static u32 set_spdif_bits(struct echoaudio *chip, u32 control_reg, u32 rate)
    146{
    147	control_reg &= E3G_SPDIF_FORMAT_CLEAR_MASK;
    148
    149	switch (rate) {
    150	case 32000 :
    151		control_reg |= E3G_SPDIF_SAMPLE_RATE0 | E3G_SPDIF_SAMPLE_RATE1;
    152		break;
    153	case 44100 :
    154		if (chip->professional_spdif)
    155			control_reg |= E3G_SPDIF_SAMPLE_RATE0;
    156		break;
    157	case 48000 :
    158		control_reg |= E3G_SPDIF_SAMPLE_RATE1;
    159		break;
    160	}
    161
    162	if (chip->professional_spdif)
    163		control_reg |= E3G_SPDIF_PRO_MODE;
    164
    165	if (chip->non_audio_spdif)
    166		control_reg |= E3G_SPDIF_NOT_AUDIO;
    167
    168	control_reg |= E3G_SPDIF_24_BIT | E3G_SPDIF_TWO_CHANNEL |
    169		E3G_SPDIF_COPY_PERMIT;
    170
    171	return control_reg;
    172}
    173
    174
    175
    176/* Set the S/PDIF output format */
    177static int set_professional_spdif(struct echoaudio *chip, char prof)
    178{
    179	u32 control_reg;
    180
    181	control_reg = le32_to_cpu(chip->comm_page->control_register);
    182	chip->professional_spdif = prof;
    183	control_reg = set_spdif_bits(chip, control_reg, chip->sample_rate);
    184	return write_control_reg(chip, control_reg, get_frq_reg(chip), 0);
    185}
    186
    187
    188
    189/* detect_input_clocks() returns a bitmask consisting of all the input clocks
    190currently connected to the hardware; this changes as the user connects and
    191disconnects clock inputs. You should use this information to determine which
    192clocks the user is allowed to select. */
    193static u32 detect_input_clocks(const struct echoaudio *chip)
    194{
    195	u32 clocks_from_dsp, clock_bits;
    196
    197	/* Map the DSP clock detect bits to the generic driver clock
    198	 * detect bits */
    199	clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
    200
    201	clock_bits = ECHO_CLOCK_BIT_INTERNAL;
    202
    203	if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD)
    204		clock_bits |= ECHO_CLOCK_BIT_WORD;
    205
    206	switch(chip->digital_mode) {
    207	case DIGITAL_MODE_SPDIF_RCA:
    208	case DIGITAL_MODE_SPDIF_OPTICAL:
    209		if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF)
    210			clock_bits |= ECHO_CLOCK_BIT_SPDIF;
    211		break;
    212	case DIGITAL_MODE_ADAT:
    213		if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_ADAT)
    214			clock_bits |= ECHO_CLOCK_BIT_ADAT;
    215		break;
    216	}
    217
    218	return clock_bits;
    219}
    220
    221
    222
    223static int load_asic(struct echoaudio *chip)
    224{
    225	int box_type, err;
    226
    227	if (chip->asic_loaded)
    228		return 0;
    229
    230	/* Give the DSP a few milliseconds to settle down */
    231	mdelay(2);
    232
    233	err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC, FW_3G_ASIC);
    234	if (err < 0)
    235		return err;
    236
    237	chip->asic_code = FW_3G_ASIC;
    238
    239	/* Now give the new ASIC some time to set up */
    240	msleep(1000);
    241	/* See if it worked */
    242	box_type = check_asic_status(chip);
    243
    244	/* Set up the control register if the load succeeded -
    245	 * 48 kHz, internal clock, S/PDIF RCA mode */
    246	if (box_type >= 0) {
    247		err = write_control_reg(chip, E3G_48KHZ,
    248					E3G_FREQ_REG_DEFAULT, true);
    249		if (err < 0)
    250			return err;
    251	}
    252
    253	return box_type;
    254}
    255
    256
    257
    258static int set_sample_rate(struct echoaudio *chip, u32 rate)
    259{
    260	u32 control_reg, clock, base_rate, frq_reg;
    261
    262	/* Only set the clock for internal mode. */
    263	if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
    264		dev_warn(chip->card->dev,
    265			 "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n");
    266		/* Save the rate anyhow */
    267		chip->comm_page->sample_rate = cpu_to_le32(rate);
    268		chip->sample_rate = rate;
    269		set_input_clock(chip, chip->input_clock);
    270		return 0;
    271	}
    272
    273	if (snd_BUG_ON(rate >= 50000 &&
    274		       chip->digital_mode == DIGITAL_MODE_ADAT))
    275		return -EINVAL;
    276
    277	clock = 0;
    278	control_reg = le32_to_cpu(chip->comm_page->control_register);
    279	control_reg &= E3G_CLOCK_CLEAR_MASK;
    280
    281	switch (rate) {
    282	case 96000:
    283		clock = E3G_96KHZ;
    284		break;
    285	case 88200:
    286		clock = E3G_88KHZ;
    287		break;
    288	case 48000:
    289		clock = E3G_48KHZ;
    290		break;
    291	case 44100:
    292		clock = E3G_44KHZ;
    293		break;
    294	case 32000:
    295		clock = E3G_32KHZ;
    296		break;
    297	default:
    298		clock = E3G_CONTINUOUS_CLOCK;
    299		if (rate > 50000)
    300			clock |= E3G_DOUBLE_SPEED_MODE;
    301		break;
    302	}
    303
    304	control_reg |= clock;
    305	control_reg = set_spdif_bits(chip, control_reg, rate);
    306
    307	base_rate = rate;
    308	if (base_rate > 50000)
    309		base_rate /= 2;
    310	if (base_rate < 32000)
    311		base_rate = 32000;
    312
    313	frq_reg = E3G_MAGIC_NUMBER / base_rate - 2;
    314	if (frq_reg > E3G_FREQ_REG_MAX)
    315		frq_reg = E3G_FREQ_REG_MAX;
    316
    317	chip->comm_page->sample_rate = cpu_to_le32(rate);	/* ignored by the DSP */
    318	chip->sample_rate = rate;
    319	dev_dbg(chip->card->dev,
    320		"SetSampleRate: %d clock %x\n", rate, control_reg);
    321
    322	/* Tell the DSP about it - DSP reads both control reg & freq reg */
    323	return write_control_reg(chip, control_reg, frq_reg, 0);
    324}
    325
    326
    327
    328/* Set the sample clock source to internal, S/PDIF, ADAT */
    329static int set_input_clock(struct echoaudio *chip, u16 clock)
    330{
    331	u32 control_reg, clocks_from_dsp;
    332
    333
    334	/* Mask off the clock select bits */
    335	control_reg = le32_to_cpu(chip->comm_page->control_register) &
    336		E3G_CLOCK_CLEAR_MASK;
    337	clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
    338
    339	switch (clock) {
    340	case ECHO_CLOCK_INTERNAL:
    341		chip->input_clock = ECHO_CLOCK_INTERNAL;
    342		return set_sample_rate(chip, chip->sample_rate);
    343	case ECHO_CLOCK_SPDIF:
    344		if (chip->digital_mode == DIGITAL_MODE_ADAT)
    345			return -EAGAIN;
    346		control_reg |= E3G_SPDIF_CLOCK;
    347		if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF96)
    348			control_reg |= E3G_DOUBLE_SPEED_MODE;
    349		else
    350			control_reg &= ~E3G_DOUBLE_SPEED_MODE;
    351		break;
    352	case ECHO_CLOCK_ADAT:
    353		if (chip->digital_mode != DIGITAL_MODE_ADAT)
    354			return -EAGAIN;
    355		control_reg |= E3G_ADAT_CLOCK;
    356		control_reg &= ~E3G_DOUBLE_SPEED_MODE;
    357		break;
    358	case ECHO_CLOCK_WORD:
    359		control_reg |= E3G_WORD_CLOCK;
    360		if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD96)
    361			control_reg |= E3G_DOUBLE_SPEED_MODE;
    362		else
    363			control_reg &= ~E3G_DOUBLE_SPEED_MODE;
    364		break;
    365	default:
    366		dev_err(chip->card->dev,
    367			"Input clock 0x%x not supported for Echo3G\n", clock);
    368		return -EINVAL;
    369	}
    370
    371	chip->input_clock = clock;
    372	return write_control_reg(chip, control_reg, get_frq_reg(chip), 1);
    373}
    374
    375
    376
    377static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
    378{
    379	u32 control_reg;
    380	int err, incompatible_clock;
    381
    382	/* Set clock to "internal" if it's not compatible with the new mode */
    383	incompatible_clock = false;
    384	switch (mode) {
    385	case DIGITAL_MODE_SPDIF_OPTICAL:
    386	case DIGITAL_MODE_SPDIF_RCA:
    387		if (chip->input_clock == ECHO_CLOCK_ADAT)
    388			incompatible_clock = true;
    389		break;
    390	case DIGITAL_MODE_ADAT:
    391		if (chip->input_clock == ECHO_CLOCK_SPDIF)
    392			incompatible_clock = true;
    393		break;
    394	default:
    395		dev_err(chip->card->dev,
    396			"Digital mode not supported: %d\n", mode);
    397		return -EINVAL;
    398	}
    399
    400	spin_lock_irq(&chip->lock);
    401
    402	if (incompatible_clock) {
    403		chip->sample_rate = 48000;
    404		set_input_clock(chip, ECHO_CLOCK_INTERNAL);
    405	}
    406
    407	/* Clear the current digital mode */
    408	control_reg = le32_to_cpu(chip->comm_page->control_register);
    409	control_reg &= E3G_DIGITAL_MODE_CLEAR_MASK;
    410
    411	/* Tweak the control reg */
    412	switch (mode) {
    413	case DIGITAL_MODE_SPDIF_OPTICAL:
    414		control_reg |= E3G_SPDIF_OPTICAL_MODE;
    415		break;
    416	case DIGITAL_MODE_SPDIF_RCA:
    417		/* E3G_SPDIF_OPTICAL_MODE bit cleared */
    418		break;
    419	case DIGITAL_MODE_ADAT:
    420		control_reg |= E3G_ADAT_MODE;
    421		control_reg &= ~E3G_DOUBLE_SPEED_MODE;	/* @@ useless */
    422		break;
    423	}
    424
    425	err = write_control_reg(chip, control_reg, get_frq_reg(chip), 1);
    426	spin_unlock_irq(&chip->lock);
    427	if (err < 0)
    428		return err;
    429	chip->digital_mode = mode;
    430
    431	dev_dbg(chip->card->dev, "set_digital_mode(%d)\n", chip->digital_mode);
    432	return incompatible_clock;
    433}