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

mona_dsp.c (10809B)


      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
     32static int write_control_reg(struct echoaudio *chip, u32 value, char force);
     33static int set_input_clock(struct echoaudio *chip, u16 clock);
     34static int set_professional_spdif(struct echoaudio *chip, char prof);
     35static int set_digital_mode(struct echoaudio *chip, u8 mode);
     36static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
     37static int check_asic_status(struct echoaudio *chip);
     38
     39
     40static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
     41{
     42	int err;
     43
     44	if (snd_BUG_ON((subdevice_id & 0xfff0) != MONA))
     45		return -ENODEV;
     46
     47	err = init_dsp_comm_page(chip);
     48	if (err) {
     49		dev_err(chip->card->dev,
     50			"init_hw - could not initialize DSP comm page\n");
     51		return err;
     52	}
     53
     54	chip->device_id = device_id;
     55	chip->subdevice_id = subdevice_id;
     56	chip->bad_board = true;
     57	chip->input_clock_types =
     58		ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
     59		ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT;
     60	chip->digital_modes =
     61		ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
     62		ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
     63		ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
     64
     65	/* Mona comes in both '301 and '361 flavors */
     66	if (chip->device_id == DEVICE_ID_56361)
     67		chip->dsp_code_to_load = FW_MONA_361_DSP;
     68	else
     69		chip->dsp_code_to_load = FW_MONA_301_DSP;
     70
     71	err = load_firmware(chip);
     72	if (err < 0)
     73		return err;
     74	chip->bad_board = false;
     75
     76	return err;
     77}
     78
     79
     80
     81static int set_mixer_defaults(struct echoaudio *chip)
     82{
     83	chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
     84	chip->professional_spdif = false;
     85	chip->digital_in_automute = true;
     86	return init_line_levels(chip);
     87}
     88
     89
     90
     91static u32 detect_input_clocks(const struct echoaudio *chip)
     92{
     93	u32 clocks_from_dsp, clock_bits;
     94
     95	/* Map the DSP clock detect bits to the generic driver clock
     96	   detect bits */
     97	clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
     98
     99	clock_bits = ECHO_CLOCK_BIT_INTERNAL;
    100
    101	if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF)
    102		clock_bits |= ECHO_CLOCK_BIT_SPDIF;
    103
    104	if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT)
    105		clock_bits |= ECHO_CLOCK_BIT_ADAT;
    106
    107	if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD)
    108		clock_bits |= ECHO_CLOCK_BIT_WORD;
    109
    110	return clock_bits;
    111}
    112
    113
    114
    115/* Mona has an ASIC on the PCI card and another ASIC in the external box; 
    116both need to be loaded. */
    117static int load_asic(struct echoaudio *chip)
    118{
    119	u32 control_reg;
    120	int err;
    121	short asic;
    122
    123	if (chip->asic_loaded)
    124		return 0;
    125
    126	mdelay(10);
    127
    128	if (chip->device_id == DEVICE_ID_56361)
    129		asic = FW_MONA_361_1_ASIC48;
    130	else
    131		asic = FW_MONA_301_1_ASIC48;
    132
    133	err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, asic);
    134	if (err < 0)
    135		return err;
    136
    137	chip->asic_code = asic;
    138	mdelay(10);
    139
    140	/* Do the external one */
    141	err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_EXTERNAL_ASIC,
    142				FW_MONA_2_ASIC);
    143	if (err < 0)
    144		return err;
    145
    146	mdelay(10);
    147	err = check_asic_status(chip);
    148
    149	/* Set up the control register if the load succeeded -
    150	   48 kHz, internal clock, S/PDIF RCA mode */
    151	if (!err) {
    152		control_reg = GML_CONVERTER_ENABLE | GML_48KHZ;
    153		err = write_control_reg(chip, control_reg, true);
    154	}
    155
    156	return err;
    157}
    158
    159
    160
    161/* Depending on what digital mode you want, Mona needs different ASICs
    162loaded.  This function checks the ASIC needed for the new mode and sees
    163if it matches the one already loaded. */
    164static int switch_asic(struct echoaudio *chip, char double_speed)
    165{
    166	int err;
    167	short asic;
    168
    169	/* Check the clock detect bits to see if this is
    170	a single-speed clock or a double-speed clock; load
    171	a new ASIC if necessary. */
    172	if (chip->device_id == DEVICE_ID_56361) {
    173		if (double_speed)
    174			asic = FW_MONA_361_1_ASIC96;
    175		else
    176			asic = FW_MONA_361_1_ASIC48;
    177	} else {
    178		if (double_speed)
    179			asic = FW_MONA_301_1_ASIC96;
    180		else
    181			asic = FW_MONA_301_1_ASIC48;
    182	}
    183
    184	if (asic != chip->asic_code) {
    185		/* Load the desired ASIC */
    186		err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC,
    187					asic);
    188		if (err < 0)
    189			return err;
    190		chip->asic_code = asic;
    191	}
    192
    193	return 0;
    194}
    195
    196
    197
    198static int set_sample_rate(struct echoaudio *chip, u32 rate)
    199{
    200	u32 control_reg, clock;
    201	short asic;
    202	char force_write;
    203
    204	/* Only set the clock for internal mode. */
    205	if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
    206		dev_dbg(chip->card->dev,
    207			"Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n");
    208		/* Save the rate anyhow */
    209		chip->comm_page->sample_rate = cpu_to_le32(rate);
    210		chip->sample_rate = rate;
    211		return 0;
    212	}
    213
    214	/* Now, check to see if the required ASIC is loaded */
    215	if (rate >= 88200) {
    216		if (chip->digital_mode == DIGITAL_MODE_ADAT)
    217			return -EINVAL;
    218		if (chip->device_id == DEVICE_ID_56361)
    219			asic = FW_MONA_361_1_ASIC96;
    220		else
    221			asic = FW_MONA_301_1_ASIC96;
    222	} else {
    223		if (chip->device_id == DEVICE_ID_56361)
    224			asic = FW_MONA_361_1_ASIC48;
    225		else
    226			asic = FW_MONA_301_1_ASIC48;
    227	}
    228
    229	force_write = 0;
    230	if (asic != chip->asic_code) {
    231		int err;
    232		/* Load the desired ASIC (load_asic_generic() can sleep) */
    233		spin_unlock_irq(&chip->lock);
    234		err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC,
    235					asic);
    236		spin_lock_irq(&chip->lock);
    237
    238		if (err < 0)
    239			return err;
    240		chip->asic_code = asic;
    241		force_write = 1;
    242	}
    243
    244	/* Compute the new control register value */
    245	clock = 0;
    246	control_reg = le32_to_cpu(chip->comm_page->control_register);
    247	control_reg &= GML_CLOCK_CLEAR_MASK;
    248	control_reg &= GML_SPDIF_RATE_CLEAR_MASK;
    249
    250	switch (rate) {
    251	case 96000:
    252		clock = GML_96KHZ;
    253		break;
    254	case 88200:
    255		clock = GML_88KHZ;
    256		break;
    257	case 48000:
    258		clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1;
    259		break;
    260	case 44100:
    261		clock = GML_44KHZ;
    262		/* Professional mode */
    263		if (control_reg & GML_SPDIF_PRO_MODE)
    264			clock |= GML_SPDIF_SAMPLE_RATE0;
    265		break;
    266	case 32000:
    267		clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 |
    268			GML_SPDIF_SAMPLE_RATE1;
    269		break;
    270	case 22050:
    271		clock = GML_22KHZ;
    272		break;
    273	case 16000:
    274		clock = GML_16KHZ;
    275		break;
    276	case 11025:
    277		clock = GML_11KHZ;
    278		break;
    279	case 8000:
    280		clock = GML_8KHZ;
    281		break;
    282	default:
    283		dev_err(chip->card->dev,
    284			"set_sample_rate: %d invalid!\n", rate);
    285		return -EINVAL;
    286	}
    287
    288	control_reg |= clock;
    289
    290	chip->comm_page->sample_rate = cpu_to_le32(rate);	/* ignored by the DSP */
    291	chip->sample_rate = rate;
    292	dev_dbg(chip->card->dev,
    293		"set_sample_rate: %d clock %d\n", rate, clock);
    294
    295	return write_control_reg(chip, control_reg, force_write);
    296}
    297
    298
    299
    300static int set_input_clock(struct echoaudio *chip, u16 clock)
    301{
    302	u32 control_reg, clocks_from_dsp;
    303	int err;
    304
    305	/* Mask off the clock select bits */
    306	control_reg = le32_to_cpu(chip->comm_page->control_register) &
    307		GML_CLOCK_CLEAR_MASK;
    308	clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
    309
    310	switch (clock) {
    311	case ECHO_CLOCK_INTERNAL:
    312		chip->input_clock = ECHO_CLOCK_INTERNAL;
    313		return set_sample_rate(chip, chip->sample_rate);
    314	case ECHO_CLOCK_SPDIF:
    315		if (chip->digital_mode == DIGITAL_MODE_ADAT)
    316			return -EAGAIN;
    317		spin_unlock_irq(&chip->lock);
    318		err = switch_asic(chip, clocks_from_dsp &
    319				  GML_CLOCK_DETECT_BIT_SPDIF96);
    320		spin_lock_irq(&chip->lock);
    321		if (err < 0)
    322			return err;
    323		control_reg |= GML_SPDIF_CLOCK;
    324		if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96)
    325			control_reg |= GML_DOUBLE_SPEED_MODE;
    326		else
    327			control_reg &= ~GML_DOUBLE_SPEED_MODE;
    328		break;
    329	case ECHO_CLOCK_WORD:
    330		spin_unlock_irq(&chip->lock);
    331		err = switch_asic(chip, clocks_from_dsp &
    332				  GML_CLOCK_DETECT_BIT_WORD96);
    333		spin_lock_irq(&chip->lock);
    334		if (err < 0)
    335			return err;
    336		control_reg |= GML_WORD_CLOCK;
    337		if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96)
    338			control_reg |= GML_DOUBLE_SPEED_MODE;
    339		else
    340			control_reg &= ~GML_DOUBLE_SPEED_MODE;
    341		break;
    342	case ECHO_CLOCK_ADAT:
    343		dev_dbg(chip->card->dev, "Set Mona clock to ADAT\n");
    344		if (chip->digital_mode != DIGITAL_MODE_ADAT)
    345			return -EAGAIN;
    346		control_reg |= GML_ADAT_CLOCK;
    347		control_reg &= ~GML_DOUBLE_SPEED_MODE;
    348		break;
    349	default:
    350		dev_err(chip->card->dev,
    351			"Input clock 0x%x not supported for Mona\n", clock);
    352		return -EINVAL;
    353	}
    354
    355	chip->input_clock = clock;
    356	return write_control_reg(chip, control_reg, true);
    357}
    358
    359
    360
    361static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
    362{
    363	u32 control_reg;
    364	int err, incompatible_clock;
    365
    366	/* Set clock to "internal" if it's not compatible with the new mode */
    367	incompatible_clock = false;
    368	switch (mode) {
    369	case DIGITAL_MODE_SPDIF_OPTICAL:
    370	case DIGITAL_MODE_SPDIF_RCA:
    371		if (chip->input_clock == ECHO_CLOCK_ADAT)
    372			incompatible_clock = true;
    373		break;
    374	case DIGITAL_MODE_ADAT:
    375		if (chip->input_clock == ECHO_CLOCK_SPDIF)
    376			incompatible_clock = true;
    377		break;
    378	default:
    379		dev_err(chip->card->dev,
    380			"Digital mode not supported: %d\n", mode);
    381		return -EINVAL;
    382	}
    383
    384	spin_lock_irq(&chip->lock);
    385
    386	if (incompatible_clock) {	/* Switch to 48KHz, internal */
    387		chip->sample_rate = 48000;
    388		set_input_clock(chip, ECHO_CLOCK_INTERNAL);
    389	}
    390
    391	/* Clear the current digital mode */
    392	control_reg = le32_to_cpu(chip->comm_page->control_register);
    393	control_reg &= GML_DIGITAL_MODE_CLEAR_MASK;
    394
    395	/* Tweak the control reg */
    396	switch (mode) {
    397	case DIGITAL_MODE_SPDIF_OPTICAL:
    398		control_reg |= GML_SPDIF_OPTICAL_MODE;
    399		break;
    400	case DIGITAL_MODE_SPDIF_RCA:
    401		/* GML_SPDIF_OPTICAL_MODE bit cleared */
    402		break;
    403	case DIGITAL_MODE_ADAT:
    404		/* If the current ASIC is the 96KHz ASIC, switch the ASIC
    405		   and set to 48 KHz */
    406		if (chip->asic_code == FW_MONA_361_1_ASIC96 ||
    407		    chip->asic_code == FW_MONA_301_1_ASIC96) {
    408			set_sample_rate(chip, 48000);
    409		}
    410		control_reg |= GML_ADAT_MODE;
    411		control_reg &= ~GML_DOUBLE_SPEED_MODE;
    412		break;
    413	}
    414
    415	err = write_control_reg(chip, control_reg, false);
    416	spin_unlock_irq(&chip->lock);
    417	if (err < 0)
    418		return err;
    419	chip->digital_mode = mode;
    420
    421	dev_dbg(chip->card->dev, "set_digital_mode to %d\n", mode);
    422	return incompatible_clock;
    423}