~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/pci/echoaudio/mona_dsp.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 static int write_control_reg(struct echoaudio *chip, u32 value, char force);
 33 static int set_input_clock(struct echoaudio *chip, u16 clock);
 34 static int set_professional_spdif(struct echoaudio *chip, char prof);
 35 static int set_digital_mode(struct echoaudio *chip, u8 mode);
 36 static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
 37 static int check_asic_status(struct echoaudio *chip);
 38 
 39 
 40 static 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 
 81 static 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 
 91 static 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; 
116 both need to be loaded. */
117 static 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
162 loaded.  This function checks the ASIC needed for the new mode and sees
163 if it matches the one already loaded. */
164 static 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 
198 static 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 
300 static 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 
361 static 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 }
424 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php