1dd7b254dSGiuliano Pochini /**************************************************************************** 2dd7b254dSGiuliano Pochini 3dd7b254dSGiuliano Pochini Copyright Echo Digital Audio Corporation (c) 1998 - 2004 4dd7b254dSGiuliano Pochini All rights reserved 5dd7b254dSGiuliano Pochini www.echoaudio.com 6dd7b254dSGiuliano Pochini 7dd7b254dSGiuliano Pochini This file is part of Echo Digital Audio's generic driver library. 8dd7b254dSGiuliano Pochini 9dd7b254dSGiuliano Pochini Echo Digital Audio's generic driver library is free software; 10dd7b254dSGiuliano Pochini you can redistribute it and/or modify it under the terms of 11dd7b254dSGiuliano Pochini the GNU General Public License as published by the Free Software 12dd7b254dSGiuliano Pochini Foundation. 13dd7b254dSGiuliano Pochini 14dd7b254dSGiuliano Pochini This program is distributed in the hope that it will be useful, 15dd7b254dSGiuliano Pochini but WITHOUT ANY WARRANTY; without even the implied warranty of 16dd7b254dSGiuliano Pochini MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17dd7b254dSGiuliano Pochini GNU General Public License for more details. 18dd7b254dSGiuliano Pochini 19dd7b254dSGiuliano Pochini You should have received a copy of the GNU General Public License 20dd7b254dSGiuliano Pochini along with this program; if not, write to the Free Software 21dd7b254dSGiuliano Pochini Foundation, Inc., 59 Temple Place - Suite 330, Boston, 22dd7b254dSGiuliano Pochini MA 02111-1307, USA. 23dd7b254dSGiuliano Pochini 24dd7b254dSGiuliano Pochini ************************************************************************* 25dd7b254dSGiuliano Pochini 26dd7b254dSGiuliano Pochini Translation from C++ and adaptation for use in ALSA-Driver 27dd7b254dSGiuliano Pochini were made by Giuliano Pochini <pochini@shiny.it> 28dd7b254dSGiuliano Pochini 29dd7b254dSGiuliano Pochini ****************************************************************************/ 30dd7b254dSGiuliano Pochini 31dd7b254dSGiuliano Pochini 32dd7b254dSGiuliano Pochini static int write_control_reg(struct echoaudio *chip, u32 value, char force); 33dd7b254dSGiuliano Pochini static int set_input_clock(struct echoaudio *chip, u16 clock); 34dd7b254dSGiuliano Pochini static int set_professional_spdif(struct echoaudio *chip, char prof); 35dd7b254dSGiuliano Pochini static int set_digital_mode(struct echoaudio *chip, u8 mode); 3619b50063SGiuliano Pochini static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic); 37dd7b254dSGiuliano Pochini static int check_asic_status(struct echoaudio *chip); 38dd7b254dSGiuliano Pochini 39dd7b254dSGiuliano Pochini 40dd7b254dSGiuliano Pochini static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) 41dd7b254dSGiuliano Pochini { 42dd7b254dSGiuliano Pochini int err; 43dd7b254dSGiuliano Pochini 44da3cec35STakashi Iwai if (snd_BUG_ON((subdevice_id & 0xfff0) != MONA)) 45da3cec35STakashi Iwai return -ENODEV; 46dd7b254dSGiuliano Pochini 47*549717fcSTakashi Iwai err = init_dsp_comm_page(chip); 48*549717fcSTakashi Iwai if (err) { 49b5b4a41bSSudip Mukherjee dev_err(chip->card->dev, 50b5b4a41bSSudip Mukherjee "init_hw - could not initialize DSP comm page\n"); 51dd7b254dSGiuliano Pochini return err; 52dd7b254dSGiuliano Pochini } 53dd7b254dSGiuliano Pochini 54dd7b254dSGiuliano Pochini chip->device_id = device_id; 55dd7b254dSGiuliano Pochini chip->subdevice_id = subdevice_id; 563f6175ecSMark Brown chip->bad_board = true; 57dd7b254dSGiuliano Pochini chip->input_clock_types = 58dd7b254dSGiuliano Pochini ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | 59dd7b254dSGiuliano Pochini ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT; 60dd7b254dSGiuliano Pochini chip->digital_modes = 61dd7b254dSGiuliano Pochini ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | 62dd7b254dSGiuliano Pochini ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | 63dd7b254dSGiuliano Pochini ECHOCAPS_HAS_DIGITAL_MODE_ADAT; 64dd7b254dSGiuliano Pochini 65dd7b254dSGiuliano Pochini /* Mona comes in both '301 and '361 flavors */ 66dd7b254dSGiuliano Pochini if (chip->device_id == DEVICE_ID_56361) 6719b50063SGiuliano Pochini chip->dsp_code_to_load = FW_MONA_361_DSP; 68dd7b254dSGiuliano Pochini else 6919b50063SGiuliano Pochini chip->dsp_code_to_load = FW_MONA_301_DSP; 70dd7b254dSGiuliano Pochini 71*549717fcSTakashi Iwai err = load_firmware(chip); 72*549717fcSTakashi Iwai if (err < 0) 73dd7b254dSGiuliano Pochini return err; 743f6175ecSMark Brown chip->bad_board = false; 75dd7b254dSGiuliano Pochini 76dd7b254dSGiuliano Pochini return err; 77dd7b254dSGiuliano Pochini } 78dd7b254dSGiuliano Pochini 79dd7b254dSGiuliano Pochini 80dd7b254dSGiuliano Pochini 81ad3499f4SGiuliano Pochini static int set_mixer_defaults(struct echoaudio *chip) 82ad3499f4SGiuliano Pochini { 83ad3499f4SGiuliano Pochini chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; 843f6175ecSMark Brown chip->professional_spdif = false; 853f6175ecSMark Brown chip->digital_in_automute = true; 86ad3499f4SGiuliano Pochini return init_line_levels(chip); 87ad3499f4SGiuliano Pochini } 88ad3499f4SGiuliano Pochini 89ad3499f4SGiuliano Pochini 90ad3499f4SGiuliano Pochini 91dd7b254dSGiuliano Pochini static u32 detect_input_clocks(const struct echoaudio *chip) 92dd7b254dSGiuliano Pochini { 93dd7b254dSGiuliano Pochini u32 clocks_from_dsp, clock_bits; 94dd7b254dSGiuliano Pochini 95dd7b254dSGiuliano Pochini /* Map the DSP clock detect bits to the generic driver clock 96dd7b254dSGiuliano Pochini detect bits */ 97dd7b254dSGiuliano Pochini clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); 98dd7b254dSGiuliano Pochini 99dd7b254dSGiuliano Pochini clock_bits = ECHO_CLOCK_BIT_INTERNAL; 100dd7b254dSGiuliano Pochini 101dd7b254dSGiuliano Pochini if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF) 102dd7b254dSGiuliano Pochini clock_bits |= ECHO_CLOCK_BIT_SPDIF; 103dd7b254dSGiuliano Pochini 104dd7b254dSGiuliano Pochini if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT) 105dd7b254dSGiuliano Pochini clock_bits |= ECHO_CLOCK_BIT_ADAT; 106dd7b254dSGiuliano Pochini 107dd7b254dSGiuliano Pochini if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD) 108dd7b254dSGiuliano Pochini clock_bits |= ECHO_CLOCK_BIT_WORD; 109dd7b254dSGiuliano Pochini 110dd7b254dSGiuliano Pochini return clock_bits; 111dd7b254dSGiuliano Pochini } 112dd7b254dSGiuliano Pochini 113dd7b254dSGiuliano Pochini 114dd7b254dSGiuliano Pochini 115dd7b254dSGiuliano Pochini /* Mona has an ASIC on the PCI card and another ASIC in the external box; 116dd7b254dSGiuliano Pochini both need to be loaded. */ 117dd7b254dSGiuliano Pochini static int load_asic(struct echoaudio *chip) 118dd7b254dSGiuliano Pochini { 119dd7b254dSGiuliano Pochini u32 control_reg; 120dd7b254dSGiuliano Pochini int err; 12119b50063SGiuliano Pochini short asic; 122dd7b254dSGiuliano Pochini 123dd7b254dSGiuliano Pochini if (chip->asic_loaded) 124dd7b254dSGiuliano Pochini return 0; 125dd7b254dSGiuliano Pochini 126dd7b254dSGiuliano Pochini mdelay(10); 127dd7b254dSGiuliano Pochini 128dd7b254dSGiuliano Pochini if (chip->device_id == DEVICE_ID_56361) 12919b50063SGiuliano Pochini asic = FW_MONA_361_1_ASIC48; 130dd7b254dSGiuliano Pochini else 13119b50063SGiuliano Pochini asic = FW_MONA_301_1_ASIC48; 132dd7b254dSGiuliano Pochini 133dd7b254dSGiuliano Pochini err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, asic); 134dd7b254dSGiuliano Pochini if (err < 0) 135dd7b254dSGiuliano Pochini return err; 136dd7b254dSGiuliano Pochini 137dd7b254dSGiuliano Pochini chip->asic_code = asic; 138dd7b254dSGiuliano Pochini mdelay(10); 139dd7b254dSGiuliano Pochini 140dd7b254dSGiuliano Pochini /* Do the external one */ 141dd7b254dSGiuliano Pochini err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_EXTERNAL_ASIC, 14219b50063SGiuliano Pochini FW_MONA_2_ASIC); 143dd7b254dSGiuliano Pochini if (err < 0) 144dd7b254dSGiuliano Pochini return err; 145dd7b254dSGiuliano Pochini 146dd7b254dSGiuliano Pochini mdelay(10); 147dd7b254dSGiuliano Pochini err = check_asic_status(chip); 148dd7b254dSGiuliano Pochini 149dd7b254dSGiuliano Pochini /* Set up the control register if the load succeeded - 150dd7b254dSGiuliano Pochini 48 kHz, internal clock, S/PDIF RCA mode */ 151dd7b254dSGiuliano Pochini if (!err) { 152dd7b254dSGiuliano Pochini control_reg = GML_CONVERTER_ENABLE | GML_48KHZ; 1533f6175ecSMark Brown err = write_control_reg(chip, control_reg, true); 154dd7b254dSGiuliano Pochini } 155dd7b254dSGiuliano Pochini 156dd7b254dSGiuliano Pochini return err; 157dd7b254dSGiuliano Pochini } 158dd7b254dSGiuliano Pochini 159dd7b254dSGiuliano Pochini 160dd7b254dSGiuliano Pochini 161dd7b254dSGiuliano Pochini /* Depending on what digital mode you want, Mona needs different ASICs 162dd7b254dSGiuliano Pochini loaded. This function checks the ASIC needed for the new mode and sees 163dd7b254dSGiuliano Pochini if it matches the one already loaded. */ 164dd7b254dSGiuliano Pochini static int switch_asic(struct echoaudio *chip, char double_speed) 165dd7b254dSGiuliano Pochini { 166dd7b254dSGiuliano Pochini int err; 16719b50063SGiuliano Pochini short asic; 168dd7b254dSGiuliano Pochini 169dd7b254dSGiuliano Pochini /* Check the clock detect bits to see if this is 170dd7b254dSGiuliano Pochini a single-speed clock or a double-speed clock; load 171dd7b254dSGiuliano Pochini a new ASIC if necessary. */ 172dd7b254dSGiuliano Pochini if (chip->device_id == DEVICE_ID_56361) { 173dd7b254dSGiuliano Pochini if (double_speed) 17419b50063SGiuliano Pochini asic = FW_MONA_361_1_ASIC96; 175dd7b254dSGiuliano Pochini else 17619b50063SGiuliano Pochini asic = FW_MONA_361_1_ASIC48; 177dd7b254dSGiuliano Pochini } else { 178dd7b254dSGiuliano Pochini if (double_speed) 17919b50063SGiuliano Pochini asic = FW_MONA_301_1_ASIC96; 180dd7b254dSGiuliano Pochini else 18119b50063SGiuliano Pochini asic = FW_MONA_301_1_ASIC48; 182dd7b254dSGiuliano Pochini } 183dd7b254dSGiuliano Pochini 184dd7b254dSGiuliano Pochini if (asic != chip->asic_code) { 185dd7b254dSGiuliano Pochini /* Load the desired ASIC */ 186dd7b254dSGiuliano Pochini err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, 187dd7b254dSGiuliano Pochini asic); 188dd7b254dSGiuliano Pochini if (err < 0) 189dd7b254dSGiuliano Pochini return err; 190dd7b254dSGiuliano Pochini chip->asic_code = asic; 191dd7b254dSGiuliano Pochini } 192dd7b254dSGiuliano Pochini 193dd7b254dSGiuliano Pochini return 0; 194dd7b254dSGiuliano Pochini } 195dd7b254dSGiuliano Pochini 196dd7b254dSGiuliano Pochini 197dd7b254dSGiuliano Pochini 198dd7b254dSGiuliano Pochini static int set_sample_rate(struct echoaudio *chip, u32 rate) 199dd7b254dSGiuliano Pochini { 200dd7b254dSGiuliano Pochini u32 control_reg, clock; 20119b50063SGiuliano Pochini short asic; 202dd7b254dSGiuliano Pochini char force_write; 203dd7b254dSGiuliano Pochini 204dd7b254dSGiuliano Pochini /* Only set the clock for internal mode. */ 205dd7b254dSGiuliano Pochini if (chip->input_clock != ECHO_CLOCK_INTERNAL) { 206b5b4a41bSSudip Mukherjee dev_dbg(chip->card->dev, 207b5b4a41bSSudip Mukherjee "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n"); 208dd7b254dSGiuliano Pochini /* Save the rate anyhow */ 209dd7b254dSGiuliano Pochini chip->comm_page->sample_rate = cpu_to_le32(rate); 210dd7b254dSGiuliano Pochini chip->sample_rate = rate; 211dd7b254dSGiuliano Pochini return 0; 212dd7b254dSGiuliano Pochini } 213dd7b254dSGiuliano Pochini 214dd7b254dSGiuliano Pochini /* Now, check to see if the required ASIC is loaded */ 215dd7b254dSGiuliano Pochini if (rate >= 88200) { 216dd7b254dSGiuliano Pochini if (chip->digital_mode == DIGITAL_MODE_ADAT) 217dd7b254dSGiuliano Pochini return -EINVAL; 218dd7b254dSGiuliano Pochini if (chip->device_id == DEVICE_ID_56361) 21919b50063SGiuliano Pochini asic = FW_MONA_361_1_ASIC96; 220dd7b254dSGiuliano Pochini else 22119b50063SGiuliano Pochini asic = FW_MONA_301_1_ASIC96; 222dd7b254dSGiuliano Pochini } else { 223dd7b254dSGiuliano Pochini if (chip->device_id == DEVICE_ID_56361) 22419b50063SGiuliano Pochini asic = FW_MONA_361_1_ASIC48; 225dd7b254dSGiuliano Pochini else 22619b50063SGiuliano Pochini asic = FW_MONA_301_1_ASIC48; 227dd7b254dSGiuliano Pochini } 228dd7b254dSGiuliano Pochini 229dd7b254dSGiuliano Pochini force_write = 0; 230dd7b254dSGiuliano Pochini if (asic != chip->asic_code) { 231dd7b254dSGiuliano Pochini int err; 232dd7b254dSGiuliano Pochini /* Load the desired ASIC (load_asic_generic() can sleep) */ 233dd7b254dSGiuliano Pochini spin_unlock_irq(&chip->lock); 234dd7b254dSGiuliano Pochini err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, 235dd7b254dSGiuliano Pochini asic); 236dd7b254dSGiuliano Pochini spin_lock_irq(&chip->lock); 237dd7b254dSGiuliano Pochini 238dd7b254dSGiuliano Pochini if (err < 0) 239dd7b254dSGiuliano Pochini return err; 240dd7b254dSGiuliano Pochini chip->asic_code = asic; 241dd7b254dSGiuliano Pochini force_write = 1; 242dd7b254dSGiuliano Pochini } 243dd7b254dSGiuliano Pochini 244dd7b254dSGiuliano Pochini /* Compute the new control register value */ 245dd7b254dSGiuliano Pochini clock = 0; 246dd7b254dSGiuliano Pochini control_reg = le32_to_cpu(chip->comm_page->control_register); 247dd7b254dSGiuliano Pochini control_reg &= GML_CLOCK_CLEAR_MASK; 248dd7b254dSGiuliano Pochini control_reg &= GML_SPDIF_RATE_CLEAR_MASK; 249dd7b254dSGiuliano Pochini 250dd7b254dSGiuliano Pochini switch (rate) { 251dd7b254dSGiuliano Pochini case 96000: 252dd7b254dSGiuliano Pochini clock = GML_96KHZ; 253dd7b254dSGiuliano Pochini break; 254dd7b254dSGiuliano Pochini case 88200: 255dd7b254dSGiuliano Pochini clock = GML_88KHZ; 256dd7b254dSGiuliano Pochini break; 257dd7b254dSGiuliano Pochini case 48000: 258dd7b254dSGiuliano Pochini clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1; 259dd7b254dSGiuliano Pochini break; 260dd7b254dSGiuliano Pochini case 44100: 261dd7b254dSGiuliano Pochini clock = GML_44KHZ; 262dd7b254dSGiuliano Pochini /* Professional mode */ 263dd7b254dSGiuliano Pochini if (control_reg & GML_SPDIF_PRO_MODE) 264dd7b254dSGiuliano Pochini clock |= GML_SPDIF_SAMPLE_RATE0; 265dd7b254dSGiuliano Pochini break; 266dd7b254dSGiuliano Pochini case 32000: 267dd7b254dSGiuliano Pochini clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 | 268dd7b254dSGiuliano Pochini GML_SPDIF_SAMPLE_RATE1; 269dd7b254dSGiuliano Pochini break; 270dd7b254dSGiuliano Pochini case 22050: 271dd7b254dSGiuliano Pochini clock = GML_22KHZ; 272dd7b254dSGiuliano Pochini break; 273dd7b254dSGiuliano Pochini case 16000: 274dd7b254dSGiuliano Pochini clock = GML_16KHZ; 275dd7b254dSGiuliano Pochini break; 276dd7b254dSGiuliano Pochini case 11025: 277dd7b254dSGiuliano Pochini clock = GML_11KHZ; 278dd7b254dSGiuliano Pochini break; 279dd7b254dSGiuliano Pochini case 8000: 280dd7b254dSGiuliano Pochini clock = GML_8KHZ; 281dd7b254dSGiuliano Pochini break; 282dd7b254dSGiuliano Pochini default: 283b5b4a41bSSudip Mukherjee dev_err(chip->card->dev, 284b5b4a41bSSudip Mukherjee "set_sample_rate: %d invalid!\n", rate); 285dd7b254dSGiuliano Pochini return -EINVAL; 286dd7b254dSGiuliano Pochini } 287dd7b254dSGiuliano Pochini 288dd7b254dSGiuliano Pochini control_reg |= clock; 289dd7b254dSGiuliano Pochini 290dd7b254dSGiuliano Pochini chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ 291dd7b254dSGiuliano Pochini chip->sample_rate = rate; 292b5b4a41bSSudip Mukherjee dev_dbg(chip->card->dev, 293b5b4a41bSSudip Mukherjee "set_sample_rate: %d clock %d\n", rate, clock); 294dd7b254dSGiuliano Pochini 295dd7b254dSGiuliano Pochini return write_control_reg(chip, control_reg, force_write); 296dd7b254dSGiuliano Pochini } 297dd7b254dSGiuliano Pochini 298dd7b254dSGiuliano Pochini 299dd7b254dSGiuliano Pochini 300dd7b254dSGiuliano Pochini static int set_input_clock(struct echoaudio *chip, u16 clock) 301dd7b254dSGiuliano Pochini { 302dd7b254dSGiuliano Pochini u32 control_reg, clocks_from_dsp; 303dd7b254dSGiuliano Pochini int err; 304dd7b254dSGiuliano Pochini 305dd7b254dSGiuliano Pochini /* Mask off the clock select bits */ 306dd7b254dSGiuliano Pochini control_reg = le32_to_cpu(chip->comm_page->control_register) & 307dd7b254dSGiuliano Pochini GML_CLOCK_CLEAR_MASK; 308dd7b254dSGiuliano Pochini clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); 309dd7b254dSGiuliano Pochini 310dd7b254dSGiuliano Pochini switch (clock) { 311dd7b254dSGiuliano Pochini case ECHO_CLOCK_INTERNAL: 312dd7b254dSGiuliano Pochini chip->input_clock = ECHO_CLOCK_INTERNAL; 313dd7b254dSGiuliano Pochini return set_sample_rate(chip, chip->sample_rate); 314dd7b254dSGiuliano Pochini case ECHO_CLOCK_SPDIF: 315dd7b254dSGiuliano Pochini if (chip->digital_mode == DIGITAL_MODE_ADAT) 316dd7b254dSGiuliano Pochini return -EAGAIN; 317dd7b254dSGiuliano Pochini spin_unlock_irq(&chip->lock); 318dd7b254dSGiuliano Pochini err = switch_asic(chip, clocks_from_dsp & 319dd7b254dSGiuliano Pochini GML_CLOCK_DETECT_BIT_SPDIF96); 320dd7b254dSGiuliano Pochini spin_lock_irq(&chip->lock); 321dd7b254dSGiuliano Pochini if (err < 0) 322dd7b254dSGiuliano Pochini return err; 323dd7b254dSGiuliano Pochini control_reg |= GML_SPDIF_CLOCK; 324dd7b254dSGiuliano Pochini if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96) 325dd7b254dSGiuliano Pochini control_reg |= GML_DOUBLE_SPEED_MODE; 326dd7b254dSGiuliano Pochini else 327dd7b254dSGiuliano Pochini control_reg &= ~GML_DOUBLE_SPEED_MODE; 328dd7b254dSGiuliano Pochini break; 329dd7b254dSGiuliano Pochini case ECHO_CLOCK_WORD: 330dd7b254dSGiuliano Pochini spin_unlock_irq(&chip->lock); 331dd7b254dSGiuliano Pochini err = switch_asic(chip, clocks_from_dsp & 332dd7b254dSGiuliano Pochini GML_CLOCK_DETECT_BIT_WORD96); 333dd7b254dSGiuliano Pochini spin_lock_irq(&chip->lock); 334dd7b254dSGiuliano Pochini if (err < 0) 335dd7b254dSGiuliano Pochini return err; 336dd7b254dSGiuliano Pochini control_reg |= GML_WORD_CLOCK; 337dd7b254dSGiuliano Pochini if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96) 338dd7b254dSGiuliano Pochini control_reg |= GML_DOUBLE_SPEED_MODE; 339dd7b254dSGiuliano Pochini else 340dd7b254dSGiuliano Pochini control_reg &= ~GML_DOUBLE_SPEED_MODE; 341dd7b254dSGiuliano Pochini break; 342dd7b254dSGiuliano Pochini case ECHO_CLOCK_ADAT: 343b5b4a41bSSudip Mukherjee dev_dbg(chip->card->dev, "Set Mona clock to ADAT\n"); 344dd7b254dSGiuliano Pochini if (chip->digital_mode != DIGITAL_MODE_ADAT) 345dd7b254dSGiuliano Pochini return -EAGAIN; 346dd7b254dSGiuliano Pochini control_reg |= GML_ADAT_CLOCK; 347dd7b254dSGiuliano Pochini control_reg &= ~GML_DOUBLE_SPEED_MODE; 348dd7b254dSGiuliano Pochini break; 349dd7b254dSGiuliano Pochini default: 350b5b4a41bSSudip Mukherjee dev_err(chip->card->dev, 351b5b4a41bSSudip Mukherjee "Input clock 0x%x not supported for Mona\n", clock); 352dd7b254dSGiuliano Pochini return -EINVAL; 353dd7b254dSGiuliano Pochini } 354dd7b254dSGiuliano Pochini 355dd7b254dSGiuliano Pochini chip->input_clock = clock; 3563f6175ecSMark Brown return write_control_reg(chip, control_reg, true); 357dd7b254dSGiuliano Pochini } 358dd7b254dSGiuliano Pochini 359dd7b254dSGiuliano Pochini 360dd7b254dSGiuliano Pochini 361dd7b254dSGiuliano Pochini static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) 362dd7b254dSGiuliano Pochini { 363dd7b254dSGiuliano Pochini u32 control_reg; 364dd7b254dSGiuliano Pochini int err, incompatible_clock; 365dd7b254dSGiuliano Pochini 366dd7b254dSGiuliano Pochini /* Set clock to "internal" if it's not compatible with the new mode */ 3673f6175ecSMark Brown incompatible_clock = false; 368dd7b254dSGiuliano Pochini switch (mode) { 369dd7b254dSGiuliano Pochini case DIGITAL_MODE_SPDIF_OPTICAL: 370dd7b254dSGiuliano Pochini case DIGITAL_MODE_SPDIF_RCA: 371dd7b254dSGiuliano Pochini if (chip->input_clock == ECHO_CLOCK_ADAT) 3723f6175ecSMark Brown incompatible_clock = true; 373dd7b254dSGiuliano Pochini break; 374dd7b254dSGiuliano Pochini case DIGITAL_MODE_ADAT: 375dd7b254dSGiuliano Pochini if (chip->input_clock == ECHO_CLOCK_SPDIF) 3763f6175ecSMark Brown incompatible_clock = true; 377dd7b254dSGiuliano Pochini break; 378dd7b254dSGiuliano Pochini default: 379b5b4a41bSSudip Mukherjee dev_err(chip->card->dev, 380b5b4a41bSSudip Mukherjee "Digital mode not supported: %d\n", mode); 381dd7b254dSGiuliano Pochini return -EINVAL; 382dd7b254dSGiuliano Pochini } 383dd7b254dSGiuliano Pochini 384dd7b254dSGiuliano Pochini spin_lock_irq(&chip->lock); 385dd7b254dSGiuliano Pochini 386dd7b254dSGiuliano Pochini if (incompatible_clock) { /* Switch to 48KHz, internal */ 387dd7b254dSGiuliano Pochini chip->sample_rate = 48000; 388dd7b254dSGiuliano Pochini set_input_clock(chip, ECHO_CLOCK_INTERNAL); 389dd7b254dSGiuliano Pochini } 390dd7b254dSGiuliano Pochini 391dd7b254dSGiuliano Pochini /* Clear the current digital mode */ 392dd7b254dSGiuliano Pochini control_reg = le32_to_cpu(chip->comm_page->control_register); 393dd7b254dSGiuliano Pochini control_reg &= GML_DIGITAL_MODE_CLEAR_MASK; 394dd7b254dSGiuliano Pochini 395dd7b254dSGiuliano Pochini /* Tweak the control reg */ 396dd7b254dSGiuliano Pochini switch (mode) { 397dd7b254dSGiuliano Pochini case DIGITAL_MODE_SPDIF_OPTICAL: 398dd7b254dSGiuliano Pochini control_reg |= GML_SPDIF_OPTICAL_MODE; 399dd7b254dSGiuliano Pochini break; 400dd7b254dSGiuliano Pochini case DIGITAL_MODE_SPDIF_RCA: 401dd7b254dSGiuliano Pochini /* GML_SPDIF_OPTICAL_MODE bit cleared */ 402dd7b254dSGiuliano Pochini break; 403dd7b254dSGiuliano Pochini case DIGITAL_MODE_ADAT: 404dd7b254dSGiuliano Pochini /* If the current ASIC is the 96KHz ASIC, switch the ASIC 405dd7b254dSGiuliano Pochini and set to 48 KHz */ 40619b50063SGiuliano Pochini if (chip->asic_code == FW_MONA_361_1_ASIC96 || 40719b50063SGiuliano Pochini chip->asic_code == FW_MONA_301_1_ASIC96) { 408dd7b254dSGiuliano Pochini set_sample_rate(chip, 48000); 409dd7b254dSGiuliano Pochini } 410dd7b254dSGiuliano Pochini control_reg |= GML_ADAT_MODE; 411dd7b254dSGiuliano Pochini control_reg &= ~GML_DOUBLE_SPEED_MODE; 412dd7b254dSGiuliano Pochini break; 413dd7b254dSGiuliano Pochini } 414dd7b254dSGiuliano Pochini 4153f6175ecSMark Brown err = write_control_reg(chip, control_reg, false); 416dd7b254dSGiuliano Pochini spin_unlock_irq(&chip->lock); 417dd7b254dSGiuliano Pochini if (err < 0) 418dd7b254dSGiuliano Pochini return err; 419dd7b254dSGiuliano Pochini chip->digital_mode = mode; 420dd7b254dSGiuliano Pochini 421b5b4a41bSSudip Mukherjee dev_dbg(chip->card->dev, "set_digital_mode to %d\n", mode); 422dd7b254dSGiuliano Pochini return incompatible_clock; 423dd7b254dSGiuliano Pochini } 424