diff options
Diffstat (limited to 'sound/pci')
42 files changed, 10986 insertions, 117 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index d37346b12dc0..23e54cedfd4a 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig | |||
@@ -233,6 +233,143 @@ config SND_CS5535AUDIO | |||
233 | To compile this driver as a module, choose M here: the module | 233 | To compile this driver as a module, choose M here: the module |
234 | will be called snd-cs5535audio. | 234 | will be called snd-cs5535audio. |
235 | 235 | ||
236 | config SND_DARLA20 | ||
237 | tristate "(Echoaudio) Darla20" | ||
238 | depends on SND | ||
239 | depends on FW_LOADER | ||
240 | select SND_PCM | ||
241 | help | ||
242 | Say 'Y' or 'M' to include support for Echoaudio Darla. | ||
243 | |||
244 | To compile this driver as a module, choose M here: the module | ||
245 | will be called snd-darla20 | ||
246 | |||
247 | config SND_GINA20 | ||
248 | tristate "(Echoaudio) Gina20" | ||
249 | depends on SND | ||
250 | depends on FW_LOADER | ||
251 | select SND_PCM | ||
252 | help | ||
253 | Say 'Y' or 'M' to include support for Echoaudio Gina. | ||
254 | |||
255 | To compile this driver as a module, choose M here: the module | ||
256 | will be called snd-gina20 | ||
257 | |||
258 | config SND_LAYLA20 | ||
259 | tristate "(Echoaudio) Layla20" | ||
260 | depends on SND | ||
261 | depends on FW_LOADER | ||
262 | select SND_RAWMIDI | ||
263 | select SND_PCM | ||
264 | help | ||
265 | Say 'Y' or 'M' to include support for Echoaudio Layla. | ||
266 | |||
267 | To compile this driver as a module, choose M here: the module | ||
268 | will be called snd-layla20 | ||
269 | |||
270 | config SND_DARLA24 | ||
271 | tristate "(Echoaudio) Darla24" | ||
272 | depends on SND | ||
273 | depends on FW_LOADER | ||
274 | select SND_PCM | ||
275 | help | ||
276 | Say 'Y' or 'M' to include support for Echoaudio Darla24. | ||
277 | |||
278 | To compile this driver as a module, choose M here: the module | ||
279 | will be called snd-darla24 | ||
280 | |||
281 | config SND_GINA24 | ||
282 | tristate "(Echoaudio) Gina24" | ||
283 | depends on SND | ||
284 | depends on FW_LOADER | ||
285 | select SND_PCM | ||
286 | help | ||
287 | Say 'Y' or 'M' to include support for Echoaudio Gina24. | ||
288 | |||
289 | To compile this driver as a module, choose M here: the module | ||
290 | will be called snd-gina24 | ||
291 | |||
292 | config SND_LAYLA24 | ||
293 | tristate "(Echoaudio) Layla24" | ||
294 | depends on SND | ||
295 | depends on FW_LOADER | ||
296 | select SND_RAWMIDI | ||
297 | select SND_PCM | ||
298 | help | ||
299 | Say 'Y' or 'M' to include support for Echoaudio Layla24. | ||
300 | |||
301 | To compile this driver as a module, choose M here: the module | ||
302 | will be called snd-layla24 | ||
303 | |||
304 | config SND_MONA | ||
305 | tristate "(Echoaudio) Mona" | ||
306 | depends on SND | ||
307 | depends on FW_LOADER | ||
308 | select SND_RAWMIDI | ||
309 | select SND_PCM | ||
310 | help | ||
311 | Say 'Y' or 'M' to include support for Echoaudio Mona. | ||
312 | |||
313 | To compile this driver as a module, choose M here: the module | ||
314 | will be called snd-mona | ||
315 | |||
316 | config SND_MIA | ||
317 | tristate "(Echoaudio) Mia" | ||
318 | depends on SND | ||
319 | depends on FW_LOADER | ||
320 | select SND_RAWMIDI | ||
321 | select SND_PCM | ||
322 | help | ||
323 | Say 'Y' or 'M' to include support for Echoaudio Mia and Mia-midi. | ||
324 | |||
325 | To compile this driver as a module, choose M here: the module | ||
326 | will be called snd-mia | ||
327 | |||
328 | config SND_ECHO3G | ||
329 | tristate "(Echoaudio) 3G cards" | ||
330 | depends on SND | ||
331 | depends on FW_LOADER | ||
332 | select SND_RAWMIDI | ||
333 | select SND_PCM | ||
334 | help | ||
335 | Say 'Y' or 'M' to include support for Echoaudio Gina3G and Layla3G. | ||
336 | |||
337 | To compile this driver as a module, choose M here: the module | ||
338 | will be called snd-echo3g | ||
339 | |||
340 | config SND_INDIGO | ||
341 | tristate "(Echoaudio) Indigo" | ||
342 | depends on SND | ||
343 | depends on FW_LOADER | ||
344 | select SND_PCM | ||
345 | help | ||
346 | Say 'Y' or 'M' to include support for Echoaudio Indigo. | ||
347 | |||
348 | To compile this driver as a module, choose M here: the module | ||
349 | will be called snd-indigo | ||
350 | |||
351 | config SND_INDIGOIO | ||
352 | tristate "(Echoaudio) Indigo IO" | ||
353 | depends on SND | ||
354 | depends on FW_LOADER | ||
355 | select SND_PCM | ||
356 | help | ||
357 | Say 'Y' or 'M' to include support for Echoaudio Indigo IO. | ||
358 | |||
359 | To compile this driver as a module, choose M here: the module | ||
360 | will be called snd-indigoio | ||
361 | |||
362 | config SND_INDIGODJ | ||
363 | tristate "(Echoaudio) Indigo DJ" | ||
364 | depends on SND | ||
365 | depends on FW_LOADER | ||
366 | select SND_PCM | ||
367 | help | ||
368 | Say 'Y' or 'M' to include support for Echoaudio Indigo DJ. | ||
369 | |||
370 | To compile this driver as a module, choose M here: the module | ||
371 | will be called snd-indigodj | ||
372 | |||
236 | config SND_EMU10K1 | 373 | config SND_EMU10K1 |
237 | tristate "Emu10k1 (SB Live!, Audigy, E-mu APS)" | 374 | tristate "Emu10k1 (SB Live!, Audigy, E-mu APS)" |
238 | depends on SND | 375 | depends on SND |
@@ -420,8 +557,8 @@ config SND_INTEL8X0 | |||
420 | will be called snd-intel8x0. | 557 | will be called snd-intel8x0. |
421 | 558 | ||
422 | config SND_INTEL8X0M | 559 | config SND_INTEL8X0M |
423 | tristate "Intel/SiS/nVidia/AMD MC97 Modem (EXPERIMENTAL)" | 560 | tristate "Intel/SiS/nVidia/AMD MC97 Modem" |
424 | depends on SND && EXPERIMENTAL | 561 | depends on SND |
425 | select SND_AC97_CODEC | 562 | select SND_AC97_CODEC |
426 | help | 563 | help |
427 | Say Y here to include support for the integrated MC97 modem on | 564 | Say Y here to include support for the integrated MC97 modem on |
diff --git a/sound/pci/Makefile b/sound/pci/Makefile index cba5105aafea..e06736da9ef1 100644 --- a/sound/pci/Makefile +++ b/sound/pci/Makefile | |||
@@ -57,6 +57,7 @@ obj-$(CONFIG_SND) += \ | |||
57 | ca0106/ \ | 57 | ca0106/ \ |
58 | cs46xx/ \ | 58 | cs46xx/ \ |
59 | cs5535audio/ \ | 59 | cs5535audio/ \ |
60 | echoaudio/ \ | ||
60 | emu10k1/ \ | 61 | emu10k1/ \ |
61 | hda/ \ | 62 | hda/ \ |
62 | ice1712/ \ | 63 | ice1712/ \ |
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 7f197c780816..094cfc1f3a19 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c | |||
@@ -1824,6 +1824,8 @@ static const struct snd_kcontrol_new snd_ac97_ad1888_controls[] = { | |||
1824 | .get = snd_ac97_ad1888_lohpsel_get, | 1824 | .get = snd_ac97_ad1888_lohpsel_get, |
1825 | .put = snd_ac97_ad1888_lohpsel_put | 1825 | .put = snd_ac97_ad1888_lohpsel_put |
1826 | }, | 1826 | }, |
1827 | AC97_SINGLE("V_REFOUT Enable", AC97_AD_MISC, 2, 1, 1), | ||
1828 | AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2, 12, 1, 1), | ||
1827 | AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC, 7, 1, 0), | 1829 | AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC, 7, 1, 0), |
1828 | { | 1830 | { |
1829 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1831 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index c33642d8d9a1..497ed6b20060 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c | |||
@@ -888,8 +888,9 @@ static int __devinit snd_bt87x_probe(struct pci_dev *pci, | |||
888 | 888 | ||
889 | strcpy(card->driver, "Bt87x"); | 889 | strcpy(card->driver, "Bt87x"); |
890 | sprintf(card->shortname, "Brooktree Bt%x", pci->device); | 890 | sprintf(card->shortname, "Brooktree Bt%x", pci->device); |
891 | sprintf(card->longname, "%s at %#lx, irq %i", | 891 | sprintf(card->longname, "%s at %#llx, irq %i", |
892 | card->shortname, pci_resource_start(pci, 0), chip->irq); | 892 | card->shortname, (unsigned long long)pci_resource_start(pci, 0), |
893 | chip->irq); | ||
893 | strcpy(card->mixername, "Bt87x"); | 894 | strcpy(card->mixername, "Bt87x"); |
894 | 895 | ||
895 | err = snd_card_register(card); | 896 | err = snd_card_register(card); |
diff --git a/sound/pci/echoaudio/Makefile b/sound/pci/echoaudio/Makefile new file mode 100644 index 000000000000..7b576aeb3f8d --- /dev/null +++ b/sound/pci/echoaudio/Makefile | |||
@@ -0,0 +1,30 @@ | |||
1 | # | ||
2 | # Makefile for ALSA Echoaudio soundcard drivers | ||
3 | # Copyright (c) 2003 by Giuliano Pochini <pochini@shiny.it> | ||
4 | # | ||
5 | |||
6 | snd-darla20-objs := darla20.o | ||
7 | snd-gina20-objs := gina20.o | ||
8 | snd-layla20-objs := layla20.o | ||
9 | snd-darla24-objs := darla24.o | ||
10 | snd-gina24-objs := gina24.o | ||
11 | snd-layla24-objs := layla24.o | ||
12 | snd-mona-objs := mona.o | ||
13 | snd-mia-objs := mia.o | ||
14 | snd-echo3g-objs := echo3g.o | ||
15 | snd-indigo-objs := indigo.o | ||
16 | snd-indigoio-objs := indigoio.o | ||
17 | snd-indigodj-objs := indigodj.o | ||
18 | |||
19 | obj-$(CONFIG_SND_DARLA20) += snd-darla20.o | ||
20 | obj-$(CONFIG_SND_GINA20) += snd-gina20.o | ||
21 | obj-$(CONFIG_SND_LAYLA20) += snd-layla20.o | ||
22 | obj-$(CONFIG_SND_DARLA24) += snd-darla24.o | ||
23 | obj-$(CONFIG_SND_GINA24) += snd-gina24.o | ||
24 | obj-$(CONFIG_SND_LAYLA24) += snd-layla24.o | ||
25 | obj-$(CONFIG_SND_MONA) += snd-mona.o | ||
26 | obj-$(CONFIG_SND_MIA) += snd-mia.o | ||
27 | obj-$(CONFIG_SND_ECHO3G) += snd-echo3g.o | ||
28 | obj-$(CONFIG_SND_INDIGO) += snd-indigo.o | ||
29 | obj-$(CONFIG_SND_INDIGOIO) += snd-indigoio.o | ||
30 | obj-$(CONFIG_SND_INDIGODJ) += snd-indigodj.o | ||
diff --git a/sound/pci/echoaudio/darla20.c b/sound/pci/echoaudio/darla20.c new file mode 100644 index 000000000000..b7108e29a668 --- /dev/null +++ b/sound/pci/echoaudio/darla20.c | |||
@@ -0,0 +1,99 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define ECHOGALS_FAMILY | ||
20 | #define ECHOCARD_DARLA20 | ||
21 | #define ECHOCARD_NAME "Darla20" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | |||
24 | /* Pipe indexes */ | ||
25 | #define PX_ANALOG_OUT 0 /* 8 */ | ||
26 | #define PX_DIGITAL_OUT 8 /* 0 */ | ||
27 | #define PX_ANALOG_IN 8 /* 2 */ | ||
28 | #define PX_DIGITAL_IN 10 /* 0 */ | ||
29 | #define PX_NUM 10 | ||
30 | |||
31 | /* Bus indexes */ | ||
32 | #define BX_ANALOG_OUT 0 /* 8 */ | ||
33 | #define BX_DIGITAL_OUT 8 /* 0 */ | ||
34 | #define BX_ANALOG_IN 8 /* 2 */ | ||
35 | #define BX_DIGITAL_IN 10 /* 0 */ | ||
36 | #define BX_NUM 10 | ||
37 | |||
38 | |||
39 | #include <sound/driver.h> | ||
40 | #include <linux/delay.h> | ||
41 | #include <linux/init.h> | ||
42 | #include <linux/interrupt.h> | ||
43 | #include <linux/pci.h> | ||
44 | #include <linux/slab.h> | ||
45 | #include <linux/moduleparam.h> | ||
46 | #include <linux/firmware.h> | ||
47 | #include <sound/core.h> | ||
48 | #include <sound/info.h> | ||
49 | #include <sound/control.h> | ||
50 | #include <sound/pcm.h> | ||
51 | #include <sound/pcm_params.h> | ||
52 | #include <sound/asoundef.h> | ||
53 | #include <sound/initval.h> | ||
54 | #include <asm/io.h> | ||
55 | #include <asm/atomic.h> | ||
56 | #include "echoaudio.h" | ||
57 | |||
58 | #define FW_DARLA20_DSP 0 | ||
59 | |||
60 | static const struct firmware card_fw[] = { | ||
61 | {0, "darla20_dsp.fw"} | ||
62 | }; | ||
63 | |||
64 | static struct pci_device_id snd_echo_ids[] = { | ||
65 | {0x1057, 0x1801, 0xECC0, 0x0010, 0, 0, 0}, /* DSP 56301 Darla20 rev.0 */ | ||
66 | {0,} | ||
67 | }; | ||
68 | |||
69 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
70 | .info = SNDRV_PCM_INFO_MMAP | | ||
71 | SNDRV_PCM_INFO_INTERLEAVED | | ||
72 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
73 | SNDRV_PCM_INFO_MMAP_VALID | | ||
74 | SNDRV_PCM_INFO_PAUSE | | ||
75 | SNDRV_PCM_INFO_SYNC_START, | ||
76 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
77 | SNDRV_PCM_FMTBIT_S16_LE | | ||
78 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
79 | SNDRV_PCM_FMTBIT_S32_LE | | ||
80 | SNDRV_PCM_FMTBIT_S32_BE, | ||
81 | .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, | ||
82 | .rate_min = 44100, | ||
83 | .rate_max = 48000, | ||
84 | .channels_min = 1, | ||
85 | .channels_max = 2, | ||
86 | .buffer_bytes_max = 262144, | ||
87 | .period_bytes_min = 32, | ||
88 | .period_bytes_max = 131072, | ||
89 | .periods_min = 2, | ||
90 | .periods_max = 220, | ||
91 | /* One page (4k) contains 512 instructions. I don't know if the hw | ||
92 | supports lists longer than this. In this case periods_max=220 is a | ||
93 | safe limit to make sure the list never exceeds 512 instructions. */ | ||
94 | }; | ||
95 | |||
96 | |||
97 | #include "darla20_dsp.c" | ||
98 | #include "echoaudio_dsp.c" | ||
99 | #include "echoaudio.c" | ||
diff --git a/sound/pci/echoaudio/darla20_dsp.c b/sound/pci/echoaudio/darla20_dsp.c new file mode 100644 index 000000000000..4159e3bc186f --- /dev/null +++ b/sound/pci/echoaudio/darla20_dsp.c | |||
@@ -0,0 +1,125 @@ | |||
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 init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
33 | { | ||
34 | int err; | ||
35 | |||
36 | DE_INIT(("init_hw() - Darla20\n")); | ||
37 | snd_assert((subdevice_id & 0xfff0) == DARLA20, return -ENODEV); | ||
38 | |||
39 | if ((err = init_dsp_comm_page(chip))) { | ||
40 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
41 | return err; | ||
42 | } | ||
43 | |||
44 | chip->device_id = device_id; | ||
45 | chip->subdevice_id = subdevice_id; | ||
46 | chip->bad_board = TRUE; | ||
47 | chip->dsp_code_to_load = &card_fw[FW_DARLA20_DSP]; | ||
48 | chip->spdif_status = GD_SPDIF_STATUS_UNDEF; | ||
49 | chip->clock_state = GD_CLOCK_UNDEF; | ||
50 | /* Since this card has no ASIC, mark it as loaded so everything | ||
51 | works OK */ | ||
52 | chip->asic_loaded = TRUE; | ||
53 | chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL; | ||
54 | |||
55 | if ((err = load_firmware(chip)) < 0) | ||
56 | return err; | ||
57 | chip->bad_board = FALSE; | ||
58 | |||
59 | if ((err = init_line_levels(chip)) < 0) | ||
60 | return err; | ||
61 | |||
62 | DE_INIT(("init_hw done\n")); | ||
63 | return err; | ||
64 | } | ||
65 | |||
66 | |||
67 | |||
68 | /* The Darla20 has no external clock sources */ | ||
69 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
70 | { | ||
71 | return ECHO_CLOCK_BIT_INTERNAL; | ||
72 | } | ||
73 | |||
74 | |||
75 | |||
76 | /* The Darla20 has no ASIC. Just do nothing */ | ||
77 | static int load_asic(struct echoaudio *chip) | ||
78 | { | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | |||
83 | |||
84 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
85 | { | ||
86 | u8 clock_state, spdif_status; | ||
87 | |||
88 | if (wait_handshake(chip)) | ||
89 | return -EIO; | ||
90 | |||
91 | switch (rate) { | ||
92 | case 44100: | ||
93 | clock_state = GD_CLOCK_44; | ||
94 | spdif_status = GD_SPDIF_STATUS_44; | ||
95 | break; | ||
96 | case 48000: | ||
97 | clock_state = GD_CLOCK_48; | ||
98 | spdif_status = GD_SPDIF_STATUS_48; | ||
99 | break; | ||
100 | default: | ||
101 | clock_state = GD_CLOCK_NOCHANGE; | ||
102 | spdif_status = GD_SPDIF_STATUS_NOCHANGE; | ||
103 | break; | ||
104 | } | ||
105 | |||
106 | if (chip->clock_state == clock_state) | ||
107 | clock_state = GD_CLOCK_NOCHANGE; | ||
108 | if (spdif_status == chip->spdif_status) | ||
109 | spdif_status = GD_SPDIF_STATUS_NOCHANGE; | ||
110 | |||
111 | chip->comm_page->sample_rate = cpu_to_le32(rate); | ||
112 | chip->comm_page->gd_clock_state = clock_state; | ||
113 | chip->comm_page->gd_spdif_status = spdif_status; | ||
114 | chip->comm_page->gd_resampler_state = 3; /* magic number - should always be 3 */ | ||
115 | |||
116 | /* Save the new audio state if it changed */ | ||
117 | if (clock_state != GD_CLOCK_NOCHANGE) | ||
118 | chip->clock_state = clock_state; | ||
119 | if (spdif_status != GD_SPDIF_STATUS_NOCHANGE) | ||
120 | chip->spdif_status = spdif_status; | ||
121 | chip->sample_rate = rate; | ||
122 | |||
123 | clear_handshake(chip); | ||
124 | return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); | ||
125 | } | ||
diff --git a/sound/pci/echoaudio/darla24.c b/sound/pci/echoaudio/darla24.c new file mode 100644 index 000000000000..e59a982ee361 --- /dev/null +++ b/sound/pci/echoaudio/darla24.c | |||
@@ -0,0 +1,106 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define ECHOGALS_FAMILY | ||
20 | #define ECHOCARD_DARLA24 | ||
21 | #define ECHOCARD_NAME "Darla24" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | #define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL | ||
24 | #define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL | ||
25 | #define ECHOCARD_HAS_EXTERNAL_CLOCK | ||
26 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
27 | |||
28 | /* Pipe indexes */ | ||
29 | #define PX_ANALOG_OUT 0 /* 8 */ | ||
30 | #define PX_DIGITAL_OUT 8 /* 0 */ | ||
31 | #define PX_ANALOG_IN 8 /* 2 */ | ||
32 | #define PX_DIGITAL_IN 10 /* 0 */ | ||
33 | #define PX_NUM 10 | ||
34 | |||
35 | /* Bus indexes */ | ||
36 | #define BX_ANALOG_OUT 0 /* 8 */ | ||
37 | #define BX_DIGITAL_OUT 8 /* 0 */ | ||
38 | #define BX_ANALOG_IN 8 /* 2 */ | ||
39 | #define BX_DIGITAL_IN 10 /* 0 */ | ||
40 | #define BX_NUM 10 | ||
41 | |||
42 | |||
43 | #include <sound/driver.h> | ||
44 | #include <linux/delay.h> | ||
45 | #include <linux/init.h> | ||
46 | #include <linux/interrupt.h> | ||
47 | #include <linux/pci.h> | ||
48 | #include <linux/slab.h> | ||
49 | #include <linux/moduleparam.h> | ||
50 | #include <linux/firmware.h> | ||
51 | #include <sound/core.h> | ||
52 | #include <sound/info.h> | ||
53 | #include <sound/control.h> | ||
54 | #include <sound/pcm.h> | ||
55 | #include <sound/pcm_params.h> | ||
56 | #include <sound/asoundef.h> | ||
57 | #include <sound/initval.h> | ||
58 | #include <asm/io.h> | ||
59 | #include <asm/atomic.h> | ||
60 | #include "echoaudio.h" | ||
61 | |||
62 | #define FW_DARLA24_DSP 0 | ||
63 | |||
64 | static const struct firmware card_fw[] = { | ||
65 | {0, "darla24_dsp.fw"} | ||
66 | }; | ||
67 | |||
68 | static struct pci_device_id snd_echo_ids[] = { | ||
69 | {0x1057, 0x1801, 0xECC0, 0x0040, 0, 0, 0}, /* DSP 56301 Darla24 rev.0 */ | ||
70 | {0x1057, 0x1801, 0xECC0, 0x0041, 0, 0, 0}, /* DSP 56301 Darla24 rev.1 */ | ||
71 | {0,} | ||
72 | }; | ||
73 | |||
74 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
75 | .info = SNDRV_PCM_INFO_MMAP | | ||
76 | SNDRV_PCM_INFO_INTERLEAVED | | ||
77 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
78 | SNDRV_PCM_INFO_MMAP_VALID | | ||
79 | SNDRV_PCM_INFO_PAUSE | | ||
80 | SNDRV_PCM_INFO_SYNC_START, | ||
81 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
82 | SNDRV_PCM_FMTBIT_S16_LE | | ||
83 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
84 | SNDRV_PCM_FMTBIT_S32_LE | | ||
85 | SNDRV_PCM_FMTBIT_S32_BE, | ||
86 | .rates = SNDRV_PCM_RATE_8000_48000 | | ||
87 | SNDRV_PCM_RATE_88200 | | ||
88 | SNDRV_PCM_RATE_96000, | ||
89 | .rate_min = 8000, | ||
90 | .rate_max = 96000, | ||
91 | .channels_min = 1, | ||
92 | .channels_max = 8, | ||
93 | .buffer_bytes_max = 262144, | ||
94 | .period_bytes_min = 32, | ||
95 | .period_bytes_max = 131072, | ||
96 | .periods_min = 2, | ||
97 | .periods_max = 220, | ||
98 | /* One page (4k) contains 512 instructions. I don't know if the hw | ||
99 | supports lists longer than this. In this case periods_max=220 is a | ||
100 | safe limit to make sure the list never exceeds 512 instructions. */ | ||
101 | }; | ||
102 | |||
103 | |||
104 | #include "darla24_dsp.c" | ||
105 | #include "echoaudio_dsp.c" | ||
106 | #include "echoaudio.c" | ||
diff --git a/sound/pci/echoaudio/darla24_dsp.c b/sound/pci/echoaudio/darla24_dsp.c new file mode 100644 index 000000000000..79938eed7e9c --- /dev/null +++ b/sound/pci/echoaudio/darla24_dsp.c | |||
@@ -0,0 +1,156 @@ | |||
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 init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
33 | { | ||
34 | int err; | ||
35 | |||
36 | DE_INIT(("init_hw() - Darla24\n")); | ||
37 | snd_assert((subdevice_id & 0xfff0) == DARLA24, return -ENODEV); | ||
38 | |||
39 | if ((err = init_dsp_comm_page(chip))) { | ||
40 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
41 | return err; | ||
42 | } | ||
43 | |||
44 | chip->device_id = device_id; | ||
45 | chip->subdevice_id = subdevice_id; | ||
46 | chip->bad_board = TRUE; | ||
47 | chip->dsp_code_to_load = &card_fw[FW_DARLA24_DSP]; | ||
48 | /* Since this card has no ASIC, mark it as loaded so everything | ||
49 | works OK */ | ||
50 | chip->asic_loaded = TRUE; | ||
51 | chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | | ||
52 | ECHO_CLOCK_BIT_ESYNC; | ||
53 | |||
54 | if ((err = load_firmware(chip)) < 0) | ||
55 | return err; | ||
56 | chip->bad_board = FALSE; | ||
57 | |||
58 | if ((err = init_line_levels(chip)) < 0) | ||
59 | return err; | ||
60 | |||
61 | DE_INIT(("init_hw done\n")); | ||
62 | return err; | ||
63 | } | ||
64 | |||
65 | |||
66 | |||
67 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
68 | { | ||
69 | u32 clocks_from_dsp, clock_bits; | ||
70 | |||
71 | /* Map the DSP clock detect bits to the generic driver clock | ||
72 | detect bits */ | ||
73 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
74 | |||
75 | clock_bits = ECHO_CLOCK_BIT_INTERNAL; | ||
76 | |||
77 | if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_ESYNC) | ||
78 | clock_bits |= ECHO_CLOCK_BIT_ESYNC; | ||
79 | |||
80 | return clock_bits; | ||
81 | } | ||
82 | |||
83 | |||
84 | |||
85 | /* The Darla24 has no ASIC. Just do nothing */ | ||
86 | static int load_asic(struct echoaudio *chip) | ||
87 | { | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | |||
92 | |||
93 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
94 | { | ||
95 | u8 clock; | ||
96 | |||
97 | switch (rate) { | ||
98 | case 96000: | ||
99 | clock = GD24_96000; | ||
100 | break; | ||
101 | case 88200: | ||
102 | clock = GD24_88200; | ||
103 | break; | ||
104 | case 48000: | ||
105 | clock = GD24_48000; | ||
106 | break; | ||
107 | case 44100: | ||
108 | clock = GD24_44100; | ||
109 | break; | ||
110 | case 32000: | ||
111 | clock = GD24_32000; | ||
112 | break; | ||
113 | case 22050: | ||
114 | clock = GD24_22050; | ||
115 | break; | ||
116 | case 16000: | ||
117 | clock = GD24_16000; | ||
118 | break; | ||
119 | case 11025: | ||
120 | clock = GD24_11025; | ||
121 | break; | ||
122 | case 8000: | ||
123 | clock = GD24_8000; | ||
124 | break; | ||
125 | default: | ||
126 | DE_ACT(("set_sample_rate: Error, invalid sample rate %d\n", | ||
127 | rate)); | ||
128 | return -EINVAL; | ||
129 | } | ||
130 | |||
131 | if (wait_handshake(chip)) | ||
132 | return -EIO; | ||
133 | |||
134 | DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); | ||
135 | chip->sample_rate = rate; | ||
136 | |||
137 | /* Override the sample rate if this card is set to Echo sync. */ | ||
138 | if (chip->input_clock == ECHO_CLOCK_ESYNC) | ||
139 | clock = GD24_EXT_SYNC; | ||
140 | |||
141 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP ? */ | ||
142 | chip->comm_page->gd_clock_state = clock; | ||
143 | clear_handshake(chip); | ||
144 | return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); | ||
145 | } | ||
146 | |||
147 | |||
148 | |||
149 | static int set_input_clock(struct echoaudio *chip, u16 clock) | ||
150 | { | ||
151 | snd_assert(clock == ECHO_CLOCK_INTERNAL || | ||
152 | clock == ECHO_CLOCK_ESYNC, return -EINVAL); | ||
153 | chip->input_clock = clock; | ||
154 | return set_sample_rate(chip, chip->sample_rate); | ||
155 | } | ||
156 | |||
diff --git a/sound/pci/echoaudio/echo3g.c b/sound/pci/echoaudio/echo3g.c new file mode 100644 index 000000000000..12099fe1547d --- /dev/null +++ b/sound/pci/echoaudio/echo3g.c | |||
@@ -0,0 +1,118 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define ECHO3G_FAMILY | ||
20 | #define ECHOCARD_ECHO3G | ||
21 | #define ECHOCARD_NAME "Echo3G" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | #define ECHOCARD_HAS_ASIC | ||
24 | #define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL | ||
25 | #define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL | ||
26 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
27 | #define ECHOCARD_HAS_DIGITAL_IO | ||
28 | #define ECHOCARD_HAS_DIGITAL_MODE_SWITCH | ||
29 | #define ECHOCARD_HAS_ADAT 6 | ||
30 | #define ECHOCARD_HAS_EXTERNAL_CLOCK | ||
31 | #define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
32 | #define ECHOCARD_HAS_MIDI | ||
33 | #define ECHOCARD_HAS_PHANTOM_POWER | ||
34 | |||
35 | /* Pipe indexes */ | ||
36 | #define PX_ANALOG_OUT 0 | ||
37 | #define PX_DIGITAL_OUT chip->px_digital_out | ||
38 | #define PX_ANALOG_IN chip->px_analog_in | ||
39 | #define PX_DIGITAL_IN chip->px_digital_in | ||
40 | #define PX_NUM chip->px_num | ||
41 | |||
42 | /* Bus indexes */ | ||
43 | #define BX_ANALOG_OUT 0 | ||
44 | #define BX_DIGITAL_OUT chip->bx_digital_out | ||
45 | #define BX_ANALOG_IN chip->bx_analog_in | ||
46 | #define BX_DIGITAL_IN chip->bx_digital_in | ||
47 | #define BX_NUM chip->bx_num | ||
48 | |||
49 | |||
50 | #include <sound/driver.h> | ||
51 | #include <linux/delay.h> | ||
52 | #include <linux/init.h> | ||
53 | #include <linux/interrupt.h> | ||
54 | #include <linux/pci.h> | ||
55 | #include <linux/slab.h> | ||
56 | #include <linux/moduleparam.h> | ||
57 | #include <linux/firmware.h> | ||
58 | #include <sound/core.h> | ||
59 | #include <sound/info.h> | ||
60 | #include <sound/control.h> | ||
61 | #include <sound/pcm.h> | ||
62 | #include <sound/pcm_params.h> | ||
63 | #include <sound/asoundef.h> | ||
64 | #include <sound/initval.h> | ||
65 | #include <sound/rawmidi.h> | ||
66 | #include <asm/io.h> | ||
67 | #include <asm/atomic.h> | ||
68 | #include "echoaudio.h" | ||
69 | |||
70 | #define FW_361_LOADER 0 | ||
71 | #define FW_ECHO3G_DSP 1 | ||
72 | #define FW_3G_ASIC 2 | ||
73 | |||
74 | static const struct firmware card_fw[] = { | ||
75 | {0, "loader_dsp.fw"}, | ||
76 | {0, "echo3g_dsp.fw"}, | ||
77 | {0, "3g_asic.fw"} | ||
78 | }; | ||
79 | |||
80 | static struct pci_device_id snd_echo_ids[] = { | ||
81 | {0x1057, 0x3410, 0xECC0, 0x0100, 0, 0, 0}, /* Echo 3G */ | ||
82 | {0,} | ||
83 | }; | ||
84 | |||
85 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
86 | .info = SNDRV_PCM_INFO_MMAP | | ||
87 | SNDRV_PCM_INFO_INTERLEAVED | | ||
88 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
89 | SNDRV_PCM_INFO_MMAP_VALID | | ||
90 | SNDRV_PCM_INFO_PAUSE | | ||
91 | SNDRV_PCM_INFO_SYNC_START, | ||
92 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
93 | SNDRV_PCM_FMTBIT_S16_LE | | ||
94 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
95 | SNDRV_PCM_FMTBIT_S32_LE | | ||
96 | SNDRV_PCM_FMTBIT_S32_BE, | ||
97 | .rates = SNDRV_PCM_RATE_32000 | | ||
98 | SNDRV_PCM_RATE_44100 | | ||
99 | SNDRV_PCM_RATE_48000 | | ||
100 | SNDRV_PCM_RATE_88200 | | ||
101 | SNDRV_PCM_RATE_96000 | | ||
102 | SNDRV_PCM_RATE_CONTINUOUS, | ||
103 | .rate_min = 32000, | ||
104 | .rate_max = 100000, | ||
105 | .channels_min = 1, | ||
106 | .channels_max = 8, | ||
107 | .buffer_bytes_max = 262144, | ||
108 | .period_bytes_min = 32, | ||
109 | .period_bytes_max = 131072, | ||
110 | .periods_min = 2, | ||
111 | .periods_max = 220, | ||
112 | }; | ||
113 | |||
114 | #include "echo3g_dsp.c" | ||
115 | #include "echoaudio_dsp.c" | ||
116 | #include "echoaudio_3g.c" | ||
117 | #include "echoaudio.c" | ||
118 | #include "midi.c" | ||
diff --git a/sound/pci/echoaudio/echo3g_dsp.c b/sound/pci/echoaudio/echo3g_dsp.c new file mode 100644 index 000000000000..d26a1d1f3ed1 --- /dev/null +++ b/sound/pci/echoaudio/echo3g_dsp.c | |||
@@ -0,0 +1,131 @@ | |||
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 | static int load_asic(struct echoaudio *chip); | ||
32 | static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode); | ||
33 | static int set_digital_mode(struct echoaudio *chip, u8 mode); | ||
34 | static int check_asic_status(struct echoaudio *chip); | ||
35 | static int set_sample_rate(struct echoaudio *chip, u32 rate); | ||
36 | static int set_input_clock(struct echoaudio *chip, u16 clock); | ||
37 | static int set_professional_spdif(struct echoaudio *chip, char prof); | ||
38 | static int set_phantom_power(struct echoaudio *chip, char on); | ||
39 | static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, | ||
40 | char force); | ||
41 | |||
42 | #include <linux/irq.h> | ||
43 | |||
44 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
45 | { | ||
46 | int err; | ||
47 | |||
48 | local_irq_enable(); | ||
49 | DE_INIT(("init_hw() - Echo3G\n")); | ||
50 | snd_assert((subdevice_id & 0xfff0) == ECHO3G, return -ENODEV); | ||
51 | |||
52 | if ((err = init_dsp_comm_page(chip))) { | ||
53 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
54 | return err; | ||
55 | } | ||
56 | |||
57 | chip->comm_page->e3g_frq_register = | ||
58 | __constant_cpu_to_le32((E3G_MAGIC_NUMBER / 48000) - 2); | ||
59 | chip->device_id = device_id; | ||
60 | chip->subdevice_id = subdevice_id; | ||
61 | chip->bad_board = TRUE; | ||
62 | chip->has_midi = TRUE; | ||
63 | chip->dsp_code_to_load = &card_fw[FW_ECHO3G_DSP]; | ||
64 | |||
65 | /* Load the DSP code and the ASIC on the PCI card and get | ||
66 | what type of external box is attached */ | ||
67 | err = load_firmware(chip); | ||
68 | |||
69 | if (err < 0) { | ||
70 | return err; | ||
71 | } else if (err == E3G_GINA3G_BOX_TYPE) { | ||
72 | chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | | ||
73 | ECHO_CLOCK_BIT_SPDIF | | ||
74 | ECHO_CLOCK_BIT_ADAT; | ||
75 | chip->card_name = "Gina3G"; | ||
76 | chip->px_digital_out = chip->bx_digital_out = 6; | ||
77 | chip->px_analog_in = chip->bx_analog_in = 14; | ||
78 | chip->px_digital_in = chip->bx_digital_in = 16; | ||
79 | chip->px_num = chip->bx_num = 24; | ||
80 | chip->has_phantom_power = TRUE; | ||
81 | chip->hasnt_input_nominal_level = TRUE; | ||
82 | } else if (err == E3G_LAYLA3G_BOX_TYPE) { | ||
83 | chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | | ||
84 | ECHO_CLOCK_BIT_SPDIF | | ||
85 | ECHO_CLOCK_BIT_ADAT | | ||
86 | ECHO_CLOCK_BIT_WORD; | ||
87 | chip->card_name = "Layla3G"; | ||
88 | chip->px_digital_out = chip->bx_digital_out = 8; | ||
89 | chip->px_analog_in = chip->bx_analog_in = 16; | ||
90 | chip->px_digital_in = chip->bx_digital_in = 24; | ||
91 | chip->px_num = chip->bx_num = 32; | ||
92 | } else { | ||
93 | return -ENODEV; | ||
94 | } | ||
95 | |||
96 | chip->digital_modes = ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | | ||
97 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | | ||
98 | ECHOCAPS_HAS_DIGITAL_MODE_ADAT; | ||
99 | chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; | ||
100 | chip->professional_spdif = FALSE; | ||
101 | chip->non_audio_spdif = FALSE; | ||
102 | chip->bad_board = FALSE; | ||
103 | |||
104 | if ((err = init_line_levels(chip)) < 0) | ||
105 | return err; | ||
106 | err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); | ||
107 | snd_assert(err >= 0, return err); | ||
108 | err = set_phantom_power(chip, 0); | ||
109 | snd_assert(err >= 0, return err); | ||
110 | err = set_professional_spdif(chip, TRUE); | ||
111 | |||
112 | DE_INIT(("init_hw done\n")); | ||
113 | return err; | ||
114 | } | ||
115 | |||
116 | |||
117 | |||
118 | static int set_phantom_power(struct echoaudio *chip, char on) | ||
119 | { | ||
120 | u32 control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
121 | |||
122 | if (on) | ||
123 | control_reg |= E3G_PHANTOM_POWER; | ||
124 | else | ||
125 | control_reg &= ~E3G_PHANTOM_POWER; | ||
126 | |||
127 | chip->phantom_power = on; | ||
128 | return write_control_reg(chip, control_reg, | ||
129 | le32_to_cpu(chip->comm_page->e3g_frq_register), | ||
130 | 0); | ||
131 | } | ||
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c new file mode 100644 index 000000000000..43b408ada1da --- /dev/null +++ b/sound/pci/echoaudio/echoaudio.c | |||
@@ -0,0 +1,2196 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | MODULE_AUTHOR("Giuliano Pochini <pochini@shiny.it>"); | ||
20 | MODULE_LICENSE("GPL v2"); | ||
21 | MODULE_DESCRIPTION("Echoaudio " ECHOCARD_NAME " soundcards driver"); | ||
22 | MODULE_SUPPORTED_DEVICE("{{Echoaudio," ECHOCARD_NAME "}}"); | ||
23 | MODULE_DEVICE_TABLE(pci, snd_echo_ids); | ||
24 | |||
25 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | ||
26 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | ||
27 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | ||
28 | |||
29 | module_param_array(index, int, NULL, 0444); | ||
30 | MODULE_PARM_DESC(index, "Index value for " ECHOCARD_NAME " soundcard."); | ||
31 | module_param_array(id, charp, NULL, 0444); | ||
32 | MODULE_PARM_DESC(id, "ID string for " ECHOCARD_NAME " soundcard."); | ||
33 | module_param_array(enable, bool, NULL, 0444); | ||
34 | MODULE_PARM_DESC(enable, "Enable " ECHOCARD_NAME " soundcard."); | ||
35 | |||
36 | static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999}; | ||
37 | |||
38 | static int get_firmware(const struct firmware **fw_entry, | ||
39 | const struct firmware *frm, struct echoaudio *chip) | ||
40 | { | ||
41 | int err; | ||
42 | char name[30]; | ||
43 | DE_ACT(("firmware requested: %s\n", frm->data)); | ||
44 | snprintf(name, sizeof(name), "ea/%s", frm->data); | ||
45 | if ((err = request_firmware(fw_entry, name, pci_device(chip))) < 0) | ||
46 | snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err); | ||
47 | return err; | ||
48 | } | ||
49 | |||
50 | static void free_firmware(const struct firmware *fw_entry) | ||
51 | { | ||
52 | release_firmware(fw_entry); | ||
53 | DE_ACT(("firmware released\n")); | ||
54 | } | ||
55 | |||
56 | |||
57 | |||
58 | /****************************************************************************** | ||
59 | PCM interface | ||
60 | ******************************************************************************/ | ||
61 | |||
62 | static void audiopipe_free(struct snd_pcm_runtime *runtime) | ||
63 | { | ||
64 | struct audiopipe *pipe = runtime->private_data; | ||
65 | |||
66 | if (pipe->sgpage.area) | ||
67 | snd_dma_free_pages(&pipe->sgpage); | ||
68 | kfree(pipe); | ||
69 | } | ||
70 | |||
71 | |||
72 | |||
73 | static int hw_rule_capture_format_by_channels(struct snd_pcm_hw_params *params, | ||
74 | struct snd_pcm_hw_rule *rule) | ||
75 | { | ||
76 | struct snd_interval *c = hw_param_interval(params, | ||
77 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
78 | struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | ||
79 | struct snd_mask fmt; | ||
80 | |||
81 | snd_mask_any(&fmt); | ||
82 | |||
83 | #ifndef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
84 | /* >=2 channels cannot be S32_BE */ | ||
85 | if (c->min == 2) { | ||
86 | fmt.bits[0] &= ~SNDRV_PCM_FMTBIT_S32_BE; | ||
87 | return snd_mask_refine(f, &fmt); | ||
88 | } | ||
89 | #endif | ||
90 | /* > 2 channels cannot be U8 and S32_BE */ | ||
91 | if (c->min > 2) { | ||
92 | fmt.bits[0] &= ~(SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_BE); | ||
93 | return snd_mask_refine(f, &fmt); | ||
94 | } | ||
95 | /* Mono is ok with any format */ | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | |||
100 | |||
101 | static int hw_rule_capture_channels_by_format(struct snd_pcm_hw_params *params, | ||
102 | struct snd_pcm_hw_rule *rule) | ||
103 | { | ||
104 | struct snd_interval *c = hw_param_interval(params, | ||
105 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
106 | struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | ||
107 | struct snd_interval ch; | ||
108 | |||
109 | snd_interval_any(&ch); | ||
110 | |||
111 | /* S32_BE is mono (and stereo) only */ | ||
112 | if (f->bits[0] == SNDRV_PCM_FMTBIT_S32_BE) { | ||
113 | ch.min = 1; | ||
114 | #ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
115 | ch.max = 2; | ||
116 | #else | ||
117 | ch.max = 1; | ||
118 | #endif | ||
119 | ch.integer = 1; | ||
120 | return snd_interval_refine(c, &ch); | ||
121 | } | ||
122 | /* U8 can be only mono or stereo */ | ||
123 | if (f->bits[0] == SNDRV_PCM_FMTBIT_U8) { | ||
124 | ch.min = 1; | ||
125 | ch.max = 2; | ||
126 | ch.integer = 1; | ||
127 | return snd_interval_refine(c, &ch); | ||
128 | } | ||
129 | /* S16_LE, S24_3LE and S32_LE support any number of channels. */ | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | |||
134 | |||
135 | static int hw_rule_playback_format_by_channels(struct snd_pcm_hw_params *params, | ||
136 | struct snd_pcm_hw_rule *rule) | ||
137 | { | ||
138 | struct snd_interval *c = hw_param_interval(params, | ||
139 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
140 | struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | ||
141 | struct snd_mask fmt; | ||
142 | u64 fmask; | ||
143 | snd_mask_any(&fmt); | ||
144 | |||
145 | fmask = fmt.bits[0] + ((u64)fmt.bits[1] << 32); | ||
146 | |||
147 | /* >2 channels must be S16_LE, S24_3LE or S32_LE */ | ||
148 | if (c->min > 2) { | ||
149 | fmask &= SNDRV_PCM_FMTBIT_S16_LE | | ||
150 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
151 | SNDRV_PCM_FMTBIT_S32_LE; | ||
152 | /* 1 channel must be S32_BE or S32_LE */ | ||
153 | } else if (c->max == 1) | ||
154 | fmask &= SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE; | ||
155 | #ifndef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
156 | /* 2 channels cannot be S32_BE */ | ||
157 | else if (c->min == 2 && c->max == 2) | ||
158 | fmask &= ~SNDRV_PCM_FMTBIT_S32_BE; | ||
159 | #endif | ||
160 | else | ||
161 | return 0; | ||
162 | |||
163 | fmt.bits[0] &= (u32)fmask; | ||
164 | fmt.bits[1] &= (u32)(fmask >> 32); | ||
165 | return snd_mask_refine(f, &fmt); | ||
166 | } | ||
167 | |||
168 | |||
169 | |||
170 | static int hw_rule_playback_channels_by_format(struct snd_pcm_hw_params *params, | ||
171 | struct snd_pcm_hw_rule *rule) | ||
172 | { | ||
173 | struct snd_interval *c = hw_param_interval(params, | ||
174 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
175 | struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | ||
176 | struct snd_interval ch; | ||
177 | u64 fmask; | ||
178 | |||
179 | snd_interval_any(&ch); | ||
180 | ch.integer = 1; | ||
181 | fmask = f->bits[0] + ((u64)f->bits[1] << 32); | ||
182 | |||
183 | /* S32_BE is mono (and stereo) only */ | ||
184 | if (fmask == SNDRV_PCM_FMTBIT_S32_BE) { | ||
185 | ch.min = 1; | ||
186 | #ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
187 | ch.max = 2; | ||
188 | #else | ||
189 | ch.max = 1; | ||
190 | #endif | ||
191 | /* U8 is stereo only */ | ||
192 | } else if (fmask == SNDRV_PCM_FMTBIT_U8) | ||
193 | ch.min = ch.max = 2; | ||
194 | /* S16_LE and S24_3LE must be at least stereo */ | ||
195 | else if (!(fmask & ~(SNDRV_PCM_FMTBIT_S16_LE | | ||
196 | SNDRV_PCM_FMTBIT_S24_3LE))) | ||
197 | ch.min = 2; | ||
198 | else | ||
199 | return 0; | ||
200 | |||
201 | return snd_interval_refine(c, &ch); | ||
202 | } | ||
203 | |||
204 | |||
205 | |||
206 | /* Since the sample rate is a global setting, do allow the user to change the | ||
207 | sample rate only if there is only one pcm device open. */ | ||
208 | static int hw_rule_sample_rate(struct snd_pcm_hw_params *params, | ||
209 | struct snd_pcm_hw_rule *rule) | ||
210 | { | ||
211 | struct snd_interval *rate = hw_param_interval(params, | ||
212 | SNDRV_PCM_HW_PARAM_RATE); | ||
213 | struct echoaudio *chip = rule->private; | ||
214 | struct snd_interval fixed; | ||
215 | |||
216 | if (!chip->can_set_rate) { | ||
217 | snd_interval_any(&fixed); | ||
218 | fixed.min = fixed.max = chip->sample_rate; | ||
219 | return snd_interval_refine(rate, &fixed); | ||
220 | } | ||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | |||
225 | static int pcm_open(struct snd_pcm_substream *substream, | ||
226 | signed char max_channels) | ||
227 | { | ||
228 | struct echoaudio *chip; | ||
229 | struct snd_pcm_runtime *runtime; | ||
230 | struct audiopipe *pipe; | ||
231 | int err, i; | ||
232 | |||
233 | if (max_channels <= 0) | ||
234 | return -EAGAIN; | ||
235 | |||
236 | chip = snd_pcm_substream_chip(substream); | ||
237 | runtime = substream->runtime; | ||
238 | |||
239 | if (!(pipe = kmalloc(sizeof(struct audiopipe), GFP_KERNEL))) | ||
240 | return -ENOMEM; | ||
241 | memset(pipe, 0, sizeof(struct audiopipe)); | ||
242 | pipe->index = -1; /* Not configured yet */ | ||
243 | |||
244 | /* Set up hw capabilities and contraints */ | ||
245 | memcpy(&pipe->hw, &pcm_hardware_skel, sizeof(struct snd_pcm_hardware)); | ||
246 | DE_HWP(("max_channels=%d\n", max_channels)); | ||
247 | pipe->constr.list = channels_list; | ||
248 | pipe->constr.mask = 0; | ||
249 | for (i = 0; channels_list[i] <= max_channels; i++); | ||
250 | pipe->constr.count = i; | ||
251 | if (pipe->hw.channels_max > max_channels) | ||
252 | pipe->hw.channels_max = max_channels; | ||
253 | if (chip->digital_mode == DIGITAL_MODE_ADAT) { | ||
254 | pipe->hw.rate_max = 48000; | ||
255 | pipe->hw.rates &= SNDRV_PCM_RATE_8000_48000; | ||
256 | } | ||
257 | |||
258 | runtime->hw = pipe->hw; | ||
259 | runtime->private_data = pipe; | ||
260 | runtime->private_free = audiopipe_free; | ||
261 | snd_pcm_set_sync(substream); | ||
262 | |||
263 | /* Only mono and any even number of channels are allowed */ | ||
264 | if ((err = snd_pcm_hw_constraint_list(runtime, 0, | ||
265 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
266 | &pipe->constr)) < 0) | ||
267 | return err; | ||
268 | |||
269 | /* All periods should have the same size */ | ||
270 | if ((err = snd_pcm_hw_constraint_integer(runtime, | ||
271 | SNDRV_PCM_HW_PARAM_PERIODS)) < 0) | ||
272 | return err; | ||
273 | |||
274 | /* The hw accesses memory in chunks 32 frames long and they should be | ||
275 | 32-bytes-aligned. It's not a requirement, but it seems that IRQs are | ||
276 | generated with a resolution of 32 frames. Thus we need the following */ | ||
277 | if ((err = snd_pcm_hw_constraint_step(runtime, 0, | ||
278 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | ||
279 | 32)) < 0) | ||
280 | return err; | ||
281 | if ((err = snd_pcm_hw_constraint_step(runtime, 0, | ||
282 | SNDRV_PCM_HW_PARAM_BUFFER_SIZE, | ||
283 | 32)) < 0) | ||
284 | return err; | ||
285 | |||
286 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
287 | SNDRV_PCM_HW_PARAM_RATE, | ||
288 | hw_rule_sample_rate, chip, | ||
289 | SNDRV_PCM_HW_PARAM_RATE, -1)) < 0) | ||
290 | return err; | ||
291 | |||
292 | /* Finally allocate a page for the scatter-gather list */ | ||
293 | if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, | ||
294 | snd_dma_pci_data(chip->pci), | ||
295 | PAGE_SIZE, &pipe->sgpage)) < 0) { | ||
296 | DE_HWP(("s-g list allocation failed\n")); | ||
297 | return err; | ||
298 | } | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | |||
304 | |||
305 | static int pcm_analog_in_open(struct snd_pcm_substream *substream) | ||
306 | { | ||
307 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
308 | int err; | ||
309 | |||
310 | DE_ACT(("pcm_analog_in_open\n")); | ||
311 | if ((err = pcm_open(substream, num_analog_busses_in(chip) - | ||
312 | substream->number)) < 0) | ||
313 | return err; | ||
314 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
315 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
316 | hw_rule_capture_channels_by_format, NULL, | ||
317 | SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0) | ||
318 | return err; | ||
319 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
320 | SNDRV_PCM_HW_PARAM_FORMAT, | ||
321 | hw_rule_capture_format_by_channels, NULL, | ||
322 | SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) | ||
323 | return err; | ||
324 | atomic_inc(&chip->opencount); | ||
325 | if (atomic_read(&chip->opencount) > 1 && chip->rate_set) | ||
326 | chip->can_set_rate=0; | ||
327 | DE_HWP(("pcm_analog_in_open cs=%d oc=%d r=%d\n", | ||
328 | chip->can_set_rate, atomic_read(&chip->opencount), | ||
329 | chip->sample_rate)); | ||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | |||
334 | |||
335 | static int pcm_analog_out_open(struct snd_pcm_substream *substream) | ||
336 | { | ||
337 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
338 | int max_channels, err; | ||
339 | |||
340 | #ifdef ECHOCARD_HAS_VMIXER | ||
341 | max_channels = num_pipes_out(chip); | ||
342 | #else | ||
343 | max_channels = num_analog_busses_out(chip); | ||
344 | #endif | ||
345 | DE_ACT(("pcm_analog_out_open\n")); | ||
346 | if ((err = pcm_open(substream, max_channels - substream->number)) < 0) | ||
347 | return err; | ||
348 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
349 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
350 | hw_rule_playback_channels_by_format, | ||
351 | NULL, | ||
352 | SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0) | ||
353 | return err; | ||
354 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
355 | SNDRV_PCM_HW_PARAM_FORMAT, | ||
356 | hw_rule_playback_format_by_channels, | ||
357 | NULL, | ||
358 | SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) | ||
359 | return err; | ||
360 | atomic_inc(&chip->opencount); | ||
361 | if (atomic_read(&chip->opencount) > 1 && chip->rate_set) | ||
362 | chip->can_set_rate=0; | ||
363 | DE_HWP(("pcm_analog_out_open cs=%d oc=%d r=%d\n", | ||
364 | chip->can_set_rate, atomic_read(&chip->opencount), | ||
365 | chip->sample_rate)); | ||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | |||
370 | |||
371 | #ifdef ECHOCARD_HAS_DIGITAL_IO | ||
372 | |||
373 | static int pcm_digital_in_open(struct snd_pcm_substream *substream) | ||
374 | { | ||
375 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
376 | int err, max_channels; | ||
377 | |||
378 | DE_ACT(("pcm_digital_in_open\n")); | ||
379 | max_channels = num_digital_busses_in(chip) - substream->number; | ||
380 | down(&chip->mode_mutex); | ||
381 | if (chip->digital_mode == DIGITAL_MODE_ADAT) | ||
382 | err = pcm_open(substream, max_channels); | ||
383 | else /* If the card has ADAT, subtract the 6 channels | ||
384 | * that S/PDIF doesn't have | ||
385 | */ | ||
386 | err = pcm_open(substream, max_channels - ECHOCARD_HAS_ADAT); | ||
387 | |||
388 | if (err < 0) | ||
389 | goto din_exit; | ||
390 | |||
391 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
392 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
393 | hw_rule_capture_channels_by_format, NULL, | ||
394 | SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0) | ||
395 | goto din_exit; | ||
396 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
397 | SNDRV_PCM_HW_PARAM_FORMAT, | ||
398 | hw_rule_capture_format_by_channels, NULL, | ||
399 | SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) | ||
400 | goto din_exit; | ||
401 | |||
402 | atomic_inc(&chip->opencount); | ||
403 | if (atomic_read(&chip->opencount) > 1 && chip->rate_set) | ||
404 | chip->can_set_rate=0; | ||
405 | |||
406 | din_exit: | ||
407 | up(&chip->mode_mutex); | ||
408 | return err; | ||
409 | } | ||
410 | |||
411 | |||
412 | |||
413 | #ifndef ECHOCARD_HAS_VMIXER /* See the note in snd_echo_new_pcm() */ | ||
414 | |||
415 | static int pcm_digital_out_open(struct snd_pcm_substream *substream) | ||
416 | { | ||
417 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
418 | int err, max_channels; | ||
419 | |||
420 | DE_ACT(("pcm_digital_out_open\n")); | ||
421 | max_channels = num_digital_busses_out(chip) - substream->number; | ||
422 | down(&chip->mode_mutex); | ||
423 | if (chip->digital_mode == DIGITAL_MODE_ADAT) | ||
424 | err = pcm_open(substream, max_channels); | ||
425 | else /* If the card has ADAT, subtract the 6 channels | ||
426 | * that S/PDIF doesn't have | ||
427 | */ | ||
428 | err = pcm_open(substream, max_channels - ECHOCARD_HAS_ADAT); | ||
429 | |||
430 | if (err < 0) | ||
431 | goto dout_exit; | ||
432 | |||
433 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
434 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
435 | hw_rule_playback_channels_by_format, | ||
436 | NULL, SNDRV_PCM_HW_PARAM_FORMAT, | ||
437 | -1)) < 0) | ||
438 | goto dout_exit; | ||
439 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
440 | SNDRV_PCM_HW_PARAM_FORMAT, | ||
441 | hw_rule_playback_format_by_channels, | ||
442 | NULL, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
443 | -1)) < 0) | ||
444 | goto dout_exit; | ||
445 | atomic_inc(&chip->opencount); | ||
446 | if (atomic_read(&chip->opencount) > 1 && chip->rate_set) | ||
447 | chip->can_set_rate=0; | ||
448 | dout_exit: | ||
449 | up(&chip->mode_mutex); | ||
450 | return err; | ||
451 | } | ||
452 | |||
453 | #endif /* !ECHOCARD_HAS_VMIXER */ | ||
454 | |||
455 | #endif /* ECHOCARD_HAS_DIGITAL_IO */ | ||
456 | |||
457 | |||
458 | |||
459 | static int pcm_close(struct snd_pcm_substream *substream) | ||
460 | { | ||
461 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
462 | int oc; | ||
463 | |||
464 | /* Nothing to do here. Audio is already off and pipe will be | ||
465 | * freed by its callback | ||
466 | */ | ||
467 | DE_ACT(("pcm_close\n")); | ||
468 | |||
469 | atomic_dec(&chip->opencount); | ||
470 | oc = atomic_read(&chip->opencount); | ||
471 | DE_ACT(("pcm_close oc=%d cs=%d rs=%d\n", oc, | ||
472 | chip->can_set_rate, chip->rate_set)); | ||
473 | if (oc < 2) | ||
474 | chip->can_set_rate = 1; | ||
475 | if (oc == 0) | ||
476 | chip->rate_set = 0; | ||
477 | DE_ACT(("pcm_close2 oc=%d cs=%d rs=%d\n", oc, | ||
478 | chip->can_set_rate,chip->rate_set)); | ||
479 | |||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | |||
484 | |||
485 | /* Channel allocation and scatter-gather list setup */ | ||
486 | static int init_engine(struct snd_pcm_substream *substream, | ||
487 | struct snd_pcm_hw_params *hw_params, | ||
488 | int pipe_index, int interleave) | ||
489 | { | ||
490 | struct echoaudio *chip; | ||
491 | int err, per, rest, page, edge, offs; | ||
492 | struct snd_sg_buf *sgbuf; | ||
493 | struct audiopipe *pipe; | ||
494 | |||
495 | chip = snd_pcm_substream_chip(substream); | ||
496 | pipe = (struct audiopipe *) substream->runtime->private_data; | ||
497 | |||
498 | /* Sets up che hardware. If it's already initialized, reset and | ||
499 | * redo with the new parameters | ||
500 | */ | ||
501 | spin_lock_irq(&chip->lock); | ||
502 | if (pipe->index >= 0) { | ||
503 | DE_HWP(("hwp_ie free(%d)\n", pipe->index)); | ||
504 | err = free_pipes(chip, pipe); | ||
505 | snd_assert(!err); | ||
506 | chip->substream[pipe->index] = NULL; | ||
507 | } | ||
508 | |||
509 | err = allocate_pipes(chip, pipe, pipe_index, interleave); | ||
510 | if (err < 0) { | ||
511 | spin_unlock_irq(&chip->lock); | ||
512 | DE_ACT((KERN_NOTICE "allocate_pipes(%d) err=%d\n", | ||
513 | pipe_index, err)); | ||
514 | return err; | ||
515 | } | ||
516 | spin_unlock_irq(&chip->lock); | ||
517 | DE_ACT((KERN_NOTICE "allocate_pipes()=%d\n", pipe_index)); | ||
518 | |||
519 | DE_HWP(("pcm_hw_params (bufsize=%dB periods=%d persize=%dB)\n", | ||
520 | params_buffer_bytes(hw_params), params_periods(hw_params), | ||
521 | params_period_bytes(hw_params))); | ||
522 | err = snd_pcm_lib_malloc_pages(substream, | ||
523 | params_buffer_bytes(hw_params)); | ||
524 | if (err < 0) { | ||
525 | snd_printk(KERN_ERR "malloc_pages err=%d\n", err); | ||
526 | spin_lock_irq(&chip->lock); | ||
527 | free_pipes(chip, pipe); | ||
528 | spin_unlock_irq(&chip->lock); | ||
529 | pipe->index = -1; | ||
530 | return err; | ||
531 | } | ||
532 | |||
533 | sgbuf = snd_pcm_substream_sgbuf(substream); | ||
534 | |||
535 | DE_HWP(("pcm_hw_params table size=%d pages=%d\n", | ||
536 | sgbuf->size, sgbuf->pages)); | ||
537 | sglist_init(chip, pipe); | ||
538 | edge = PAGE_SIZE; | ||
539 | for (offs = page = per = 0; offs < params_buffer_bytes(hw_params); | ||
540 | per++) { | ||
541 | rest = params_period_bytes(hw_params); | ||
542 | if (offs + rest > params_buffer_bytes(hw_params)) | ||
543 | rest = params_buffer_bytes(hw_params) - offs; | ||
544 | while (rest) { | ||
545 | if (rest <= edge - offs) { | ||
546 | sglist_add_mapping(chip, pipe, | ||
547 | snd_sgbuf_get_addr(sgbuf, offs), | ||
548 | rest); | ||
549 | sglist_add_irq(chip, pipe); | ||
550 | offs += rest; | ||
551 | rest = 0; | ||
552 | } else { | ||
553 | sglist_add_mapping(chip, pipe, | ||
554 | snd_sgbuf_get_addr(sgbuf, offs), | ||
555 | edge - offs); | ||
556 | rest -= edge - offs; | ||
557 | offs = edge; | ||
558 | } | ||
559 | if (offs == edge) { | ||
560 | edge += PAGE_SIZE; | ||
561 | page++; | ||
562 | } | ||
563 | } | ||
564 | } | ||
565 | |||
566 | /* Close the ring buffer */ | ||
567 | sglist_wrap(chip, pipe); | ||
568 | |||
569 | /* This stuff is used by the irq handler, so it must be | ||
570 | * initialized before chip->substream | ||
571 | */ | ||
572 | chip->last_period[pipe_index] = 0; | ||
573 | pipe->last_counter = 0; | ||
574 | pipe->position = 0; | ||
575 | smp_wmb(); | ||
576 | chip->substream[pipe_index] = substream; | ||
577 | chip->rate_set = 1; | ||
578 | spin_lock_irq(&chip->lock); | ||
579 | set_sample_rate(chip, hw_params->rate_num / hw_params->rate_den); | ||
580 | spin_unlock_irq(&chip->lock); | ||
581 | DE_HWP(("pcm_hw_params ok\n")); | ||
582 | return 0; | ||
583 | } | ||
584 | |||
585 | |||
586 | |||
587 | static int pcm_analog_in_hw_params(struct snd_pcm_substream *substream, | ||
588 | struct snd_pcm_hw_params *hw_params) | ||
589 | { | ||
590 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
591 | |||
592 | return init_engine(substream, hw_params, px_analog_in(chip) + | ||
593 | substream->number, params_channels(hw_params)); | ||
594 | } | ||
595 | |||
596 | |||
597 | |||
598 | static int pcm_analog_out_hw_params(struct snd_pcm_substream *substream, | ||
599 | struct snd_pcm_hw_params *hw_params) | ||
600 | { | ||
601 | return init_engine(substream, hw_params, substream->number, | ||
602 | params_channels(hw_params)); | ||
603 | } | ||
604 | |||
605 | |||
606 | |||
607 | #ifdef ECHOCARD_HAS_DIGITAL_IO | ||
608 | |||
609 | static int pcm_digital_in_hw_params(struct snd_pcm_substream *substream, | ||
610 | struct snd_pcm_hw_params *hw_params) | ||
611 | { | ||
612 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
613 | |||
614 | return init_engine(substream, hw_params, px_digital_in(chip) + | ||
615 | substream->number, params_channels(hw_params)); | ||
616 | } | ||
617 | |||
618 | |||
619 | |||
620 | #ifndef ECHOCARD_HAS_VMIXER /* See the note in snd_echo_new_pcm() */ | ||
621 | static int pcm_digital_out_hw_params(struct snd_pcm_substream *substream, | ||
622 | struct snd_pcm_hw_params *hw_params) | ||
623 | { | ||
624 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
625 | |||
626 | return init_engine(substream, hw_params, px_digital_out(chip) + | ||
627 | substream->number, params_channels(hw_params)); | ||
628 | } | ||
629 | #endif /* !ECHOCARD_HAS_VMIXER */ | ||
630 | |||
631 | #endif /* ECHOCARD_HAS_DIGITAL_IO */ | ||
632 | |||
633 | |||
634 | |||
635 | static int pcm_hw_free(struct snd_pcm_substream *substream) | ||
636 | { | ||
637 | struct echoaudio *chip; | ||
638 | struct audiopipe *pipe; | ||
639 | |||
640 | chip = snd_pcm_substream_chip(substream); | ||
641 | pipe = (struct audiopipe *) substream->runtime->private_data; | ||
642 | |||
643 | spin_lock_irq(&chip->lock); | ||
644 | if (pipe->index >= 0) { | ||
645 | DE_HWP(("pcm_hw_free(%d)\n", pipe->index)); | ||
646 | free_pipes(chip, pipe); | ||
647 | chip->substream[pipe->index] = NULL; | ||
648 | pipe->index = -1; | ||
649 | } | ||
650 | spin_unlock_irq(&chip->lock); | ||
651 | |||
652 | DE_HWP(("pcm_hw_freed\n")); | ||
653 | snd_pcm_lib_free_pages(substream); | ||
654 | return 0; | ||
655 | } | ||
656 | |||
657 | |||
658 | |||
659 | static int pcm_prepare(struct snd_pcm_substream *substream) | ||
660 | { | ||
661 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
662 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
663 | struct audioformat format; | ||
664 | int pipe_index = ((struct audiopipe *)runtime->private_data)->index; | ||
665 | |||
666 | DE_HWP(("Prepare rate=%d format=%d channels=%d\n", | ||
667 | runtime->rate, runtime->format, runtime->channels)); | ||
668 | format.interleave = runtime->channels; | ||
669 | format.data_are_bigendian = 0; | ||
670 | format.mono_to_stereo = 0; | ||
671 | switch (runtime->format) { | ||
672 | case SNDRV_PCM_FORMAT_U8: | ||
673 | format.bits_per_sample = 8; | ||
674 | break; | ||
675 | case SNDRV_PCM_FORMAT_S16_LE: | ||
676 | format.bits_per_sample = 16; | ||
677 | break; | ||
678 | case SNDRV_PCM_FORMAT_S24_3LE: | ||
679 | format.bits_per_sample = 24; | ||
680 | break; | ||
681 | case SNDRV_PCM_FORMAT_S32_BE: | ||
682 | format.data_are_bigendian = 1; | ||
683 | case SNDRV_PCM_FORMAT_S32_LE: | ||
684 | format.bits_per_sample = 32; | ||
685 | break; | ||
686 | default: | ||
687 | DE_HWP(("Prepare error: unsupported format %d\n", | ||
688 | runtime->format)); | ||
689 | return -EINVAL; | ||
690 | } | ||
691 | |||
692 | snd_assert(pipe_index < px_num(chip), return -EINVAL); | ||
693 | snd_assert(is_pipe_allocated(chip, pipe_index), return -EINVAL); | ||
694 | set_audio_format(chip, pipe_index, &format); | ||
695 | return 0; | ||
696 | } | ||
697 | |||
698 | |||
699 | |||
700 | static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) | ||
701 | { | ||
702 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
703 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
704 | struct audiopipe *pipe = runtime->private_data; | ||
705 | int i, err; | ||
706 | u32 channelmask = 0; | ||
707 | struct list_head *pos; | ||
708 | struct snd_pcm_substream *s; | ||
709 | |||
710 | snd_pcm_group_for_each(pos, substream) { | ||
711 | s = snd_pcm_group_substream_entry(pos); | ||
712 | for (i = 0; i < DSP_MAXPIPES; i++) { | ||
713 | if (s == chip->substream[i]) { | ||
714 | channelmask |= 1 << i; | ||
715 | snd_pcm_trigger_done(s, substream); | ||
716 | } | ||
717 | } | ||
718 | } | ||
719 | |||
720 | spin_lock(&chip->lock); | ||
721 | switch (cmd) { | ||
722 | case SNDRV_PCM_TRIGGER_START: | ||
723 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
724 | DE_ACT(("pcm_trigger start\n")); | ||
725 | for (i = 0; i < DSP_MAXPIPES; i++) { | ||
726 | if (channelmask & (1 << i)) { | ||
727 | pipe = chip->substream[i]->runtime->private_data; | ||
728 | switch (pipe->state) { | ||
729 | case PIPE_STATE_STOPPED: | ||
730 | chip->last_period[i] = 0; | ||
731 | pipe->last_counter = 0; | ||
732 | pipe->position = 0; | ||
733 | *pipe->dma_counter = 0; | ||
734 | case PIPE_STATE_PAUSED: | ||
735 | pipe->state = PIPE_STATE_STARTED; | ||
736 | break; | ||
737 | case PIPE_STATE_STARTED: | ||
738 | break; | ||
739 | } | ||
740 | } | ||
741 | } | ||
742 | err = start_transport(chip, channelmask, | ||
743 | chip->pipe_cyclic_mask); | ||
744 | break; | ||
745 | case SNDRV_PCM_TRIGGER_STOP: | ||
746 | DE_ACT(("pcm_trigger stop\n")); | ||
747 | for (i = 0; i < DSP_MAXPIPES; i++) { | ||
748 | if (channelmask & (1 << i)) { | ||
749 | pipe = chip->substream[i]->runtime->private_data; | ||
750 | pipe->state = PIPE_STATE_STOPPED; | ||
751 | } | ||
752 | } | ||
753 | err = stop_transport(chip, channelmask); | ||
754 | break; | ||
755 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
756 | DE_ACT(("pcm_trigger pause\n")); | ||
757 | for (i = 0; i < DSP_MAXPIPES; i++) { | ||
758 | if (channelmask & (1 << i)) { | ||
759 | pipe = chip->substream[i]->runtime->private_data; | ||
760 | pipe->state = PIPE_STATE_PAUSED; | ||
761 | } | ||
762 | } | ||
763 | err = pause_transport(chip, channelmask); | ||
764 | break; | ||
765 | default: | ||
766 | err = -EINVAL; | ||
767 | } | ||
768 | spin_unlock(&chip->lock); | ||
769 | return err; | ||
770 | } | ||
771 | |||
772 | |||
773 | |||
774 | static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream) | ||
775 | { | ||
776 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
777 | struct audiopipe *pipe = runtime->private_data; | ||
778 | size_t cnt, bufsize, pos; | ||
779 | |||
780 | cnt = le32_to_cpu(*pipe->dma_counter); | ||
781 | pipe->position += cnt - pipe->last_counter; | ||
782 | pipe->last_counter = cnt; | ||
783 | bufsize = substream->runtime->buffer_size; | ||
784 | pos = bytes_to_frames(substream->runtime, pipe->position); | ||
785 | |||
786 | while (pos >= bufsize) { | ||
787 | pipe->position -= frames_to_bytes(substream->runtime, bufsize); | ||
788 | pos -= bufsize; | ||
789 | } | ||
790 | return pos; | ||
791 | } | ||
792 | |||
793 | |||
794 | |||
795 | /* pcm *_ops structures */ | ||
796 | static struct snd_pcm_ops analog_playback_ops = { | ||
797 | .open = pcm_analog_out_open, | ||
798 | .close = pcm_close, | ||
799 | .ioctl = snd_pcm_lib_ioctl, | ||
800 | .hw_params = pcm_analog_out_hw_params, | ||
801 | .hw_free = pcm_hw_free, | ||
802 | .prepare = pcm_prepare, | ||
803 | .trigger = pcm_trigger, | ||
804 | .pointer = pcm_pointer, | ||
805 | .page = snd_pcm_sgbuf_ops_page, | ||
806 | }; | ||
807 | static struct snd_pcm_ops analog_capture_ops = { | ||
808 | .open = pcm_analog_in_open, | ||
809 | .close = pcm_close, | ||
810 | .ioctl = snd_pcm_lib_ioctl, | ||
811 | .hw_params = pcm_analog_in_hw_params, | ||
812 | .hw_free = pcm_hw_free, | ||
813 | .prepare = pcm_prepare, | ||
814 | .trigger = pcm_trigger, | ||
815 | .pointer = pcm_pointer, | ||
816 | .page = snd_pcm_sgbuf_ops_page, | ||
817 | }; | ||
818 | #ifdef ECHOCARD_HAS_DIGITAL_IO | ||
819 | #ifndef ECHOCARD_HAS_VMIXER | ||
820 | static struct snd_pcm_ops digital_playback_ops = { | ||
821 | .open = pcm_digital_out_open, | ||
822 | .close = pcm_close, | ||
823 | .ioctl = snd_pcm_lib_ioctl, | ||
824 | .hw_params = pcm_digital_out_hw_params, | ||
825 | .hw_free = pcm_hw_free, | ||
826 | .prepare = pcm_prepare, | ||
827 | .trigger = pcm_trigger, | ||
828 | .pointer = pcm_pointer, | ||
829 | .page = snd_pcm_sgbuf_ops_page, | ||
830 | }; | ||
831 | #endif /* !ECHOCARD_HAS_VMIXER */ | ||
832 | static struct snd_pcm_ops digital_capture_ops = { | ||
833 | .open = pcm_digital_in_open, | ||
834 | .close = pcm_close, | ||
835 | .ioctl = snd_pcm_lib_ioctl, | ||
836 | .hw_params = pcm_digital_in_hw_params, | ||
837 | .hw_free = pcm_hw_free, | ||
838 | .prepare = pcm_prepare, | ||
839 | .trigger = pcm_trigger, | ||
840 | .pointer = pcm_pointer, | ||
841 | .page = snd_pcm_sgbuf_ops_page, | ||
842 | }; | ||
843 | #endif /* ECHOCARD_HAS_DIGITAL_IO */ | ||
844 | |||
845 | |||
846 | |||
847 | /* Preallocate memory only for the first substream because it's the most | ||
848 | * used one | ||
849 | */ | ||
850 | static int snd_echo_preallocate_pages(struct snd_pcm *pcm, struct device *dev) | ||
851 | { | ||
852 | struct snd_pcm_substream *ss; | ||
853 | int stream, err; | ||
854 | |||
855 | for (stream = 0; stream < 2; stream++) | ||
856 | for (ss = pcm->streams[stream].substream; ss; ss = ss->next) { | ||
857 | err = snd_pcm_lib_preallocate_pages(ss, SNDRV_DMA_TYPE_DEV_SG, | ||
858 | dev, | ||
859 | ss->number ? 0 : 128<<10, | ||
860 | 256<<10); | ||
861 | if (err < 0) | ||
862 | return err; | ||
863 | } | ||
864 | return 0; | ||
865 | } | ||
866 | |||
867 | |||
868 | |||
869 | /*<--snd_echo_probe() */ | ||
870 | static int __devinit snd_echo_new_pcm(struct echoaudio *chip) | ||
871 | { | ||
872 | struct snd_pcm *pcm; | ||
873 | int err; | ||
874 | |||
875 | #ifdef ECHOCARD_HAS_VMIXER | ||
876 | /* This card has a Vmixer, that is there is no direct mapping from PCM | ||
877 | streams to physical outputs. The user can mix the streams as he wishes | ||
878 | via control interface and it's possible to send any stream to any | ||
879 | output, thus it makes no sense to keep analog and digital outputs | ||
880 | separated */ | ||
881 | |||
882 | /* PCM#0 Virtual outputs and analog inputs */ | ||
883 | if ((err = snd_pcm_new(chip->card, "PCM", 0, num_pipes_out(chip), | ||
884 | num_analog_busses_in(chip), &pcm)) < 0) | ||
885 | return err; | ||
886 | pcm->private_data = chip; | ||
887 | chip->analog_pcm = pcm; | ||
888 | strcpy(pcm->name, chip->card->shortname); | ||
889 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &analog_playback_ops); | ||
890 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops); | ||
891 | if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) | ||
892 | return err; | ||
893 | DE_INIT(("Analog PCM ok\n")); | ||
894 | |||
895 | #ifdef ECHOCARD_HAS_DIGITAL_IO | ||
896 | /* PCM#1 Digital inputs, no outputs */ | ||
897 | if ((err = snd_pcm_new(chip->card, "Digital PCM", 1, 0, | ||
898 | num_digital_busses_in(chip), &pcm)) < 0) | ||
899 | return err; | ||
900 | pcm->private_data = chip; | ||
901 | chip->digital_pcm = pcm; | ||
902 | strcpy(pcm->name, chip->card->shortname); | ||
903 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops); | ||
904 | if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) | ||
905 | return err; | ||
906 | DE_INIT(("Digital PCM ok\n")); | ||
907 | #endif /* ECHOCARD_HAS_DIGITAL_IO */ | ||
908 | |||
909 | #else /* ECHOCARD_HAS_VMIXER */ | ||
910 | |||
911 | /* The card can manage substreams formed by analog and digital channels | ||
912 | at the same time, but I prefer to keep analog and digital channels | ||
913 | separated, because that mixed thing is confusing and useless. So we | ||
914 | register two PCM devices: */ | ||
915 | |||
916 | /* PCM#0 Analog i/o */ | ||
917 | if ((err = snd_pcm_new(chip->card, "Analog PCM", 0, | ||
918 | num_analog_busses_out(chip), | ||
919 | num_analog_busses_in(chip), &pcm)) < 0) | ||
920 | return err; | ||
921 | pcm->private_data = chip; | ||
922 | chip->analog_pcm = pcm; | ||
923 | strcpy(pcm->name, chip->card->shortname); | ||
924 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &analog_playback_ops); | ||
925 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops); | ||
926 | if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) | ||
927 | return err; | ||
928 | DE_INIT(("Analog PCM ok\n")); | ||
929 | |||
930 | #ifdef ECHOCARD_HAS_DIGITAL_IO | ||
931 | /* PCM#1 Digital i/o */ | ||
932 | if ((err = snd_pcm_new(chip->card, "Digital PCM", 1, | ||
933 | num_digital_busses_out(chip), | ||
934 | num_digital_busses_in(chip), &pcm)) < 0) | ||
935 | return err; | ||
936 | pcm->private_data = chip; | ||
937 | chip->digital_pcm = pcm; | ||
938 | strcpy(pcm->name, chip->card->shortname); | ||
939 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &digital_playback_ops); | ||
940 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops); | ||
941 | if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) | ||
942 | return err; | ||
943 | DE_INIT(("Digital PCM ok\n")); | ||
944 | #endif /* ECHOCARD_HAS_DIGITAL_IO */ | ||
945 | |||
946 | #endif /* ECHOCARD_HAS_VMIXER */ | ||
947 | |||
948 | return 0; | ||
949 | } | ||
950 | |||
951 | |||
952 | |||
953 | |||
954 | /****************************************************************************** | ||
955 | Control interface | ||
956 | ******************************************************************************/ | ||
957 | |||
958 | /******************* PCM output volume *******************/ | ||
959 | static int snd_echo_output_gain_info(struct snd_kcontrol *kcontrol, | ||
960 | struct snd_ctl_elem_info *uinfo) | ||
961 | { | ||
962 | struct echoaudio *chip; | ||
963 | |||
964 | chip = snd_kcontrol_chip(kcontrol); | ||
965 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
966 | uinfo->count = num_busses_out(chip); | ||
967 | uinfo->value.integer.min = ECHOGAIN_MINOUT; | ||
968 | uinfo->value.integer.max = ECHOGAIN_MAXOUT; | ||
969 | return 0; | ||
970 | } | ||
971 | |||
972 | static int snd_echo_output_gain_get(struct snd_kcontrol *kcontrol, | ||
973 | struct snd_ctl_elem_value *ucontrol) | ||
974 | { | ||
975 | struct echoaudio *chip; | ||
976 | int c; | ||
977 | |||
978 | chip = snd_kcontrol_chip(kcontrol); | ||
979 | for (c = 0; c < num_busses_out(chip); c++) | ||
980 | ucontrol->value.integer.value[c] = chip->output_gain[c]; | ||
981 | return 0; | ||
982 | } | ||
983 | |||
984 | static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol, | ||
985 | struct snd_ctl_elem_value *ucontrol) | ||
986 | { | ||
987 | struct echoaudio *chip; | ||
988 | int c, changed, gain; | ||
989 | |||
990 | changed = 0; | ||
991 | chip = snd_kcontrol_chip(kcontrol); | ||
992 | spin_lock_irq(&chip->lock); | ||
993 | for (c = 0; c < num_busses_out(chip); c++) { | ||
994 | gain = ucontrol->value.integer.value[c]; | ||
995 | /* Ignore out of range values */ | ||
996 | if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT) | ||
997 | continue; | ||
998 | if (chip->output_gain[c] != gain) { | ||
999 | set_output_gain(chip, c, gain); | ||
1000 | changed = 1; | ||
1001 | } | ||
1002 | } | ||
1003 | if (changed) | ||
1004 | update_output_line_level(chip); | ||
1005 | spin_unlock_irq(&chip->lock); | ||
1006 | return changed; | ||
1007 | } | ||
1008 | |||
1009 | #ifdef ECHOCARD_HAS_VMIXER | ||
1010 | /* On Vmixer cards this one controls the line-out volume */ | ||
1011 | static struct snd_kcontrol_new snd_echo_line_output_gain __devinitdata = { | ||
1012 | .name = "Line Playback Volume", | ||
1013 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1014 | .info = snd_echo_output_gain_info, | ||
1015 | .get = snd_echo_output_gain_get, | ||
1016 | .put = snd_echo_output_gain_put, | ||
1017 | }; | ||
1018 | #else | ||
1019 | static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = { | ||
1020 | .name = "PCM Playback Volume", | ||
1021 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1022 | .info = snd_echo_output_gain_info, | ||
1023 | .get = snd_echo_output_gain_get, | ||
1024 | .put = snd_echo_output_gain_put, | ||
1025 | }; | ||
1026 | #endif | ||
1027 | |||
1028 | |||
1029 | |||
1030 | #ifdef ECHOCARD_HAS_INPUT_GAIN | ||
1031 | |||
1032 | /******************* Analog input volume *******************/ | ||
1033 | static int snd_echo_input_gain_info(struct snd_kcontrol *kcontrol, | ||
1034 | struct snd_ctl_elem_info *uinfo) | ||
1035 | { | ||
1036 | struct echoaudio *chip; | ||
1037 | |||
1038 | chip = snd_kcontrol_chip(kcontrol); | ||
1039 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1040 | uinfo->count = num_analog_busses_in(chip); | ||
1041 | uinfo->value.integer.min = ECHOGAIN_MININP; | ||
1042 | uinfo->value.integer.max = ECHOGAIN_MAXINP; | ||
1043 | return 0; | ||
1044 | } | ||
1045 | |||
1046 | static int snd_echo_input_gain_get(struct snd_kcontrol *kcontrol, | ||
1047 | struct snd_ctl_elem_value *ucontrol) | ||
1048 | { | ||
1049 | struct echoaudio *chip; | ||
1050 | int c; | ||
1051 | |||
1052 | chip = snd_kcontrol_chip(kcontrol); | ||
1053 | for (c = 0; c < num_analog_busses_in(chip); c++) | ||
1054 | ucontrol->value.integer.value[c] = chip->input_gain[c]; | ||
1055 | return 0; | ||
1056 | } | ||
1057 | |||
1058 | static int snd_echo_input_gain_put(struct snd_kcontrol *kcontrol, | ||
1059 | struct snd_ctl_elem_value *ucontrol) | ||
1060 | { | ||
1061 | struct echoaudio *chip; | ||
1062 | int c, gain, changed; | ||
1063 | |||
1064 | changed = 0; | ||
1065 | chip = snd_kcontrol_chip(kcontrol); | ||
1066 | spin_lock_irq(&chip->lock); | ||
1067 | for (c = 0; c < num_analog_busses_in(chip); c++) { | ||
1068 | gain = ucontrol->value.integer.value[c]; | ||
1069 | /* Ignore out of range values */ | ||
1070 | if (gain < ECHOGAIN_MININP || gain > ECHOGAIN_MAXINP) | ||
1071 | continue; | ||
1072 | if (chip->input_gain[c] != gain) { | ||
1073 | set_input_gain(chip, c, gain); | ||
1074 | changed = 1; | ||
1075 | } | ||
1076 | } | ||
1077 | if (changed) | ||
1078 | update_input_line_level(chip); | ||
1079 | spin_unlock_irq(&chip->lock); | ||
1080 | return changed; | ||
1081 | } | ||
1082 | |||
1083 | static struct snd_kcontrol_new snd_echo_line_input_gain __devinitdata = { | ||
1084 | .name = "Line Capture Volume", | ||
1085 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1086 | .info = snd_echo_input_gain_info, | ||
1087 | .get = snd_echo_input_gain_get, | ||
1088 | .put = snd_echo_input_gain_put, | ||
1089 | }; | ||
1090 | |||
1091 | #endif /* ECHOCARD_HAS_INPUT_GAIN */ | ||
1092 | |||
1093 | |||
1094 | |||
1095 | #ifdef ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL | ||
1096 | |||
1097 | /************ Analog output nominal level (+4dBu / -10dBV) ***************/ | ||
1098 | static int snd_echo_output_nominal_info (struct snd_kcontrol *kcontrol, | ||
1099 | struct snd_ctl_elem_info *uinfo) | ||
1100 | { | ||
1101 | struct echoaudio *chip; | ||
1102 | |||
1103 | chip = snd_kcontrol_chip(kcontrol); | ||
1104 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
1105 | uinfo->count = num_analog_busses_out(chip); | ||
1106 | uinfo->value.integer.min = 0; | ||
1107 | uinfo->value.integer.max = 1; | ||
1108 | return 0; | ||
1109 | } | ||
1110 | |||
1111 | static int snd_echo_output_nominal_get(struct snd_kcontrol *kcontrol, | ||
1112 | struct snd_ctl_elem_value *ucontrol) | ||
1113 | { | ||
1114 | struct echoaudio *chip; | ||
1115 | int c; | ||
1116 | |||
1117 | chip = snd_kcontrol_chip(kcontrol); | ||
1118 | for (c = 0; c < num_analog_busses_out(chip); c++) | ||
1119 | ucontrol->value.integer.value[c] = chip->nominal_level[c]; | ||
1120 | return 0; | ||
1121 | } | ||
1122 | |||
1123 | static int snd_echo_output_nominal_put(struct snd_kcontrol *kcontrol, | ||
1124 | struct snd_ctl_elem_value *ucontrol) | ||
1125 | { | ||
1126 | struct echoaudio *chip; | ||
1127 | int c, changed; | ||
1128 | |||
1129 | changed = 0; | ||
1130 | chip = snd_kcontrol_chip(kcontrol); | ||
1131 | spin_lock_irq(&chip->lock); | ||
1132 | for (c = 0; c < num_analog_busses_out(chip); c++) { | ||
1133 | if (chip->nominal_level[c] != ucontrol->value.integer.value[c]) { | ||
1134 | set_nominal_level(chip, c, | ||
1135 | ucontrol->value.integer.value[c]); | ||
1136 | changed = 1; | ||
1137 | } | ||
1138 | } | ||
1139 | if (changed) | ||
1140 | update_output_line_level(chip); | ||
1141 | spin_unlock_irq(&chip->lock); | ||
1142 | return changed; | ||
1143 | } | ||
1144 | |||
1145 | static struct snd_kcontrol_new snd_echo_output_nominal_level __devinitdata = { | ||
1146 | .name = "Line Playback Switch (-10dBV)", | ||
1147 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1148 | .info = snd_echo_output_nominal_info, | ||
1149 | .get = snd_echo_output_nominal_get, | ||
1150 | .put = snd_echo_output_nominal_put, | ||
1151 | }; | ||
1152 | |||
1153 | #endif /* ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL */ | ||
1154 | |||
1155 | |||
1156 | |||
1157 | #ifdef ECHOCARD_HAS_INPUT_NOMINAL_LEVEL | ||
1158 | |||
1159 | /*************** Analog input nominal level (+4dBu / -10dBV) ***************/ | ||
1160 | static int snd_echo_input_nominal_info(struct snd_kcontrol *kcontrol, | ||
1161 | struct snd_ctl_elem_info *uinfo) | ||
1162 | { | ||
1163 | struct echoaudio *chip; | ||
1164 | |||
1165 | chip = snd_kcontrol_chip(kcontrol); | ||
1166 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
1167 | uinfo->count = num_analog_busses_in(chip); | ||
1168 | uinfo->value.integer.min = 0; | ||
1169 | uinfo->value.integer.max = 1; | ||
1170 | return 0; | ||
1171 | } | ||
1172 | |||
1173 | static int snd_echo_input_nominal_get(struct snd_kcontrol *kcontrol, | ||
1174 | struct snd_ctl_elem_value *ucontrol) | ||
1175 | { | ||
1176 | struct echoaudio *chip; | ||
1177 | int c; | ||
1178 | |||
1179 | chip = snd_kcontrol_chip(kcontrol); | ||
1180 | for (c = 0; c < num_analog_busses_in(chip); c++) | ||
1181 | ucontrol->value.integer.value[c] = | ||
1182 | chip->nominal_level[bx_analog_in(chip) + c]; | ||
1183 | return 0; | ||
1184 | } | ||
1185 | |||
1186 | static int snd_echo_input_nominal_put(struct snd_kcontrol *kcontrol, | ||
1187 | struct snd_ctl_elem_value *ucontrol) | ||
1188 | { | ||
1189 | struct echoaudio *chip; | ||
1190 | int c, changed; | ||
1191 | |||
1192 | changed = 0; | ||
1193 | chip = snd_kcontrol_chip(kcontrol); | ||
1194 | spin_lock_irq(&chip->lock); | ||
1195 | for (c = 0; c < num_analog_busses_in(chip); c++) { | ||
1196 | if (chip->nominal_level[bx_analog_in(chip) + c] != | ||
1197 | ucontrol->value.integer.value[c]) { | ||
1198 | set_nominal_level(chip, bx_analog_in(chip) + c, | ||
1199 | ucontrol->value.integer.value[c]); | ||
1200 | changed = 1; | ||
1201 | } | ||
1202 | } | ||
1203 | if (changed) | ||
1204 | update_output_line_level(chip); /* "Output" is not a mistake | ||
1205 | * here. | ||
1206 | */ | ||
1207 | spin_unlock_irq(&chip->lock); | ||
1208 | return changed; | ||
1209 | } | ||
1210 | |||
1211 | static struct snd_kcontrol_new snd_echo_intput_nominal_level __devinitdata = { | ||
1212 | .name = "Line Capture Switch (-10dBV)", | ||
1213 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1214 | .info = snd_echo_input_nominal_info, | ||
1215 | .get = snd_echo_input_nominal_get, | ||
1216 | .put = snd_echo_input_nominal_put, | ||
1217 | }; | ||
1218 | |||
1219 | #endif /* ECHOCARD_HAS_INPUT_NOMINAL_LEVEL */ | ||
1220 | |||
1221 | |||
1222 | |||
1223 | #ifdef ECHOCARD_HAS_MONITOR | ||
1224 | |||
1225 | /******************* Monitor mixer *******************/ | ||
1226 | static int snd_echo_mixer_info(struct snd_kcontrol *kcontrol, | ||
1227 | struct snd_ctl_elem_info *uinfo) | ||
1228 | { | ||
1229 | struct echoaudio *chip; | ||
1230 | |||
1231 | chip = snd_kcontrol_chip(kcontrol); | ||
1232 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1233 | uinfo->count = 1; | ||
1234 | uinfo->value.integer.min = ECHOGAIN_MINOUT; | ||
1235 | uinfo->value.integer.max = ECHOGAIN_MAXOUT; | ||
1236 | uinfo->dimen.d[0] = num_busses_out(chip); | ||
1237 | uinfo->dimen.d[1] = num_busses_in(chip); | ||
1238 | return 0; | ||
1239 | } | ||
1240 | |||
1241 | static int snd_echo_mixer_get(struct snd_kcontrol *kcontrol, | ||
1242 | struct snd_ctl_elem_value *ucontrol) | ||
1243 | { | ||
1244 | struct echoaudio *chip; | ||
1245 | |||
1246 | chip = snd_kcontrol_chip(kcontrol); | ||
1247 | ucontrol->value.integer.value[0] = | ||
1248 | chip->monitor_gain[ucontrol->id.index / num_busses_in(chip)] | ||
1249 | [ucontrol->id.index % num_busses_in(chip)]; | ||
1250 | return 0; | ||
1251 | } | ||
1252 | |||
1253 | static int snd_echo_mixer_put(struct snd_kcontrol *kcontrol, | ||
1254 | struct snd_ctl_elem_value *ucontrol) | ||
1255 | { | ||
1256 | struct echoaudio *chip; | ||
1257 | int changed, gain; | ||
1258 | short out, in; | ||
1259 | |||
1260 | changed = 0; | ||
1261 | chip = snd_kcontrol_chip(kcontrol); | ||
1262 | out = ucontrol->id.index / num_busses_in(chip); | ||
1263 | in = ucontrol->id.index % num_busses_in(chip); | ||
1264 | gain = ucontrol->value.integer.value[0]; | ||
1265 | if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT) | ||
1266 | return -EINVAL; | ||
1267 | if (chip->monitor_gain[out][in] != gain) { | ||
1268 | spin_lock_irq(&chip->lock); | ||
1269 | set_monitor_gain(chip, out, in, gain); | ||
1270 | update_output_line_level(chip); | ||
1271 | spin_unlock_irq(&chip->lock); | ||
1272 | changed = 1; | ||
1273 | } | ||
1274 | return changed; | ||
1275 | } | ||
1276 | |||
1277 | static struct snd_kcontrol_new snd_echo_monitor_mixer __devinitdata = { | ||
1278 | .name = "Monitor Mixer Volume", | ||
1279 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1280 | .info = snd_echo_mixer_info, | ||
1281 | .get = snd_echo_mixer_get, | ||
1282 | .put = snd_echo_mixer_put, | ||
1283 | }; | ||
1284 | |||
1285 | #endif /* ECHOCARD_HAS_MONITOR */ | ||
1286 | |||
1287 | |||
1288 | |||
1289 | #ifdef ECHOCARD_HAS_VMIXER | ||
1290 | |||
1291 | /******************* Vmixer *******************/ | ||
1292 | static int snd_echo_vmixer_info(struct snd_kcontrol *kcontrol, | ||
1293 | struct snd_ctl_elem_info *uinfo) | ||
1294 | { | ||
1295 | struct echoaudio *chip; | ||
1296 | |||
1297 | chip = snd_kcontrol_chip(kcontrol); | ||
1298 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1299 | uinfo->count = 1; | ||
1300 | uinfo->value.integer.min = ECHOGAIN_MINOUT; | ||
1301 | uinfo->value.integer.max = ECHOGAIN_MAXOUT; | ||
1302 | uinfo->dimen.d[0] = num_busses_out(chip); | ||
1303 | uinfo->dimen.d[1] = num_pipes_out(chip); | ||
1304 | return 0; | ||
1305 | } | ||
1306 | |||
1307 | static int snd_echo_vmixer_get(struct snd_kcontrol *kcontrol, | ||
1308 | struct snd_ctl_elem_value *ucontrol) | ||
1309 | { | ||
1310 | struct echoaudio *chip; | ||
1311 | |||
1312 | chip = snd_kcontrol_chip(kcontrol); | ||
1313 | ucontrol->value.integer.value[0] = | ||
1314 | chip->vmixer_gain[ucontrol->id.index / num_pipes_out(chip)] | ||
1315 | [ucontrol->id.index % num_pipes_out(chip)]; | ||
1316 | return 0; | ||
1317 | } | ||
1318 | |||
1319 | static int snd_echo_vmixer_put(struct snd_kcontrol *kcontrol, | ||
1320 | struct snd_ctl_elem_value *ucontrol) | ||
1321 | { | ||
1322 | struct echoaudio *chip; | ||
1323 | int gain, changed; | ||
1324 | short vch, out; | ||
1325 | |||
1326 | changed = 0; | ||
1327 | chip = snd_kcontrol_chip(kcontrol); | ||
1328 | out = ucontrol->id.index / num_pipes_out(chip); | ||
1329 | vch = ucontrol->id.index % num_pipes_out(chip); | ||
1330 | gain = ucontrol->value.integer.value[0]; | ||
1331 | if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT) | ||
1332 | return -EINVAL; | ||
1333 | if (chip->vmixer_gain[out][vch] != ucontrol->value.integer.value[0]) { | ||
1334 | spin_lock_irq(&chip->lock); | ||
1335 | set_vmixer_gain(chip, out, vch, ucontrol->value.integer.value[0]); | ||
1336 | update_vmixer_level(chip); | ||
1337 | spin_unlock_irq(&chip->lock); | ||
1338 | changed = 1; | ||
1339 | } | ||
1340 | return changed; | ||
1341 | } | ||
1342 | |||
1343 | static struct snd_kcontrol_new snd_echo_vmixer __devinitdata = { | ||
1344 | .name = "VMixer Volume", | ||
1345 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1346 | .info = snd_echo_vmixer_info, | ||
1347 | .get = snd_echo_vmixer_get, | ||
1348 | .put = snd_echo_vmixer_put, | ||
1349 | }; | ||
1350 | |||
1351 | #endif /* ECHOCARD_HAS_VMIXER */ | ||
1352 | |||
1353 | |||
1354 | |||
1355 | #ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH | ||
1356 | |||
1357 | /******************* Digital mode switch *******************/ | ||
1358 | static int snd_echo_digital_mode_info(struct snd_kcontrol *kcontrol, | ||
1359 | struct snd_ctl_elem_info *uinfo) | ||
1360 | { | ||
1361 | static char *names[4] = { | ||
1362 | "S/PDIF Coaxial", "S/PDIF Optical", "ADAT Optical", | ||
1363 | "S/PDIF Cdrom" | ||
1364 | }; | ||
1365 | struct echoaudio *chip; | ||
1366 | |||
1367 | chip = snd_kcontrol_chip(kcontrol); | ||
1368 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
1369 | uinfo->value.enumerated.items = chip->num_digital_modes; | ||
1370 | uinfo->count = 1; | ||
1371 | if (uinfo->value.enumerated.item >= chip->num_digital_modes) | ||
1372 | uinfo->value.enumerated.item = chip->num_digital_modes - 1; | ||
1373 | strcpy(uinfo->value.enumerated.name, names[ | ||
1374 | chip->digital_mode_list[uinfo->value.enumerated.item]]); | ||
1375 | return 0; | ||
1376 | } | ||
1377 | |||
1378 | static int snd_echo_digital_mode_get(struct snd_kcontrol *kcontrol, | ||
1379 | struct snd_ctl_elem_value *ucontrol) | ||
1380 | { | ||
1381 | struct echoaudio *chip; | ||
1382 | int i, mode; | ||
1383 | |||
1384 | chip = snd_kcontrol_chip(kcontrol); | ||
1385 | mode = chip->digital_mode; | ||
1386 | for (i = chip->num_digital_modes - 1; i >= 0; i--) | ||
1387 | if (mode == chip->digital_mode_list[i]) { | ||
1388 | ucontrol->value.enumerated.item[0] = i; | ||
1389 | break; | ||
1390 | } | ||
1391 | return 0; | ||
1392 | } | ||
1393 | |||
1394 | static int snd_echo_digital_mode_put(struct snd_kcontrol *kcontrol, | ||
1395 | struct snd_ctl_elem_value *ucontrol) | ||
1396 | { | ||
1397 | struct echoaudio *chip; | ||
1398 | int changed; | ||
1399 | unsigned short emode, dmode; | ||
1400 | |||
1401 | changed = 0; | ||
1402 | chip = snd_kcontrol_chip(kcontrol); | ||
1403 | |||
1404 | emode = ucontrol->value.enumerated.item[0]; | ||
1405 | if (emode >= chip->num_digital_modes) | ||
1406 | return -EINVAL; | ||
1407 | dmode = chip->digital_mode_list[emode]; | ||
1408 | |||
1409 | if (dmode != chip->digital_mode) { | ||
1410 | /* mode_mutex is required to make this operation atomic wrt | ||
1411 | pcm_digital_*_open() and set_input_clock() functions. */ | ||
1412 | down(&chip->mode_mutex); | ||
1413 | |||
1414 | /* Do not allow the user to change the digital mode when a pcm | ||
1415 | device is open because it also changes the number of channels | ||
1416 | and the allowed sample rates */ | ||
1417 | if (atomic_read(&chip->opencount)) { | ||
1418 | changed = -EAGAIN; | ||
1419 | } else { | ||
1420 | changed = set_digital_mode(chip, dmode); | ||
1421 | /* If we had to change the clock source, report it */ | ||
1422 | if (changed > 0 && chip->clock_src_ctl) { | ||
1423 | snd_ctl_notify(chip->card, | ||
1424 | SNDRV_CTL_EVENT_MASK_VALUE, | ||
1425 | &chip->clock_src_ctl->id); | ||
1426 | DE_ACT(("SDM() =%d\n", changed)); | ||
1427 | } | ||
1428 | if (changed >= 0) | ||
1429 | changed = 1; /* No errors */ | ||
1430 | } | ||
1431 | up(&chip->mode_mutex); | ||
1432 | } | ||
1433 | return changed; | ||
1434 | } | ||
1435 | |||
1436 | static struct snd_kcontrol_new snd_echo_digital_mode_switch __devinitdata = { | ||
1437 | .name = "Digital mode Switch", | ||
1438 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, | ||
1439 | .info = snd_echo_digital_mode_info, | ||
1440 | .get = snd_echo_digital_mode_get, | ||
1441 | .put = snd_echo_digital_mode_put, | ||
1442 | }; | ||
1443 | |||
1444 | #endif /* ECHOCARD_HAS_DIGITAL_MODE_SWITCH */ | ||
1445 | |||
1446 | |||
1447 | |||
1448 | #ifdef ECHOCARD_HAS_DIGITAL_IO | ||
1449 | |||
1450 | /******************* S/PDIF mode switch *******************/ | ||
1451 | static int snd_echo_spdif_mode_info(struct snd_kcontrol *kcontrol, | ||
1452 | struct snd_ctl_elem_info *uinfo) | ||
1453 | { | ||
1454 | static char *names[2] = {"Consumer", "Professional"}; | ||
1455 | |||
1456 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
1457 | uinfo->value.enumerated.items = 2; | ||
1458 | uinfo->count = 1; | ||
1459 | if (uinfo->value.enumerated.item) | ||
1460 | uinfo->value.enumerated.item = 1; | ||
1461 | strcpy(uinfo->value.enumerated.name, | ||
1462 | names[uinfo->value.enumerated.item]); | ||
1463 | return 0; | ||
1464 | } | ||
1465 | |||
1466 | static int snd_echo_spdif_mode_get(struct snd_kcontrol *kcontrol, | ||
1467 | struct snd_ctl_elem_value *ucontrol) | ||
1468 | { | ||
1469 | struct echoaudio *chip; | ||
1470 | |||
1471 | chip = snd_kcontrol_chip(kcontrol); | ||
1472 | ucontrol->value.enumerated.item[0] = !!chip->professional_spdif; | ||
1473 | return 0; | ||
1474 | } | ||
1475 | |||
1476 | static int snd_echo_spdif_mode_put(struct snd_kcontrol *kcontrol, | ||
1477 | struct snd_ctl_elem_value *ucontrol) | ||
1478 | { | ||
1479 | struct echoaudio *chip; | ||
1480 | int mode; | ||
1481 | |||
1482 | chip = snd_kcontrol_chip(kcontrol); | ||
1483 | mode = !!ucontrol->value.enumerated.item[0]; | ||
1484 | if (mode != chip->professional_spdif) { | ||
1485 | spin_lock_irq(&chip->lock); | ||
1486 | set_professional_spdif(chip, mode); | ||
1487 | spin_unlock_irq(&chip->lock); | ||
1488 | return 1; | ||
1489 | } | ||
1490 | return 0; | ||
1491 | } | ||
1492 | |||
1493 | static struct snd_kcontrol_new snd_echo_spdif_mode_switch __devinitdata = { | ||
1494 | .name = "S/PDIF mode Switch", | ||
1495 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, | ||
1496 | .info = snd_echo_spdif_mode_info, | ||
1497 | .get = snd_echo_spdif_mode_get, | ||
1498 | .put = snd_echo_spdif_mode_put, | ||
1499 | }; | ||
1500 | |||
1501 | #endif /* ECHOCARD_HAS_DIGITAL_IO */ | ||
1502 | |||
1503 | |||
1504 | |||
1505 | #ifdef ECHOCARD_HAS_EXTERNAL_CLOCK | ||
1506 | |||
1507 | /******************* Select input clock source *******************/ | ||
1508 | static int snd_echo_clock_source_info(struct snd_kcontrol *kcontrol, | ||
1509 | struct snd_ctl_elem_info *uinfo) | ||
1510 | { | ||
1511 | static char *names[8] = { | ||
1512 | "Internal", "Word", "Super", "S/PDIF", "ADAT", "ESync", | ||
1513 | "ESync96", "MTC" | ||
1514 | }; | ||
1515 | struct echoaudio *chip; | ||
1516 | |||
1517 | chip = snd_kcontrol_chip(kcontrol); | ||
1518 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
1519 | uinfo->value.enumerated.items = chip->num_clock_sources; | ||
1520 | uinfo->count = 1; | ||
1521 | if (uinfo->value.enumerated.item >= chip->num_clock_sources) | ||
1522 | uinfo->value.enumerated.item = chip->num_clock_sources - 1; | ||
1523 | strcpy(uinfo->value.enumerated.name, names[ | ||
1524 | chip->clock_source_list[uinfo->value.enumerated.item]]); | ||
1525 | return 0; | ||
1526 | } | ||
1527 | |||
1528 | static int snd_echo_clock_source_get(struct snd_kcontrol *kcontrol, | ||
1529 | struct snd_ctl_elem_value *ucontrol) | ||
1530 | { | ||
1531 | struct echoaudio *chip; | ||
1532 | int i, clock; | ||
1533 | |||
1534 | chip = snd_kcontrol_chip(kcontrol); | ||
1535 | clock = chip->input_clock; | ||
1536 | |||
1537 | for (i = 0; i < chip->num_clock_sources; i++) | ||
1538 | if (clock == chip->clock_source_list[i]) | ||
1539 | ucontrol->value.enumerated.item[0] = i; | ||
1540 | |||
1541 | return 0; | ||
1542 | } | ||
1543 | |||
1544 | static int snd_echo_clock_source_put(struct snd_kcontrol *kcontrol, | ||
1545 | struct snd_ctl_elem_value *ucontrol) | ||
1546 | { | ||
1547 | struct echoaudio *chip; | ||
1548 | int changed; | ||
1549 | unsigned int eclock, dclock; | ||
1550 | |||
1551 | changed = 0; | ||
1552 | chip = snd_kcontrol_chip(kcontrol); | ||
1553 | eclock = ucontrol->value.enumerated.item[0]; | ||
1554 | if (eclock >= chip->input_clock_types) | ||
1555 | return -EINVAL; | ||
1556 | dclock = chip->clock_source_list[eclock]; | ||
1557 | if (chip->input_clock != dclock) { | ||
1558 | down(&chip->mode_mutex); | ||
1559 | spin_lock_irq(&chip->lock); | ||
1560 | if ((changed = set_input_clock(chip, dclock)) == 0) | ||
1561 | changed = 1; /* no errors */ | ||
1562 | spin_unlock_irq(&chip->lock); | ||
1563 | up(&chip->mode_mutex); | ||
1564 | } | ||
1565 | |||
1566 | if (changed < 0) | ||
1567 | DE_ACT(("seticlk val%d err 0x%x\n", dclock, changed)); | ||
1568 | |||
1569 | return changed; | ||
1570 | } | ||
1571 | |||
1572 | static struct snd_kcontrol_new snd_echo_clock_source_switch __devinitdata = { | ||
1573 | .name = "Sample Clock Source", | ||
1574 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
1575 | .info = snd_echo_clock_source_info, | ||
1576 | .get = snd_echo_clock_source_get, | ||
1577 | .put = snd_echo_clock_source_put, | ||
1578 | }; | ||
1579 | |||
1580 | #endif /* ECHOCARD_HAS_EXTERNAL_CLOCK */ | ||
1581 | |||
1582 | |||
1583 | |||
1584 | #ifdef ECHOCARD_HAS_PHANTOM_POWER | ||
1585 | |||
1586 | /******************* Phantom power switch *******************/ | ||
1587 | static int snd_echo_phantom_power_info(struct snd_kcontrol *kcontrol, | ||
1588 | struct snd_ctl_elem_info *uinfo) | ||
1589 | { | ||
1590 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
1591 | uinfo->count = 1; | ||
1592 | uinfo->value.integer.min = 0; | ||
1593 | uinfo->value.integer.max = 1; | ||
1594 | return 0; | ||
1595 | } | ||
1596 | |||
1597 | static int snd_echo_phantom_power_get(struct snd_kcontrol *kcontrol, | ||
1598 | struct snd_ctl_elem_value *ucontrol) | ||
1599 | { | ||
1600 | struct echoaudio *chip = snd_kcontrol_chip(kcontrol); | ||
1601 | |||
1602 | ucontrol->value.integer.value[0] = chip->phantom_power; | ||
1603 | return 0; | ||
1604 | } | ||
1605 | |||
1606 | static int snd_echo_phantom_power_put(struct snd_kcontrol *kcontrol, | ||
1607 | struct snd_ctl_elem_value *ucontrol) | ||
1608 | { | ||
1609 | struct echoaudio *chip = snd_kcontrol_chip(kcontrol); | ||
1610 | int power, changed = 0; | ||
1611 | |||
1612 | power = !!ucontrol->value.integer.value[0]; | ||
1613 | if (chip->phantom_power != power) { | ||
1614 | spin_lock_irq(&chip->lock); | ||
1615 | changed = set_phantom_power(chip, power); | ||
1616 | spin_unlock_irq(&chip->lock); | ||
1617 | if (changed == 0) | ||
1618 | changed = 1; /* no errors */ | ||
1619 | } | ||
1620 | return changed; | ||
1621 | } | ||
1622 | |||
1623 | static struct snd_kcontrol_new snd_echo_phantom_power_switch __devinitdata = { | ||
1624 | .name = "Phantom power Switch", | ||
1625 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, | ||
1626 | .info = snd_echo_phantom_power_info, | ||
1627 | .get = snd_echo_phantom_power_get, | ||
1628 | .put = snd_echo_phantom_power_put, | ||
1629 | }; | ||
1630 | |||
1631 | #endif /* ECHOCARD_HAS_PHANTOM_POWER */ | ||
1632 | |||
1633 | |||
1634 | |||
1635 | #ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE | ||
1636 | |||
1637 | /******************* Digital input automute switch *******************/ | ||
1638 | static int snd_echo_automute_info(struct snd_kcontrol *kcontrol, | ||
1639 | struct snd_ctl_elem_info *uinfo) | ||
1640 | { | ||
1641 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
1642 | uinfo->count = 1; | ||
1643 | uinfo->value.integer.min = 0; | ||
1644 | uinfo->value.integer.max = 1; | ||
1645 | return 0; | ||
1646 | } | ||
1647 | |||
1648 | static int snd_echo_automute_get(struct snd_kcontrol *kcontrol, | ||
1649 | struct snd_ctl_elem_value *ucontrol) | ||
1650 | { | ||
1651 | struct echoaudio *chip = snd_kcontrol_chip(kcontrol); | ||
1652 | |||
1653 | ucontrol->value.integer.value[0] = chip->digital_in_automute; | ||
1654 | return 0; | ||
1655 | } | ||
1656 | |||
1657 | static int snd_echo_automute_put(struct snd_kcontrol *kcontrol, | ||
1658 | struct snd_ctl_elem_value *ucontrol) | ||
1659 | { | ||
1660 | struct echoaudio *chip = snd_kcontrol_chip(kcontrol); | ||
1661 | int automute, changed = 0; | ||
1662 | |||
1663 | automute = !!ucontrol->value.integer.value[0]; | ||
1664 | if (chip->digital_in_automute != automute) { | ||
1665 | spin_lock_irq(&chip->lock); | ||
1666 | changed = set_input_auto_mute(chip, automute); | ||
1667 | spin_unlock_irq(&chip->lock); | ||
1668 | if (changed == 0) | ||
1669 | changed = 1; /* no errors */ | ||
1670 | } | ||
1671 | return changed; | ||
1672 | } | ||
1673 | |||
1674 | static struct snd_kcontrol_new snd_echo_automute_switch __devinitdata = { | ||
1675 | .name = "Digital Capture Switch (automute)", | ||
1676 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, | ||
1677 | .info = snd_echo_automute_info, | ||
1678 | .get = snd_echo_automute_get, | ||
1679 | .put = snd_echo_automute_put, | ||
1680 | }; | ||
1681 | |||
1682 | #endif /* ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE */ | ||
1683 | |||
1684 | |||
1685 | |||
1686 | /******************* VU-meters switch *******************/ | ||
1687 | static int snd_echo_vumeters_switch_info(struct snd_kcontrol *kcontrol, | ||
1688 | struct snd_ctl_elem_info *uinfo) | ||
1689 | { | ||
1690 | struct echoaudio *chip; | ||
1691 | |||
1692 | chip = snd_kcontrol_chip(kcontrol); | ||
1693 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
1694 | uinfo->count = 1; | ||
1695 | uinfo->value.integer.min = 0; | ||
1696 | uinfo->value.integer.max = 1; | ||
1697 | return 0; | ||
1698 | } | ||
1699 | |||
1700 | static int snd_echo_vumeters_switch_put(struct snd_kcontrol *kcontrol, | ||
1701 | struct snd_ctl_elem_value *ucontrol) | ||
1702 | { | ||
1703 | struct echoaudio *chip; | ||
1704 | |||
1705 | chip = snd_kcontrol_chip(kcontrol); | ||
1706 | spin_lock_irq(&chip->lock); | ||
1707 | set_meters_on(chip, ucontrol->value.integer.value[0]); | ||
1708 | spin_unlock_irq(&chip->lock); | ||
1709 | return 1; | ||
1710 | } | ||
1711 | |||
1712 | static struct snd_kcontrol_new snd_echo_vumeters_switch __devinitdata = { | ||
1713 | .name = "VU-meters Switch", | ||
1714 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, | ||
1715 | .access = SNDRV_CTL_ELEM_ACCESS_WRITE, | ||
1716 | .info = snd_echo_vumeters_switch_info, | ||
1717 | .put = snd_echo_vumeters_switch_put, | ||
1718 | }; | ||
1719 | |||
1720 | |||
1721 | |||
1722 | /***** Read VU-meters (input, output, analog and digital together) *****/ | ||
1723 | static int snd_echo_vumeters_info(struct snd_kcontrol *kcontrol, | ||
1724 | struct snd_ctl_elem_info *uinfo) | ||
1725 | { | ||
1726 | struct echoaudio *chip; | ||
1727 | |||
1728 | chip = snd_kcontrol_chip(kcontrol); | ||
1729 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1730 | uinfo->count = 96; | ||
1731 | uinfo->value.integer.min = ECHOGAIN_MINOUT; | ||
1732 | uinfo->value.integer.max = 0; | ||
1733 | #ifdef ECHOCARD_HAS_VMIXER | ||
1734 | uinfo->dimen.d[0] = 3; /* Out, In, Virt */ | ||
1735 | #else | ||
1736 | uinfo->dimen.d[0] = 2; /* Out, In */ | ||
1737 | #endif | ||
1738 | uinfo->dimen.d[1] = 16; /* 16 channels */ | ||
1739 | uinfo->dimen.d[2] = 2; /* 0=level, 1=peak */ | ||
1740 | return 0; | ||
1741 | } | ||
1742 | |||
1743 | static int snd_echo_vumeters_get(struct snd_kcontrol *kcontrol, | ||
1744 | struct snd_ctl_elem_value *ucontrol) | ||
1745 | { | ||
1746 | struct echoaudio *chip; | ||
1747 | |||
1748 | chip = snd_kcontrol_chip(kcontrol); | ||
1749 | get_audio_meters(chip, ucontrol->value.integer.value); | ||
1750 | return 0; | ||
1751 | } | ||
1752 | |||
1753 | static struct snd_kcontrol_new snd_echo_vumeters __devinitdata = { | ||
1754 | .name = "VU-meters", | ||
1755 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1756 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | ||
1757 | .info = snd_echo_vumeters_info, | ||
1758 | .get = snd_echo_vumeters_get, | ||
1759 | }; | ||
1760 | |||
1761 | |||
1762 | |||
1763 | /*** Channels info - it exports informations about the number of channels ***/ | ||
1764 | static int snd_echo_channels_info_info(struct snd_kcontrol *kcontrol, | ||
1765 | struct snd_ctl_elem_info *uinfo) | ||
1766 | { | ||
1767 | struct echoaudio *chip; | ||
1768 | |||
1769 | chip = snd_kcontrol_chip(kcontrol); | ||
1770 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1771 | uinfo->count = 6; | ||
1772 | uinfo->value.integer.min = 0; | ||
1773 | uinfo->value.integer.max = 1 << ECHO_CLOCK_NUMBER; | ||
1774 | return 0; | ||
1775 | } | ||
1776 | |||
1777 | static int snd_echo_channels_info_get(struct snd_kcontrol *kcontrol, | ||
1778 | struct snd_ctl_elem_value *ucontrol) | ||
1779 | { | ||
1780 | struct echoaudio *chip; | ||
1781 | int detected, clocks, bit, src; | ||
1782 | |||
1783 | chip = snd_kcontrol_chip(kcontrol); | ||
1784 | ucontrol->value.integer.value[0] = num_busses_in(chip); | ||
1785 | ucontrol->value.integer.value[1] = num_analog_busses_in(chip); | ||
1786 | ucontrol->value.integer.value[2] = num_busses_out(chip); | ||
1787 | ucontrol->value.integer.value[3] = num_analog_busses_out(chip); | ||
1788 | ucontrol->value.integer.value[4] = num_pipes_out(chip); | ||
1789 | |||
1790 | /* Compute the bitmask of the currently valid input clocks */ | ||
1791 | detected = detect_input_clocks(chip); | ||
1792 | clocks = 0; | ||
1793 | src = chip->num_clock_sources - 1; | ||
1794 | for (bit = ECHO_CLOCK_NUMBER - 1; bit >= 0; bit--) | ||
1795 | if (detected & (1 << bit)) | ||
1796 | for (; src >= 0; src--) | ||
1797 | if (bit == chip->clock_source_list[src]) { | ||
1798 | clocks |= 1 << src; | ||
1799 | break; | ||
1800 | } | ||
1801 | ucontrol->value.integer.value[5] = clocks; | ||
1802 | |||
1803 | return 0; | ||
1804 | } | ||
1805 | |||
1806 | static struct snd_kcontrol_new snd_echo_channels_info __devinitdata = { | ||
1807 | .name = "Channels info", | ||
1808 | .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, | ||
1809 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | ||
1810 | .info = snd_echo_channels_info_info, | ||
1811 | .get = snd_echo_channels_info_get, | ||
1812 | }; | ||
1813 | |||
1814 | |||
1815 | |||
1816 | |||
1817 | /****************************************************************************** | ||
1818 | IRQ Handler | ||
1819 | ******************************************************************************/ | ||
1820 | |||
1821 | static irqreturn_t snd_echo_interrupt(int irq, void *dev_id, | ||
1822 | struct pt_regs *regs) | ||
1823 | { | ||
1824 | struct echoaudio *chip = dev_id; | ||
1825 | struct snd_pcm_substream *substream; | ||
1826 | int period, ss, st; | ||
1827 | |||
1828 | spin_lock(&chip->lock); | ||
1829 | st = service_irq(chip); | ||
1830 | if (st < 0) { | ||
1831 | spin_unlock(&chip->lock); | ||
1832 | return IRQ_NONE; | ||
1833 | } | ||
1834 | /* The hardware doesn't tell us which substream caused the irq, | ||
1835 | thus we have to check all running substreams. */ | ||
1836 | for (ss = 0; ss < DSP_MAXPIPES; ss++) { | ||
1837 | if ((substream = chip->substream[ss])) { | ||
1838 | period = pcm_pointer(substream) / | ||
1839 | substream->runtime->period_size; | ||
1840 | if (period != chip->last_period[ss]) { | ||
1841 | chip->last_period[ss] = period; | ||
1842 | spin_unlock(&chip->lock); | ||
1843 | snd_pcm_period_elapsed(substream); | ||
1844 | spin_lock(&chip->lock); | ||
1845 | } | ||
1846 | } | ||
1847 | } | ||
1848 | spin_unlock(&chip->lock); | ||
1849 | |||
1850 | #ifdef ECHOCARD_HAS_MIDI | ||
1851 | if (st > 0 && chip->midi_in) { | ||
1852 | snd_rawmidi_receive(chip->midi_in, chip->midi_buffer, st); | ||
1853 | DE_MID(("rawmidi_iread=%d\n", st)); | ||
1854 | } | ||
1855 | #endif | ||
1856 | return IRQ_HANDLED; | ||
1857 | } | ||
1858 | |||
1859 | |||
1860 | |||
1861 | |||
1862 | /****************************************************************************** | ||
1863 | Module construction / destruction | ||
1864 | ******************************************************************************/ | ||
1865 | |||
1866 | static int snd_echo_free(struct echoaudio *chip) | ||
1867 | { | ||
1868 | DE_INIT(("Stop DSP...\n")); | ||
1869 | if (chip->comm_page) { | ||
1870 | rest_in_peace(chip); | ||
1871 | snd_dma_free_pages(&chip->commpage_dma_buf); | ||
1872 | } | ||
1873 | DE_INIT(("Stopped.\n")); | ||
1874 | |||
1875 | if (chip->irq >= 0) | ||
1876 | free_irq(chip->irq, (void *)chip); | ||
1877 | |||
1878 | if (chip->dsp_registers) | ||
1879 | iounmap(chip->dsp_registers); | ||
1880 | |||
1881 | if (chip->iores) | ||
1882 | release_and_free_resource(chip->iores); | ||
1883 | |||
1884 | DE_INIT(("MMIO freed.\n")); | ||
1885 | |||
1886 | pci_disable_device(chip->pci); | ||
1887 | |||
1888 | /* release chip data */ | ||
1889 | kfree(chip); | ||
1890 | DE_INIT(("Chip freed.\n")); | ||
1891 | return 0; | ||
1892 | } | ||
1893 | |||
1894 | |||
1895 | |||
1896 | static int snd_echo_dev_free(struct snd_device *device) | ||
1897 | { | ||
1898 | struct echoaudio *chip = device->device_data; | ||
1899 | |||
1900 | DE_INIT(("snd_echo_dev_free()...\n")); | ||
1901 | return snd_echo_free(chip); | ||
1902 | } | ||
1903 | |||
1904 | |||
1905 | |||
1906 | /* <--snd_echo_probe() */ | ||
1907 | static __devinit int snd_echo_create(struct snd_card *card, | ||
1908 | struct pci_dev *pci, | ||
1909 | struct echoaudio **rchip) | ||
1910 | { | ||
1911 | struct echoaudio *chip; | ||
1912 | int err; | ||
1913 | size_t sz; | ||
1914 | static struct snd_device_ops ops = { | ||
1915 | .dev_free = snd_echo_dev_free, | ||
1916 | }; | ||
1917 | |||
1918 | *rchip = NULL; | ||
1919 | |||
1920 | pci_write_config_byte(pci, PCI_LATENCY_TIMER, 0xC0); | ||
1921 | |||
1922 | if ((err = pci_enable_device(pci)) < 0) | ||
1923 | return err; | ||
1924 | pci_set_master(pci); | ||
1925 | |||
1926 | /* allocate a chip-specific data */ | ||
1927 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
1928 | if (!chip) { | ||
1929 | pci_disable_device(pci); | ||
1930 | return -ENOMEM; | ||
1931 | } | ||
1932 | DE_INIT(("chip=%p\n", chip)); | ||
1933 | |||
1934 | spin_lock_init(&chip->lock); | ||
1935 | chip->card = card; | ||
1936 | chip->pci = pci; | ||
1937 | chip->irq = -1; | ||
1938 | |||
1939 | /* PCI resource allocation */ | ||
1940 | chip->dsp_registers_phys = pci_resource_start(pci, 0); | ||
1941 | sz = pci_resource_len(pci, 0); | ||
1942 | if (sz > PAGE_SIZE) | ||
1943 | sz = PAGE_SIZE; /* We map only the required part */ | ||
1944 | |||
1945 | if ((chip->iores = request_mem_region(chip->dsp_registers_phys, sz, | ||
1946 | ECHOCARD_NAME)) == NULL) { | ||
1947 | snd_echo_free(chip); | ||
1948 | snd_printk(KERN_ERR "cannot get memory region\n"); | ||
1949 | return -EBUSY; | ||
1950 | } | ||
1951 | chip->dsp_registers = (volatile u32 __iomem *) | ||
1952 | ioremap_nocache(chip->dsp_registers_phys, sz); | ||
1953 | |||
1954 | if (request_irq(pci->irq, snd_echo_interrupt, SA_INTERRUPT | SA_SHIRQ, | ||
1955 | ECHOCARD_NAME, (void *)chip)) { | ||
1956 | snd_echo_free(chip); | ||
1957 | snd_printk(KERN_ERR "cannot grab irq\n"); | ||
1958 | return -EBUSY; | ||
1959 | } | ||
1960 | chip->irq = pci->irq; | ||
1961 | DE_INIT(("pci=%p irq=%d subdev=%04x Init hardware...\n", | ||
1962 | chip->pci, chip->irq, chip->pci->subsystem_device)); | ||
1963 | |||
1964 | /* Create the DSP comm page - this is the area of memory used for most | ||
1965 | of the communication with the DSP, which accesses it via bus mastering */ | ||
1966 | if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), | ||
1967 | sizeof(struct comm_page), | ||
1968 | &chip->commpage_dma_buf) < 0) { | ||
1969 | snd_echo_free(chip); | ||
1970 | snd_printk(KERN_ERR "cannot allocate the comm page\n"); | ||
1971 | return -ENOMEM; | ||
1972 | } | ||
1973 | chip->comm_page_phys = chip->commpage_dma_buf.addr; | ||
1974 | chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area; | ||
1975 | |||
1976 | err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); | ||
1977 | if (err) { | ||
1978 | DE_INIT(("init_hw err=%d\n", err)); | ||
1979 | snd_echo_free(chip); | ||
1980 | return err; | ||
1981 | } | ||
1982 | DE_INIT(("Card init OK\n")); | ||
1983 | |||
1984 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { | ||
1985 | snd_echo_free(chip); | ||
1986 | return err; | ||
1987 | } | ||
1988 | atomic_set(&chip->opencount, 0); | ||
1989 | init_MUTEX(&chip->mode_mutex); | ||
1990 | chip->can_set_rate = 1; | ||
1991 | *rchip = chip; | ||
1992 | /* Init done ! */ | ||
1993 | return 0; | ||
1994 | } | ||
1995 | |||
1996 | |||
1997 | |||
1998 | /* constructor */ | ||
1999 | static int __devinit snd_echo_probe(struct pci_dev *pci, | ||
2000 | const struct pci_device_id *pci_id) | ||
2001 | { | ||
2002 | static int dev; | ||
2003 | struct snd_card *card; | ||
2004 | struct echoaudio *chip; | ||
2005 | char *dsp; | ||
2006 | int i, err; | ||
2007 | |||
2008 | if (dev >= SNDRV_CARDS) | ||
2009 | return -ENODEV; | ||
2010 | if (!enable[dev]) { | ||
2011 | dev++; | ||
2012 | return -ENOENT; | ||
2013 | } | ||
2014 | |||
2015 | DE_INIT(("Echoaudio driver starting...\n")); | ||
2016 | i = 0; | ||
2017 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | ||
2018 | if (card == NULL) | ||
2019 | return -ENOMEM; | ||
2020 | |||
2021 | if ((err = snd_echo_create(card, pci, &chip)) < 0) { | ||
2022 | snd_card_free(card); | ||
2023 | return err; | ||
2024 | } | ||
2025 | |||
2026 | strcpy(card->driver, "Echo_" ECHOCARD_NAME); | ||
2027 | strcpy(card->shortname, chip->card_name); | ||
2028 | |||
2029 | dsp = "56301"; | ||
2030 | if (pci_id->device == 0x3410) | ||
2031 | dsp = "56361"; | ||
2032 | |||
2033 | sprintf(card->longname, "%s rev.%d (DSP%s) at 0x%lx irq %i", | ||
2034 | card->shortname, pci_id->subdevice & 0x000f, dsp, | ||
2035 | chip->dsp_registers_phys, chip->irq); | ||
2036 | |||
2037 | if ((err = snd_echo_new_pcm(chip)) < 0) { | ||
2038 | snd_printk(KERN_ERR "new pcm error %d\n", err); | ||
2039 | snd_card_free(card); | ||
2040 | return err; | ||
2041 | } | ||
2042 | |||
2043 | #ifdef ECHOCARD_HAS_MIDI | ||
2044 | if (chip->has_midi) { /* Some Mia's do not have midi */ | ||
2045 | if ((err = snd_echo_midi_create(card, chip)) < 0) { | ||
2046 | snd_printk(KERN_ERR "new midi error %d\n", err); | ||
2047 | snd_card_free(card); | ||
2048 | return err; | ||
2049 | } | ||
2050 | } | ||
2051 | #endif | ||
2052 | |||
2053 | #ifdef ECHOCARD_HAS_VMIXER | ||
2054 | snd_echo_vmixer.count = num_pipes_out(chip) * num_busses_out(chip); | ||
2055 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_output_gain, chip))) < 0) | ||
2056 | goto ctl_error; | ||
2057 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vmixer, chip))) < 0) | ||
2058 | goto ctl_error; | ||
2059 | #else | ||
2060 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_pcm_output_gain, chip))) < 0) | ||
2061 | goto ctl_error; | ||
2062 | #endif | ||
2063 | |||
2064 | #ifdef ECHOCARD_HAS_INPUT_GAIN | ||
2065 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_input_gain, chip))) < 0) | ||
2066 | goto ctl_error; | ||
2067 | #endif | ||
2068 | |||
2069 | #ifdef ECHOCARD_HAS_INPUT_NOMINAL_LEVEL | ||
2070 | if (!chip->hasnt_input_nominal_level) | ||
2071 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_intput_nominal_level, chip))) < 0) | ||
2072 | goto ctl_error; | ||
2073 | #endif | ||
2074 | |||
2075 | #ifdef ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL | ||
2076 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_output_nominal_level, chip))) < 0) | ||
2077 | goto ctl_error; | ||
2078 | #endif | ||
2079 | |||
2080 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters_switch, chip))) < 0) | ||
2081 | goto ctl_error; | ||
2082 | |||
2083 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters, chip))) < 0) | ||
2084 | goto ctl_error; | ||
2085 | |||
2086 | #ifdef ECHOCARD_HAS_MONITOR | ||
2087 | snd_echo_monitor_mixer.count = num_busses_in(chip) * num_busses_out(chip); | ||
2088 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_monitor_mixer, chip))) < 0) | ||
2089 | goto ctl_error; | ||
2090 | #endif | ||
2091 | |||
2092 | #ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE | ||
2093 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_automute_switch, chip))) < 0) | ||
2094 | goto ctl_error; | ||
2095 | #endif | ||
2096 | |||
2097 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_channels_info, chip))) < 0) | ||
2098 | goto ctl_error; | ||
2099 | |||
2100 | #ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH | ||
2101 | /* Creates a list of available digital modes */ | ||
2102 | chip->num_digital_modes = 0; | ||
2103 | for (i = 0; i < 6; i++) | ||
2104 | if (chip->digital_modes & (1 << i)) | ||
2105 | chip->digital_mode_list[chip->num_digital_modes++] = i; | ||
2106 | |||
2107 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_digital_mode_switch, chip))) < 0) | ||
2108 | goto ctl_error; | ||
2109 | #endif /* ECHOCARD_HAS_DIGITAL_MODE_SWITCH */ | ||
2110 | |||
2111 | #ifdef ECHOCARD_HAS_EXTERNAL_CLOCK | ||
2112 | /* Creates a list of available clock sources */ | ||
2113 | chip->num_clock_sources = 0; | ||
2114 | for (i = 0; i < 10; i++) | ||
2115 | if (chip->input_clock_types & (1 << i)) | ||
2116 | chip->clock_source_list[chip->num_clock_sources++] = i; | ||
2117 | |||
2118 | if (chip->num_clock_sources > 1) { | ||
2119 | chip->clock_src_ctl = snd_ctl_new1(&snd_echo_clock_source_switch, chip); | ||
2120 | if ((err = snd_ctl_add(chip->card, chip->clock_src_ctl)) < 0) | ||
2121 | goto ctl_error; | ||
2122 | } | ||
2123 | #endif /* ECHOCARD_HAS_EXTERNAL_CLOCK */ | ||
2124 | |||
2125 | #ifdef ECHOCARD_HAS_DIGITAL_IO | ||
2126 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_spdif_mode_switch, chip))) < 0) | ||
2127 | goto ctl_error; | ||
2128 | #endif | ||
2129 | |||
2130 | #ifdef ECHOCARD_HAS_PHANTOM_POWER | ||
2131 | if (chip->has_phantom_power) | ||
2132 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_phantom_power_switch, chip))) < 0) | ||
2133 | goto ctl_error; | ||
2134 | #endif | ||
2135 | |||
2136 | if ((err = snd_card_register(card)) < 0) { | ||
2137 | snd_card_free(card); | ||
2138 | goto ctl_error; | ||
2139 | } | ||
2140 | snd_printk(KERN_INFO "Card registered: %s\n", card->longname); | ||
2141 | |||
2142 | pci_set_drvdata(pci, chip); | ||
2143 | dev++; | ||
2144 | return 0; | ||
2145 | |||
2146 | ctl_error: | ||
2147 | snd_printk(KERN_ERR "new control error %d\n", err); | ||
2148 | snd_card_free(card); | ||
2149 | return err; | ||
2150 | } | ||
2151 | |||
2152 | |||
2153 | |||
2154 | static void __devexit snd_echo_remove(struct pci_dev *pci) | ||
2155 | { | ||
2156 | struct echoaudio *chip; | ||
2157 | |||
2158 | chip = pci_get_drvdata(pci); | ||
2159 | if (chip) | ||
2160 | snd_card_free(chip->card); | ||
2161 | pci_set_drvdata(pci, NULL); | ||
2162 | } | ||
2163 | |||
2164 | |||
2165 | |||
2166 | /****************************************************************************** | ||
2167 | Everything starts and ends here | ||
2168 | ******************************************************************************/ | ||
2169 | |||
2170 | /* pci_driver definition */ | ||
2171 | static struct pci_driver driver = { | ||
2172 | .name = "Echoaudio " ECHOCARD_NAME, | ||
2173 | .id_table = snd_echo_ids, | ||
2174 | .probe = snd_echo_probe, | ||
2175 | .remove = __devexit_p(snd_echo_remove), | ||
2176 | }; | ||
2177 | |||
2178 | |||
2179 | |||
2180 | /* initialization of the module */ | ||
2181 | static int __init alsa_card_echo_init(void) | ||
2182 | { | ||
2183 | return pci_register_driver(&driver); | ||
2184 | } | ||
2185 | |||
2186 | |||
2187 | |||
2188 | /* clean up the module */ | ||
2189 | static void __exit alsa_card_echo_exit(void) | ||
2190 | { | ||
2191 | pci_unregister_driver(&driver); | ||
2192 | } | ||
2193 | |||
2194 | |||
2195 | module_init(alsa_card_echo_init) | ||
2196 | module_exit(alsa_card_echo_exit) | ||
diff --git a/sound/pci/echoaudio/echoaudio.h b/sound/pci/echoaudio/echoaudio.h new file mode 100644 index 000000000000..7e88c968e22f --- /dev/null +++ b/sound/pci/echoaudio/echoaudio.h | |||
@@ -0,0 +1,590 @@ | |||
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 | Here's a block diagram of how most of the cards work: | ||
33 | |||
34 | +-----------+ | ||
35 | record | |<-------------------- Inputs | ||
36 | <-------| | | | ||
37 | PCI | Transport | | | ||
38 | bus | engine | \|/ | ||
39 | ------->| | +-------+ | ||
40 | play | |--->|monitor|-------> Outputs | ||
41 | +-----------+ | mixer | | ||
42 | +-------+ | ||
43 | |||
44 | The lines going to and from the PCI bus represent "pipes". A pipe performs | ||
45 | audio transport - moving audio data to and from buffers on the host via | ||
46 | bus mastering. | ||
47 | |||
48 | The inputs and outputs on the right represent input and output "busses." | ||
49 | A bus is a physical, real connection to the outside world. An example | ||
50 | of a bus would be the 1/4" analog connectors on the back of Layla or | ||
51 | an RCA S/PDIF connector. | ||
52 | |||
53 | For most cards, there is a one-to-one correspondence between outputs | ||
54 | and busses; that is, each individual pipe is hard-wired to a single bus. | ||
55 | |||
56 | Cards that work this way are Darla20, Gina20, Layla20, Darla24, Gina24, | ||
57 | Layla24, Mona, and Indigo. | ||
58 | |||
59 | |||
60 | Mia has a feature called "virtual outputs." | ||
61 | |||
62 | |||
63 | +-----------+ | ||
64 | record | |<----------------------------- Inputs | ||
65 | <-------| | | | ||
66 | PCI | Transport | | | ||
67 | bus | engine | \|/ | ||
68 | ------->| | +------+ +-------+ | ||
69 | play | |-->|vmixer|-->|monitor|-------> Outputs | ||
70 | +-----------+ +------+ | mixer | | ||
71 | +-------+ | ||
72 | |||
73 | |||
74 | Obviously, the difference here is the box labeled "vmixer." Vmixer is | ||
75 | short for "virtual output mixer." For Mia, pipes are *not* hard-wired | ||
76 | to a single bus; the vmixer lets you mix any pipe to any bus in any | ||
77 | combination. | ||
78 | |||
79 | Note, however, that the left-hand side of the diagram is unchanged. | ||
80 | Transport works exactly the same way - the difference is in the mixer stage. | ||
81 | |||
82 | |||
83 | Pipes and busses are numbered starting at zero. | ||
84 | |||
85 | |||
86 | |||
87 | Pipe index | ||
88 | ========== | ||
89 | |||
90 | A number of calls in CEchoGals refer to a "pipe index". A pipe index is | ||
91 | a unique number for a pipe that unambiguously refers to a playback or record | ||
92 | pipe. Pipe indices are numbered starting with analog outputs, followed by | ||
93 | digital outputs, then analog inputs, then digital inputs. | ||
94 | |||
95 | Take Gina24 as an example: | ||
96 | |||
97 | Pipe index | ||
98 | |||
99 | 0-7 Analog outputs (0 .. FirstDigitalBusOut-1) | ||
100 | 8-15 Digital outputs (FirstDigitalBusOut .. NumBussesOut-1) | ||
101 | 16-17 Analog inputs | ||
102 | 18-25 Digital inputs | ||
103 | |||
104 | |||
105 | You get the pipe index by calling CEchoGals::OpenAudio; the other transport | ||
106 | functions take the pipe index as a parameter. If you need a pipe index for | ||
107 | some other reason, use the handy Makepipe_index method. | ||
108 | |||
109 | |||
110 | Some calls take a CChannelMask parameter; CChannelMask is a handy way to | ||
111 | group pipe indices. | ||
112 | |||
113 | |||
114 | |||
115 | Digital mode switch | ||
116 | =================== | ||
117 | |||
118 | Some cards (right now, Gina24, Layla24, and Mona) have a Digital Mode Switch | ||
119 | or DMS. Cards with a DMS can be set to one of three mutually exclusive | ||
120 | digital modes: S/PDIF RCA, S/PDIF optical, or ADAT optical. | ||
121 | |||
122 | This may create some confusion since ADAT optical is 8 channels wide and | ||
123 | S/PDIF is only two channels wide. Gina24, Layla24, and Mona handle this | ||
124 | by acting as if they always have 8 digital outs and ins. If you are in | ||
125 | either S/PDIF mode, the last 6 channels don't do anything - data sent | ||
126 | out these channels is thrown away and you will always record zeros. | ||
127 | |||
128 | Note that with Gina24, Layla24, and Mona, sample rates above 50 kHz are | ||
129 | only available if you have the card configured for S/PDIF optical or S/PDIF | ||
130 | RCA. | ||
131 | |||
132 | |||
133 | |||
134 | Double speed mode | ||
135 | ================= | ||
136 | |||
137 | Some of the cards support 88.2 kHz and 96 kHz sampling (Darla24, Gina24, | ||
138 | Layla24, Mona, Mia, and Indigo). For these cards, the driver sometimes has | ||
139 | to worry about "double speed mode"; double speed mode applies whenever the | ||
140 | sampling rate is above 50 kHz. | ||
141 | |||
142 | For instance, Mona and Layla24 support word clock sync. However, they | ||
143 | actually support two different word clock modes - single speed (below | ||
144 | 50 kHz) and double speed (above 50 kHz). The hardware detects if a single | ||
145 | or double speed word clock signal is present; the generic code uses that | ||
146 | information to determine which mode to use. | ||
147 | |||
148 | The generic code takes care of all this for you. | ||
149 | */ | ||
150 | |||
151 | |||
152 | #ifndef _ECHOAUDIO_H_ | ||
153 | #define _ECHOAUDIO_H_ | ||
154 | |||
155 | |||
156 | #define TRUE 1 | ||
157 | #define FALSE 0 | ||
158 | |||
159 | #include "echoaudio_dsp.h" | ||
160 | |||
161 | |||
162 | |||
163 | /*********************************************************************** | ||
164 | |||
165 | PCI configuration space | ||
166 | |||
167 | ***********************************************************************/ | ||
168 | |||
169 | /* | ||
170 | * PCI vendor ID and device IDs for the hardware | ||
171 | */ | ||
172 | #define VENDOR_ID 0x1057 | ||
173 | #define DEVICE_ID_56301 0x1801 | ||
174 | #define DEVICE_ID_56361 0x3410 | ||
175 | #define SUBVENDOR_ID 0xECC0 | ||
176 | |||
177 | |||
178 | /* | ||
179 | * Valid Echo PCI subsystem card IDs | ||
180 | */ | ||
181 | #define DARLA20 0x0010 | ||
182 | #define GINA20 0x0020 | ||
183 | #define LAYLA20 0x0030 | ||
184 | #define DARLA24 0x0040 | ||
185 | #define GINA24 0x0050 | ||
186 | #define LAYLA24 0x0060 | ||
187 | #define MONA 0x0070 | ||
188 | #define MIA 0x0080 | ||
189 | #define INDIGO 0x0090 | ||
190 | #define INDIGO_IO 0x00a0 | ||
191 | #define INDIGO_DJ 0x00b0 | ||
192 | #define ECHO3G 0x0100 | ||
193 | |||
194 | |||
195 | /************************************************************************ | ||
196 | |||
197 | Array sizes and so forth | ||
198 | |||
199 | ***********************************************************************/ | ||
200 | |||
201 | /* | ||
202 | * Sizes | ||
203 | */ | ||
204 | #define ECHO_MAXAUDIOINPUTS 32 /* Max audio input channels */ | ||
205 | #define ECHO_MAXAUDIOOUTPUTS 32 /* Max audio output channels */ | ||
206 | #define ECHO_MAXAUDIOPIPES 32 /* Max number of input and output | ||
207 | * pipes */ | ||
208 | #define E3G_MAX_OUTPUTS 16 | ||
209 | #define ECHO_MAXMIDIJACKS 1 /* Max MIDI ports */ | ||
210 | #define ECHO_MIDI_QUEUE_SZ 512 /* Max MIDI input queue entries */ | ||
211 | #define ECHO_MTC_QUEUE_SZ 32 /* Max MIDI time code input queue | ||
212 | * entries */ | ||
213 | |||
214 | /* | ||
215 | * MIDI activity indicator timeout | ||
216 | */ | ||
217 | #define MIDI_ACTIVITY_TIMEOUT_USEC 200000 | ||
218 | |||
219 | |||
220 | /**************************************************************************** | ||
221 | |||
222 | Clocks | ||
223 | |||
224 | *****************************************************************************/ | ||
225 | |||
226 | /* | ||
227 | * Clock numbers | ||
228 | */ | ||
229 | #define ECHO_CLOCK_INTERNAL 0 | ||
230 | #define ECHO_CLOCK_WORD 1 | ||
231 | #define ECHO_CLOCK_SUPER 2 | ||
232 | #define ECHO_CLOCK_SPDIF 3 | ||
233 | #define ECHO_CLOCK_ADAT 4 | ||
234 | #define ECHO_CLOCK_ESYNC 5 | ||
235 | #define ECHO_CLOCK_ESYNC96 6 | ||
236 | #define ECHO_CLOCK_MTC 7 | ||
237 | #define ECHO_CLOCK_NUMBER 8 | ||
238 | #define ECHO_CLOCKS 0xffff | ||
239 | |||
240 | /* | ||
241 | * Clock bit numbers - used to report capabilities and whatever clocks | ||
242 | * are being detected dynamically. | ||
243 | */ | ||
244 | #define ECHO_CLOCK_BIT_INTERNAL (1 << ECHO_CLOCK_INTERNAL) | ||
245 | #define ECHO_CLOCK_BIT_WORD (1 << ECHO_CLOCK_WORD) | ||
246 | #define ECHO_CLOCK_BIT_SUPER (1 << ECHO_CLOCK_SUPER) | ||
247 | #define ECHO_CLOCK_BIT_SPDIF (1 << ECHO_CLOCK_SPDIF) | ||
248 | #define ECHO_CLOCK_BIT_ADAT (1 << ECHO_CLOCK_ADAT) | ||
249 | #define ECHO_CLOCK_BIT_ESYNC (1 << ECHO_CLOCK_ESYNC) | ||
250 | #define ECHO_CLOCK_BIT_ESYNC96 (1 << ECHO_CLOCK_ESYNC96) | ||
251 | #define ECHO_CLOCK_BIT_MTC (1<<ECHO_CLOCK_MTC) | ||
252 | |||
253 | |||
254 | /*************************************************************************** | ||
255 | |||
256 | Digital modes | ||
257 | |||
258 | ****************************************************************************/ | ||
259 | |||
260 | /* | ||
261 | * Digital modes for Mona, Layla24, and Gina24 | ||
262 | */ | ||
263 | #define DIGITAL_MODE_NONE 0xFF | ||
264 | #define DIGITAL_MODE_SPDIF_RCA 0 | ||
265 | #define DIGITAL_MODE_SPDIF_OPTICAL 1 | ||
266 | #define DIGITAL_MODE_ADAT 2 | ||
267 | #define DIGITAL_MODE_SPDIF_CDROM 3 | ||
268 | #define DIGITAL_MODES 4 | ||
269 | |||
270 | /* | ||
271 | * Digital mode capability masks | ||
272 | */ | ||
273 | #define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA (1 << DIGITAL_MODE_SPDIF_RCA) | ||
274 | #define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL (1 << DIGITAL_MODE_SPDIF_OPTICAL) | ||
275 | #define ECHOCAPS_HAS_DIGITAL_MODE_ADAT (1 << DIGITAL_MODE_ADAT) | ||
276 | #define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_CDROM (1 << DIGITAL_MODE_SPDIF_CDROM) | ||
277 | |||
278 | |||
279 | #define EXT_3GBOX_NC 0x01 /* 3G box not connected */ | ||
280 | #define EXT_3GBOX_NOT_SET 0x02 /* 3G box not detected yet */ | ||
281 | |||
282 | |||
283 | #define ECHOGAIN_MUTED (-128) /* Minimum possible gain */ | ||
284 | #define ECHOGAIN_MINOUT (-128) /* Min output gain (dB) */ | ||
285 | #define ECHOGAIN_MAXOUT (6) /* Max output gain (dB) */ | ||
286 | #define ECHOGAIN_MININP (-50) /* Min input gain (0.5 dB) */ | ||
287 | #define ECHOGAIN_MAXINP (50) /* Max input gain (0.5 dB) */ | ||
288 | |||
289 | #define PIPE_STATE_STOPPED 0 /* Pipe has been reset */ | ||
290 | #define PIPE_STATE_PAUSED 1 /* Pipe has been stopped */ | ||
291 | #define PIPE_STATE_STARTED 2 /* Pipe has been started */ | ||
292 | #define PIPE_STATE_PENDING 3 /* Pipe has pending start */ | ||
293 | |||
294 | |||
295 | /* Debug initialization */ | ||
296 | #ifdef CONFIG_SND_DEBUG | ||
297 | #define DE_INIT(x) snd_printk x | ||
298 | #else | ||
299 | #define DE_INIT(x) | ||
300 | #endif | ||
301 | |||
302 | /* Debug hw_params callbacks */ | ||
303 | #ifdef CONFIG_SND_DEBUG | ||
304 | #define DE_HWP(x) snd_printk x | ||
305 | #else | ||
306 | #define DE_HWP(x) | ||
307 | #endif | ||
308 | |||
309 | /* Debug normal activity (open, start, stop...) */ | ||
310 | #ifdef CONFIG_SND_DEBUG | ||
311 | #define DE_ACT(x) snd_printk x | ||
312 | #else | ||
313 | #define DE_ACT(x) | ||
314 | #endif | ||
315 | |||
316 | /* Debug midi activity */ | ||
317 | #ifdef CONFIG_SND_DEBUG | ||
318 | #define DE_MID(x) snd_printk x | ||
319 | #else | ||
320 | #define DE_MID(x) | ||
321 | #endif | ||
322 | |||
323 | |||
324 | struct audiopipe { | ||
325 | volatile u32 *dma_counter; /* Commpage register that contains | ||
326 | * the current dma position | ||
327 | * (lower 32 bits only) | ||
328 | */ | ||
329 | u32 last_counter; /* The last position, which is used | ||
330 | * to compute... | ||
331 | */ | ||
332 | u32 position; /* ...the number of bytes tranferred | ||
333 | * by the DMA engine, modulo the | ||
334 | * buffer size | ||
335 | */ | ||
336 | short index; /* Index of the first channel or <0 | ||
337 | * if hw is not configured yet | ||
338 | */ | ||
339 | short interleave; | ||
340 | struct snd_dma_buffer sgpage; /* Room for the scatter-gather list */ | ||
341 | struct snd_pcm_hardware hw; | ||
342 | struct snd_pcm_hw_constraint_list constr; | ||
343 | short sglist_head; | ||
344 | char state; /* pipe state */ | ||
345 | }; | ||
346 | |||
347 | |||
348 | struct audioformat { | ||
349 | u8 interleave; /* How the data is arranged in memory: | ||
350 | * mono = 1, stereo = 2, ... | ||
351 | */ | ||
352 | u8 bits_per_sample; /* 8, 16, 24, 32 (24 bits left aligned) */ | ||
353 | char mono_to_stereo; /* Only used if interleave is 1 and | ||
354 | * if this is an output pipe. | ||
355 | */ | ||
356 | char data_are_bigendian; /* 1 = big endian, 0 = little endian */ | ||
357 | }; | ||
358 | |||
359 | |||
360 | struct echoaudio { | ||
361 | spinlock_t lock; | ||
362 | struct snd_pcm_substream *substream[DSP_MAXPIPES]; | ||
363 | int last_period[DSP_MAXPIPES]; | ||
364 | struct semaphore mode_mutex; | ||
365 | u16 num_digital_modes, digital_mode_list[6]; | ||
366 | u16 num_clock_sources, clock_source_list[10]; | ||
367 | atomic_t opencount; | ||
368 | struct snd_kcontrol *clock_src_ctl; | ||
369 | struct snd_pcm *analog_pcm, *digital_pcm; | ||
370 | struct snd_card *card; | ||
371 | const char *card_name; | ||
372 | struct pci_dev *pci; | ||
373 | unsigned long dsp_registers_phys; | ||
374 | struct resource *iores; | ||
375 | struct snd_dma_buffer commpage_dma_buf; | ||
376 | int irq; | ||
377 | #ifdef ECHOCARD_HAS_MIDI | ||
378 | struct snd_rawmidi *rmidi; | ||
379 | struct snd_rawmidi_substream *midi_in, *midi_out; | ||
380 | #endif | ||
381 | struct timer_list timer; | ||
382 | char tinuse; /* Timer in use */ | ||
383 | char midi_full; /* MIDI output buffer is full */ | ||
384 | char can_set_rate; | ||
385 | char rate_set; | ||
386 | |||
387 | /* This stuff is used mainly by the lowlevel code */ | ||
388 | struct comm_page *comm_page; /* Virtual address of the memory | ||
389 | * seen by DSP | ||
390 | */ | ||
391 | u32 pipe_alloc_mask; /* Bitmask of allocated pipes */ | ||
392 | u32 pipe_cyclic_mask; /* Bitmask of pipes with cyclic | ||
393 | * buffers | ||
394 | */ | ||
395 | u32 sample_rate; /* Card sample rate in Hz */ | ||
396 | u8 digital_mode; /* Current digital mode | ||
397 | * (see DIGITAL_MODE_*) | ||
398 | */ | ||
399 | u8 spdif_status; /* Gina20, Darla20, Darla24 - only */ | ||
400 | u8 clock_state; /* Gina20, Darla20, Darla24 - only */ | ||
401 | u8 input_clock; /* Currently selected sample clock | ||
402 | * source | ||
403 | */ | ||
404 | u8 output_clock; /* Layla20 only */ | ||
405 | char meters_enabled; /* VU-meters status */ | ||
406 | char asic_loaded; /* Set TRUE when ASIC loaded */ | ||
407 | char bad_board; /* Set TRUE if DSP won't load */ | ||
408 | char professional_spdif; /* 0 = consumer; 1 = professional */ | ||
409 | char non_audio_spdif; /* 3G - only */ | ||
410 | char digital_in_automute; /* Gina24, Layla24, Mona - only */ | ||
411 | char has_phantom_power; | ||
412 | char hasnt_input_nominal_level; /* Gina3G */ | ||
413 | char phantom_power; /* Gina3G - only */ | ||
414 | char has_midi; | ||
415 | char midi_input_enabled; | ||
416 | |||
417 | #ifdef ECHOCARD_ECHO3G | ||
418 | /* External module -dependent pipe and bus indexes */ | ||
419 | char px_digital_out, px_analog_in, px_digital_in, px_num; | ||
420 | char bx_digital_out, bx_analog_in, bx_digital_in, bx_num; | ||
421 | #endif | ||
422 | |||
423 | char nominal_level[ECHO_MAXAUDIOPIPES]; /* True == -10dBV | ||
424 | * False == +4dBu */ | ||
425 | s8 input_gain[ECHO_MAXAUDIOINPUTS]; /* Input level -50..+50 | ||
426 | * unit is 0.5dB */ | ||
427 | s8 output_gain[ECHO_MAXAUDIOOUTPUTS]; /* Output level -128..+6 dB | ||
428 | * (-128=muted) */ | ||
429 | s8 monitor_gain[ECHO_MAXAUDIOOUTPUTS][ECHO_MAXAUDIOINPUTS]; | ||
430 | /* -128..+6 dB */ | ||
431 | s8 vmixer_gain[ECHO_MAXAUDIOOUTPUTS][ECHO_MAXAUDIOOUTPUTS]; | ||
432 | /* -128..+6 dB */ | ||
433 | |||
434 | u16 digital_modes; /* Bitmask of supported modes | ||
435 | * (see ECHOCAPS_HAS_DIGITAL_MODE_*) */ | ||
436 | u16 input_clock_types; /* Suppoted input clock types */ | ||
437 | u16 output_clock_types; /* Suppoted output clock types - | ||
438 | * Layla20 only */ | ||
439 | u16 device_id, subdevice_id; | ||
440 | u16 *dsp_code; /* Current DSP code loaded, | ||
441 | * NULL if nothing loaded */ | ||
442 | const struct firmware *dsp_code_to_load;/* DSP code to load */ | ||
443 | const struct firmware *asic_code; /* Current ASIC code */ | ||
444 | u32 comm_page_phys; /* Physical address of the | ||
445 | * memory seen by DSP */ | ||
446 | volatile u32 __iomem *dsp_registers; /* DSP's register base */ | ||
447 | u32 active_mask; /* Chs. active mask or | ||
448 | * punks out */ | ||
449 | |||
450 | #ifdef ECHOCARD_HAS_MIDI | ||
451 | u16 mtc_state; /* State for MIDI input parsing state machine */ | ||
452 | u8 midi_buffer[MIDI_IN_BUFFER_SIZE]; | ||
453 | #endif | ||
454 | }; | ||
455 | |||
456 | |||
457 | static int init_dsp_comm_page(struct echoaudio *chip); | ||
458 | static int init_line_levels(struct echoaudio *chip); | ||
459 | static int free_pipes(struct echoaudio *chip, struct audiopipe *pipe); | ||
460 | static int load_firmware(struct echoaudio *chip); | ||
461 | static int wait_handshake(struct echoaudio *chip); | ||
462 | static int send_vector(struct echoaudio *chip, u32 command); | ||
463 | static int get_firmware(const struct firmware **fw_entry, | ||
464 | const struct firmware *frm, struct echoaudio *chip); | ||
465 | static void free_firmware(const struct firmware *fw_entry); | ||
466 | |||
467 | #ifdef ECHOCARD_HAS_MIDI | ||
468 | static int enable_midi_input(struct echoaudio *chip, char enable); | ||
469 | static int midi_service_irq(struct echoaudio *chip); | ||
470 | static int __devinit snd_echo_midi_create(struct snd_card *card, | ||
471 | struct echoaudio *chip); | ||
472 | #endif | ||
473 | |||
474 | |||
475 | static inline void clear_handshake(struct echoaudio *chip) | ||
476 | { | ||
477 | chip->comm_page->handshake = 0; | ||
478 | } | ||
479 | |||
480 | static inline u32 get_dsp_register(struct echoaudio *chip, u32 index) | ||
481 | { | ||
482 | return readl(&chip->dsp_registers[index]); | ||
483 | } | ||
484 | |||
485 | static inline void set_dsp_register(struct echoaudio *chip, u32 index, | ||
486 | u32 value) | ||
487 | { | ||
488 | writel(value, &chip->dsp_registers[index]); | ||
489 | } | ||
490 | |||
491 | |||
492 | /* Pipe and bus indexes. PX_* and BX_* are defined as chip->px_* and chip->bx_* | ||
493 | for 3G cards because they depend on the external box. They are integer | ||
494 | constants for all other cards. | ||
495 | Never use those defines directly, use the following functions instead. */ | ||
496 | |||
497 | static inline int px_digital_out(const struct echoaudio *chip) | ||
498 | { | ||
499 | return PX_DIGITAL_OUT; | ||
500 | } | ||
501 | |||
502 | static inline int px_analog_in(const struct echoaudio *chip) | ||
503 | { | ||
504 | return PX_ANALOG_IN; | ||
505 | } | ||
506 | |||
507 | static inline int px_digital_in(const struct echoaudio *chip) | ||
508 | { | ||
509 | return PX_DIGITAL_IN; | ||
510 | } | ||
511 | |||
512 | static inline int px_num(const struct echoaudio *chip) | ||
513 | { | ||
514 | return PX_NUM; | ||
515 | } | ||
516 | |||
517 | static inline int bx_digital_out(const struct echoaudio *chip) | ||
518 | { | ||
519 | return BX_DIGITAL_OUT; | ||
520 | } | ||
521 | |||
522 | static inline int bx_analog_in(const struct echoaudio *chip) | ||
523 | { | ||
524 | return BX_ANALOG_IN; | ||
525 | } | ||
526 | |||
527 | static inline int bx_digital_in(const struct echoaudio *chip) | ||
528 | { | ||
529 | return BX_DIGITAL_IN; | ||
530 | } | ||
531 | |||
532 | static inline int bx_num(const struct echoaudio *chip) | ||
533 | { | ||
534 | return BX_NUM; | ||
535 | } | ||
536 | |||
537 | static inline int num_pipes_out(const struct echoaudio *chip) | ||
538 | { | ||
539 | return px_analog_in(chip); | ||
540 | } | ||
541 | |||
542 | static inline int num_pipes_in(const struct echoaudio *chip) | ||
543 | { | ||
544 | return px_num(chip) - px_analog_in(chip); | ||
545 | } | ||
546 | |||
547 | static inline int num_busses_out(const struct echoaudio *chip) | ||
548 | { | ||
549 | return bx_analog_in(chip); | ||
550 | } | ||
551 | |||
552 | static inline int num_busses_in(const struct echoaudio *chip) | ||
553 | { | ||
554 | return bx_num(chip) - bx_analog_in(chip); | ||
555 | } | ||
556 | |||
557 | static inline int num_analog_busses_out(const struct echoaudio *chip) | ||
558 | { | ||
559 | return bx_digital_out(chip); | ||
560 | } | ||
561 | |||
562 | static inline int num_analog_busses_in(const struct echoaudio *chip) | ||
563 | { | ||
564 | return bx_digital_in(chip) - bx_analog_in(chip); | ||
565 | } | ||
566 | |||
567 | static inline int num_digital_busses_out(const struct echoaudio *chip) | ||
568 | { | ||
569 | return num_busses_out(chip) - num_analog_busses_out(chip); | ||
570 | } | ||
571 | |||
572 | static inline int num_digital_busses_in(const struct echoaudio *chip) | ||
573 | { | ||
574 | return num_busses_in(chip) - num_analog_busses_in(chip); | ||
575 | } | ||
576 | |||
577 | /* The monitor array is a one-dimensional array; compute the offset | ||
578 | * into the array */ | ||
579 | static inline int monitor_index(const struct echoaudio *chip, int out, int in) | ||
580 | { | ||
581 | return out * num_busses_in(chip) + in; | ||
582 | } | ||
583 | |||
584 | |||
585 | #ifndef pci_device | ||
586 | #define pci_device(chip) (&chip->pci->dev) | ||
587 | #endif | ||
588 | |||
589 | |||
590 | #endif /* _ECHOAUDIO_H_ */ | ||
diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c new file mode 100644 index 000000000000..9f439ea459f4 --- /dev/null +++ b/sound/pci/echoaudio/echoaudio_3g.c | |||
@@ -0,0 +1,431 @@ | |||
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 | |||
36 | static 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 = | ||
44 | __constant_cpu_to_le32(E3G_ASIC_NOT_LOADED); | ||
45 | chip->asic_loaded = FALSE; | ||
46 | clear_handshake(chip); | ||
47 | send_vector(chip, DSP_VC_TEST_ASIC); | ||
48 | |||
49 | if (wait_handshake(chip)) { | ||
50 | chip->dsp_code = NULL; | ||
51 | return -EIO; | ||
52 | } | ||
53 | |||
54 | box_status = le32_to_cpu(chip->comm_page->ext_box_status); | ||
55 | DE_INIT(("box_status=%x\n", box_status)); | ||
56 | if (box_status == E3G_ASIC_NOT_LOADED) | ||
57 | return -ENODEV; | ||
58 | |||
59 | chip->asic_loaded = TRUE; | ||
60 | return box_status & E3G_BOX_TYPE_MASK; | ||
61 | } | ||
62 | |||
63 | |||
64 | |||
65 | static inline u32 get_frq_reg(struct echoaudio *chip) | ||
66 | { | ||
67 | return le32_to_cpu(chip->comm_page->e3g_frq_register); | ||
68 | } | ||
69 | |||
70 | |||
71 | |||
72 | /* Most configuration of 3G cards is accomplished by writing the control | ||
73 | register. write_control_reg sends the new control register value to the DSP. */ | ||
74 | static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, | ||
75 | char force) | ||
76 | { | ||
77 | if (wait_handshake(chip)) | ||
78 | return -EIO; | ||
79 | |||
80 | DE_ACT(("WriteControlReg: Setting 0x%x, 0x%x\n", ctl, frq)); | ||
81 | |||
82 | ctl = cpu_to_le32(ctl); | ||
83 | frq = cpu_to_le32(frq); | ||
84 | |||
85 | if (ctl != chip->comm_page->control_register || | ||
86 | frq != chip->comm_page->e3g_frq_register || force) { | ||
87 | chip->comm_page->e3g_frq_register = frq; | ||
88 | chip->comm_page->control_register = ctl; | ||
89 | clear_handshake(chip); | ||
90 | return send_vector(chip, DSP_VC_WRITE_CONTROL_REG); | ||
91 | } | ||
92 | |||
93 | DE_ACT(("WriteControlReg: not written, no change\n")); | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | |||
98 | |||
99 | /* Set the digital mode - currently for Gina24, Layla24, Mona, 3G */ | ||
100 | static int set_digital_mode(struct echoaudio *chip, u8 mode) | ||
101 | { | ||
102 | u8 previous_mode; | ||
103 | int err, i, o; | ||
104 | |||
105 | /* All audio channels must be closed before changing the digital mode */ | ||
106 | snd_assert(!chip->pipe_alloc_mask, return -EAGAIN); | ||
107 | |||
108 | snd_assert(chip->digital_modes & (1 << mode), return -EINVAL); | ||
109 | |||
110 | previous_mode = chip->digital_mode; | ||
111 | err = dsp_set_digital_mode(chip, mode); | ||
112 | |||
113 | /* If we successfully changed the digital mode from or to ADAT, | ||
114 | * then make sure all output, input and monitor levels are | ||
115 | * updated by the DSP comm object. */ | ||
116 | if (err >= 0 && previous_mode != mode && | ||
117 | (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) { | ||
118 | spin_lock_irq(&chip->lock); | ||
119 | for (o = 0; o < num_busses_out(chip); o++) | ||
120 | for (i = 0; i < num_busses_in(chip); i++) | ||
121 | set_monitor_gain(chip, o, i, | ||
122 | chip->monitor_gain[o][i]); | ||
123 | |||
124 | #ifdef ECHOCARD_HAS_INPUT_GAIN | ||
125 | for (i = 0; i < num_busses_in(chip); i++) | ||
126 | set_input_gain(chip, i, chip->input_gain[i]); | ||
127 | update_input_line_level(chip); | ||
128 | #endif | ||
129 | |||
130 | for (o = 0; o < num_busses_out(chip); o++) | ||
131 | set_output_gain(chip, o, chip->output_gain[o]); | ||
132 | update_output_line_level(chip); | ||
133 | spin_unlock_irq(&chip->lock); | ||
134 | } | ||
135 | |||
136 | return err; | ||
137 | } | ||
138 | |||
139 | |||
140 | |||
141 | static u32 set_spdif_bits(struct echoaudio *chip, u32 control_reg, u32 rate) | ||
142 | { | ||
143 | control_reg &= E3G_SPDIF_FORMAT_CLEAR_MASK; | ||
144 | |||
145 | switch (rate) { | ||
146 | case 32000 : | ||
147 | control_reg |= E3G_SPDIF_SAMPLE_RATE0 | E3G_SPDIF_SAMPLE_RATE1; | ||
148 | break; | ||
149 | case 44100 : | ||
150 | if (chip->professional_spdif) | ||
151 | control_reg |= E3G_SPDIF_SAMPLE_RATE0; | ||
152 | break; | ||
153 | case 48000 : | ||
154 | control_reg |= E3G_SPDIF_SAMPLE_RATE1; | ||
155 | break; | ||
156 | } | ||
157 | |||
158 | if (chip->professional_spdif) | ||
159 | control_reg |= E3G_SPDIF_PRO_MODE; | ||
160 | |||
161 | if (chip->non_audio_spdif) | ||
162 | control_reg |= E3G_SPDIF_NOT_AUDIO; | ||
163 | |||
164 | control_reg |= E3G_SPDIF_24_BIT | E3G_SPDIF_TWO_CHANNEL | | ||
165 | E3G_SPDIF_COPY_PERMIT; | ||
166 | |||
167 | return control_reg; | ||
168 | } | ||
169 | |||
170 | |||
171 | |||
172 | /* Set the S/PDIF output format */ | ||
173 | static int set_professional_spdif(struct echoaudio *chip, char prof) | ||
174 | { | ||
175 | u32 control_reg; | ||
176 | |||
177 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
178 | chip->professional_spdif = prof; | ||
179 | control_reg = set_spdif_bits(chip, control_reg, chip->sample_rate); | ||
180 | return write_control_reg(chip, control_reg, get_frq_reg(chip), 0); | ||
181 | } | ||
182 | |||
183 | |||
184 | |||
185 | /* detect_input_clocks() returns a bitmask consisting of all the input clocks | ||
186 | currently connected to the hardware; this changes as the user connects and | ||
187 | disconnects clock inputs. You should use this information to determine which | ||
188 | clocks the user is allowed to select. */ | ||
189 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
190 | { | ||
191 | u32 clocks_from_dsp, clock_bits; | ||
192 | |||
193 | /* Map the DSP clock detect bits to the generic driver clock | ||
194 | * detect bits */ | ||
195 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
196 | |||
197 | clock_bits = ECHO_CLOCK_BIT_INTERNAL; | ||
198 | |||
199 | if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD) | ||
200 | clock_bits |= ECHO_CLOCK_BIT_WORD; | ||
201 | |||
202 | switch(chip->digital_mode) { | ||
203 | case DIGITAL_MODE_SPDIF_RCA: | ||
204 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
205 | if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF) | ||
206 | clock_bits |= ECHO_CLOCK_BIT_SPDIF; | ||
207 | break; | ||
208 | case DIGITAL_MODE_ADAT: | ||
209 | if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_ADAT) | ||
210 | clock_bits |= ECHO_CLOCK_BIT_ADAT; | ||
211 | break; | ||
212 | } | ||
213 | |||
214 | return clock_bits; | ||
215 | } | ||
216 | |||
217 | |||
218 | |||
219 | static int load_asic(struct echoaudio *chip) | ||
220 | { | ||
221 | int box_type, err; | ||
222 | |||
223 | if (chip->asic_loaded) | ||
224 | return 0; | ||
225 | |||
226 | /* Give the DSP a few milliseconds to settle down */ | ||
227 | mdelay(2); | ||
228 | |||
229 | err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC, | ||
230 | &card_fw[FW_3G_ASIC]); | ||
231 | if (err < 0) | ||
232 | return err; | ||
233 | |||
234 | chip->asic_code = &card_fw[FW_3G_ASIC]; | ||
235 | |||
236 | /* Now give the new ASIC a little time to set up */ | ||
237 | mdelay(2); | ||
238 | /* See if it worked */ | ||
239 | box_type = check_asic_status(chip); | ||
240 | |||
241 | /* Set up the control register if the load succeeded - | ||
242 | * 48 kHz, internal clock, S/PDIF RCA mode */ | ||
243 | if (box_type >= 0) { | ||
244 | err = write_control_reg(chip, E3G_48KHZ, | ||
245 | E3G_FREQ_REG_DEFAULT, TRUE); | ||
246 | if (err < 0) | ||
247 | return err; | ||
248 | } | ||
249 | |||
250 | return box_type; | ||
251 | } | ||
252 | |||
253 | |||
254 | |||
255 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
256 | { | ||
257 | u32 control_reg, clock, base_rate, frq_reg; | ||
258 | |||
259 | /* Only set the clock for internal mode. */ | ||
260 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { | ||
261 | DE_ACT(("set_sample_rate: Cannot set sample rate - " | ||
262 | "clock not set to CLK_CLOCKININTERNAL\n")); | ||
263 | /* Save the rate anyhow */ | ||
264 | chip->comm_page->sample_rate = cpu_to_le32(rate); | ||
265 | chip->sample_rate = rate; | ||
266 | set_input_clock(chip, chip->input_clock); | ||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT, | ||
271 | return -EINVAL); | ||
272 | |||
273 | clock = 0; | ||
274 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
275 | control_reg &= E3G_CLOCK_CLEAR_MASK; | ||
276 | |||
277 | switch (rate) { | ||
278 | case 96000: | ||
279 | clock = E3G_96KHZ; | ||
280 | break; | ||
281 | case 88200: | ||
282 | clock = E3G_88KHZ; | ||
283 | break; | ||
284 | case 48000: | ||
285 | clock = E3G_48KHZ; | ||
286 | break; | ||
287 | case 44100: | ||
288 | clock = E3G_44KHZ; | ||
289 | break; | ||
290 | case 32000: | ||
291 | clock = E3G_32KHZ; | ||
292 | break; | ||
293 | default: | ||
294 | clock = E3G_CONTINUOUS_CLOCK; | ||
295 | if (rate > 50000) | ||
296 | clock |= E3G_DOUBLE_SPEED_MODE; | ||
297 | break; | ||
298 | } | ||
299 | |||
300 | control_reg |= clock; | ||
301 | control_reg = set_spdif_bits(chip, control_reg, rate); | ||
302 | |||
303 | base_rate = rate; | ||
304 | if (base_rate > 50000) | ||
305 | base_rate /= 2; | ||
306 | if (base_rate < 32000) | ||
307 | base_rate = 32000; | ||
308 | |||
309 | frq_reg = E3G_MAGIC_NUMBER / base_rate - 2; | ||
310 | if (frq_reg > E3G_FREQ_REG_MAX) | ||
311 | frq_reg = E3G_FREQ_REG_MAX; | ||
312 | |||
313 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ | ||
314 | chip->sample_rate = rate; | ||
315 | DE_ACT(("SetSampleRate: %d clock %x\n", rate, control_reg)); | ||
316 | |||
317 | /* Tell the DSP about it - DSP reads both control reg & freq reg */ | ||
318 | return write_control_reg(chip, control_reg, frq_reg, 0); | ||
319 | } | ||
320 | |||
321 | |||
322 | |||
323 | /* Set the sample clock source to internal, S/PDIF, ADAT */ | ||
324 | static int set_input_clock(struct echoaudio *chip, u16 clock) | ||
325 | { | ||
326 | u32 control_reg, clocks_from_dsp; | ||
327 | |||
328 | DE_ACT(("set_input_clock:\n")); | ||
329 | |||
330 | /* Mask off the clock select bits */ | ||
331 | control_reg = le32_to_cpu(chip->comm_page->control_register) & | ||
332 | E3G_CLOCK_CLEAR_MASK; | ||
333 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
334 | |||
335 | switch (clock) { | ||
336 | case ECHO_CLOCK_INTERNAL: | ||
337 | DE_ACT(("Set Echo3G clock to INTERNAL\n")); | ||
338 | chip->input_clock = ECHO_CLOCK_INTERNAL; | ||
339 | return set_sample_rate(chip, chip->sample_rate); | ||
340 | case ECHO_CLOCK_SPDIF: | ||
341 | if (chip->digital_mode == DIGITAL_MODE_ADAT) | ||
342 | return -EAGAIN; | ||
343 | DE_ACT(("Set Echo3G clock to SPDIF\n")); | ||
344 | control_reg |= E3G_SPDIF_CLOCK; | ||
345 | if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF96) | ||
346 | control_reg |= E3G_DOUBLE_SPEED_MODE; | ||
347 | else | ||
348 | control_reg &= ~E3G_DOUBLE_SPEED_MODE; | ||
349 | break; | ||
350 | case ECHO_CLOCK_ADAT: | ||
351 | if (chip->digital_mode != DIGITAL_MODE_ADAT) | ||
352 | return -EAGAIN; | ||
353 | DE_ACT(("Set Echo3G clock to ADAT\n")); | ||
354 | control_reg |= E3G_ADAT_CLOCK; | ||
355 | control_reg &= ~E3G_DOUBLE_SPEED_MODE; | ||
356 | break; | ||
357 | case ECHO_CLOCK_WORD: | ||
358 | DE_ACT(("Set Echo3G clock to WORD\n")); | ||
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 | DE_ACT(("Input clock 0x%x not supported for Echo3G\n", clock)); | ||
367 | return -EINVAL; | ||
368 | } | ||
369 | |||
370 | chip->input_clock = clock; | ||
371 | return write_control_reg(chip, control_reg, get_frq_reg(chip), 1); | ||
372 | } | ||
373 | |||
374 | |||
375 | |||
376 | static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | ||
377 | { | ||
378 | u32 control_reg; | ||
379 | int err, incompatible_clock; | ||
380 | |||
381 | /* Set clock to "internal" if it's not compatible with the new mode */ | ||
382 | incompatible_clock = FALSE; | ||
383 | switch (mode) { | ||
384 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
385 | case DIGITAL_MODE_SPDIF_RCA: | ||
386 | if (chip->input_clock == ECHO_CLOCK_ADAT) | ||
387 | incompatible_clock = TRUE; | ||
388 | break; | ||
389 | case DIGITAL_MODE_ADAT: | ||
390 | if (chip->input_clock == ECHO_CLOCK_SPDIF) | ||
391 | incompatible_clock = TRUE; | ||
392 | break; | ||
393 | default: | ||
394 | DE_ACT(("Digital mode not supported: %d\n", mode)); | ||
395 | return -EINVAL; | ||
396 | } | ||
397 | |||
398 | spin_lock_irq(&chip->lock); | ||
399 | |||
400 | if (incompatible_clock) { | ||
401 | chip->sample_rate = 48000; | ||
402 | set_input_clock(chip, ECHO_CLOCK_INTERNAL); | ||
403 | } | ||
404 | |||
405 | /* Clear the current digital mode */ | ||
406 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
407 | control_reg &= E3G_DIGITAL_MODE_CLEAR_MASK; | ||
408 | |||
409 | /* Tweak the control reg */ | ||
410 | switch (mode) { | ||
411 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
412 | control_reg |= E3G_SPDIF_OPTICAL_MODE; | ||
413 | break; | ||
414 | case DIGITAL_MODE_SPDIF_RCA: | ||
415 | /* E3G_SPDIF_OPTICAL_MODE bit cleared */ | ||
416 | break; | ||
417 | case DIGITAL_MODE_ADAT: | ||
418 | control_reg |= E3G_ADAT_MODE; | ||
419 | control_reg &= ~E3G_DOUBLE_SPEED_MODE; /* @@ useless */ | ||
420 | break; | ||
421 | } | ||
422 | |||
423 | err = write_control_reg(chip, control_reg, get_frq_reg(chip), 1); | ||
424 | spin_unlock_irq(&chip->lock); | ||
425 | if (err < 0) | ||
426 | return err; | ||
427 | chip->digital_mode = mode; | ||
428 | |||
429 | DE_ACT(("set_digital_mode(%d)\n", chip->digital_mode)); | ||
430 | return incompatible_clock; | ||
431 | } | ||
diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c new file mode 100644 index 000000000000..42afa837d9b4 --- /dev/null +++ b/sound/pci/echoaudio/echoaudio_dsp.c | |||
@@ -0,0 +1,1125 @@ | |||
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 | #if PAGE_SIZE < 4096 | ||
32 | #error PAGE_SIZE is < 4k | ||
33 | #endif | ||
34 | |||
35 | static int restore_dsp_rettings(struct echoaudio *chip); | ||
36 | |||
37 | |||
38 | /* Some vector commands involve the DSP reading or writing data to and from the | ||
39 | comm page; if you send one of these commands to the DSP, it will complete the | ||
40 | command and then write a non-zero value to the Handshake field in the | ||
41 | comm page. This function waits for the handshake to show up. */ | ||
42 | static int wait_handshake(struct echoaudio *chip) | ||
43 | { | ||
44 | int i; | ||
45 | |||
46 | /* Wait up to 10ms for the handshake from the DSP */ | ||
47 | for (i = 0; i < HANDSHAKE_TIMEOUT; i++) { | ||
48 | /* Look for the handshake value */ | ||
49 | if (chip->comm_page->handshake) { | ||
50 | /*if (i) DE_ACT(("Handshake time: %d\n", i));*/ | ||
51 | return 0; | ||
52 | } | ||
53 | udelay(1); | ||
54 | } | ||
55 | |||
56 | snd_printk(KERN_ERR "wait_handshake(): Timeout waiting for DSP\n"); | ||
57 | return -EBUSY; | ||
58 | } | ||
59 | |||
60 | |||
61 | |||
62 | /* Much of the interaction between the DSP and the driver is done via vector | ||
63 | commands; send_vector writes a vector command to the DSP. Typically, this | ||
64 | causes the DSP to read or write fields in the comm page. | ||
65 | PCI posting is not required thanks to the handshake logic. */ | ||
66 | static int send_vector(struct echoaudio *chip, u32 command) | ||
67 | { | ||
68 | int i; | ||
69 | |||
70 | wmb(); /* Flush all pending writes before sending the command */ | ||
71 | |||
72 | /* Wait up to 100ms for the "vector busy" bit to be off */ | ||
73 | for (i = 0; i < VECTOR_BUSY_TIMEOUT; i++) { | ||
74 | if (!(get_dsp_register(chip, CHI32_VECTOR_REG) & | ||
75 | CHI32_VECTOR_BUSY)) { | ||
76 | set_dsp_register(chip, CHI32_VECTOR_REG, command); | ||
77 | /*if (i) DE_ACT(("send_vector time: %d\n", i));*/ | ||
78 | return 0; | ||
79 | } | ||
80 | udelay(1); | ||
81 | } | ||
82 | |||
83 | DE_ACT((KERN_ERR "timeout on send_vector\n")); | ||
84 | return -EBUSY; | ||
85 | } | ||
86 | |||
87 | |||
88 | |||
89 | /* write_dsp writes a 32-bit value to the DSP; this is used almost | ||
90 | exclusively for loading the DSP. */ | ||
91 | static int write_dsp(struct echoaudio *chip, u32 data) | ||
92 | { | ||
93 | u32 status, i; | ||
94 | |||
95 | for (i = 0; i < 10000000; i++) { /* timeout = 10s */ | ||
96 | status = get_dsp_register(chip, CHI32_STATUS_REG); | ||
97 | if ((status & CHI32_STATUS_HOST_WRITE_EMPTY) != 0) { | ||
98 | set_dsp_register(chip, CHI32_DATA_REG, data); | ||
99 | wmb(); /* write it immediately */ | ||
100 | return 0; | ||
101 | } | ||
102 | udelay(1); | ||
103 | cond_resched(); | ||
104 | } | ||
105 | |||
106 | chip->bad_board = TRUE; /* Set TRUE until DSP re-loaded */ | ||
107 | DE_ACT((KERN_ERR "write_dsp: Set bad_board to TRUE\n")); | ||
108 | return -EIO; | ||
109 | } | ||
110 | |||
111 | |||
112 | |||
113 | /* read_dsp reads a 32-bit value from the DSP; this is used almost | ||
114 | exclusively for loading the DSP and checking the status of the ASIC. */ | ||
115 | static int read_dsp(struct echoaudio *chip, u32 *data) | ||
116 | { | ||
117 | u32 status, i; | ||
118 | |||
119 | for (i = 0; i < READ_DSP_TIMEOUT; i++) { | ||
120 | status = get_dsp_register(chip, CHI32_STATUS_REG); | ||
121 | if ((status & CHI32_STATUS_HOST_READ_FULL) != 0) { | ||
122 | *data = get_dsp_register(chip, CHI32_DATA_REG); | ||
123 | return 0; | ||
124 | } | ||
125 | udelay(1); | ||
126 | cond_resched(); | ||
127 | } | ||
128 | |||
129 | chip->bad_board = TRUE; /* Set TRUE until DSP re-loaded */ | ||
130 | DE_INIT((KERN_ERR "read_dsp: Set bad_board to TRUE\n")); | ||
131 | return -EIO; | ||
132 | } | ||
133 | |||
134 | |||
135 | |||
136 | /**************************************************************************** | ||
137 | Firmware loading functions | ||
138 | ****************************************************************************/ | ||
139 | |||
140 | /* This function is used to read back the serial number from the DSP; | ||
141 | this is triggered by the SET_COMMPAGE_ADDR command. | ||
142 | Only some early Echogals products have serial numbers in the ROM; | ||
143 | the serial number is not used, but you still need to do this as | ||
144 | part of the DSP load process. */ | ||
145 | static int read_sn(struct echoaudio *chip) | ||
146 | { | ||
147 | int i; | ||
148 | u32 sn[6]; | ||
149 | |||
150 | for (i = 0; i < 5; i++) { | ||
151 | if (read_dsp(chip, &sn[i])) { | ||
152 | snd_printk(KERN_ERR "Failed to read serial number\n"); | ||
153 | return -EIO; | ||
154 | } | ||
155 | } | ||
156 | DE_INIT(("Read serial number %08x %08x %08x %08x %08x\n", | ||
157 | sn[0], sn[1], sn[2], sn[3], sn[4])); | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | |||
162 | |||
163 | #ifndef ECHOCARD_HAS_ASIC | ||
164 | /* This card has no ASIC, just return ok */ | ||
165 | static inline int check_asic_status(struct echoaudio *chip) | ||
166 | { | ||
167 | chip->asic_loaded = TRUE; | ||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | #endif /* !ECHOCARD_HAS_ASIC */ | ||
172 | |||
173 | |||
174 | |||
175 | #ifdef ECHOCARD_HAS_ASIC | ||
176 | |||
177 | /* Load ASIC code - done after the DSP is loaded */ | ||
178 | static int load_asic_generic(struct echoaudio *chip, u32 cmd, | ||
179 | const struct firmware *asic) | ||
180 | { | ||
181 | const struct firmware *fw; | ||
182 | int err; | ||
183 | u32 i, size; | ||
184 | u8 *code; | ||
185 | |||
186 | if ((err = get_firmware(&fw, asic, chip)) < 0) { | ||
187 | snd_printk(KERN_WARNING "Firmware not found !\n"); | ||
188 | return err; | ||
189 | } | ||
190 | |||
191 | code = (u8 *)fw->data; | ||
192 | size = fw->size; | ||
193 | |||
194 | /* Send the "Here comes the ASIC" command */ | ||
195 | if (write_dsp(chip, cmd) < 0) | ||
196 | goto la_error; | ||
197 | |||
198 | /* Write length of ASIC file in bytes */ | ||
199 | if (write_dsp(chip, size) < 0) | ||
200 | goto la_error; | ||
201 | |||
202 | for (i = 0; i < size; i++) { | ||
203 | if (write_dsp(chip, code[i]) < 0) | ||
204 | goto la_error; | ||
205 | } | ||
206 | |||
207 | DE_INIT(("ASIC loaded\n")); | ||
208 | free_firmware(fw); | ||
209 | return 0; | ||
210 | |||
211 | la_error: | ||
212 | DE_INIT(("failed on write_dsp\n")); | ||
213 | free_firmware(fw); | ||
214 | return -EIO; | ||
215 | } | ||
216 | |||
217 | #endif /* ECHOCARD_HAS_ASIC */ | ||
218 | |||
219 | |||
220 | |||
221 | #ifdef DSP_56361 | ||
222 | |||
223 | /* Install the resident loader for 56361 DSPs; The resident loader is on | ||
224 | the EPROM on the board for 56301 DSP. The resident loader is a tiny little | ||
225 | program that is used to load the real DSP code. */ | ||
226 | static int install_resident_loader(struct echoaudio *chip) | ||
227 | { | ||
228 | u32 address; | ||
229 | int index, words, i; | ||
230 | u16 *code; | ||
231 | u32 status; | ||
232 | const struct firmware *fw; | ||
233 | |||
234 | /* 56361 cards only! This check is required by the old 56301-based | ||
235 | Mona and Gina24 */ | ||
236 | if (chip->device_id != DEVICE_ID_56361) | ||
237 | return 0; | ||
238 | |||
239 | /* Look to see if the resident loader is present. If the resident | ||
240 | loader is already installed, host flag 5 will be on. */ | ||
241 | status = get_dsp_register(chip, CHI32_STATUS_REG); | ||
242 | if (status & CHI32_STATUS_REG_HF5) { | ||
243 | DE_INIT(("Resident loader already installed; status is 0x%x\n", | ||
244 | status)); | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | if ((i = get_firmware(&fw, &card_fw[FW_361_LOADER], chip)) < 0) { | ||
249 | snd_printk(KERN_WARNING "Firmware not found !\n"); | ||
250 | return i; | ||
251 | } | ||
252 | |||
253 | /* The DSP code is an array of 16 bit words. The array is divided up | ||
254 | into sections. The first word of each section is the size in words, | ||
255 | followed by the section type. | ||
256 | Since DSP addresses and data are 24 bits wide, they each take up two | ||
257 | 16 bit words in the array. | ||
258 | This is a lot like the other loader loop, but it's not a loop, you | ||
259 | don't write the memory type, and you don't write a zero at the end. */ | ||
260 | |||
261 | /* Set DSP format bits for 24 bit mode */ | ||
262 | set_dsp_register(chip, CHI32_CONTROL_REG, | ||
263 | get_dsp_register(chip, CHI32_CONTROL_REG) | 0x900); | ||
264 | |||
265 | code = (u16 *)fw->data; | ||
266 | |||
267 | /* Skip the header section; the first word in the array is the size | ||
268 | of the first section, so the first real section of code is pointed | ||
269 | to by Code[0]. */ | ||
270 | index = code[0]; | ||
271 | |||
272 | /* Skip the section size, LRS block type, and DSP memory type */ | ||
273 | index += 3; | ||
274 | |||
275 | /* Get the number of DSP words to write */ | ||
276 | words = code[index++]; | ||
277 | |||
278 | /* Get the DSP address for this block; 24 bits, so build from two words */ | ||
279 | address = ((u32)code[index] << 16) + code[index + 1]; | ||
280 | index += 2; | ||
281 | |||
282 | /* Write the count to the DSP */ | ||
283 | if (write_dsp(chip, words)) { | ||
284 | DE_INIT(("install_resident_loader: Failed to write word count!\n")); | ||
285 | goto irl_error; | ||
286 | } | ||
287 | /* Write the DSP address */ | ||
288 | if (write_dsp(chip, address)) { | ||
289 | DE_INIT(("install_resident_loader: Failed to write DSP address!\n")); | ||
290 | goto irl_error; | ||
291 | } | ||
292 | /* Write out this block of code to the DSP */ | ||
293 | for (i = 0; i < words; i++) { | ||
294 | u32 data; | ||
295 | |||
296 | data = ((u32)code[index] << 16) + code[index + 1]; | ||
297 | if (write_dsp(chip, data)) { | ||
298 | DE_INIT(("install_resident_loader: Failed to write DSP code\n")); | ||
299 | goto irl_error; | ||
300 | } | ||
301 | index += 2; | ||
302 | } | ||
303 | |||
304 | /* Wait for flag 5 to come up */ | ||
305 | for (i = 0; i < 200; i++) { /* Timeout is 50us * 200 = 10ms */ | ||
306 | udelay(50); | ||
307 | status = get_dsp_register(chip, CHI32_STATUS_REG); | ||
308 | if (status & CHI32_STATUS_REG_HF5) | ||
309 | break; | ||
310 | } | ||
311 | |||
312 | if (i == 200) { | ||
313 | DE_INIT(("Resident loader failed to set HF5\n")); | ||
314 | goto irl_error; | ||
315 | } | ||
316 | |||
317 | DE_INIT(("Resident loader successfully installed\n")); | ||
318 | free_firmware(fw); | ||
319 | return 0; | ||
320 | |||
321 | irl_error: | ||
322 | free_firmware(fw); | ||
323 | return -EIO; | ||
324 | } | ||
325 | |||
326 | #endif /* DSP_56361 */ | ||
327 | |||
328 | |||
329 | static int load_dsp(struct echoaudio *chip, u16 *code) | ||
330 | { | ||
331 | u32 address, data; | ||
332 | int index, words, i; | ||
333 | |||
334 | if (chip->dsp_code == code) { | ||
335 | DE_INIT(("DSP is already loaded!\n")); | ||
336 | return 0; | ||
337 | } | ||
338 | chip->bad_board = TRUE; /* Set TRUE until DSP loaded */ | ||
339 | chip->dsp_code = NULL; /* Current DSP code not loaded */ | ||
340 | chip->asic_loaded = FALSE; /* Loading the DSP code will reset the ASIC */ | ||
341 | |||
342 | DE_INIT(("load_dsp: Set bad_board to TRUE\n")); | ||
343 | |||
344 | /* If this board requires a resident loader, install it. */ | ||
345 | #ifdef DSP_56361 | ||
346 | if ((i = install_resident_loader(chip)) < 0) | ||
347 | return i; | ||
348 | #endif | ||
349 | |||
350 | /* Send software reset command */ | ||
351 | if (send_vector(chip, DSP_VC_RESET) < 0) { | ||
352 | DE_INIT(("LoadDsp: send_vector DSP_VC_RESET failed, Critical Failure\n")); | ||
353 | return -EIO; | ||
354 | } | ||
355 | /* Delay 10us */ | ||
356 | udelay(10); | ||
357 | |||
358 | /* Wait 10ms for HF3 to indicate that software reset is complete */ | ||
359 | for (i = 0; i < 1000; i++) { /* Timeout is 10us * 1000 = 10ms */ | ||
360 | if (get_dsp_register(chip, CHI32_STATUS_REG) & | ||
361 | CHI32_STATUS_REG_HF3) | ||
362 | break; | ||
363 | udelay(10); | ||
364 | } | ||
365 | |||
366 | if (i == 1000) { | ||
367 | DE_INIT(("load_dsp: Timeout waiting for CHI32_STATUS_REG_HF3\n")); | ||
368 | return -EIO; | ||
369 | } | ||
370 | |||
371 | /* Set DSP format bits for 24 bit mode now that soft reset is done */ | ||
372 | set_dsp_register(chip, CHI32_CONTROL_REG, | ||
373 | get_dsp_register(chip, CHI32_CONTROL_REG) | 0x900); | ||
374 | |||
375 | /* Main loader loop */ | ||
376 | |||
377 | index = code[0]; | ||
378 | for (;;) { | ||
379 | int block_type, mem_type; | ||
380 | |||
381 | /* Total Block Size */ | ||
382 | index++; | ||
383 | |||
384 | /* Block Type */ | ||
385 | block_type = code[index]; | ||
386 | if (block_type == 4) /* We're finished */ | ||
387 | break; | ||
388 | |||
389 | index++; | ||
390 | |||
391 | /* Memory Type P=0,X=1,Y=2 */ | ||
392 | mem_type = code[index++]; | ||
393 | |||
394 | /* Block Code Size */ | ||
395 | words = code[index++]; | ||
396 | if (words == 0) /* We're finished */ | ||
397 | break; | ||
398 | |||
399 | /* Start Address */ | ||
400 | address = ((u32)code[index] << 16) + code[index + 1]; | ||
401 | index += 2; | ||
402 | |||
403 | if (write_dsp(chip, words) < 0) { | ||
404 | DE_INIT(("load_dsp: failed to write number of DSP words\n")); | ||
405 | return -EIO; | ||
406 | } | ||
407 | if (write_dsp(chip, address) < 0) { | ||
408 | DE_INIT(("load_dsp: failed to write DSP address\n")); | ||
409 | return -EIO; | ||
410 | } | ||
411 | if (write_dsp(chip, mem_type) < 0) { | ||
412 | DE_INIT(("load_dsp: failed to write DSP memory type\n")); | ||
413 | return -EIO; | ||
414 | } | ||
415 | /* Code */ | ||
416 | for (i = 0; i < words; i++, index+=2) { | ||
417 | data = ((u32)code[index] << 16) + code[index + 1]; | ||
418 | if (write_dsp(chip, data) < 0) { | ||
419 | DE_INIT(("load_dsp: failed to write DSP data\n")); | ||
420 | return -EIO; | ||
421 | } | ||
422 | } | ||
423 | } | ||
424 | |||
425 | if (write_dsp(chip, 0) < 0) { /* We're done!!! */ | ||
426 | DE_INIT(("load_dsp: Failed to write final zero\n")); | ||
427 | return -EIO; | ||
428 | } | ||
429 | udelay(10); | ||
430 | |||
431 | for (i = 0; i < 5000; i++) { /* Timeout is 100us * 5000 = 500ms */ | ||
432 | /* Wait for flag 4 - indicates that the DSP loaded OK */ | ||
433 | if (get_dsp_register(chip, CHI32_STATUS_REG) & | ||
434 | CHI32_STATUS_REG_HF4) { | ||
435 | set_dsp_register(chip, CHI32_CONTROL_REG, | ||
436 | get_dsp_register(chip, CHI32_CONTROL_REG) & ~0x1b00); | ||
437 | |||
438 | if (write_dsp(chip, DSP_FNC_SET_COMMPAGE_ADDR) < 0) { | ||
439 | DE_INIT(("load_dsp: Failed to write DSP_FNC_SET_COMMPAGE_ADDR\n")); | ||
440 | return -EIO; | ||
441 | } | ||
442 | |||
443 | if (write_dsp(chip, chip->comm_page_phys) < 0) { | ||
444 | DE_INIT(("load_dsp: Failed to write comm page address\n")); | ||
445 | return -EIO; | ||
446 | } | ||
447 | |||
448 | /* Get the serial number via slave mode. | ||
449 | This is triggered by the SET_COMMPAGE_ADDR command. | ||
450 | We don't actually use the serial number but we have to | ||
451 | get it as part of the DSP init voodoo. */ | ||
452 | if (read_sn(chip) < 0) { | ||
453 | DE_INIT(("load_dsp: Failed to read serial number\n")); | ||
454 | return -EIO; | ||
455 | } | ||
456 | |||
457 | chip->dsp_code = code; /* Show which DSP code loaded */ | ||
458 | chip->bad_board = FALSE; /* DSP OK */ | ||
459 | DE_INIT(("load_dsp: OK!\n")); | ||
460 | return 0; | ||
461 | } | ||
462 | udelay(100); | ||
463 | } | ||
464 | |||
465 | DE_INIT(("load_dsp: DSP load timed out waiting for HF4\n")); | ||
466 | return -EIO; | ||
467 | } | ||
468 | |||
469 | |||
470 | |||
471 | /* load_firmware takes care of loading the DSP and any ASIC code. */ | ||
472 | static int load_firmware(struct echoaudio *chip) | ||
473 | { | ||
474 | const struct firmware *fw; | ||
475 | int box_type, err; | ||
476 | |||
477 | snd_assert(chip->dsp_code_to_load && chip->comm_page, return -EPERM); | ||
478 | |||
479 | /* See if the ASIC is present and working - only if the DSP is already loaded */ | ||
480 | if (chip->dsp_code) { | ||
481 | if ((box_type = check_asic_status(chip)) >= 0) | ||
482 | return box_type; | ||
483 | /* ASIC check failed; force the DSP to reload */ | ||
484 | chip->dsp_code = NULL; | ||
485 | } | ||
486 | |||
487 | if ((err = get_firmware(&fw, chip->dsp_code_to_load, chip)) < 0) | ||
488 | return err; | ||
489 | err = load_dsp(chip, (u16 *)fw->data); | ||
490 | free_firmware(fw); | ||
491 | if (err < 0) | ||
492 | return err; | ||
493 | |||
494 | if ((box_type = load_asic(chip)) < 0) | ||
495 | return box_type; /* error */ | ||
496 | |||
497 | if ((err = restore_dsp_rettings(chip)) < 0) | ||
498 | return err; | ||
499 | |||
500 | return box_type; | ||
501 | } | ||
502 | |||
503 | |||
504 | |||
505 | /**************************************************************************** | ||
506 | Mixer functions | ||
507 | ****************************************************************************/ | ||
508 | |||
509 | #if defined(ECHOCARD_HAS_INPUT_NOMINAL_LEVEL) || \ | ||
510 | defined(ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL) | ||
511 | |||
512 | /* Set the nominal level for an input or output bus (true = -10dBV, false = +4dBu) */ | ||
513 | static int set_nominal_level(struct echoaudio *chip, u16 index, char consumer) | ||
514 | { | ||
515 | snd_assert(index < num_busses_out(chip) + num_busses_in(chip), | ||
516 | return -EINVAL); | ||
517 | |||
518 | /* Wait for the handshake (OK even if ASIC is not loaded) */ | ||
519 | if (wait_handshake(chip)) | ||
520 | return -EIO; | ||
521 | |||
522 | chip->nominal_level[index] = consumer; | ||
523 | |||
524 | if (consumer) | ||
525 | chip->comm_page->nominal_level_mask |= cpu_to_le32(1 << index); | ||
526 | else | ||
527 | chip->comm_page->nominal_level_mask &= ~cpu_to_le32(1 << index); | ||
528 | |||
529 | return 0; | ||
530 | } | ||
531 | |||
532 | #endif /* ECHOCARD_HAS_*_NOMINAL_LEVEL */ | ||
533 | |||
534 | |||
535 | |||
536 | /* Set the gain for a single physical output channel (dB). */ | ||
537 | static int set_output_gain(struct echoaudio *chip, u16 channel, s8 gain) | ||
538 | { | ||
539 | snd_assert(channel < num_busses_out(chip), return -EINVAL); | ||
540 | |||
541 | if (wait_handshake(chip)) | ||
542 | return -EIO; | ||
543 | |||
544 | /* Save the new value */ | ||
545 | chip->output_gain[channel] = gain; | ||
546 | chip->comm_page->line_out_level[channel] = gain; | ||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | |||
551 | |||
552 | #ifdef ECHOCARD_HAS_MONITOR | ||
553 | /* Set the monitor level from an input bus to an output bus. */ | ||
554 | static int set_monitor_gain(struct echoaudio *chip, u16 output, u16 input, | ||
555 | s8 gain) | ||
556 | { | ||
557 | snd_assert(output < num_busses_out(chip) && | ||
558 | input < num_busses_in(chip), return -EINVAL); | ||
559 | |||
560 | if (wait_handshake(chip)) | ||
561 | return -EIO; | ||
562 | |||
563 | chip->monitor_gain[output][input] = gain; | ||
564 | chip->comm_page->monitors[monitor_index(chip, output, input)] = gain; | ||
565 | return 0; | ||
566 | } | ||
567 | #endif /* ECHOCARD_HAS_MONITOR */ | ||
568 | |||
569 | |||
570 | /* Tell the DSP to read and update output, nominal & monitor levels in comm page. */ | ||
571 | static int update_output_line_level(struct echoaudio *chip) | ||
572 | { | ||
573 | if (wait_handshake(chip)) | ||
574 | return -EIO; | ||
575 | clear_handshake(chip); | ||
576 | return send_vector(chip, DSP_VC_UPDATE_OUTVOL); | ||
577 | } | ||
578 | |||
579 | |||
580 | |||
581 | /* Tell the DSP to read and update input levels in comm page */ | ||
582 | static int update_input_line_level(struct echoaudio *chip) | ||
583 | { | ||
584 | if (wait_handshake(chip)) | ||
585 | return -EIO; | ||
586 | clear_handshake(chip); | ||
587 | return send_vector(chip, DSP_VC_UPDATE_INGAIN); | ||
588 | } | ||
589 | |||
590 | |||
591 | |||
592 | /* set_meters_on turns the meters on or off. If meters are turned on, the DSP | ||
593 | will write the meter and clock detect values to the comm page at about 30Hz */ | ||
594 | static void set_meters_on(struct echoaudio *chip, char on) | ||
595 | { | ||
596 | if (on && !chip->meters_enabled) { | ||
597 | send_vector(chip, DSP_VC_METERS_ON); | ||
598 | chip->meters_enabled = 1; | ||
599 | } else if (!on && chip->meters_enabled) { | ||
600 | send_vector(chip, DSP_VC_METERS_OFF); | ||
601 | chip->meters_enabled = 0; | ||
602 | memset((s8 *)chip->comm_page->vu_meter, ECHOGAIN_MUTED, | ||
603 | DSP_MAXPIPES); | ||
604 | memset((s8 *)chip->comm_page->peak_meter, ECHOGAIN_MUTED, | ||
605 | DSP_MAXPIPES); | ||
606 | } | ||
607 | } | ||
608 | |||
609 | |||
610 | |||
611 | /* Fill out an the given array using the current values in the comm page. | ||
612 | Meters are written in the comm page by the DSP in this order: | ||
613 | Output busses | ||
614 | Input busses | ||
615 | Output pipes (vmixer cards only) | ||
616 | |||
617 | This function assumes there are no more than 16 in/out busses or pipes | ||
618 | Meters is an array [3][16][2] of long. */ | ||
619 | static void get_audio_meters(struct echoaudio *chip, long *meters) | ||
620 | { | ||
621 | int i, m, n; | ||
622 | |||
623 | m = 0; | ||
624 | n = 0; | ||
625 | for (i = 0; i < num_busses_out(chip); i++, m++) { | ||
626 | meters[n++] = chip->comm_page->vu_meter[m]; | ||
627 | meters[n++] = chip->comm_page->peak_meter[m]; | ||
628 | } | ||
629 | for (; n < 32; n++) | ||
630 | meters[n] = 0; | ||
631 | |||
632 | #ifdef ECHOCARD_ECHO3G | ||
633 | m = E3G_MAX_OUTPUTS; /* Skip unused meters */ | ||
634 | #endif | ||
635 | |||
636 | for (i = 0; i < num_busses_in(chip); i++, m++) { | ||
637 | meters[n++] = chip->comm_page->vu_meter[m]; | ||
638 | meters[n++] = chip->comm_page->peak_meter[m]; | ||
639 | } | ||
640 | for (; n < 64; n++) | ||
641 | meters[n] = 0; | ||
642 | |||
643 | #ifdef ECHOCARD_HAS_VMIXER | ||
644 | for (i = 0; i < num_pipes_out(chip); i++, m++) { | ||
645 | meters[n++] = chip->comm_page->vu_meter[m]; | ||
646 | meters[n++] = chip->comm_page->peak_meter[m]; | ||
647 | } | ||
648 | #endif | ||
649 | for (; n < 96; n++) | ||
650 | meters[n] = 0; | ||
651 | } | ||
652 | |||
653 | |||
654 | |||
655 | static int restore_dsp_rettings(struct echoaudio *chip) | ||
656 | { | ||
657 | int err; | ||
658 | DE_INIT(("restore_dsp_settings\n")); | ||
659 | |||
660 | if ((err = check_asic_status(chip)) < 0) | ||
661 | return err; | ||
662 | |||
663 | /* @ Gina20/Darla20 only. Should be harmless for other cards. */ | ||
664 | chip->comm_page->gd_clock_state = GD_CLOCK_UNDEF; | ||
665 | chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_UNDEF; | ||
666 | chip->comm_page->handshake = 0xffffffff; | ||
667 | |||
668 | if ((err = set_sample_rate(chip, chip->sample_rate)) < 0) | ||
669 | return err; | ||
670 | |||
671 | if (chip->meters_enabled) | ||
672 | if (send_vector(chip, DSP_VC_METERS_ON) < 0) | ||
673 | return -EIO; | ||
674 | |||
675 | #ifdef ECHOCARD_HAS_EXTERNAL_CLOCK | ||
676 | if (set_input_clock(chip, chip->input_clock) < 0) | ||
677 | return -EIO; | ||
678 | #endif | ||
679 | |||
680 | #ifdef ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH | ||
681 | if (set_output_clock(chip, chip->output_clock) < 0) | ||
682 | return -EIO; | ||
683 | #endif | ||
684 | |||
685 | if (update_output_line_level(chip) < 0) | ||
686 | return -EIO; | ||
687 | |||
688 | if (update_input_line_level(chip) < 0) | ||
689 | return -EIO; | ||
690 | |||
691 | #ifdef ECHOCARD_HAS_VMIXER | ||
692 | if (update_vmixer_level(chip) < 0) | ||
693 | return -EIO; | ||
694 | #endif | ||
695 | |||
696 | if (wait_handshake(chip) < 0) | ||
697 | return -EIO; | ||
698 | clear_handshake(chip); | ||
699 | |||
700 | DE_INIT(("restore_dsp_rettings done\n")); | ||
701 | return send_vector(chip, DSP_VC_UPDATE_FLAGS); | ||
702 | } | ||
703 | |||
704 | |||
705 | |||
706 | /**************************************************************************** | ||
707 | Transport functions | ||
708 | ****************************************************************************/ | ||
709 | |||
710 | /* set_audio_format() sets the format of the audio data in host memory for | ||
711 | this pipe. Note that _MS_ (mono-to-stereo) playback modes are not used by ALSA | ||
712 | but they are here because they are just mono while capturing */ | ||
713 | static void set_audio_format(struct echoaudio *chip, u16 pipe_index, | ||
714 | const struct audioformat *format) | ||
715 | { | ||
716 | u16 dsp_format; | ||
717 | |||
718 | dsp_format = DSP_AUDIOFORM_SS_16LE; | ||
719 | |||
720 | /* Look for super-interleave (no big-endian and 8 bits) */ | ||
721 | if (format->interleave > 2) { | ||
722 | switch (format->bits_per_sample) { | ||
723 | case 16: | ||
724 | dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_16LE; | ||
725 | break; | ||
726 | case 24: | ||
727 | dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_24LE; | ||
728 | break; | ||
729 | case 32: | ||
730 | dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_32LE; | ||
731 | break; | ||
732 | } | ||
733 | dsp_format |= format->interleave; | ||
734 | } else if (format->data_are_bigendian) { | ||
735 | /* For big-endian data, only 32 bit samples are supported */ | ||
736 | switch (format->interleave) { | ||
737 | case 1: | ||
738 | dsp_format = DSP_AUDIOFORM_MM_32BE; | ||
739 | break; | ||
740 | #ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
741 | case 2: | ||
742 | dsp_format = DSP_AUDIOFORM_SS_32BE; | ||
743 | break; | ||
744 | #endif | ||
745 | } | ||
746 | } else if (format->interleave == 1 && | ||
747 | format->bits_per_sample == 32 && !format->mono_to_stereo) { | ||
748 | /* 32 bit little-endian mono->mono case */ | ||
749 | dsp_format = DSP_AUDIOFORM_MM_32LE; | ||
750 | } else { | ||
751 | /* Handle the other little-endian formats */ | ||
752 | switch (format->bits_per_sample) { | ||
753 | case 8: | ||
754 | if (format->interleave == 2) | ||
755 | dsp_format = DSP_AUDIOFORM_SS_8; | ||
756 | else | ||
757 | dsp_format = DSP_AUDIOFORM_MS_8; | ||
758 | break; | ||
759 | default: | ||
760 | case 16: | ||
761 | if (format->interleave == 2) | ||
762 | dsp_format = DSP_AUDIOFORM_SS_16LE; | ||
763 | else | ||
764 | dsp_format = DSP_AUDIOFORM_MS_16LE; | ||
765 | break; | ||
766 | case 24: | ||
767 | if (format->interleave == 2) | ||
768 | dsp_format = DSP_AUDIOFORM_SS_24LE; | ||
769 | else | ||
770 | dsp_format = DSP_AUDIOFORM_MS_24LE; | ||
771 | break; | ||
772 | case 32: | ||
773 | if (format->interleave == 2) | ||
774 | dsp_format = DSP_AUDIOFORM_SS_32LE; | ||
775 | else | ||
776 | dsp_format = DSP_AUDIOFORM_MS_32LE; | ||
777 | break; | ||
778 | } | ||
779 | } | ||
780 | DE_ACT(("set_audio_format[%d] = %x\n", pipe_index, dsp_format)); | ||
781 | chip->comm_page->audio_format[pipe_index] = cpu_to_le16(dsp_format); | ||
782 | } | ||
783 | |||
784 | |||
785 | |||
786 | /* start_transport starts transport for a set of pipes. | ||
787 | The bits 1 in channel_mask specify what pipes to start. Only the bit of the | ||
788 | first channel must be set, regardless its interleave. | ||
789 | Same thing for pause_ and stop_ -trasport below. */ | ||
790 | static int start_transport(struct echoaudio *chip, u32 channel_mask, | ||
791 | u32 cyclic_mask) | ||
792 | { | ||
793 | DE_ACT(("start_transport %x\n", channel_mask)); | ||
794 | |||
795 | if (wait_handshake(chip)) | ||
796 | return -EIO; | ||
797 | |||
798 | chip->comm_page->cmd_start |= cpu_to_le32(channel_mask); | ||
799 | |||
800 | if (chip->comm_page->cmd_start) { | ||
801 | clear_handshake(chip); | ||
802 | send_vector(chip, DSP_VC_START_TRANSFER); | ||
803 | if (wait_handshake(chip)) | ||
804 | return -EIO; | ||
805 | /* Keep track of which pipes are transporting */ | ||
806 | chip->active_mask |= channel_mask; | ||
807 | chip->comm_page->cmd_start = 0; | ||
808 | return 0; | ||
809 | } | ||
810 | |||
811 | DE_ACT(("start_transport: No pipes to start!\n")); | ||
812 | return -EINVAL; | ||
813 | } | ||
814 | |||
815 | |||
816 | |||
817 | static int pause_transport(struct echoaudio *chip, u32 channel_mask) | ||
818 | { | ||
819 | DE_ACT(("pause_transport %x\n", channel_mask)); | ||
820 | |||
821 | if (wait_handshake(chip)) | ||
822 | return -EIO; | ||
823 | |||
824 | chip->comm_page->cmd_stop |= cpu_to_le32(channel_mask); | ||
825 | chip->comm_page->cmd_reset = 0; | ||
826 | if (chip->comm_page->cmd_stop) { | ||
827 | clear_handshake(chip); | ||
828 | send_vector(chip, DSP_VC_STOP_TRANSFER); | ||
829 | if (wait_handshake(chip)) | ||
830 | return -EIO; | ||
831 | /* Keep track of which pipes are transporting */ | ||
832 | chip->active_mask &= ~channel_mask; | ||
833 | chip->comm_page->cmd_stop = 0; | ||
834 | chip->comm_page->cmd_reset = 0; | ||
835 | return 0; | ||
836 | } | ||
837 | |||
838 | DE_ACT(("pause_transport: No pipes to stop!\n")); | ||
839 | return 0; | ||
840 | } | ||
841 | |||
842 | |||
843 | |||
844 | static int stop_transport(struct echoaudio *chip, u32 channel_mask) | ||
845 | { | ||
846 | DE_ACT(("stop_transport %x\n", channel_mask)); | ||
847 | |||
848 | if (wait_handshake(chip)) | ||
849 | return -EIO; | ||
850 | |||
851 | chip->comm_page->cmd_stop |= cpu_to_le32(channel_mask); | ||
852 | chip->comm_page->cmd_reset |= cpu_to_le32(channel_mask); | ||
853 | if (chip->comm_page->cmd_reset) { | ||
854 | clear_handshake(chip); | ||
855 | send_vector(chip, DSP_VC_STOP_TRANSFER); | ||
856 | if (wait_handshake(chip)) | ||
857 | return -EIO; | ||
858 | /* Keep track of which pipes are transporting */ | ||
859 | chip->active_mask &= ~channel_mask; | ||
860 | chip->comm_page->cmd_stop = 0; | ||
861 | chip->comm_page->cmd_reset = 0; | ||
862 | return 0; | ||
863 | } | ||
864 | |||
865 | DE_ACT(("stop_transport: No pipes to stop!\n")); | ||
866 | return 0; | ||
867 | } | ||
868 | |||
869 | |||
870 | |||
871 | static inline int is_pipe_allocated(struct echoaudio *chip, u16 pipe_index) | ||
872 | { | ||
873 | return (chip->pipe_alloc_mask & (1 << pipe_index)); | ||
874 | } | ||
875 | |||
876 | |||
877 | |||
878 | /* Stops everything and turns off the DSP. All pipes should be already | ||
879 | stopped and unallocated. */ | ||
880 | static int rest_in_peace(struct echoaudio *chip) | ||
881 | { | ||
882 | DE_ACT(("rest_in_peace() open=%x\n", chip->pipe_alloc_mask)); | ||
883 | |||
884 | /* Stops all active pipes (just to be sure) */ | ||
885 | stop_transport(chip, chip->active_mask); | ||
886 | |||
887 | set_meters_on(chip, FALSE); | ||
888 | |||
889 | #ifdef ECHOCARD_HAS_MIDI | ||
890 | enable_midi_input(chip, FALSE); | ||
891 | #endif | ||
892 | |||
893 | /* Go to sleep */ | ||
894 | if (chip->dsp_code) { | ||
895 | /* Make load_firmware do a complete reload */ | ||
896 | chip->dsp_code = NULL; | ||
897 | /* Put the DSP to sleep */ | ||
898 | return send_vector(chip, DSP_VC_GO_COMATOSE); | ||
899 | } | ||
900 | return 0; | ||
901 | } | ||
902 | |||
903 | |||
904 | |||
905 | /* Fills the comm page with default values */ | ||
906 | static int init_dsp_comm_page(struct echoaudio *chip) | ||
907 | { | ||
908 | /* Check if the compiler added extra padding inside the structure */ | ||
909 | if (offsetof(struct comm_page, midi_output) != 0xbe0) { | ||
910 | DE_INIT(("init_dsp_comm_page() - Invalid struct comm_page structure\n")); | ||
911 | return -EPERM; | ||
912 | } | ||
913 | |||
914 | /* Init all the basic stuff */ | ||
915 | chip->card_name = ECHOCARD_NAME; | ||
916 | chip->bad_board = TRUE; /* Set TRUE until DSP loaded */ | ||
917 | chip->dsp_code = NULL; /* Current DSP code not loaded */ | ||
918 | chip->digital_mode = DIGITAL_MODE_NONE; | ||
919 | chip->input_clock = ECHO_CLOCK_INTERNAL; | ||
920 | chip->output_clock = ECHO_CLOCK_WORD; | ||
921 | chip->asic_loaded = FALSE; | ||
922 | memset(chip->comm_page, 0, sizeof(struct comm_page)); | ||
923 | |||
924 | /* Init the comm page */ | ||
925 | chip->comm_page->comm_size = | ||
926 | __constant_cpu_to_le32(sizeof(struct comm_page)); | ||
927 | chip->comm_page->handshake = 0xffffffff; | ||
928 | chip->comm_page->midi_out_free_count = | ||
929 | __constant_cpu_to_le32(DSP_MIDI_OUT_FIFO_SIZE); | ||
930 | chip->comm_page->sample_rate = __constant_cpu_to_le32(44100); | ||
931 | chip->sample_rate = 44100; | ||
932 | |||
933 | /* Set line levels so we don't blast any inputs on startup */ | ||
934 | memset(chip->comm_page->monitors, ECHOGAIN_MUTED, MONITOR_ARRAY_SIZE); | ||
935 | memset(chip->comm_page->vmixer, ECHOGAIN_MUTED, VMIXER_ARRAY_SIZE); | ||
936 | |||
937 | return 0; | ||
938 | } | ||
939 | |||
940 | |||
941 | |||
942 | /* This function initializes the several volume controls for busses and pipes. | ||
943 | This MUST be called after the DSP is up and running ! */ | ||
944 | static int init_line_levels(struct echoaudio *chip) | ||
945 | { | ||
946 | int st, i, o; | ||
947 | |||
948 | DE_INIT(("init_line_levels\n")); | ||
949 | |||
950 | /* Mute output busses */ | ||
951 | for (i = 0; i < num_busses_out(chip); i++) | ||
952 | if ((st = set_output_gain(chip, i, ECHOGAIN_MUTED))) | ||
953 | return st; | ||
954 | if ((st = update_output_line_level(chip))) | ||
955 | return st; | ||
956 | |||
957 | #ifdef ECHOCARD_HAS_VMIXER | ||
958 | /* Mute the Vmixer */ | ||
959 | for (i = 0; i < num_pipes_out(chip); i++) | ||
960 | for (o = 0; o < num_busses_out(chip); o++) | ||
961 | if ((st = set_vmixer_gain(chip, o, i, ECHOGAIN_MUTED))) | ||
962 | return st; | ||
963 | if ((st = update_vmixer_level(chip))) | ||
964 | return st; | ||
965 | #endif /* ECHOCARD_HAS_VMIXER */ | ||
966 | |||
967 | #ifdef ECHOCARD_HAS_MONITOR | ||
968 | /* Mute the monitor mixer */ | ||
969 | for (o = 0; o < num_busses_out(chip); o++) | ||
970 | for (i = 0; i < num_busses_in(chip); i++) | ||
971 | if ((st = set_monitor_gain(chip, o, i, ECHOGAIN_MUTED))) | ||
972 | return st; | ||
973 | if ((st = update_output_line_level(chip))) | ||
974 | return st; | ||
975 | #endif /* ECHOCARD_HAS_MONITOR */ | ||
976 | |||
977 | #ifdef ECHOCARD_HAS_INPUT_GAIN | ||
978 | for (i = 0; i < num_busses_in(chip); i++) | ||
979 | if ((st = set_input_gain(chip, i, ECHOGAIN_MUTED))) | ||
980 | return st; | ||
981 | if ((st = update_input_line_level(chip))) | ||
982 | return st; | ||
983 | #endif /* ECHOCARD_HAS_INPUT_GAIN */ | ||
984 | |||
985 | return 0; | ||
986 | } | ||
987 | |||
988 | |||
989 | |||
990 | /* This is low level part of the interrupt handler. | ||
991 | It returns -1 if the IRQ is not ours, or N>=0 if it is, where N is the number | ||
992 | of midi data in the input queue. */ | ||
993 | static int service_irq(struct echoaudio *chip) | ||
994 | { | ||
995 | int st; | ||
996 | |||
997 | /* Read the DSP status register and see if this DSP generated this interrupt */ | ||
998 | if (get_dsp_register(chip, CHI32_STATUS_REG) & CHI32_STATUS_IRQ) { | ||
999 | st = 0; | ||
1000 | #ifdef ECHOCARD_HAS_MIDI | ||
1001 | /* Get and parse midi data if present */ | ||
1002 | if (chip->comm_page->midi_input[0]) /* The count is at index 0 */ | ||
1003 | st = midi_service_irq(chip); /* Returns how many midi bytes we received */ | ||
1004 | #endif | ||
1005 | /* Clear the hardware interrupt */ | ||
1006 | chip->comm_page->midi_input[0] = 0; | ||
1007 | send_vector(chip, DSP_VC_ACK_INT); | ||
1008 | return st; | ||
1009 | } | ||
1010 | return -1; | ||
1011 | } | ||
1012 | |||
1013 | |||
1014 | |||
1015 | |||
1016 | /****************************************************************************** | ||
1017 | Functions for opening and closing pipes | ||
1018 | ******************************************************************************/ | ||
1019 | |||
1020 | /* allocate_pipes is used to reserve audio pipes for your exclusive use. | ||
1021 | The call will fail if some pipes are already allocated. */ | ||
1022 | static int allocate_pipes(struct echoaudio *chip, struct audiopipe *pipe, | ||
1023 | int pipe_index, int interleave) | ||
1024 | { | ||
1025 | int i; | ||
1026 | u32 channel_mask; | ||
1027 | char is_cyclic; | ||
1028 | |||
1029 | DE_ACT(("allocate_pipes: ch=%d int=%d\n", pipe_index, interleave)); | ||
1030 | |||
1031 | if (chip->bad_board) | ||
1032 | return -EIO; | ||
1033 | |||
1034 | is_cyclic = 1; /* This driver uses cyclic buffers only */ | ||
1035 | |||
1036 | for (channel_mask = i = 0; i < interleave; i++) | ||
1037 | channel_mask |= 1 << (pipe_index + i); | ||
1038 | if (chip->pipe_alloc_mask & channel_mask) { | ||
1039 | DE_ACT(("allocate_pipes: channel already open\n")); | ||
1040 | return -EAGAIN; | ||
1041 | } | ||
1042 | |||
1043 | chip->comm_page->position[pipe_index] = 0; | ||
1044 | chip->pipe_alloc_mask |= channel_mask; | ||
1045 | if (is_cyclic) | ||
1046 | chip->pipe_cyclic_mask |= channel_mask; | ||
1047 | pipe->index = pipe_index; | ||
1048 | pipe->interleave = interleave; | ||
1049 | pipe->state = PIPE_STATE_STOPPED; | ||
1050 | |||
1051 | /* The counter register is where the DSP writes the 32 bit DMA | ||
1052 | position for a pipe. The DSP is constantly updating this value as | ||
1053 | it moves data. The DMA counter is in units of bytes, not samples. */ | ||
1054 | pipe->dma_counter = &chip->comm_page->position[pipe_index]; | ||
1055 | *pipe->dma_counter = 0; | ||
1056 | DE_ACT(("allocate_pipes: ok\n")); | ||
1057 | return pipe_index; | ||
1058 | } | ||
1059 | |||
1060 | |||
1061 | |||
1062 | static int free_pipes(struct echoaudio *chip, struct audiopipe *pipe) | ||
1063 | { | ||
1064 | u32 channel_mask; | ||
1065 | int i; | ||
1066 | |||
1067 | DE_ACT(("free_pipes: Pipe %d\n", pipe->index)); | ||
1068 | snd_assert(is_pipe_allocated(chip, pipe->index), return -EINVAL); | ||
1069 | snd_assert(pipe->state == PIPE_STATE_STOPPED, return -EINVAL); | ||
1070 | |||
1071 | for (channel_mask = i = 0; i < pipe->interleave; i++) | ||
1072 | channel_mask |= 1 << (pipe->index + i); | ||
1073 | |||
1074 | chip->pipe_alloc_mask &= ~channel_mask; | ||
1075 | chip->pipe_cyclic_mask &= ~channel_mask; | ||
1076 | return 0; | ||
1077 | } | ||
1078 | |||
1079 | |||
1080 | |||
1081 | /****************************************************************************** | ||
1082 | Functions for managing the scatter-gather list | ||
1083 | ******************************************************************************/ | ||
1084 | |||
1085 | static int sglist_init(struct echoaudio *chip, struct audiopipe *pipe) | ||
1086 | { | ||
1087 | pipe->sglist_head = 0; | ||
1088 | memset(pipe->sgpage.area, 0, PAGE_SIZE); | ||
1089 | chip->comm_page->sglist_addr[pipe->index].addr = | ||
1090 | cpu_to_le32(pipe->sgpage.addr); | ||
1091 | return 0; | ||
1092 | } | ||
1093 | |||
1094 | |||
1095 | |||
1096 | static int sglist_add_mapping(struct echoaudio *chip, struct audiopipe *pipe, | ||
1097 | dma_addr_t address, size_t length) | ||
1098 | { | ||
1099 | int head = pipe->sglist_head; | ||
1100 | struct sg_entry *list = (struct sg_entry *)pipe->sgpage.area; | ||
1101 | |||
1102 | if (head < MAX_SGLIST_ENTRIES - 1) { | ||
1103 | list[head].addr = cpu_to_le32(address); | ||
1104 | list[head].size = cpu_to_le32(length); | ||
1105 | pipe->sglist_head++; | ||
1106 | } else { | ||
1107 | DE_ACT(("SGlist: too many fragments\n")); | ||
1108 | return -ENOMEM; | ||
1109 | } | ||
1110 | return 0; | ||
1111 | } | ||
1112 | |||
1113 | |||
1114 | |||
1115 | static inline int sglist_add_irq(struct echoaudio *chip, struct audiopipe *pipe) | ||
1116 | { | ||
1117 | return sglist_add_mapping(chip, pipe, 0, 0); | ||
1118 | } | ||
1119 | |||
1120 | |||
1121 | |||
1122 | static inline int sglist_wrap(struct echoaudio *chip, struct audiopipe *pipe) | ||
1123 | { | ||
1124 | return sglist_add_mapping(chip, pipe, pipe->sgpage.addr, 0); | ||
1125 | } | ||
diff --git a/sound/pci/echoaudio/echoaudio_dsp.h b/sound/pci/echoaudio/echoaudio_dsp.h new file mode 100644 index 000000000000..e55ee00991ac --- /dev/null +++ b/sound/pci/echoaudio/echoaudio_dsp.h | |||
@@ -0,0 +1,694 @@ | |||
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 | #ifndef _ECHO_DSP_ | ||
32 | #define _ECHO_DSP_ | ||
33 | |||
34 | |||
35 | /**** Echogals: Darla20, Gina20, Layla20, and Darla24 ****/ | ||
36 | #if defined(ECHOGALS_FAMILY) | ||
37 | |||
38 | #define NUM_ASIC_TESTS 5 | ||
39 | #define READ_DSP_TIMEOUT 1000000L /* one second */ | ||
40 | |||
41 | /**** Echo24: Gina24, Layla24, Mona, Mia, Mia-midi ****/ | ||
42 | #elif defined(ECHO24_FAMILY) | ||
43 | |||
44 | #define DSP_56361 /* Some Echo24 cards use the 56361 DSP */ | ||
45 | #define READ_DSP_TIMEOUT 100000L /* .1 second */ | ||
46 | |||
47 | /**** 3G: Gina3G, Layla3G ****/ | ||
48 | #elif defined(ECHO3G_FAMILY) | ||
49 | |||
50 | #define DSP_56361 | ||
51 | #define READ_DSP_TIMEOUT 100000L /* .1 second */ | ||
52 | #define MIN_MTC_1X_RATE 32000 | ||
53 | |||
54 | /**** Indigo: Indigo, Indigo IO, Indigo DJ ****/ | ||
55 | #elif defined(INDIGO_FAMILY) | ||
56 | |||
57 | #define DSP_56361 | ||
58 | #define READ_DSP_TIMEOUT 100000L /* .1 second */ | ||
59 | |||
60 | #else | ||
61 | |||
62 | #error No family is defined | ||
63 | |||
64 | #endif | ||
65 | |||
66 | |||
67 | |||
68 | /* | ||
69 | * | ||
70 | * Max inputs and outputs | ||
71 | * | ||
72 | */ | ||
73 | |||
74 | #define DSP_MAXAUDIOINPUTS 16 /* Max audio input channels */ | ||
75 | #define DSP_MAXAUDIOOUTPUTS 16 /* Max audio output channels */ | ||
76 | #define DSP_MAXPIPES 32 /* Max total pipes (input + output) */ | ||
77 | |||
78 | |||
79 | /* | ||
80 | * | ||
81 | * These are the offsets for the memory-mapped DSP registers; the DSP base | ||
82 | * address is treated as the start of a u32 array. | ||
83 | */ | ||
84 | |||
85 | #define CHI32_CONTROL_REG 4 | ||
86 | #define CHI32_STATUS_REG 5 | ||
87 | #define CHI32_VECTOR_REG 6 | ||
88 | #define CHI32_DATA_REG 7 | ||
89 | |||
90 | |||
91 | /* | ||
92 | * | ||
93 | * Interesting bits within the DSP registers | ||
94 | * | ||
95 | */ | ||
96 | |||
97 | #define CHI32_VECTOR_BUSY 0x00000001 | ||
98 | #define CHI32_STATUS_REG_HF3 0x00000008 | ||
99 | #define CHI32_STATUS_REG_HF4 0x00000010 | ||
100 | #define CHI32_STATUS_REG_HF5 0x00000020 | ||
101 | #define CHI32_STATUS_HOST_READ_FULL 0x00000004 | ||
102 | #define CHI32_STATUS_HOST_WRITE_EMPTY 0x00000002 | ||
103 | #define CHI32_STATUS_IRQ 0x00000040 | ||
104 | |||
105 | |||
106 | /* | ||
107 | * | ||
108 | * DSP commands sent via slave mode; these are sent to the DSP by write_dsp() | ||
109 | * | ||
110 | */ | ||
111 | |||
112 | #define DSP_FNC_SET_COMMPAGE_ADDR 0x02 | ||
113 | #define DSP_FNC_LOAD_LAYLA_ASIC 0xa0 | ||
114 | #define DSP_FNC_LOAD_GINA24_ASIC 0xa0 | ||
115 | #define DSP_FNC_LOAD_MONA_PCI_CARD_ASIC 0xa0 | ||
116 | #define DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC 0xa0 | ||
117 | #define DSP_FNC_LOAD_MONA_EXTERNAL_ASIC 0xa1 | ||
118 | #define DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC 0xa1 | ||
119 | #define DSP_FNC_LOAD_3G_ASIC 0xa0 | ||
120 | |||
121 | |||
122 | /* | ||
123 | * | ||
124 | * Defines to handle the MIDI input state engine; these are used to properly | ||
125 | * extract MIDI time code bytes and their timestamps from the MIDI input stream. | ||
126 | * | ||
127 | */ | ||
128 | |||
129 | #define MIDI_IN_STATE_NORMAL 0 | ||
130 | #define MIDI_IN_STATE_TS_HIGH 1 | ||
131 | #define MIDI_IN_STATE_TS_LOW 2 | ||
132 | #define MIDI_IN_STATE_F1_DATA 3 | ||
133 | #define MIDI_IN_SKIP_DATA (-1) | ||
134 | |||
135 | |||
136 | /*---------------------------------------------------------------------------- | ||
137 | |||
138 | Setting the sample rates on Layla24 is somewhat schizophrenic. | ||
139 | |||
140 | For standard rates, it works exactly like Mona and Gina24. That is, for | ||
141 | 8, 11.025, 16, 22.05, 32, 44.1, 48, 88.2, and 96 kHz, you just set the | ||
142 | appropriate bits in the control register and write the control register. | ||
143 | |||
144 | In order to support MIDI time code sync (and possibly SMPTE LTC sync in | ||
145 | the future), Layla24 also has "continuous sample rate mode". In this mode, | ||
146 | Layla24 can generate any sample rate between 25 and 50 kHz inclusive, or | ||
147 | 50 to 100 kHz inclusive for double speed mode. | ||
148 | |||
149 | To use continuous mode: | ||
150 | |||
151 | -Set the clock select bits in the control register to 0xe (see the #define | ||
152 | below) | ||
153 | |||
154 | -Set double-speed mode if you want to use sample rates above 50 kHz | ||
155 | |||
156 | -Write the control register as you would normally | ||
157 | |||
158 | -Now, you need to set the frequency register. First, you need to determine the | ||
159 | value for the frequency register. This is given by the following formula: | ||
160 | |||
161 | frequency_reg = (LAYLA24_MAGIC_NUMBER / sample_rate) - 2 | ||
162 | |||
163 | Note the #define below for the magic number | ||
164 | |||
165 | -Wait for the DSP handshake | ||
166 | -Write the frequency_reg value to the .SampleRate field of the comm page | ||
167 | -Send the vector command SET_LAYLA24_FREQUENCY_REG (see vmonkey.h) | ||
168 | |||
169 | Once you have set the control register up for continuous mode, you can just | ||
170 | write the frequency register to change the sample rate. This could be | ||
171 | used for MIDI time code sync. For MTC sync, the control register is set for | ||
172 | continuous mode. The driver then just keeps writing the | ||
173 | SET_LAYLA24_FREQUENCY_REG command. | ||
174 | |||
175 | -----------------------------------------------------------------------------*/ | ||
176 | |||
177 | #define LAYLA24_MAGIC_NUMBER 677376000 | ||
178 | #define LAYLA24_CONTINUOUS_CLOCK 0x000e | ||
179 | |||
180 | |||
181 | /* | ||
182 | * | ||
183 | * DSP vector commands | ||
184 | * | ||
185 | */ | ||
186 | |||
187 | #define DSP_VC_RESET 0x80ff | ||
188 | |||
189 | #ifndef DSP_56361 | ||
190 | |||
191 | #define DSP_VC_ACK_INT 0x8073 | ||
192 | #define DSP_VC_SET_VMIXER_GAIN 0x0000 /* Not used, only for compile */ | ||
193 | #define DSP_VC_START_TRANSFER 0x0075 /* Handshke rqd. */ | ||
194 | #define DSP_VC_METERS_ON 0x0079 | ||
195 | #define DSP_VC_METERS_OFF 0x007b | ||
196 | #define DSP_VC_UPDATE_OUTVOL 0x007d /* Handshke rqd. */ | ||
197 | #define DSP_VC_UPDATE_INGAIN 0x007f /* Handshke rqd. */ | ||
198 | #define DSP_VC_ADD_AUDIO_BUFFER 0x0081 /* Handshke rqd. */ | ||
199 | #define DSP_VC_TEST_ASIC 0x00eb | ||
200 | #define DSP_VC_UPDATE_CLOCKS 0x00ef /* Handshke rqd. */ | ||
201 | #define DSP_VC_SET_LAYLA_SAMPLE_RATE 0x00f1 /* Handshke rqd. */ | ||
202 | #define DSP_VC_SET_GD_AUDIO_STATE 0x00f1 /* Handshke rqd. */ | ||
203 | #define DSP_VC_WRITE_CONTROL_REG 0x00f1 /* Handshke rqd. */ | ||
204 | #define DSP_VC_MIDI_WRITE 0x00f5 /* Handshke rqd. */ | ||
205 | #define DSP_VC_STOP_TRANSFER 0x00f7 /* Handshke rqd. */ | ||
206 | #define DSP_VC_UPDATE_FLAGS 0x00fd /* Handshke rqd. */ | ||
207 | #define DSP_VC_GO_COMATOSE 0x00f9 | ||
208 | |||
209 | #else /* !DSP_56361 */ | ||
210 | |||
211 | /* Vector commands for families that use either the 56301 or 56361 */ | ||
212 | #define DSP_VC_ACK_INT 0x80F5 | ||
213 | #define DSP_VC_SET_VMIXER_GAIN 0x00DB /* Handshke rqd. */ | ||
214 | #define DSP_VC_START_TRANSFER 0x00DD /* Handshke rqd. */ | ||
215 | #define DSP_VC_METERS_ON 0x00EF | ||
216 | #define DSP_VC_METERS_OFF 0x00F1 | ||
217 | #define DSP_VC_UPDATE_OUTVOL 0x00E3 /* Handshke rqd. */ | ||
218 | #define DSP_VC_UPDATE_INGAIN 0x00E5 /* Handshke rqd. */ | ||
219 | #define DSP_VC_ADD_AUDIO_BUFFER 0x00E1 /* Handshke rqd. */ | ||
220 | #define DSP_VC_TEST_ASIC 0x00ED | ||
221 | #define DSP_VC_UPDATE_CLOCKS 0x00E9 /* Handshke rqd. */ | ||
222 | #define DSP_VC_SET_LAYLA24_FREQUENCY_REG 0x00E9 /* Handshke rqd. */ | ||
223 | #define DSP_VC_SET_LAYLA_SAMPLE_RATE 0x00EB /* Handshke rqd. */ | ||
224 | #define DSP_VC_SET_GD_AUDIO_STATE 0x00EB /* Handshke rqd. */ | ||
225 | #define DSP_VC_WRITE_CONTROL_REG 0x00EB /* Handshke rqd. */ | ||
226 | #define DSP_VC_MIDI_WRITE 0x00E7 /* Handshke rqd. */ | ||
227 | #define DSP_VC_STOP_TRANSFER 0x00DF /* Handshke rqd. */ | ||
228 | #define DSP_VC_UPDATE_FLAGS 0x00FB /* Handshke rqd. */ | ||
229 | #define DSP_VC_GO_COMATOSE 0x00d9 | ||
230 | |||
231 | #endif /* !DSP_56361 */ | ||
232 | |||
233 | |||
234 | /* | ||
235 | * | ||
236 | * Timeouts | ||
237 | * | ||
238 | */ | ||
239 | |||
240 | #define HANDSHAKE_TIMEOUT 20000 /* send_vector command timeout (20ms) */ | ||
241 | #define VECTOR_BUSY_TIMEOUT 100000 /* 100ms */ | ||
242 | #define MIDI_OUT_DELAY_USEC 2000 /* How long to wait after MIDI fills up */ | ||
243 | |||
244 | |||
245 | /* | ||
246 | * | ||
247 | * Flags for .Flags field in the comm page | ||
248 | * | ||
249 | */ | ||
250 | |||
251 | #define DSP_FLAG_MIDI_INPUT 0x0001 /* Enable MIDI input */ | ||
252 | #define DSP_FLAG_SPDIF_NONAUDIO 0x0002 /* Sets the "non-audio" bit | ||
253 | * in the S/PDIF out status | ||
254 | * bits. Clear this flag for | ||
255 | * audio data; | ||
256 | * set it for AC3 or WMA or | ||
257 | * some such */ | ||
258 | #define DSP_FLAG_PROFESSIONAL_SPDIF 0x0008 /* 1 Professional, 0 Consumer */ | ||
259 | |||
260 | |||
261 | /* | ||
262 | * | ||
263 | * Clock detect bits reported by the DSP for Gina20, Layla20, Darla24, and Mia | ||
264 | * | ||
265 | */ | ||
266 | |||
267 | #define GLDM_CLOCK_DETECT_BIT_WORD 0x0002 | ||
268 | #define GLDM_CLOCK_DETECT_BIT_SUPER 0x0004 | ||
269 | #define GLDM_CLOCK_DETECT_BIT_SPDIF 0x0008 | ||
270 | #define GLDM_CLOCK_DETECT_BIT_ESYNC 0x0010 | ||
271 | |||
272 | |||
273 | /* | ||
274 | * | ||
275 | * Clock detect bits reported by the DSP for Gina24, Mona, and Layla24 | ||
276 | * | ||
277 | */ | ||
278 | |||
279 | #define GML_CLOCK_DETECT_BIT_WORD96 0x0002 | ||
280 | #define GML_CLOCK_DETECT_BIT_WORD48 0x0004 | ||
281 | #define GML_CLOCK_DETECT_BIT_SPDIF48 0x0008 | ||
282 | #define GML_CLOCK_DETECT_BIT_SPDIF96 0x0010 | ||
283 | #define GML_CLOCK_DETECT_BIT_WORD (GML_CLOCK_DETECT_BIT_WORD96 | GML_CLOCK_DETECT_BIT_WORD48) | ||
284 | #define GML_CLOCK_DETECT_BIT_SPDIF (GML_CLOCK_DETECT_BIT_SPDIF48 | GML_CLOCK_DETECT_BIT_SPDIF96) | ||
285 | #define GML_CLOCK_DETECT_BIT_ESYNC 0x0020 | ||
286 | #define GML_CLOCK_DETECT_BIT_ADAT 0x0040 | ||
287 | |||
288 | |||
289 | /* | ||
290 | * | ||
291 | * Layla clock numbers to send to DSP | ||
292 | * | ||
293 | */ | ||
294 | |||
295 | #define LAYLA20_CLOCK_INTERNAL 0 | ||
296 | #define LAYLA20_CLOCK_SPDIF 1 | ||
297 | #define LAYLA20_CLOCK_WORD 2 | ||
298 | #define LAYLA20_CLOCK_SUPER 3 | ||
299 | |||
300 | |||
301 | /* | ||
302 | * | ||
303 | * Gina/Darla clock states | ||
304 | * | ||
305 | */ | ||
306 | |||
307 | #define GD_CLOCK_NOCHANGE 0 | ||
308 | #define GD_CLOCK_44 1 | ||
309 | #define GD_CLOCK_48 2 | ||
310 | #define GD_CLOCK_SPDIFIN 3 | ||
311 | #define GD_CLOCK_UNDEF 0xff | ||
312 | |||
313 | |||
314 | /* | ||
315 | * | ||
316 | * Gina/Darla S/PDIF status bits | ||
317 | * | ||
318 | */ | ||
319 | |||
320 | #define GD_SPDIF_STATUS_NOCHANGE 0 | ||
321 | #define GD_SPDIF_STATUS_44 1 | ||
322 | #define GD_SPDIF_STATUS_48 2 | ||
323 | #define GD_SPDIF_STATUS_UNDEF 0xff | ||
324 | |||
325 | |||
326 | /* | ||
327 | * | ||
328 | * Layla20 output clocks | ||
329 | * | ||
330 | */ | ||
331 | |||
332 | #define LAYLA20_OUTPUT_CLOCK_SUPER 0 | ||
333 | #define LAYLA20_OUTPUT_CLOCK_WORD 1 | ||
334 | |||
335 | |||
336 | /**************************************************************************** | ||
337 | |||
338 | Magic constants for the Darla24 hardware | ||
339 | |||
340 | ****************************************************************************/ | ||
341 | |||
342 | #define GD24_96000 0x0 | ||
343 | #define GD24_48000 0x1 | ||
344 | #define GD24_44100 0x2 | ||
345 | #define GD24_32000 0x3 | ||
346 | #define GD24_22050 0x4 | ||
347 | #define GD24_16000 0x5 | ||
348 | #define GD24_11025 0x6 | ||
349 | #define GD24_8000 0x7 | ||
350 | #define GD24_88200 0x8 | ||
351 | #define GD24_EXT_SYNC 0x9 | ||
352 | |||
353 | |||
354 | /* | ||
355 | * | ||
356 | * Return values from the DSP when ASIC is loaded | ||
357 | * | ||
358 | */ | ||
359 | |||
360 | #define ASIC_ALREADY_LOADED 0x1 | ||
361 | #define ASIC_NOT_LOADED 0x0 | ||
362 | |||
363 | |||
364 | /* | ||
365 | * | ||
366 | * DSP Audio formats | ||
367 | * | ||
368 | * These are the audio formats that the DSP can transfer | ||
369 | * via input and output pipes. LE means little-endian, | ||
370 | * BE means big-endian. | ||
371 | * | ||
372 | * DSP_AUDIOFORM_MS_8 | ||
373 | * | ||
374 | * 8-bit mono unsigned samples. For playback, | ||
375 | * mono data is duplicated out the left and right channels | ||
376 | * of the output bus. The "MS" part of the name | ||
377 | * means mono->stereo. | ||
378 | * | ||
379 | * DSP_AUDIOFORM_MS_16LE | ||
380 | * | ||
381 | * 16-bit signed little-endian mono samples. Playback works | ||
382 | * like the previous code. | ||
383 | * | ||
384 | * DSP_AUDIOFORM_MS_24LE | ||
385 | * | ||
386 | * 24-bit signed little-endian mono samples. Data is packed | ||
387 | * three bytes per sample; if you had two samples 0x112233 and 0x445566 | ||
388 | * they would be stored in memory like this: 33 22 11 66 55 44. | ||
389 | * | ||
390 | * DSP_AUDIOFORM_MS_32LE | ||
391 | * | ||
392 | * 24-bit signed little-endian mono samples in a 32-bit | ||
393 | * container. In other words, each sample is a 32-bit signed | ||
394 | * integer, where the actual audio data is left-justified | ||
395 | * in the 32 bits and only the 24 most significant bits are valid. | ||
396 | * | ||
397 | * DSP_AUDIOFORM_SS_8 | ||
398 | * DSP_AUDIOFORM_SS_16LE | ||
399 | * DSP_AUDIOFORM_SS_24LE | ||
400 | * DSP_AUDIOFORM_SS_32LE | ||
401 | * | ||
402 | * Like the previous ones, except now with stereo interleaved | ||
403 | * data. "SS" means stereo->stereo. | ||
404 | * | ||
405 | * DSP_AUDIOFORM_MM_32LE | ||
406 | * | ||
407 | * Similar to DSP_AUDIOFORM_MS_32LE, except that the mono | ||
408 | * data is not duplicated out both the left and right outputs. | ||
409 | * This mode is used by the ASIO driver. Here, "MM" means | ||
410 | * mono->mono. | ||
411 | * | ||
412 | * DSP_AUDIOFORM_MM_32BE | ||
413 | * | ||
414 | * Just like DSP_AUDIOFORM_MM_32LE, but now the data is | ||
415 | * in big-endian format. | ||
416 | * | ||
417 | */ | ||
418 | |||
419 | #define DSP_AUDIOFORM_MS_8 0 /* 8 bit mono */ | ||
420 | #define DSP_AUDIOFORM_MS_16LE 1 /* 16 bit mono */ | ||
421 | #define DSP_AUDIOFORM_MS_24LE 2 /* 24 bit mono */ | ||
422 | #define DSP_AUDIOFORM_MS_32LE 3 /* 32 bit mono */ | ||
423 | #define DSP_AUDIOFORM_SS_8 4 /* 8 bit stereo */ | ||
424 | #define DSP_AUDIOFORM_SS_16LE 5 /* 16 bit stereo */ | ||
425 | #define DSP_AUDIOFORM_SS_24LE 6 /* 24 bit stereo */ | ||
426 | #define DSP_AUDIOFORM_SS_32LE 7 /* 32 bit stereo */ | ||
427 | #define DSP_AUDIOFORM_MM_32LE 8 /* 32 bit mono->mono little-endian */ | ||
428 | #define DSP_AUDIOFORM_MM_32BE 9 /* 32 bit mono->mono big-endian */ | ||
429 | #define DSP_AUDIOFORM_SS_32BE 10 /* 32 bit stereo big endian */ | ||
430 | #define DSP_AUDIOFORM_INVALID 0xFF /* Invalid audio format */ | ||
431 | |||
432 | |||
433 | /* | ||
434 | * | ||
435 | * Super-interleave is defined as interleaving by 4 or more. Darla20 and Gina20 | ||
436 | * do not support super interleave. | ||
437 | * | ||
438 | * 16 bit, 24 bit, and 32 bit little endian samples are supported for super | ||
439 | * interleave. The interleave factor must be even. 16 - way interleave is the | ||
440 | * current maximum, so you can interleave by 4, 6, 8, 10, 12, 14, and 16. | ||
441 | * | ||
442 | * The actual format code is derived by taking the define below and or-ing with | ||
443 | * the interleave factor. So, 32 bit interleave by 6 is 0x86 and | ||
444 | * 16 bit interleave by 16 is (0x40 | 0x10) = 0x50. | ||
445 | * | ||
446 | */ | ||
447 | |||
448 | #define DSP_AUDIOFORM_SUPER_INTERLEAVE_16LE 0x40 | ||
449 | #define DSP_AUDIOFORM_SUPER_INTERLEAVE_24LE 0xc0 | ||
450 | #define DSP_AUDIOFORM_SUPER_INTERLEAVE_32LE 0x80 | ||
451 | |||
452 | |||
453 | /* | ||
454 | * | ||
455 | * Gina24, Mona, and Layla24 control register defines | ||
456 | * | ||
457 | */ | ||
458 | |||
459 | #define GML_CONVERTER_ENABLE 0x0010 | ||
460 | #define GML_SPDIF_PRO_MODE 0x0020 /* Professional S/PDIF == 1, | ||
461 | consumer == 0 */ | ||
462 | #define GML_SPDIF_SAMPLE_RATE0 0x0040 | ||
463 | #define GML_SPDIF_SAMPLE_RATE1 0x0080 | ||
464 | #define GML_SPDIF_TWO_CHANNEL 0x0100 /* 1 == two channels, | ||
465 | 0 == one channel */ | ||
466 | #define GML_SPDIF_NOT_AUDIO 0x0200 | ||
467 | #define GML_SPDIF_COPY_PERMIT 0x0400 | ||
468 | #define GML_SPDIF_24_BIT 0x0800 /* 1 == 24 bit, 0 == 20 bit */ | ||
469 | #define GML_ADAT_MODE 0x1000 /* 1 == ADAT mode, 0 == S/PDIF mode */ | ||
470 | #define GML_SPDIF_OPTICAL_MODE 0x2000 /* 1 == optical mode, 0 == RCA mode */ | ||
471 | #define GML_SPDIF_CDROM_MODE 0x3000 /* 1 == CDROM mode, | ||
472 | * 0 == RCA or optical mode */ | ||
473 | #define GML_DOUBLE_SPEED_MODE 0x4000 /* 1 == double speed, | ||
474 | 0 == single speed */ | ||
475 | |||
476 | #define GML_DIGITAL_IN_AUTO_MUTE 0x800000 | ||
477 | |||
478 | #define GML_96KHZ (0x0 | GML_DOUBLE_SPEED_MODE) | ||
479 | #define GML_88KHZ (0x1 | GML_DOUBLE_SPEED_MODE) | ||
480 | #define GML_48KHZ 0x2 | ||
481 | #define GML_44KHZ 0x3 | ||
482 | #define GML_32KHZ 0x4 | ||
483 | #define GML_22KHZ 0x5 | ||
484 | #define GML_16KHZ 0x6 | ||
485 | #define GML_11KHZ 0x7 | ||
486 | #define GML_8KHZ 0x8 | ||
487 | #define GML_SPDIF_CLOCK 0x9 | ||
488 | #define GML_ADAT_CLOCK 0xA | ||
489 | #define GML_WORD_CLOCK 0xB | ||
490 | #define GML_ESYNC_CLOCK 0xC | ||
491 | #define GML_ESYNCx2_CLOCK 0xD | ||
492 | |||
493 | #define GML_CLOCK_CLEAR_MASK 0xffffbff0 | ||
494 | #define GML_SPDIF_RATE_CLEAR_MASK (~(GML_SPDIF_SAMPLE_RATE0|GML_SPDIF_SAMPLE_RATE1)) | ||
495 | #define GML_DIGITAL_MODE_CLEAR_MASK 0xffffcfff | ||
496 | #define GML_SPDIF_FORMAT_CLEAR_MASK 0xfffff01f | ||
497 | |||
498 | |||
499 | /* | ||
500 | * | ||
501 | * Mia sample rate and clock setting constants | ||
502 | * | ||
503 | */ | ||
504 | |||
505 | #define MIA_32000 0x0040 | ||
506 | #define MIA_44100 0x0042 | ||
507 | #define MIA_48000 0x0041 | ||
508 | #define MIA_88200 0x0142 | ||
509 | #define MIA_96000 0x0141 | ||
510 | |||
511 | #define MIA_SPDIF 0x00000044 | ||
512 | #define MIA_SPDIF96 0x00000144 | ||
513 | |||
514 | #define MIA_MIDI_REV 1 /* Must be Mia rev 1 for MIDI support */ | ||
515 | |||
516 | |||
517 | /* | ||
518 | * | ||
519 | * 3G register bits | ||
520 | * | ||
521 | */ | ||
522 | |||
523 | #define E3G_CONVERTER_ENABLE 0x0010 | ||
524 | #define E3G_SPDIF_PRO_MODE 0x0020 /* Professional S/PDIF == 1, | ||
525 | consumer == 0 */ | ||
526 | #define E3G_SPDIF_SAMPLE_RATE0 0x0040 | ||
527 | #define E3G_SPDIF_SAMPLE_RATE1 0x0080 | ||
528 | #define E3G_SPDIF_TWO_CHANNEL 0x0100 /* 1 == two channels, | ||
529 | 0 == one channel */ | ||
530 | #define E3G_SPDIF_NOT_AUDIO 0x0200 | ||
531 | #define E3G_SPDIF_COPY_PERMIT 0x0400 | ||
532 | #define E3G_SPDIF_24_BIT 0x0800 /* 1 == 24 bit, 0 == 20 bit */ | ||
533 | #define E3G_DOUBLE_SPEED_MODE 0x4000 /* 1 == double speed, | ||
534 | 0 == single speed */ | ||
535 | #define E3G_PHANTOM_POWER 0x8000 /* 1 == phantom power on, | ||
536 | 0 == phantom power off */ | ||
537 | |||
538 | #define E3G_96KHZ (0x0 | E3G_DOUBLE_SPEED_MODE) | ||
539 | #define E3G_88KHZ (0x1 | E3G_DOUBLE_SPEED_MODE) | ||
540 | #define E3G_48KHZ 0x2 | ||
541 | #define E3G_44KHZ 0x3 | ||
542 | #define E3G_32KHZ 0x4 | ||
543 | #define E3G_22KHZ 0x5 | ||
544 | #define E3G_16KHZ 0x6 | ||
545 | #define E3G_11KHZ 0x7 | ||
546 | #define E3G_8KHZ 0x8 | ||
547 | #define E3G_SPDIF_CLOCK 0x9 | ||
548 | #define E3G_ADAT_CLOCK 0xA | ||
549 | #define E3G_WORD_CLOCK 0xB | ||
550 | #define E3G_CONTINUOUS_CLOCK 0xE | ||
551 | |||
552 | #define E3G_ADAT_MODE 0x1000 | ||
553 | #define E3G_SPDIF_OPTICAL_MODE 0x2000 | ||
554 | |||
555 | #define E3G_CLOCK_CLEAR_MASK 0xbfffbff0 | ||
556 | #define E3G_DIGITAL_MODE_CLEAR_MASK 0xffffcfff | ||
557 | #define E3G_SPDIF_FORMAT_CLEAR_MASK 0xfffff01f | ||
558 | |||
559 | /* Clock detect bits reported by the DSP */ | ||
560 | #define E3G_CLOCK_DETECT_BIT_WORD96 0x0001 | ||
561 | #define E3G_CLOCK_DETECT_BIT_WORD48 0x0002 | ||
562 | #define E3G_CLOCK_DETECT_BIT_SPDIF48 0x0004 | ||
563 | #define E3G_CLOCK_DETECT_BIT_ADAT 0x0004 | ||
564 | #define E3G_CLOCK_DETECT_BIT_SPDIF96 0x0008 | ||
565 | #define E3G_CLOCK_DETECT_BIT_WORD (E3G_CLOCK_DETECT_BIT_WORD96|E3G_CLOCK_DETECT_BIT_WORD48) | ||
566 | #define E3G_CLOCK_DETECT_BIT_SPDIF (E3G_CLOCK_DETECT_BIT_SPDIF48|E3G_CLOCK_DETECT_BIT_SPDIF96) | ||
567 | |||
568 | /* Frequency control register */ | ||
569 | #define E3G_MAGIC_NUMBER 677376000 | ||
570 | #define E3G_FREQ_REG_DEFAULT (E3G_MAGIC_NUMBER / 48000 - 2) | ||
571 | #define E3G_FREQ_REG_MAX 0xffff | ||
572 | |||
573 | /* 3G external box types */ | ||
574 | #define E3G_GINA3G_BOX_TYPE 0x00 | ||
575 | #define E3G_LAYLA3G_BOX_TYPE 0x10 | ||
576 | #define E3G_ASIC_NOT_LOADED 0xffff | ||
577 | #define E3G_BOX_TYPE_MASK 0xf0 | ||
578 | |||
579 | #define EXT_3GBOX_NC 0x01 | ||
580 | #define EXT_3GBOX_NOT_SET 0x02 | ||
581 | |||
582 | |||
583 | /* | ||
584 | * | ||
585 | * Gina20 & Layla20 have input gain controls for the analog inputs; | ||
586 | * this is the magic number for the hardware that gives you 0 dB at -10. | ||
587 | * | ||
588 | */ | ||
589 | |||
590 | #define GL20_INPUT_GAIN_MAGIC_NUMBER 0xC8 | ||
591 | |||
592 | |||
593 | /* | ||
594 | * | ||
595 | * Defines how much time must pass between DSP load attempts | ||
596 | * | ||
597 | */ | ||
598 | |||
599 | #define DSP_LOAD_ATTEMPT_PERIOD 1000000L /* One second */ | ||
600 | |||
601 | |||
602 | /* | ||
603 | * | ||
604 | * Size of arrays for the comm page. MAX_PLAY_TAPS and MAX_REC_TAPS are | ||
605 | * no longer used, but the sizes must still be right for the DSP to see | ||
606 | * the comm page correctly. | ||
607 | * | ||
608 | */ | ||
609 | |||
610 | #define MONITOR_ARRAY_SIZE 0x180 | ||
611 | #define VMIXER_ARRAY_SIZE 0x40 | ||
612 | #define MIDI_OUT_BUFFER_SIZE 32 | ||
613 | #define MIDI_IN_BUFFER_SIZE 256 | ||
614 | #define MAX_PLAY_TAPS 168 | ||
615 | #define MAX_REC_TAPS 192 | ||
616 | #define DSP_MIDI_OUT_FIFO_SIZE 64 | ||
617 | |||
618 | |||
619 | /* sg_entry is a single entry for the scatter-gather list. The array of struct | ||
620 | sg_entry struct is read by the DSP, so all values must be little-endian. */ | ||
621 | |||
622 | #define MAX_SGLIST_ENTRIES 512 | ||
623 | |||
624 | struct sg_entry { | ||
625 | u32 addr; | ||
626 | u32 size; | ||
627 | }; | ||
628 | |||
629 | |||
630 | /**************************************************************************** | ||
631 | |||
632 | The comm page. This structure is read and written by the DSP; the | ||
633 | DSP code is a firm believer in the byte offsets written in the comments | ||
634 | at the end of each line. This structure should not be changed. | ||
635 | |||
636 | Any reads from or writes to this structure should be in little-endian format. | ||
637 | |||
638 | ****************************************************************************/ | ||
639 | |||
640 | struct comm_page { /* Base Length*/ | ||
641 | u32 comm_size; /* size of this object 0x000 4 */ | ||
642 | u32 flags; /* See Appendix A below 0x004 4 */ | ||
643 | u32 unused; /* Unused entry 0x008 4 */ | ||
644 | u32 sample_rate; /* Card sample rate in Hz 0x00c 4 */ | ||
645 | volatile u32 handshake; /* DSP command handshake 0x010 4 */ | ||
646 | u32 cmd_start; /* Chs. to start mask 0x014 4 */ | ||
647 | u32 cmd_stop; /* Chs. to stop mask 0x018 4 */ | ||
648 | u32 cmd_reset; /* Chs. to reset mask 0x01c 4 */ | ||
649 | u16 audio_format[DSP_MAXPIPES]; /* Chs. audio format 0x020 32*2 */ | ||
650 | struct sg_entry sglist_addr[DSP_MAXPIPES]; | ||
651 | /* Chs. Physical sglist addrs 0x060 32*8 */ | ||
652 | volatile u32 position[DSP_MAXPIPES]; | ||
653 | /* Positions for ea. ch. 0x160 32*4 */ | ||
654 | volatile s8 vu_meter[DSP_MAXPIPES]; | ||
655 | /* VU meters 0x1e0 32*1 */ | ||
656 | volatile s8 peak_meter[DSP_MAXPIPES]; | ||
657 | /* Peak meters 0x200 32*1 */ | ||
658 | s8 line_out_level[DSP_MAXAUDIOOUTPUTS]; | ||
659 | /* Output gain 0x220 16*1 */ | ||
660 | s8 line_in_level[DSP_MAXAUDIOINPUTS]; | ||
661 | /* Input gain 0x230 16*1 */ | ||
662 | s8 monitors[MONITOR_ARRAY_SIZE]; | ||
663 | /* Monitor map 0x240 0x180 */ | ||
664 | u32 play_coeff[MAX_PLAY_TAPS]; | ||
665 | /* Gina/Darla play filters - obsolete 0x3c0 168*4 */ | ||
666 | u32 rec_coeff[MAX_REC_TAPS]; | ||
667 | /* Gina/Darla record filters - obsolete 0x660 192*4 */ | ||
668 | volatile u16 midi_input[MIDI_IN_BUFFER_SIZE]; | ||
669 | /* MIDI input data transfer buffer 0x960 256*2 */ | ||
670 | u8 gd_clock_state; /* Chg Gina/Darla clock state 0xb60 1 */ | ||
671 | u8 gd_spdif_status; /* Chg. Gina/Darla S/PDIF state 0xb61 1 */ | ||
672 | u8 gd_resampler_state; /* Should always be 3 0xb62 1 */ | ||
673 | u8 filler2; /* 0xb63 1 */ | ||
674 | u32 nominal_level_mask; /* -10 level enable mask 0xb64 4 */ | ||
675 | u16 input_clock; /* Chg. Input clock state 0xb68 2 */ | ||
676 | u16 output_clock; /* Chg. Output clock state 0xb6a 2 */ | ||
677 | volatile u32 status_clocks; | ||
678 | /* Current Input clock state 0xb6c 4 */ | ||
679 | u32 ext_box_status; /* External box status 0xb70 4 */ | ||
680 | u32 cmd_add_buffer; /* Pipes to add (obsolete) 0xb74 4 */ | ||
681 | volatile u32 midi_out_free_count; | ||
682 | /* # of bytes free in MIDI output FIFO 0xb78 4 */ | ||
683 | u32 unused2; /* Cyclic pipes 0xb7c 4 */ | ||
684 | u32 control_register; | ||
685 | /* Mona, Gina24, Layla24, 3G ctrl reg 0xb80 4 */ | ||
686 | u32 e3g_frq_register; /* 3G frequency register 0xb84 4 */ | ||
687 | u8 filler[24]; /* filler 0xb88 24*1 */ | ||
688 | s8 vmixer[VMIXER_ARRAY_SIZE]; | ||
689 | /* Vmixer levels 0xba0 64*1 */ | ||
690 | u8 midi_output[MIDI_OUT_BUFFER_SIZE]; | ||
691 | /* MIDI output data 0xbe0 32*1 */ | ||
692 | }; | ||
693 | |||
694 | #endif /* _ECHO_DSP_ */ | ||
diff --git a/sound/pci/echoaudio/echoaudio_gml.c b/sound/pci/echoaudio/echoaudio_gml.c new file mode 100644 index 000000000000..3aa37e76ebab --- /dev/null +++ b/sound/pci/echoaudio/echoaudio_gml.c | |||
@@ -0,0 +1,198 @@ | |||
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 | /* These functions are common for Gina24, Layla24 and Mona cards */ | ||
33 | |||
34 | |||
35 | /* ASIC status check - some cards have one or two ASICs that need to be | ||
36 | loaded. Once that load is complete, this function is called to see if | ||
37 | the load was successful. | ||
38 | If this load fails, it does not necessarily mean that the hardware is | ||
39 | defective - the external box may be disconnected or turned off. */ | ||
40 | static int check_asic_status(struct echoaudio *chip) | ||
41 | { | ||
42 | u32 asic_status; | ||
43 | |||
44 | send_vector(chip, DSP_VC_TEST_ASIC); | ||
45 | |||
46 | /* The DSP will return a value to indicate whether or not the | ||
47 | ASIC is currently loaded */ | ||
48 | if (read_dsp(chip, &asic_status) < 0) { | ||
49 | DE_INIT(("check_asic_status: failed on read_dsp\n")); | ||
50 | chip->asic_loaded = FALSE; | ||
51 | return -EIO; | ||
52 | } | ||
53 | |||
54 | chip->asic_loaded = (asic_status == ASIC_ALREADY_LOADED); | ||
55 | return chip->asic_loaded ? 0 : -EIO; | ||
56 | } | ||
57 | |||
58 | |||
59 | |||
60 | /* Most configuration of Gina24, Layla24, or Mona is accomplished by writing | ||
61 | the control register. write_control_reg sends the new control register | ||
62 | value to the DSP. */ | ||
63 | static int write_control_reg(struct echoaudio *chip, u32 value, char force) | ||
64 | { | ||
65 | /* Handle the digital input auto-mute */ | ||
66 | if (chip->digital_in_automute) | ||
67 | value |= GML_DIGITAL_IN_AUTO_MUTE; | ||
68 | else | ||
69 | value &= ~GML_DIGITAL_IN_AUTO_MUTE; | ||
70 | |||
71 | DE_ACT(("write_control_reg: 0x%x\n", value)); | ||
72 | |||
73 | /* Write the control register */ | ||
74 | value = cpu_to_le32(value); | ||
75 | if (value != chip->comm_page->control_register || force) { | ||
76 | if (wait_handshake(chip)) | ||
77 | return -EIO; | ||
78 | chip->comm_page->control_register = value; | ||
79 | clear_handshake(chip); | ||
80 | return send_vector(chip, DSP_VC_WRITE_CONTROL_REG); | ||
81 | } | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | |||
86 | |||
87 | /* Gina24, Layla24, and Mona support digital input auto-mute. If the digital | ||
88 | input auto-mute is enabled, the DSP will only enable the digital inputs if | ||
89 | the card is syncing to a valid clock on the ADAT or S/PDIF inputs. | ||
90 | If the auto-mute is disabled, the digital inputs are enabled regardless of | ||
91 | what the input clock is set or what is connected. */ | ||
92 | static int set_input_auto_mute(struct echoaudio *chip, int automute) | ||
93 | { | ||
94 | DE_ACT(("set_input_auto_mute %d\n", automute)); | ||
95 | |||
96 | chip->digital_in_automute = automute; | ||
97 | |||
98 | /* Re-set the input clock to the current value - indirectly causes | ||
99 | the auto-mute flag to be sent to the DSP */ | ||
100 | return set_input_clock(chip, chip->input_clock); | ||
101 | } | ||
102 | |||
103 | |||
104 | |||
105 | /* S/PDIF coax / S/PDIF optical / ADAT - switch */ | ||
106 | static int set_digital_mode(struct echoaudio *chip, u8 mode) | ||
107 | { | ||
108 | u8 previous_mode; | ||
109 | int err, i, o; | ||
110 | |||
111 | if (chip->bad_board) | ||
112 | return -EIO; | ||
113 | |||
114 | /* All audio channels must be closed before changing the digital mode */ | ||
115 | snd_assert(!chip->pipe_alloc_mask, return -EAGAIN); | ||
116 | |||
117 | snd_assert(chip->digital_modes & (1 << mode), return -EINVAL); | ||
118 | |||
119 | previous_mode = chip->digital_mode; | ||
120 | err = dsp_set_digital_mode(chip, mode); | ||
121 | |||
122 | /* If we successfully changed the digital mode from or to ADAT, | ||
123 | then make sure all output, input and monitor levels are | ||
124 | updated by the DSP comm object. */ | ||
125 | if (err >= 0 && previous_mode != mode && | ||
126 | (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) { | ||
127 | spin_lock_irq(&chip->lock); | ||
128 | for (o = 0; o < num_busses_out(chip); o++) | ||
129 | for (i = 0; i < num_busses_in(chip); i++) | ||
130 | set_monitor_gain(chip, o, i, | ||
131 | chip->monitor_gain[o][i]); | ||
132 | |||
133 | #ifdef ECHOCARD_HAS_INPUT_GAIN | ||
134 | for (i = 0; i < num_busses_in(chip); i++) | ||
135 | set_input_gain(chip, i, chip->input_gain[i]); | ||
136 | update_input_line_level(chip); | ||
137 | #endif | ||
138 | |||
139 | for (o = 0; o < num_busses_out(chip); o++) | ||
140 | set_output_gain(chip, o, chip->output_gain[o]); | ||
141 | update_output_line_level(chip); | ||
142 | spin_unlock_irq(&chip->lock); | ||
143 | } | ||
144 | |||
145 | return err; | ||
146 | } | ||
147 | |||
148 | |||
149 | |||
150 | /* Set the S/PDIF output format */ | ||
151 | static int set_professional_spdif(struct echoaudio *chip, char prof) | ||
152 | { | ||
153 | u32 control_reg; | ||
154 | int err; | ||
155 | |||
156 | /* Clear the current S/PDIF flags */ | ||
157 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
158 | control_reg &= GML_SPDIF_FORMAT_CLEAR_MASK; | ||
159 | |||
160 | /* Set the new S/PDIF flags depending on the mode */ | ||
161 | control_reg |= GML_SPDIF_TWO_CHANNEL | GML_SPDIF_24_BIT | | ||
162 | GML_SPDIF_COPY_PERMIT; | ||
163 | if (prof) { | ||
164 | /* Professional mode */ | ||
165 | control_reg |= GML_SPDIF_PRO_MODE; | ||
166 | |||
167 | switch (chip->sample_rate) { | ||
168 | case 32000: | ||
169 | control_reg |= GML_SPDIF_SAMPLE_RATE0 | | ||
170 | GML_SPDIF_SAMPLE_RATE1; | ||
171 | break; | ||
172 | case 44100: | ||
173 | control_reg |= GML_SPDIF_SAMPLE_RATE0; | ||
174 | break; | ||
175 | case 48000: | ||
176 | control_reg |= GML_SPDIF_SAMPLE_RATE1; | ||
177 | break; | ||
178 | } | ||
179 | } else { | ||
180 | /* Consumer mode */ | ||
181 | switch (chip->sample_rate) { | ||
182 | case 32000: | ||
183 | control_reg |= GML_SPDIF_SAMPLE_RATE0 | | ||
184 | GML_SPDIF_SAMPLE_RATE1; | ||
185 | break; | ||
186 | case 48000: | ||
187 | control_reg |= GML_SPDIF_SAMPLE_RATE1; | ||
188 | break; | ||
189 | } | ||
190 | } | ||
191 | |||
192 | if ((err = write_control_reg(chip, control_reg, FALSE))) | ||
193 | return err; | ||
194 | chip->professional_spdif = prof; | ||
195 | DE_ACT(("set_professional_spdif to %s\n", | ||
196 | prof ? "Professional" : "Consumer")); | ||
197 | return 0; | ||
198 | } | ||
diff --git a/sound/pci/echoaudio/gina20.c b/sound/pci/echoaudio/gina20.c new file mode 100644 index 000000000000..29d6d12f80ca --- /dev/null +++ b/sound/pci/echoaudio/gina20.c | |||
@@ -0,0 +1,103 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define ECHOGALS_FAMILY | ||
20 | #define ECHOCARD_GINA20 | ||
21 | #define ECHOCARD_NAME "Gina20" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | #define ECHOCARD_HAS_INPUT_GAIN | ||
24 | #define ECHOCARD_HAS_DIGITAL_IO | ||
25 | #define ECHOCARD_HAS_EXTERNAL_CLOCK | ||
26 | #define ECHOCARD_HAS_ADAT FALSE | ||
27 | |||
28 | /* Pipe indexes */ | ||
29 | #define PX_ANALOG_OUT 0 /* 8 */ | ||
30 | #define PX_DIGITAL_OUT 8 /* 2 */ | ||
31 | #define PX_ANALOG_IN 10 /* 2 */ | ||
32 | #define PX_DIGITAL_IN 12 /* 2 */ | ||
33 | #define PX_NUM 14 | ||
34 | |||
35 | /* Bus indexes */ | ||
36 | #define BX_ANALOG_OUT 0 /* 8 */ | ||
37 | #define BX_DIGITAL_OUT 8 /* 2 */ | ||
38 | #define BX_ANALOG_IN 10 /* 2 */ | ||
39 | #define BX_DIGITAL_IN 12 /* 2 */ | ||
40 | #define BX_NUM 14 | ||
41 | |||
42 | |||
43 | #include <sound/driver.h> | ||
44 | #include <linux/delay.h> | ||
45 | #include <linux/init.h> | ||
46 | #include <linux/interrupt.h> | ||
47 | #include <linux/pci.h> | ||
48 | #include <linux/slab.h> | ||
49 | #include <linux/moduleparam.h> | ||
50 | #include <linux/firmware.h> | ||
51 | #include <sound/core.h> | ||
52 | #include <sound/info.h> | ||
53 | #include <sound/control.h> | ||
54 | #include <sound/pcm.h> | ||
55 | #include <sound/pcm_params.h> | ||
56 | #include <sound/asoundef.h> | ||
57 | #include <sound/initval.h> | ||
58 | #include <asm/io.h> | ||
59 | #include <asm/atomic.h> | ||
60 | #include "echoaudio.h" | ||
61 | |||
62 | #define FW_GINA20_DSP 0 | ||
63 | |||
64 | static const struct firmware card_fw[] = { | ||
65 | {0, "gina20_dsp.fw"} | ||
66 | }; | ||
67 | |||
68 | static struct pci_device_id snd_echo_ids[] = { | ||
69 | {0x1057, 0x1801, 0xECC0, 0x0020, 0, 0, 0}, /* DSP 56301 Gina20 rev.0 */ | ||
70 | {0,} | ||
71 | }; | ||
72 | |||
73 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
74 | .info = SNDRV_PCM_INFO_MMAP | | ||
75 | SNDRV_PCM_INFO_INTERLEAVED | | ||
76 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
77 | SNDRV_PCM_INFO_MMAP_VALID | | ||
78 | SNDRV_PCM_INFO_PAUSE | | ||
79 | SNDRV_PCM_INFO_SYNC_START, | ||
80 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
81 | SNDRV_PCM_FMTBIT_S16_LE | | ||
82 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
83 | SNDRV_PCM_FMTBIT_S32_LE | | ||
84 | SNDRV_PCM_FMTBIT_S32_BE, | ||
85 | .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, | ||
86 | .rate_min = 44100, | ||
87 | .rate_max = 48000, | ||
88 | .channels_min = 1, | ||
89 | .channels_max = 2, | ||
90 | .buffer_bytes_max = 262144, | ||
91 | .period_bytes_min = 32, | ||
92 | .period_bytes_max = 131072, | ||
93 | .periods_min = 2, | ||
94 | .periods_max = 220, | ||
95 | /* One page (4k) contains 512 instructions. I don't know if the hw | ||
96 | supports lists longer than this. In this case periods_max=220 is a | ||
97 | safe limit to make sure the list never exceeds 512 instructions. */ | ||
98 | }; | ||
99 | |||
100 | |||
101 | #include "gina20_dsp.c" | ||
102 | #include "echoaudio_dsp.c" | ||
103 | #include "echoaudio.c" | ||
diff --git a/sound/pci/echoaudio/gina20_dsp.c b/sound/pci/echoaudio/gina20_dsp.c new file mode 100644 index 000000000000..2757c8960843 --- /dev/null +++ b/sound/pci/echoaudio/gina20_dsp.c | |||
@@ -0,0 +1,215 @@ | |||
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 set_professional_spdif(struct echoaudio *chip, char prof); | ||
33 | static int update_flags(struct echoaudio *chip); | ||
34 | |||
35 | |||
36 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
37 | { | ||
38 | int err; | ||
39 | |||
40 | DE_INIT(("init_hw() - Gina20\n")); | ||
41 | snd_assert((subdevice_id & 0xfff0) == GINA20, return -ENODEV); | ||
42 | |||
43 | if ((err = init_dsp_comm_page(chip))) { | ||
44 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
45 | return err; | ||
46 | } | ||
47 | |||
48 | chip->device_id = device_id; | ||
49 | chip->subdevice_id = subdevice_id; | ||
50 | chip->bad_board = TRUE; | ||
51 | chip->dsp_code_to_load = &card_fw[FW_GINA20_DSP]; | ||
52 | chip->spdif_status = GD_SPDIF_STATUS_UNDEF; | ||
53 | chip->clock_state = GD_CLOCK_UNDEF; | ||
54 | /* Since this card has no ASIC, mark it as loaded so everything | ||
55 | works OK */ | ||
56 | chip->asic_loaded = TRUE; | ||
57 | chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | | ||
58 | ECHO_CLOCK_BIT_SPDIF; | ||
59 | |||
60 | if ((err = load_firmware(chip)) < 0) | ||
61 | return err; | ||
62 | chip->bad_board = FALSE; | ||
63 | |||
64 | if ((err = init_line_levels(chip)) < 0) | ||
65 | return err; | ||
66 | |||
67 | err = set_professional_spdif(chip, TRUE); | ||
68 | |||
69 | DE_INIT(("init_hw done\n")); | ||
70 | return err; | ||
71 | } | ||
72 | |||
73 | |||
74 | |||
75 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
76 | { | ||
77 | u32 clocks_from_dsp, clock_bits; | ||
78 | |||
79 | /* Map the DSP clock detect bits to the generic driver clock | ||
80 | detect bits */ | ||
81 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
82 | |||
83 | clock_bits = ECHO_CLOCK_BIT_INTERNAL; | ||
84 | |||
85 | if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF) | ||
86 | clock_bits |= ECHO_CLOCK_BIT_SPDIF; | ||
87 | |||
88 | return clock_bits; | ||
89 | } | ||
90 | |||
91 | |||
92 | |||
93 | /* The Gina20 has no ASIC. Just do nothing */ | ||
94 | static int load_asic(struct echoaudio *chip) | ||
95 | { | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | |||
100 | |||
101 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
102 | { | ||
103 | u8 clock_state, spdif_status; | ||
104 | |||
105 | if (wait_handshake(chip)) | ||
106 | return -EIO; | ||
107 | |||
108 | switch (rate) { | ||
109 | case 44100: | ||
110 | clock_state = GD_CLOCK_44; | ||
111 | spdif_status = GD_SPDIF_STATUS_44; | ||
112 | break; | ||
113 | case 48000: | ||
114 | clock_state = GD_CLOCK_48; | ||
115 | spdif_status = GD_SPDIF_STATUS_48; | ||
116 | break; | ||
117 | default: | ||
118 | clock_state = GD_CLOCK_NOCHANGE; | ||
119 | spdif_status = GD_SPDIF_STATUS_NOCHANGE; | ||
120 | break; | ||
121 | } | ||
122 | |||
123 | if (chip->clock_state == clock_state) | ||
124 | clock_state = GD_CLOCK_NOCHANGE; | ||
125 | if (spdif_status == chip->spdif_status) | ||
126 | spdif_status = GD_SPDIF_STATUS_NOCHANGE; | ||
127 | |||
128 | chip->comm_page->sample_rate = cpu_to_le32(rate); | ||
129 | chip->comm_page->gd_clock_state = clock_state; | ||
130 | chip->comm_page->gd_spdif_status = spdif_status; | ||
131 | chip->comm_page->gd_resampler_state = 3; /* magic number - should always be 3 */ | ||
132 | |||
133 | /* Save the new audio state if it changed */ | ||
134 | if (clock_state != GD_CLOCK_NOCHANGE) | ||
135 | chip->clock_state = clock_state; | ||
136 | if (spdif_status != GD_SPDIF_STATUS_NOCHANGE) | ||
137 | chip->spdif_status = spdif_status; | ||
138 | chip->sample_rate = rate; | ||
139 | |||
140 | clear_handshake(chip); | ||
141 | return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); | ||
142 | } | ||
143 | |||
144 | |||
145 | |||
146 | static int set_input_clock(struct echoaudio *chip, u16 clock) | ||
147 | { | ||
148 | DE_ACT(("set_input_clock:\n")); | ||
149 | |||
150 | switch (clock) { | ||
151 | case ECHO_CLOCK_INTERNAL: | ||
152 | /* Reset the audio state to unknown (just in case) */ | ||
153 | chip->clock_state = GD_CLOCK_UNDEF; | ||
154 | chip->spdif_status = GD_SPDIF_STATUS_UNDEF; | ||
155 | set_sample_rate(chip, chip->sample_rate); | ||
156 | chip->input_clock = clock; | ||
157 | DE_ACT(("Set Gina clock to INTERNAL\n")); | ||
158 | break; | ||
159 | case ECHO_CLOCK_SPDIF: | ||
160 | chip->comm_page->gd_clock_state = GD_CLOCK_SPDIFIN; | ||
161 | chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_NOCHANGE; | ||
162 | clear_handshake(chip); | ||
163 | send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); | ||
164 | chip->clock_state = GD_CLOCK_SPDIFIN; | ||
165 | DE_ACT(("Set Gina20 clock to SPDIF\n")); | ||
166 | chip->input_clock = clock; | ||
167 | break; | ||
168 | default: | ||
169 | return -EINVAL; | ||
170 | } | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | |||
176 | |||
177 | /* Set input bus gain (one unit is 0.5dB !) */ | ||
178 | static int set_input_gain(struct echoaudio *chip, u16 input, int gain) | ||
179 | { | ||
180 | snd_assert(input < num_busses_in(chip), return -EINVAL); | ||
181 | |||
182 | if (wait_handshake(chip)) | ||
183 | return -EIO; | ||
184 | |||
185 | chip->input_gain[input] = gain; | ||
186 | gain += GL20_INPUT_GAIN_MAGIC_NUMBER; | ||
187 | chip->comm_page->line_in_level[input] = gain; | ||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | |||
192 | |||
193 | /* Tell the DSP to reread the flags from the comm page */ | ||
194 | static int update_flags(struct echoaudio *chip) | ||
195 | { | ||
196 | if (wait_handshake(chip)) | ||
197 | return -EIO; | ||
198 | clear_handshake(chip); | ||
199 | return send_vector(chip, DSP_VC_UPDATE_FLAGS); | ||
200 | } | ||
201 | |||
202 | |||
203 | |||
204 | static int set_professional_spdif(struct echoaudio *chip, char prof) | ||
205 | { | ||
206 | DE_ACT(("set_professional_spdif %d\n", prof)); | ||
207 | if (prof) | ||
208 | chip->comm_page->flags |= | ||
209 | __constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); | ||
210 | else | ||
211 | chip->comm_page->flags &= | ||
212 | ~__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); | ||
213 | chip->professional_spdif = prof; | ||
214 | return update_flags(chip); | ||
215 | } | ||
diff --git a/sound/pci/echoaudio/gina24.c b/sound/pci/echoaudio/gina24.c new file mode 100644 index 000000000000..e464d720d0bd --- /dev/null +++ b/sound/pci/echoaudio/gina24.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define ECHO24_FAMILY | ||
20 | #define ECHOCARD_GINA24 | ||
21 | #define ECHOCARD_NAME "Gina24" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | #define ECHOCARD_HAS_ASIC | ||
24 | #define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL | ||
25 | #define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL | ||
26 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
27 | #define ECHOCARD_HAS_DIGITAL_IO | ||
28 | #define ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE | ||
29 | #define ECHOCARD_HAS_DIGITAL_MODE_SWITCH | ||
30 | #define ECHOCARD_HAS_EXTERNAL_CLOCK | ||
31 | #define ECHOCARD_HAS_ADAT 6 | ||
32 | #define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
33 | |||
34 | /* Pipe indexes */ | ||
35 | #define PX_ANALOG_OUT 0 /* 8 */ | ||
36 | #define PX_DIGITAL_OUT 8 /* 8 */ | ||
37 | #define PX_ANALOG_IN 16 /* 2 */ | ||
38 | #define PX_DIGITAL_IN 18 /* 8 */ | ||
39 | #define PX_NUM 26 | ||
40 | |||
41 | /* Bus indexes */ | ||
42 | #define BX_ANALOG_OUT 0 /* 8 */ | ||
43 | #define BX_DIGITAL_OUT 8 /* 8 */ | ||
44 | #define BX_ANALOG_IN 16 /* 2 */ | ||
45 | #define BX_DIGITAL_IN 18 /* 8 */ | ||
46 | #define BX_NUM 26 | ||
47 | |||
48 | |||
49 | #include <sound/driver.h> | ||
50 | #include <linux/delay.h> | ||
51 | #include <linux/init.h> | ||
52 | #include <linux/interrupt.h> | ||
53 | #include <linux/pci.h> | ||
54 | #include <linux/slab.h> | ||
55 | #include <linux/moduleparam.h> | ||
56 | #include <linux/firmware.h> | ||
57 | #include <sound/core.h> | ||
58 | #include <sound/info.h> | ||
59 | #include <sound/control.h> | ||
60 | #include <sound/pcm.h> | ||
61 | #include <sound/pcm_params.h> | ||
62 | #include <sound/asoundef.h> | ||
63 | #include <sound/initval.h> | ||
64 | #include <asm/io.h> | ||
65 | #include <asm/atomic.h> | ||
66 | #include "echoaudio.h" | ||
67 | |||
68 | #define FW_361_LOADER 0 | ||
69 | #define FW_GINA24_301_DSP 1 | ||
70 | #define FW_GINA24_361_DSP 2 | ||
71 | #define FW_GINA24_301_ASIC 3 | ||
72 | #define FW_GINA24_361_ASIC 4 | ||
73 | |||
74 | static const struct firmware card_fw[] = { | ||
75 | {0, "loader_dsp.fw"}, | ||
76 | {0, "gina24_301_dsp.fw"}, | ||
77 | {0, "gina24_361_dsp.fw"}, | ||
78 | {0, "gina24_301_asic.fw"}, | ||
79 | {0, "gina24_361_asic.fw"} | ||
80 | }; | ||
81 | |||
82 | static struct pci_device_id snd_echo_ids[] = { | ||
83 | {0x1057, 0x1801, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56301 Gina24 rev.0 */ | ||
84 | {0x1057, 0x1801, 0xECC0, 0x0051, 0, 0, 0}, /* DSP 56301 Gina24 rev.1 */ | ||
85 | {0x1057, 0x3410, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56361 Gina24 rev.0 */ | ||
86 | {0x1057, 0x3410, 0xECC0, 0x0051, 0, 0, 0}, /* DSP 56361 Gina24 rev.1 */ | ||
87 | {0,} | ||
88 | }; | ||
89 | |||
90 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
91 | .info = SNDRV_PCM_INFO_MMAP | | ||
92 | SNDRV_PCM_INFO_INTERLEAVED | | ||
93 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
94 | SNDRV_PCM_INFO_MMAP_VALID | | ||
95 | SNDRV_PCM_INFO_PAUSE | | ||
96 | SNDRV_PCM_INFO_SYNC_START, | ||
97 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
98 | SNDRV_PCM_FMTBIT_S16_LE | | ||
99 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
100 | SNDRV_PCM_FMTBIT_S32_LE | | ||
101 | SNDRV_PCM_FMTBIT_S32_BE, | ||
102 | .rates = SNDRV_PCM_RATE_8000_48000 | | ||
103 | SNDRV_PCM_RATE_88200 | | ||
104 | SNDRV_PCM_RATE_96000, | ||
105 | .rate_min = 8000, | ||
106 | .rate_max = 96000, | ||
107 | .channels_min = 1, | ||
108 | .channels_max = 8, | ||
109 | .buffer_bytes_max = 262144, | ||
110 | .period_bytes_min = 32, | ||
111 | .period_bytes_max = 131072, | ||
112 | .periods_min = 2, | ||
113 | .periods_max = 220, | ||
114 | /* One page (4k) contains 512 instructions. I don't know if the hw | ||
115 | supports lists longer than this. In this case periods_max=220 is a | ||
116 | safe limit to make sure the list never exceeds 512 instructions. | ||
117 | 220 ~= (512 - 1 - (BUFFER_BYTES_MAX / PAGE_SIZE)) / 2 */ | ||
118 | }; | ||
119 | |||
120 | #include "gina24_dsp.c" | ||
121 | #include "echoaudio_dsp.c" | ||
122 | #include "echoaudio_gml.c" | ||
123 | #include "echoaudio.c" | ||
diff --git a/sound/pci/echoaudio/gina24_dsp.c b/sound/pci/echoaudio/gina24_dsp.c new file mode 100644 index 000000000000..144fc567becf --- /dev/null +++ b/sound/pci/echoaudio/gina24_dsp.c | |||
@@ -0,0 +1,346 @@ | |||
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, | ||
37 | const struct firmware *asic); | ||
38 | static int check_asic_status(struct echoaudio *chip); | ||
39 | |||
40 | |||
41 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
42 | { | ||
43 | int err; | ||
44 | |||
45 | DE_INIT(("init_hw() - Gina24\n")); | ||
46 | snd_assert((subdevice_id & 0xfff0) == GINA24, return -ENODEV); | ||
47 | |||
48 | if ((err = init_dsp_comm_page(chip))) { | ||
49 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
50 | return err; | ||
51 | } | ||
52 | |||
53 | chip->device_id = device_id; | ||
54 | chip->subdevice_id = subdevice_id; | ||
55 | chip->bad_board = TRUE; | ||
56 | chip->input_clock_types = | ||
57 | ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | | ||
58 | ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96 | | ||
59 | ECHO_CLOCK_BIT_ADAT; | ||
60 | chip->professional_spdif = FALSE; | ||
61 | chip->digital_in_automute = TRUE; | ||
62 | chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; | ||
63 | |||
64 | /* Gina24 comes in both '301 and '361 flavors */ | ||
65 | if (chip->device_id == DEVICE_ID_56361) { | ||
66 | chip->dsp_code_to_load = &card_fw[FW_GINA24_361_DSP]; | ||
67 | chip->digital_modes = | ||
68 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | | ||
69 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | | ||
70 | ECHOCAPS_HAS_DIGITAL_MODE_ADAT; | ||
71 | } else { | ||
72 | chip->dsp_code_to_load = &card_fw[FW_GINA24_301_DSP]; | ||
73 | chip->digital_modes = | ||
74 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | | ||
75 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | | ||
76 | ECHOCAPS_HAS_DIGITAL_MODE_ADAT | | ||
77 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_CDROM; | ||
78 | } | ||
79 | |||
80 | if ((err = load_firmware(chip)) < 0) | ||
81 | return err; | ||
82 | chip->bad_board = FALSE; | ||
83 | |||
84 | if ((err = init_line_levels(chip)) < 0) | ||
85 | return err; | ||
86 | err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); | ||
87 | snd_assert(err >= 0, return err); | ||
88 | err = set_professional_spdif(chip, TRUE); | ||
89 | |||
90 | DE_INIT(("init_hw done\n")); | ||
91 | return err; | ||
92 | } | ||
93 | |||
94 | |||
95 | |||
96 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
97 | { | ||
98 | u32 clocks_from_dsp, clock_bits; | ||
99 | |||
100 | /* Map the DSP clock detect bits to the generic driver clock | ||
101 | detect bits */ | ||
102 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
103 | |||
104 | clock_bits = ECHO_CLOCK_BIT_INTERNAL; | ||
105 | |||
106 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF) | ||
107 | clock_bits |= ECHO_CLOCK_BIT_SPDIF; | ||
108 | |||
109 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT) | ||
110 | clock_bits |= ECHO_CLOCK_BIT_ADAT; | ||
111 | |||
112 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ESYNC) | ||
113 | clock_bits |= ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96; | ||
114 | |||
115 | return clock_bits; | ||
116 | } | ||
117 | |||
118 | |||
119 | |||
120 | /* Gina24 has an ASIC on the PCI card which must be loaded for anything | ||
121 | interesting to happen. */ | ||
122 | static int load_asic(struct echoaudio *chip) | ||
123 | { | ||
124 | u32 control_reg; | ||
125 | int err; | ||
126 | const struct firmware *fw; | ||
127 | |||
128 | if (chip->asic_loaded) | ||
129 | return 1; | ||
130 | |||
131 | /* Give the DSP a few milliseconds to settle down */ | ||
132 | mdelay(10); | ||
133 | |||
134 | /* Pick the correct ASIC for '301 or '361 Gina24 */ | ||
135 | if (chip->device_id == DEVICE_ID_56361) | ||
136 | fw = &card_fw[FW_GINA24_361_ASIC]; | ||
137 | else | ||
138 | fw = &card_fw[FW_GINA24_301_ASIC]; | ||
139 | |||
140 | if ((err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, fw)) < 0) | ||
141 | return err; | ||
142 | |||
143 | chip->asic_code = fw; | ||
144 | |||
145 | /* Now give the new ASIC a little time to set up */ | ||
146 | mdelay(10); | ||
147 | /* See if it worked */ | ||
148 | err = check_asic_status(chip); | ||
149 | |||
150 | /* Set up the control register if the load succeeded - | ||
151 | 48 kHz, internal clock, S/PDIF RCA mode */ | ||
152 | if (!err) { | ||
153 | control_reg = GML_CONVERTER_ENABLE | GML_48KHZ; | ||
154 | err = write_control_reg(chip, control_reg, TRUE); | ||
155 | } | ||
156 | DE_INIT(("load_asic() done\n")); | ||
157 | return err; | ||
158 | } | ||
159 | |||
160 | |||
161 | |||
162 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
163 | { | ||
164 | u32 control_reg, clock; | ||
165 | |||
166 | snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT, | ||
167 | return -EINVAL); | ||
168 | |||
169 | /* Only set the clock for internal mode. */ | ||
170 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { | ||
171 | DE_ACT(("set_sample_rate: Cannot set sample rate - " | ||
172 | "clock not set to CLK_CLOCKININTERNAL\n")); | ||
173 | /* Save the rate anyhow */ | ||
174 | chip->comm_page->sample_rate = cpu_to_le32(rate); | ||
175 | chip->sample_rate = rate; | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | clock = 0; | ||
180 | |||
181 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
182 | control_reg &= GML_CLOCK_CLEAR_MASK & GML_SPDIF_RATE_CLEAR_MASK; | ||
183 | |||
184 | switch (rate) { | ||
185 | case 96000: | ||
186 | clock = GML_96KHZ; | ||
187 | break; | ||
188 | case 88200: | ||
189 | clock = GML_88KHZ; | ||
190 | break; | ||
191 | case 48000: | ||
192 | clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1; | ||
193 | break; | ||
194 | case 44100: | ||
195 | clock = GML_44KHZ; | ||
196 | /* Professional mode ? */ | ||
197 | if (control_reg & GML_SPDIF_PRO_MODE) | ||
198 | clock |= GML_SPDIF_SAMPLE_RATE0; | ||
199 | break; | ||
200 | case 32000: | ||
201 | clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 | | ||
202 | GML_SPDIF_SAMPLE_RATE1; | ||
203 | break; | ||
204 | case 22050: | ||
205 | clock = GML_22KHZ; | ||
206 | break; | ||
207 | case 16000: | ||
208 | clock = GML_16KHZ; | ||
209 | break; | ||
210 | case 11025: | ||
211 | clock = GML_11KHZ; | ||
212 | break; | ||
213 | case 8000: | ||
214 | clock = GML_8KHZ; | ||
215 | break; | ||
216 | default: | ||
217 | DE_ACT(("set_sample_rate: %d invalid!\n", rate)); | ||
218 | return -EINVAL; | ||
219 | } | ||
220 | |||
221 | control_reg |= clock; | ||
222 | |||
223 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ | ||
224 | chip->sample_rate = rate; | ||
225 | DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); | ||
226 | |||
227 | return write_control_reg(chip, control_reg, FALSE); | ||
228 | } | ||
229 | |||
230 | |||
231 | |||
232 | static int set_input_clock(struct echoaudio *chip, u16 clock) | ||
233 | { | ||
234 | u32 control_reg, clocks_from_dsp; | ||
235 | |||
236 | DE_ACT(("set_input_clock:\n")); | ||
237 | |||
238 | /* Mask off the clock select bits */ | ||
239 | control_reg = le32_to_cpu(chip->comm_page->control_register) & | ||
240 | GML_CLOCK_CLEAR_MASK; | ||
241 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
242 | |||
243 | switch (clock) { | ||
244 | case ECHO_CLOCK_INTERNAL: | ||
245 | DE_ACT(("Set Gina24 clock to INTERNAL\n")); | ||
246 | chip->input_clock = ECHO_CLOCK_INTERNAL; | ||
247 | return set_sample_rate(chip, chip->sample_rate); | ||
248 | case ECHO_CLOCK_SPDIF: | ||
249 | if (chip->digital_mode == DIGITAL_MODE_ADAT) | ||
250 | return -EAGAIN; | ||
251 | DE_ACT(("Set Gina24 clock to SPDIF\n")); | ||
252 | control_reg |= GML_SPDIF_CLOCK; | ||
253 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96) | ||
254 | control_reg |= GML_DOUBLE_SPEED_MODE; | ||
255 | else | ||
256 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
257 | break; | ||
258 | case ECHO_CLOCK_ADAT: | ||
259 | if (chip->digital_mode != DIGITAL_MODE_ADAT) | ||
260 | return -EAGAIN; | ||
261 | DE_ACT(("Set Gina24 clock to ADAT\n")); | ||
262 | control_reg |= GML_ADAT_CLOCK; | ||
263 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
264 | break; | ||
265 | case ECHO_CLOCK_ESYNC: | ||
266 | DE_ACT(("Set Gina24 clock to ESYNC\n")); | ||
267 | control_reg |= GML_ESYNC_CLOCK; | ||
268 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
269 | break; | ||
270 | case ECHO_CLOCK_ESYNC96: | ||
271 | DE_ACT(("Set Gina24 clock to ESYNC96\n")); | ||
272 | control_reg |= GML_ESYNC_CLOCK | GML_DOUBLE_SPEED_MODE; | ||
273 | break; | ||
274 | default: | ||
275 | DE_ACT(("Input clock 0x%x not supported for Gina24\n", clock)); | ||
276 | return -EINVAL; | ||
277 | } | ||
278 | |||
279 | chip->input_clock = clock; | ||
280 | return write_control_reg(chip, control_reg, TRUE); | ||
281 | } | ||
282 | |||
283 | |||
284 | |||
285 | static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | ||
286 | { | ||
287 | u32 control_reg; | ||
288 | int err, incompatible_clock; | ||
289 | |||
290 | /* Set clock to "internal" if it's not compatible with the new mode */ | ||
291 | incompatible_clock = FALSE; | ||
292 | switch (mode) { | ||
293 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
294 | case DIGITAL_MODE_SPDIF_CDROM: | ||
295 | case DIGITAL_MODE_SPDIF_RCA: | ||
296 | if (chip->input_clock == ECHO_CLOCK_ADAT) | ||
297 | incompatible_clock = TRUE; | ||
298 | break; | ||
299 | case DIGITAL_MODE_ADAT: | ||
300 | if (chip->input_clock == ECHO_CLOCK_SPDIF) | ||
301 | incompatible_clock = TRUE; | ||
302 | break; | ||
303 | default: | ||
304 | DE_ACT(("Digital mode not supported: %d\n", mode)); | ||
305 | return -EINVAL; | ||
306 | } | ||
307 | |||
308 | spin_lock_irq(&chip->lock); | ||
309 | |||
310 | if (incompatible_clock) { /* Switch to 48KHz, internal */ | ||
311 | chip->sample_rate = 48000; | ||
312 | set_input_clock(chip, ECHO_CLOCK_INTERNAL); | ||
313 | } | ||
314 | |||
315 | /* Clear the current digital mode */ | ||
316 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
317 | control_reg &= GML_DIGITAL_MODE_CLEAR_MASK; | ||
318 | |||
319 | /* Tweak the control reg */ | ||
320 | switch (mode) { | ||
321 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
322 | control_reg |= GML_SPDIF_OPTICAL_MODE; | ||
323 | break; | ||
324 | case DIGITAL_MODE_SPDIF_CDROM: | ||
325 | /* '361 Gina24 cards do not have the S/PDIF CD-ROM mode */ | ||
326 | if (chip->device_id == DEVICE_ID_56301) | ||
327 | control_reg |= GML_SPDIF_CDROM_MODE; | ||
328 | break; | ||
329 | case DIGITAL_MODE_SPDIF_RCA: | ||
330 | /* GML_SPDIF_OPTICAL_MODE bit cleared */ | ||
331 | break; | ||
332 | case DIGITAL_MODE_ADAT: | ||
333 | control_reg |= GML_ADAT_MODE; | ||
334 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
335 | break; | ||
336 | } | ||
337 | |||
338 | err = write_control_reg(chip, control_reg, TRUE); | ||
339 | spin_unlock_irq(&chip->lock); | ||
340 | if (err < 0) | ||
341 | return err; | ||
342 | chip->digital_mode = mode; | ||
343 | |||
344 | DE_ACT(("set_digital_mode to %d\n", chip->digital_mode)); | ||
345 | return incompatible_clock; | ||
346 | } | ||
diff --git a/sound/pci/echoaudio/indigo.c b/sound/pci/echoaudio/indigo.c new file mode 100644 index 000000000000..bfd2467099ac --- /dev/null +++ b/sound/pci/echoaudio/indigo.c | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define INDIGO_FAMILY | ||
20 | #define ECHOCARD_INDIGO | ||
21 | #define ECHOCARD_NAME "Indigo" | ||
22 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
23 | #define ECHOCARD_HAS_VMIXER | ||
24 | #define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
25 | |||
26 | /* Pipe indexes */ | ||
27 | #define PX_ANALOG_OUT 0 /* 8 */ | ||
28 | #define PX_DIGITAL_OUT 8 /* 0 */ | ||
29 | #define PX_ANALOG_IN 8 /* 0 */ | ||
30 | #define PX_DIGITAL_IN 8 /* 0 */ | ||
31 | #define PX_NUM 8 | ||
32 | |||
33 | /* Bus indexes */ | ||
34 | #define BX_ANALOG_OUT 0 /* 2 */ | ||
35 | #define BX_DIGITAL_OUT 2 /* 0 */ | ||
36 | #define BX_ANALOG_IN 2 /* 0 */ | ||
37 | #define BX_DIGITAL_IN 2 /* 0 */ | ||
38 | #define BX_NUM 2 | ||
39 | |||
40 | |||
41 | #include <sound/driver.h> | ||
42 | #include <linux/delay.h> | ||
43 | #include <linux/init.h> | ||
44 | #include <linux/interrupt.h> | ||
45 | #include <linux/pci.h> | ||
46 | #include <linux/slab.h> | ||
47 | #include <linux/moduleparam.h> | ||
48 | #include <linux/firmware.h> | ||
49 | #include <sound/core.h> | ||
50 | #include <sound/info.h> | ||
51 | #include <sound/control.h> | ||
52 | #include <sound/pcm.h> | ||
53 | #include <sound/pcm_params.h> | ||
54 | #include <sound/asoundef.h> | ||
55 | #include <sound/initval.h> | ||
56 | #include <asm/io.h> | ||
57 | #include <asm/atomic.h> | ||
58 | #include "echoaudio.h" | ||
59 | |||
60 | #define FW_361_LOADER 0 | ||
61 | #define FW_INDIGO_DSP 1 | ||
62 | |||
63 | static const struct firmware card_fw[] = { | ||
64 | {0, "loader_dsp.fw"}, | ||
65 | {0, "indigo_dsp.fw"} | ||
66 | }; | ||
67 | |||
68 | static struct pci_device_id snd_echo_ids[] = { | ||
69 | {0x1057, 0x3410, 0xECC0, 0x0090, 0, 0, 0}, /* Indigo */ | ||
70 | {0,} | ||
71 | }; | ||
72 | |||
73 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
74 | .info = SNDRV_PCM_INFO_MMAP | | ||
75 | SNDRV_PCM_INFO_INTERLEAVED | | ||
76 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
77 | SNDRV_PCM_INFO_MMAP_VALID | | ||
78 | SNDRV_PCM_INFO_PAUSE | | ||
79 | SNDRV_PCM_INFO_SYNC_START, | ||
80 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
81 | SNDRV_PCM_FMTBIT_S16_LE | | ||
82 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
83 | SNDRV_PCM_FMTBIT_S32_LE | | ||
84 | SNDRV_PCM_FMTBIT_S32_BE, | ||
85 | .rates = SNDRV_PCM_RATE_32000 | | ||
86 | SNDRV_PCM_RATE_44100 | | ||
87 | SNDRV_PCM_RATE_48000 | | ||
88 | SNDRV_PCM_RATE_88200 | | ||
89 | SNDRV_PCM_RATE_96000, | ||
90 | .rate_min = 32000, | ||
91 | .rate_max = 96000, | ||
92 | .channels_min = 1, | ||
93 | .channels_max = 8, | ||
94 | .buffer_bytes_max = 262144, | ||
95 | .period_bytes_min = 32, | ||
96 | .period_bytes_max = 131072, | ||
97 | .periods_min = 2, | ||
98 | .periods_max = 220, | ||
99 | }; | ||
100 | |||
101 | #include "indigo_dsp.c" | ||
102 | #include "echoaudio_dsp.c" | ||
103 | #include "echoaudio.c" | ||
104 | |||
diff --git a/sound/pci/echoaudio/indigo_dsp.c b/sound/pci/echoaudio/indigo_dsp.c new file mode 100644 index 000000000000..d6ac7734609e --- /dev/null +++ b/sound/pci/echoaudio/indigo_dsp.c | |||
@@ -0,0 +1,170 @@ | |||
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 set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | ||
33 | int gain); | ||
34 | static int update_vmixer_level(struct echoaudio *chip); | ||
35 | |||
36 | |||
37 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
38 | { | ||
39 | int err; | ||
40 | |||
41 | DE_INIT(("init_hw() - Indigo\n")); | ||
42 | snd_assert((subdevice_id & 0xfff0) == INDIGO, return -ENODEV); | ||
43 | |||
44 | if ((err = init_dsp_comm_page(chip))) { | ||
45 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
46 | return err; | ||
47 | } | ||
48 | |||
49 | chip->device_id = device_id; | ||
50 | chip->subdevice_id = subdevice_id; | ||
51 | chip->bad_board = TRUE; | ||
52 | chip->dsp_code_to_load = &card_fw[FW_INDIGO_DSP]; | ||
53 | /* Since this card has no ASIC, mark it as loaded so everything | ||
54 | works OK */ | ||
55 | chip->asic_loaded = TRUE; | ||
56 | chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL; | ||
57 | |||
58 | if ((err = load_firmware(chip)) < 0) | ||
59 | return err; | ||
60 | chip->bad_board = FALSE; | ||
61 | |||
62 | if ((err = init_line_levels(chip)) < 0) | ||
63 | return err; | ||
64 | |||
65 | /* Default routing of the virtual channels: all vchannels are routed | ||
66 | to the stereo output */ | ||
67 | set_vmixer_gain(chip, 0, 0, 0); | ||
68 | set_vmixer_gain(chip, 1, 1, 0); | ||
69 | set_vmixer_gain(chip, 0, 2, 0); | ||
70 | set_vmixer_gain(chip, 1, 3, 0); | ||
71 | set_vmixer_gain(chip, 0, 4, 0); | ||
72 | set_vmixer_gain(chip, 1, 5, 0); | ||
73 | set_vmixer_gain(chip, 0, 6, 0); | ||
74 | set_vmixer_gain(chip, 1, 7, 0); | ||
75 | err = update_vmixer_level(chip); | ||
76 | |||
77 | DE_INIT(("init_hw done\n")); | ||
78 | return err; | ||
79 | } | ||
80 | |||
81 | |||
82 | |||
83 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
84 | { | ||
85 | return ECHO_CLOCK_BIT_INTERNAL; | ||
86 | } | ||
87 | |||
88 | |||
89 | |||
90 | /* The Indigo has no ASIC. Just do nothing */ | ||
91 | static int load_asic(struct echoaudio *chip) | ||
92 | { | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | |||
97 | |||
98 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
99 | { | ||
100 | u32 control_reg; | ||
101 | |||
102 | switch (rate) { | ||
103 | case 96000: | ||
104 | control_reg = MIA_96000; | ||
105 | break; | ||
106 | case 88200: | ||
107 | control_reg = MIA_88200; | ||
108 | break; | ||
109 | case 48000: | ||
110 | control_reg = MIA_48000; | ||
111 | break; | ||
112 | case 44100: | ||
113 | control_reg = MIA_44100; | ||
114 | break; | ||
115 | case 32000: | ||
116 | control_reg = MIA_32000; | ||
117 | break; | ||
118 | default: | ||
119 | DE_ACT(("set_sample_rate: %d invalid!\n", rate)); | ||
120 | return -EINVAL; | ||
121 | } | ||
122 | |||
123 | /* Set the control register if it has changed */ | ||
124 | if (control_reg != le32_to_cpu(chip->comm_page->control_register)) { | ||
125 | if (wait_handshake(chip)) | ||
126 | return -EIO; | ||
127 | |||
128 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ | ||
129 | chip->comm_page->control_register = cpu_to_le32(control_reg); | ||
130 | chip->sample_rate = rate; | ||
131 | |||
132 | clear_handshake(chip); | ||
133 | return send_vector(chip, DSP_VC_UPDATE_CLOCKS); | ||
134 | } | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | |||
139 | |||
140 | /* This function routes the sound from a virtual channel to a real output */ | ||
141 | static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | ||
142 | int gain) | ||
143 | { | ||
144 | int index; | ||
145 | |||
146 | snd_assert(pipe < num_pipes_out(chip) && | ||
147 | output < num_busses_out(chip), return -EINVAL); | ||
148 | |||
149 | if (wait_handshake(chip)) | ||
150 | return -EIO; | ||
151 | |||
152 | chip->vmixer_gain[output][pipe] = gain; | ||
153 | index = output * num_pipes_out(chip) + pipe; | ||
154 | chip->comm_page->vmixer[index] = gain; | ||
155 | |||
156 | DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | |||
161 | |||
162 | /* Tell the DSP to read and update virtual mixer levels in comm page. */ | ||
163 | static int update_vmixer_level(struct echoaudio *chip) | ||
164 | { | ||
165 | if (wait_handshake(chip)) | ||
166 | return -EIO; | ||
167 | clear_handshake(chip); | ||
168 | return send_vector(chip, DSP_VC_SET_VMIXER_GAIN); | ||
169 | } | ||
170 | |||
diff --git a/sound/pci/echoaudio/indigodj.c b/sound/pci/echoaudio/indigodj.c new file mode 100644 index 000000000000..8ed7ff1fd875 --- /dev/null +++ b/sound/pci/echoaudio/indigodj.c | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define INDIGO_FAMILY | ||
20 | #define ECHOCARD_INDIGO_DJ | ||
21 | #define ECHOCARD_NAME "Indigo DJ" | ||
22 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
23 | #define ECHOCARD_HAS_VMIXER | ||
24 | #define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
25 | |||
26 | /* Pipe indexes */ | ||
27 | #define PX_ANALOG_OUT 0 /* 8 */ | ||
28 | #define PX_DIGITAL_OUT 8 /* 0 */ | ||
29 | #define PX_ANALOG_IN 8 /* 0 */ | ||
30 | #define PX_DIGITAL_IN 8 /* 0 */ | ||
31 | #define PX_NUM 8 | ||
32 | |||
33 | /* Bus indexes */ | ||
34 | #define BX_ANALOG_OUT 0 /* 4 */ | ||
35 | #define BX_DIGITAL_OUT 4 /* 0 */ | ||
36 | #define BX_ANALOG_IN 4 /* 0 */ | ||
37 | #define BX_DIGITAL_IN 4 /* 0 */ | ||
38 | #define BX_NUM 4 | ||
39 | |||
40 | |||
41 | #include <sound/driver.h> | ||
42 | #include <linux/delay.h> | ||
43 | #include <linux/init.h> | ||
44 | #include <linux/interrupt.h> | ||
45 | #include <linux/pci.h> | ||
46 | #include <linux/slab.h> | ||
47 | #include <linux/moduleparam.h> | ||
48 | #include <linux/firmware.h> | ||
49 | #include <sound/core.h> | ||
50 | #include <sound/info.h> | ||
51 | #include <sound/control.h> | ||
52 | #include <sound/pcm.h> | ||
53 | #include <sound/pcm_params.h> | ||
54 | #include <sound/asoundef.h> | ||
55 | #include <sound/initval.h> | ||
56 | #include <asm/io.h> | ||
57 | #include <asm/atomic.h> | ||
58 | #include "echoaudio.h" | ||
59 | |||
60 | #define FW_361_LOADER 0 | ||
61 | #define FW_INDIGO_DJ_DSP 1 | ||
62 | |||
63 | static const struct firmware card_fw[] = { | ||
64 | {0, "loader_dsp.fw"}, | ||
65 | {0, "indigo_dj_dsp.fw"} | ||
66 | }; | ||
67 | |||
68 | static struct pci_device_id snd_echo_ids[] = { | ||
69 | {0x1057, 0x3410, 0xECC0, 0x00B0, 0, 0, 0}, /* Indigo DJ*/ | ||
70 | {0,} | ||
71 | }; | ||
72 | |||
73 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
74 | .info = SNDRV_PCM_INFO_MMAP | | ||
75 | SNDRV_PCM_INFO_INTERLEAVED | | ||
76 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
77 | SNDRV_PCM_INFO_MMAP_VALID | | ||
78 | SNDRV_PCM_INFO_PAUSE | | ||
79 | SNDRV_PCM_INFO_SYNC_START, | ||
80 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
81 | SNDRV_PCM_FMTBIT_S16_LE | | ||
82 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
83 | SNDRV_PCM_FMTBIT_S32_LE | | ||
84 | SNDRV_PCM_FMTBIT_S32_BE, | ||
85 | .rates = SNDRV_PCM_RATE_32000 | | ||
86 | SNDRV_PCM_RATE_44100 | | ||
87 | SNDRV_PCM_RATE_48000 | | ||
88 | SNDRV_PCM_RATE_88200 | | ||
89 | SNDRV_PCM_RATE_96000, | ||
90 | .rate_min = 32000, | ||
91 | .rate_max = 96000, | ||
92 | .channels_min = 1, | ||
93 | .channels_max = 4, | ||
94 | .buffer_bytes_max = 262144, | ||
95 | .period_bytes_min = 32, | ||
96 | .period_bytes_max = 131072, | ||
97 | .periods_min = 2, | ||
98 | .periods_max = 220, | ||
99 | }; | ||
100 | |||
101 | #include "indigodj_dsp.c" | ||
102 | #include "echoaudio_dsp.c" | ||
103 | #include "echoaudio.c" | ||
104 | |||
diff --git a/sound/pci/echoaudio/indigodj_dsp.c b/sound/pci/echoaudio/indigodj_dsp.c new file mode 100644 index 000000000000..500e150b49fc --- /dev/null +++ b/sound/pci/echoaudio/indigodj_dsp.c | |||
@@ -0,0 +1,170 @@ | |||
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 set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | ||
33 | int gain); | ||
34 | static int update_vmixer_level(struct echoaudio *chip); | ||
35 | |||
36 | |||
37 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
38 | { | ||
39 | int err; | ||
40 | |||
41 | DE_INIT(("init_hw() - Indigo DJ\n")); | ||
42 | snd_assert((subdevice_id & 0xfff0) == INDIGO_DJ, return -ENODEV); | ||
43 | |||
44 | if ((err = init_dsp_comm_page(chip))) { | ||
45 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
46 | return err; | ||
47 | } | ||
48 | |||
49 | chip->device_id = device_id; | ||
50 | chip->subdevice_id = subdevice_id; | ||
51 | chip->bad_board = TRUE; | ||
52 | chip->dsp_code_to_load = &card_fw[FW_INDIGO_DJ_DSP]; | ||
53 | /* Since this card has no ASIC, mark it as loaded so everything | ||
54 | works OK */ | ||
55 | chip->asic_loaded = TRUE; | ||
56 | chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL; | ||
57 | |||
58 | if ((err = load_firmware(chip)) < 0) | ||
59 | return err; | ||
60 | chip->bad_board = FALSE; | ||
61 | |||
62 | if ((err = init_line_levels(chip)) < 0) | ||
63 | return err; | ||
64 | |||
65 | /* Default routing of the virtual channels: vchannels 0-3 and | ||
66 | vchannels 4-7 are routed to real channels 0-4 */ | ||
67 | set_vmixer_gain(chip, 0, 0, 0); | ||
68 | set_vmixer_gain(chip, 1, 1, 0); | ||
69 | set_vmixer_gain(chip, 2, 2, 0); | ||
70 | set_vmixer_gain(chip, 3, 3, 0); | ||
71 | set_vmixer_gain(chip, 0, 4, 0); | ||
72 | set_vmixer_gain(chip, 1, 5, 0); | ||
73 | set_vmixer_gain(chip, 2, 6, 0); | ||
74 | set_vmixer_gain(chip, 3, 7, 0); | ||
75 | err = update_vmixer_level(chip); | ||
76 | |||
77 | DE_INIT(("init_hw done\n")); | ||
78 | return err; | ||
79 | } | ||
80 | |||
81 | |||
82 | |||
83 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
84 | { | ||
85 | return ECHO_CLOCK_BIT_INTERNAL; | ||
86 | } | ||
87 | |||
88 | |||
89 | |||
90 | /* The IndigoDJ has no ASIC. Just do nothing */ | ||
91 | static int load_asic(struct echoaudio *chip) | ||
92 | { | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | |||
97 | |||
98 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
99 | { | ||
100 | u32 control_reg; | ||
101 | |||
102 | switch (rate) { | ||
103 | case 96000: | ||
104 | control_reg = MIA_96000; | ||
105 | break; | ||
106 | case 88200: | ||
107 | control_reg = MIA_88200; | ||
108 | break; | ||
109 | case 48000: | ||
110 | control_reg = MIA_48000; | ||
111 | break; | ||
112 | case 44100: | ||
113 | control_reg = MIA_44100; | ||
114 | break; | ||
115 | case 32000: | ||
116 | control_reg = MIA_32000; | ||
117 | break; | ||
118 | default: | ||
119 | DE_ACT(("set_sample_rate: %d invalid!\n", rate)); | ||
120 | return -EINVAL; | ||
121 | } | ||
122 | |||
123 | /* Set the control register if it has changed */ | ||
124 | if (control_reg != le32_to_cpu(chip->comm_page->control_register)) { | ||
125 | if (wait_handshake(chip)) | ||
126 | return -EIO; | ||
127 | |||
128 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ | ||
129 | chip->comm_page->control_register = cpu_to_le32(control_reg); | ||
130 | chip->sample_rate = rate; | ||
131 | |||
132 | clear_handshake(chip); | ||
133 | return send_vector(chip, DSP_VC_UPDATE_CLOCKS); | ||
134 | } | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | |||
139 | |||
140 | /* This function routes the sound from a virtual channel to a real output */ | ||
141 | static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | ||
142 | int gain) | ||
143 | { | ||
144 | int index; | ||
145 | |||
146 | snd_assert(pipe < num_pipes_out(chip) && | ||
147 | output < num_busses_out(chip), return -EINVAL); | ||
148 | |||
149 | if (wait_handshake(chip)) | ||
150 | return -EIO; | ||
151 | |||
152 | chip->vmixer_gain[output][pipe] = gain; | ||
153 | index = output * num_pipes_out(chip) + pipe; | ||
154 | chip->comm_page->vmixer[index] = gain; | ||
155 | |||
156 | DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | |||
161 | |||
162 | /* Tell the DSP to read and update virtual mixer levels in comm page. */ | ||
163 | static int update_vmixer_level(struct echoaudio *chip) | ||
164 | { | ||
165 | if (wait_handshake(chip)) | ||
166 | return -EIO; | ||
167 | clear_handshake(chip); | ||
168 | return send_vector(chip, DSP_VC_SET_VMIXER_GAIN); | ||
169 | } | ||
170 | |||
diff --git a/sound/pci/echoaudio/indigoio.c b/sound/pci/echoaudio/indigoio.c new file mode 100644 index 000000000000..a8788e959171 --- /dev/null +++ b/sound/pci/echoaudio/indigoio.c | |||
@@ -0,0 +1,105 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define INDIGO_FAMILY | ||
20 | #define ECHOCARD_INDIGO_IO | ||
21 | #define ECHOCARD_NAME "Indigo IO" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
24 | #define ECHOCARD_HAS_VMIXER | ||
25 | #define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
26 | |||
27 | /* Pipe indexes */ | ||
28 | #define PX_ANALOG_OUT 0 /* 8 */ | ||
29 | #define PX_DIGITAL_OUT 8 /* 0 */ | ||
30 | #define PX_ANALOG_IN 8 /* 2 */ | ||
31 | #define PX_DIGITAL_IN 10 /* 0 */ | ||
32 | #define PX_NUM 10 | ||
33 | |||
34 | /* Bus indexes */ | ||
35 | #define BX_ANALOG_OUT 0 /* 2 */ | ||
36 | #define BX_DIGITAL_OUT 2 /* 0 */ | ||
37 | #define BX_ANALOG_IN 2 /* 2 */ | ||
38 | #define BX_DIGITAL_IN 4 /* 0 */ | ||
39 | #define BX_NUM 4 | ||
40 | |||
41 | |||
42 | #include <sound/driver.h> | ||
43 | #include <linux/delay.h> | ||
44 | #include <linux/init.h> | ||
45 | #include <linux/interrupt.h> | ||
46 | #include <linux/pci.h> | ||
47 | #include <linux/slab.h> | ||
48 | #include <linux/moduleparam.h> | ||
49 | #include <linux/firmware.h> | ||
50 | #include <sound/core.h> | ||
51 | #include <sound/info.h> | ||
52 | #include <sound/control.h> | ||
53 | #include <sound/pcm.h> | ||
54 | #include <sound/pcm_params.h> | ||
55 | #include <sound/asoundef.h> | ||
56 | #include <sound/initval.h> | ||
57 | #include <asm/io.h> | ||
58 | #include <asm/atomic.h> | ||
59 | #include "echoaudio.h" | ||
60 | |||
61 | #define FW_361_LOADER 0 | ||
62 | #define FW_INDIGO_IO_DSP 1 | ||
63 | |||
64 | static const struct firmware card_fw[] = { | ||
65 | {0, "loader_dsp.fw"}, | ||
66 | {0, "indigo_io_dsp.fw"} | ||
67 | }; | ||
68 | |||
69 | static struct pci_device_id snd_echo_ids[] = { | ||
70 | {0x1057, 0x3410, 0xECC0, 0x00A0, 0, 0, 0}, /* Indigo IO*/ | ||
71 | {0,} | ||
72 | }; | ||
73 | |||
74 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
75 | .info = SNDRV_PCM_INFO_MMAP | | ||
76 | SNDRV_PCM_INFO_INTERLEAVED | | ||
77 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
78 | SNDRV_PCM_INFO_MMAP_VALID | | ||
79 | SNDRV_PCM_INFO_PAUSE | | ||
80 | SNDRV_PCM_INFO_SYNC_START, | ||
81 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
82 | SNDRV_PCM_FMTBIT_S16_LE | | ||
83 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
84 | SNDRV_PCM_FMTBIT_S32_LE | | ||
85 | SNDRV_PCM_FMTBIT_S32_BE, | ||
86 | .rates = SNDRV_PCM_RATE_32000 | | ||
87 | SNDRV_PCM_RATE_44100 | | ||
88 | SNDRV_PCM_RATE_48000 | | ||
89 | SNDRV_PCM_RATE_88200 | | ||
90 | SNDRV_PCM_RATE_96000, | ||
91 | .rate_min = 32000, | ||
92 | .rate_max = 96000, | ||
93 | .channels_min = 1, | ||
94 | .channels_max = 8, | ||
95 | .buffer_bytes_max = 262144, | ||
96 | .period_bytes_min = 32, | ||
97 | .period_bytes_max = 131072, | ||
98 | .periods_min = 2, | ||
99 | .periods_max = 220, | ||
100 | }; | ||
101 | |||
102 | #include "indigoio_dsp.c" | ||
103 | #include "echoaudio_dsp.c" | ||
104 | #include "echoaudio.c" | ||
105 | |||
diff --git a/sound/pci/echoaudio/indigoio_dsp.c b/sound/pci/echoaudio/indigoio_dsp.c new file mode 100644 index 000000000000..f3ad13d06be0 --- /dev/null +++ b/sound/pci/echoaudio/indigoio_dsp.c | |||
@@ -0,0 +1,141 @@ | |||
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 set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | ||
33 | int gain); | ||
34 | static int update_vmixer_level(struct echoaudio *chip); | ||
35 | |||
36 | |||
37 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
38 | { | ||
39 | int err; | ||
40 | |||
41 | DE_INIT(("init_hw() - Indigo IO\n")); | ||
42 | snd_assert((subdevice_id & 0xfff0) == INDIGO_IO, return -ENODEV); | ||
43 | |||
44 | if ((err = init_dsp_comm_page(chip))) { | ||
45 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
46 | return err; | ||
47 | } | ||
48 | |||
49 | chip->device_id = device_id; | ||
50 | chip->subdevice_id = subdevice_id; | ||
51 | chip->bad_board = TRUE; | ||
52 | chip->dsp_code_to_load = &card_fw[FW_INDIGO_IO_DSP]; | ||
53 | /* Since this card has no ASIC, mark it as loaded so everything | ||
54 | works OK */ | ||
55 | chip->asic_loaded = TRUE; | ||
56 | chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL; | ||
57 | |||
58 | if ((err = load_firmware(chip)) < 0) | ||
59 | return err; | ||
60 | chip->bad_board = FALSE; | ||
61 | |||
62 | if ((err = init_line_levels(chip)) < 0) | ||
63 | return err; | ||
64 | |||
65 | /* Default routing of the virtual channels: all vchannels are routed | ||
66 | to the stereo output */ | ||
67 | set_vmixer_gain(chip, 0, 0, 0); | ||
68 | set_vmixer_gain(chip, 1, 1, 0); | ||
69 | set_vmixer_gain(chip, 0, 2, 0); | ||
70 | set_vmixer_gain(chip, 1, 3, 0); | ||
71 | set_vmixer_gain(chip, 0, 4, 0); | ||
72 | set_vmixer_gain(chip, 1, 5, 0); | ||
73 | set_vmixer_gain(chip, 0, 6, 0); | ||
74 | set_vmixer_gain(chip, 1, 7, 0); | ||
75 | err = update_vmixer_level(chip); | ||
76 | |||
77 | DE_INIT(("init_hw done\n")); | ||
78 | return err; | ||
79 | } | ||
80 | |||
81 | |||
82 | |||
83 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
84 | { | ||
85 | return ECHO_CLOCK_BIT_INTERNAL; | ||
86 | } | ||
87 | |||
88 | |||
89 | |||
90 | /* The IndigoIO has no ASIC. Just do nothing */ | ||
91 | static int load_asic(struct echoaudio *chip) | ||
92 | { | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | |||
97 | |||
98 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
99 | { | ||
100 | if (wait_handshake(chip)) | ||
101 | return -EIO; | ||
102 | |||
103 | chip->sample_rate = rate; | ||
104 | chip->comm_page->sample_rate = cpu_to_le32(rate); | ||
105 | clear_handshake(chip); | ||
106 | return send_vector(chip, DSP_VC_UPDATE_CLOCKS); | ||
107 | } | ||
108 | |||
109 | |||
110 | |||
111 | /* This function routes the sound from a virtual channel to a real output */ | ||
112 | static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | ||
113 | int gain) | ||
114 | { | ||
115 | int index; | ||
116 | |||
117 | snd_assert(pipe < num_pipes_out(chip) && | ||
118 | output < num_busses_out(chip), return -EINVAL); | ||
119 | |||
120 | if (wait_handshake(chip)) | ||
121 | return -EIO; | ||
122 | |||
123 | chip->vmixer_gain[output][pipe] = gain; | ||
124 | index = output * num_pipes_out(chip) + pipe; | ||
125 | chip->comm_page->vmixer[index] = gain; | ||
126 | |||
127 | DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | |||
132 | |||
133 | /* Tell the DSP to read and update virtual mixer levels in comm page. */ | ||
134 | static int update_vmixer_level(struct echoaudio *chip) | ||
135 | { | ||
136 | if (wait_handshake(chip)) | ||
137 | return -EIO; | ||
138 | clear_handshake(chip); | ||
139 | return send_vector(chip, DSP_VC_SET_VMIXER_GAIN); | ||
140 | } | ||
141 | |||
diff --git a/sound/pci/echoaudio/layla20.c b/sound/pci/echoaudio/layla20.c new file mode 100644 index 000000000000..e503d74b3ba9 --- /dev/null +++ b/sound/pci/echoaudio/layla20.c | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define ECHOGALS_FAMILY | ||
20 | #define ECHOCARD_LAYLA20 | ||
21 | #define ECHOCARD_NAME "Layla20" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | #define ECHOCARD_HAS_ASIC | ||
24 | #define ECHOCARD_HAS_INPUT_GAIN | ||
25 | #define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL | ||
26 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
27 | #define ECHOCARD_HAS_DIGITAL_IO | ||
28 | #define ECHOCARD_HAS_EXTERNAL_CLOCK | ||
29 | #define ECHOCARD_HAS_ADAT FALSE | ||
30 | #define ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH | ||
31 | #define ECHOCARD_HAS_MIDI | ||
32 | |||
33 | /* Pipe indexes */ | ||
34 | #define PX_ANALOG_OUT 0 /* 10 */ | ||
35 | #define PX_DIGITAL_OUT 10 /* 2 */ | ||
36 | #define PX_ANALOG_IN 12 /* 8 */ | ||
37 | #define PX_DIGITAL_IN 20 /* 2 */ | ||
38 | #define PX_NUM 22 | ||
39 | |||
40 | /* Bus indexes */ | ||
41 | #define BX_ANALOG_OUT 0 /* 10 */ | ||
42 | #define BX_DIGITAL_OUT 10 /* 2 */ | ||
43 | #define BX_ANALOG_IN 12 /* 8 */ | ||
44 | #define BX_DIGITAL_IN 20 /* 2 */ | ||
45 | #define BX_NUM 22 | ||
46 | |||
47 | |||
48 | #include <sound/driver.h> | ||
49 | #include <linux/delay.h> | ||
50 | #include <linux/init.h> | ||
51 | #include <linux/interrupt.h> | ||
52 | #include <linux/pci.h> | ||
53 | #include <linux/slab.h> | ||
54 | #include <linux/moduleparam.h> | ||
55 | #include <linux/firmware.h> | ||
56 | #include <sound/core.h> | ||
57 | #include <sound/info.h> | ||
58 | #include <sound/control.h> | ||
59 | #include <sound/pcm.h> | ||
60 | #include <sound/pcm_params.h> | ||
61 | #include <sound/asoundef.h> | ||
62 | #include <sound/initval.h> | ||
63 | #include <sound/rawmidi.h> | ||
64 | #include <asm/io.h> | ||
65 | #include <asm/atomic.h> | ||
66 | #include "echoaudio.h" | ||
67 | |||
68 | #define FW_LAYLA20_DSP 0 | ||
69 | #define FW_LAYLA20_ASIC 1 | ||
70 | |||
71 | static const struct firmware card_fw[] = { | ||
72 | {0, "layla20_dsp.fw"}, | ||
73 | {0, "layla20_asic.fw"} | ||
74 | }; | ||
75 | |||
76 | static struct pci_device_id snd_echo_ids[] = { | ||
77 | {0x1057, 0x1801, 0xECC0, 0x0030, 0, 0, 0}, /* DSP 56301 Layla20 rev.0 */ | ||
78 | {0x1057, 0x1801, 0xECC0, 0x0031, 0, 0, 0}, /* DSP 56301 Layla20 rev.1 */ | ||
79 | {0,} | ||
80 | }; | ||
81 | |||
82 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
83 | .info = SNDRV_PCM_INFO_MMAP | | ||
84 | SNDRV_PCM_INFO_INTERLEAVED | | ||
85 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
86 | SNDRV_PCM_INFO_MMAP_VALID | | ||
87 | SNDRV_PCM_INFO_PAUSE | | ||
88 | SNDRV_PCM_INFO_SYNC_START, | ||
89 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
90 | SNDRV_PCM_FMTBIT_S16_LE | | ||
91 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
92 | SNDRV_PCM_FMTBIT_S32_LE | | ||
93 | SNDRV_PCM_FMTBIT_S32_BE, | ||
94 | .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS, | ||
95 | .rate_min = 8000, | ||
96 | .rate_max = 50000, | ||
97 | .channels_min = 1, | ||
98 | .channels_max = 10, | ||
99 | .buffer_bytes_max = 262144, | ||
100 | .period_bytes_min = 32, | ||
101 | .period_bytes_max = 131072, | ||
102 | .periods_min = 2, | ||
103 | .periods_max = 220, | ||
104 | /* One page (4k) contains 512 instructions. I don't know if the hw | ||
105 | supports lists longer than this. In this case periods_max=220 is a | ||
106 | safe limit to make sure the list never exceeds 512 instructions. */ | ||
107 | }; | ||
108 | |||
109 | #include "layla20_dsp.c" | ||
110 | #include "echoaudio_dsp.c" | ||
111 | #include "echoaudio.c" | ||
112 | #include "midi.c" | ||
diff --git a/sound/pci/echoaudio/layla20_dsp.c b/sound/pci/echoaudio/layla20_dsp.c new file mode 100644 index 000000000000..990c9a60a0a8 --- /dev/null +++ b/sound/pci/echoaudio/layla20_dsp.c | |||
@@ -0,0 +1,290 @@ | |||
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 read_dsp(struct echoaudio *chip, u32 *data); | ||
33 | static int set_professional_spdif(struct echoaudio *chip, char prof); | ||
34 | static int load_asic_generic(struct echoaudio *chip, u32 cmd, | ||
35 | const struct firmware *asic); | ||
36 | static int check_asic_status(struct echoaudio *chip); | ||
37 | static int update_flags(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 | DE_INIT(("init_hw() - Layla20\n")); | ||
45 | snd_assert((subdevice_id & 0xfff0) == LAYLA20, return -ENODEV); | ||
46 | |||
47 | if ((err = init_dsp_comm_page(chip))) { | ||
48 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
49 | return err; | ||
50 | } | ||
51 | |||
52 | chip->device_id = device_id; | ||
53 | chip->subdevice_id = subdevice_id; | ||
54 | chip->bad_board = TRUE; | ||
55 | chip->has_midi = TRUE; | ||
56 | chip->dsp_code_to_load = &card_fw[FW_LAYLA20_DSP]; | ||
57 | chip->input_clock_types = | ||
58 | ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | | ||
59 | ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER; | ||
60 | chip->output_clock_types = | ||
61 | ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER; | ||
62 | |||
63 | if ((err = load_firmware(chip)) < 0) | ||
64 | return err; | ||
65 | chip->bad_board = FALSE; | ||
66 | |||
67 | if ((err = init_line_levels(chip)) < 0) | ||
68 | return err; | ||
69 | |||
70 | err = set_professional_spdif(chip, TRUE); | ||
71 | |||
72 | DE_INIT(("init_hw done\n")); | ||
73 | return err; | ||
74 | } | ||
75 | |||
76 | |||
77 | |||
78 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
79 | { | ||
80 | u32 clocks_from_dsp, clock_bits; | ||
81 | |||
82 | /* Map the DSP clock detect bits to the generic driver clock detect bits */ | ||
83 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
84 | |||
85 | clock_bits = ECHO_CLOCK_BIT_INTERNAL; | ||
86 | |||
87 | if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF) | ||
88 | clock_bits |= ECHO_CLOCK_BIT_SPDIF; | ||
89 | |||
90 | if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_WORD) { | ||
91 | if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SUPER) | ||
92 | clock_bits |= ECHO_CLOCK_BIT_SUPER; | ||
93 | else | ||
94 | clock_bits |= ECHO_CLOCK_BIT_WORD; | ||
95 | } | ||
96 | |||
97 | return clock_bits; | ||
98 | } | ||
99 | |||
100 | |||
101 | |||
102 | /* ASIC status check - some cards have one or two ASICs that need to be | ||
103 | loaded. Once that load is complete, this function is called to see if | ||
104 | the load was successful. | ||
105 | If this load fails, it does not necessarily mean that the hardware is | ||
106 | defective - the external box may be disconnected or turned off. | ||
107 | This routine sometimes fails for Layla20; for Layla20, the loop runs | ||
108 | 5 times and succeeds if it wins on three of the loops. */ | ||
109 | static int check_asic_status(struct echoaudio *chip) | ||
110 | { | ||
111 | u32 asic_status; | ||
112 | int goodcnt, i; | ||
113 | |||
114 | chip->asic_loaded = FALSE; | ||
115 | for (i = goodcnt = 0; i < 5; i++) { | ||
116 | send_vector(chip, DSP_VC_TEST_ASIC); | ||
117 | |||
118 | /* The DSP will return a value to indicate whether or not | ||
119 | the ASIC is currently loaded */ | ||
120 | if (read_dsp(chip, &asic_status) < 0) { | ||
121 | DE_ACT(("check_asic_status: failed on read_dsp\n")); | ||
122 | return -EIO; | ||
123 | } | ||
124 | |||
125 | if (asic_status == ASIC_ALREADY_LOADED) { | ||
126 | if (++goodcnt == 3) { | ||
127 | chip->asic_loaded = TRUE; | ||
128 | return 0; | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | return -EIO; | ||
133 | } | ||
134 | |||
135 | |||
136 | |||
137 | /* Layla20 has an ASIC in the external box */ | ||
138 | static int load_asic(struct echoaudio *chip) | ||
139 | { | ||
140 | int err; | ||
141 | |||
142 | if (chip->asic_loaded) | ||
143 | return 0; | ||
144 | |||
145 | err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC, | ||
146 | &card_fw[FW_LAYLA20_ASIC]); | ||
147 | if (err < 0) | ||
148 | return err; | ||
149 | |||
150 | /* Check if ASIC is alive and well. */ | ||
151 | return check_asic_status(chip); | ||
152 | } | ||
153 | |||
154 | |||
155 | |||
156 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
157 | { | ||
158 | snd_assert(rate >= 8000 && rate <= 50000, return -EINVAL); | ||
159 | |||
160 | /* Only set the clock for internal mode. Do not return failure, | ||
161 | simply treat it as a non-event. */ | ||
162 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { | ||
163 | DE_ACT(("set_sample_rate: Cannot set sample rate - " | ||
164 | "clock not set to CLK_CLOCKININTERNAL\n")); | ||
165 | chip->comm_page->sample_rate = cpu_to_le32(rate); | ||
166 | chip->sample_rate = rate; | ||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | if (wait_handshake(chip)) | ||
171 | return -EIO; | ||
172 | |||
173 | DE_ACT(("set_sample_rate(%d)\n", rate)); | ||
174 | chip->sample_rate = rate; | ||
175 | chip->comm_page->sample_rate = cpu_to_le32(rate); | ||
176 | clear_handshake(chip); | ||
177 | return send_vector(chip, DSP_VC_SET_LAYLA_SAMPLE_RATE); | ||
178 | } | ||
179 | |||
180 | |||
181 | |||
182 | static int set_input_clock(struct echoaudio *chip, u16 clock_source) | ||
183 | { | ||
184 | u16 clock; | ||
185 | u32 rate; | ||
186 | |||
187 | DE_ACT(("set_input_clock:\n")); | ||
188 | rate = 0; | ||
189 | switch (clock_source) { | ||
190 | case ECHO_CLOCK_INTERNAL: | ||
191 | DE_ACT(("Set Layla20 clock to INTERNAL\n")); | ||
192 | rate = chip->sample_rate; | ||
193 | clock = LAYLA20_CLOCK_INTERNAL; | ||
194 | break; | ||
195 | case ECHO_CLOCK_SPDIF: | ||
196 | DE_ACT(("Set Layla20 clock to SPDIF\n")); | ||
197 | clock = LAYLA20_CLOCK_SPDIF; | ||
198 | break; | ||
199 | case ECHO_CLOCK_WORD: | ||
200 | DE_ACT(("Set Layla20 clock to WORD\n")); | ||
201 | clock = LAYLA20_CLOCK_WORD; | ||
202 | break; | ||
203 | case ECHO_CLOCK_SUPER: | ||
204 | DE_ACT(("Set Layla20 clock to SUPER\n")); | ||
205 | clock = LAYLA20_CLOCK_SUPER; | ||
206 | break; | ||
207 | default: | ||
208 | DE_ACT(("Input clock 0x%x not supported for Layla24\n", | ||
209 | clock_source)); | ||
210 | return -EINVAL; | ||
211 | } | ||
212 | chip->input_clock = clock_source; | ||
213 | |||
214 | chip->comm_page->input_clock = cpu_to_le16(clock); | ||
215 | clear_handshake(chip); | ||
216 | send_vector(chip, DSP_VC_UPDATE_CLOCKS); | ||
217 | |||
218 | if (rate) | ||
219 | set_sample_rate(chip, rate); | ||
220 | |||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | |||
225 | |||
226 | static int set_output_clock(struct echoaudio *chip, u16 clock) | ||
227 | { | ||
228 | DE_ACT(("set_output_clock: %d\n", clock)); | ||
229 | switch (clock) { | ||
230 | case ECHO_CLOCK_SUPER: | ||
231 | clock = LAYLA20_OUTPUT_CLOCK_SUPER; | ||
232 | break; | ||
233 | case ECHO_CLOCK_WORD: | ||
234 | clock = LAYLA20_OUTPUT_CLOCK_WORD; | ||
235 | break; | ||
236 | default: | ||
237 | DE_ACT(("set_output_clock wrong clock\n")); | ||
238 | return -EINVAL; | ||
239 | } | ||
240 | |||
241 | if (wait_handshake(chip)) | ||
242 | return -EIO; | ||
243 | |||
244 | chip->comm_page->output_clock = cpu_to_le16(clock); | ||
245 | chip->output_clock = clock; | ||
246 | clear_handshake(chip); | ||
247 | return send_vector(chip, DSP_VC_UPDATE_CLOCKS); | ||
248 | } | ||
249 | |||
250 | |||
251 | |||
252 | /* Set input bus gain (one unit is 0.5dB !) */ | ||
253 | static int set_input_gain(struct echoaudio *chip, u16 input, int gain) | ||
254 | { | ||
255 | snd_assert(input < num_busses_in(chip), return -EINVAL); | ||
256 | |||
257 | if (wait_handshake(chip)) | ||
258 | return -EIO; | ||
259 | |||
260 | chip->input_gain[input] = gain; | ||
261 | gain += GL20_INPUT_GAIN_MAGIC_NUMBER; | ||
262 | chip->comm_page->line_in_level[input] = gain; | ||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | |||
267 | |||
268 | /* Tell the DSP to reread the flags from the comm page */ | ||
269 | static int update_flags(struct echoaudio *chip) | ||
270 | { | ||
271 | if (wait_handshake(chip)) | ||
272 | return -EIO; | ||
273 | clear_handshake(chip); | ||
274 | return send_vector(chip, DSP_VC_UPDATE_FLAGS); | ||
275 | } | ||
276 | |||
277 | |||
278 | |||
279 | static int set_professional_spdif(struct echoaudio *chip, char prof) | ||
280 | { | ||
281 | DE_ACT(("set_professional_spdif %d\n", prof)); | ||
282 | if (prof) | ||
283 | chip->comm_page->flags |= | ||
284 | __constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); | ||
285 | else | ||
286 | chip->comm_page->flags &= | ||
287 | ~__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); | ||
288 | chip->professional_spdif = prof; | ||
289 | return update_flags(chip); | ||
290 | } | ||
diff --git a/sound/pci/echoaudio/layla24.c b/sound/pci/echoaudio/layla24.c new file mode 100644 index 000000000000..d4581fdc841c --- /dev/null +++ b/sound/pci/echoaudio/layla24.c | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define ECHO24_FAMILY | ||
20 | #define ECHOCARD_LAYLA24 | ||
21 | #define ECHOCARD_NAME "Layla24" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | #define ECHOCARD_HAS_ASIC | ||
24 | #define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL | ||
25 | #define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL | ||
26 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
27 | #define ECHOCARD_HAS_DIGITAL_IO | ||
28 | #define ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE | ||
29 | #define ECHOCARD_HAS_DIGITAL_MODE_SWITCH | ||
30 | #define ECHOCARD_HAS_EXTERNAL_CLOCK | ||
31 | #define ECHOCARD_HAS_ADAT 6 | ||
32 | #define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
33 | #define ECHOCARD_HAS_MIDI | ||
34 | |||
35 | /* Pipe indexes */ | ||
36 | #define PX_ANALOG_OUT 0 /* 8 */ | ||
37 | #define PX_DIGITAL_OUT 8 /* 8 */ | ||
38 | #define PX_ANALOG_IN 16 /* 8 */ | ||
39 | #define PX_DIGITAL_IN 24 /* 8 */ | ||
40 | #define PX_NUM 32 | ||
41 | |||
42 | /* Bus indexes */ | ||
43 | #define BX_ANALOG_OUT 0 /* 8 */ | ||
44 | #define BX_DIGITAL_OUT 8 /* 8 */ | ||
45 | #define BX_ANALOG_IN 16 /* 8 */ | ||
46 | #define BX_DIGITAL_IN 24 /* 8 */ | ||
47 | #define BX_NUM 32 | ||
48 | |||
49 | |||
50 | #include <sound/driver.h> | ||
51 | #include <linux/delay.h> | ||
52 | #include <linux/init.h> | ||
53 | #include <linux/interrupt.h> | ||
54 | #include <linux/pci.h> | ||
55 | #include <linux/slab.h> | ||
56 | #include <linux/moduleparam.h> | ||
57 | #include <linux/firmware.h> | ||
58 | #include <sound/core.h> | ||
59 | #include <sound/info.h> | ||
60 | #include <sound/control.h> | ||
61 | #include <sound/pcm.h> | ||
62 | #include <sound/pcm_params.h> | ||
63 | #include <sound/asoundef.h> | ||
64 | #include <sound/initval.h> | ||
65 | #include <sound/rawmidi.h> | ||
66 | #include <asm/io.h> | ||
67 | #include <asm/atomic.h> | ||
68 | #include "echoaudio.h" | ||
69 | |||
70 | #define FW_361_LOADER 0 | ||
71 | #define FW_LAYLA24_DSP 1 | ||
72 | #define FW_LAYLA24_1_ASIC 2 | ||
73 | #define FW_LAYLA24_2A_ASIC 3 | ||
74 | #define FW_LAYLA24_2S_ASIC 4 | ||
75 | |||
76 | static const struct firmware card_fw[] = { | ||
77 | {0, "loader_dsp.fw"}, | ||
78 | {0, "layla24_dsp.fw"}, | ||
79 | {0, "layla24_1_asic.fw"}, | ||
80 | {0, "layla24_2A_asic.fw"}, | ||
81 | {0, "layla24_2S_asic.fw"} | ||
82 | }; | ||
83 | |||
84 | static struct pci_device_id snd_echo_ids[] = { | ||
85 | {0x1057, 0x3410, 0xECC0, 0x0060, 0, 0, 0}, /* DSP 56361 Layla24 rev.0 */ | ||
86 | {0,} | ||
87 | }; | ||
88 | |||
89 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
90 | .info = SNDRV_PCM_INFO_MMAP | | ||
91 | SNDRV_PCM_INFO_INTERLEAVED | | ||
92 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
93 | SNDRV_PCM_INFO_MMAP_VALID | | ||
94 | SNDRV_PCM_INFO_PAUSE | | ||
95 | SNDRV_PCM_INFO_SYNC_START, | ||
96 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
97 | SNDRV_PCM_FMTBIT_S16_LE | | ||
98 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
99 | SNDRV_PCM_FMTBIT_S32_LE | | ||
100 | SNDRV_PCM_FMTBIT_S32_BE, | ||
101 | .rates = SNDRV_PCM_RATE_8000_96000, | ||
102 | .rate_min = 8000, | ||
103 | .rate_max = 100000, | ||
104 | .channels_min = 1, | ||
105 | .channels_max = 8, | ||
106 | .buffer_bytes_max = 262144, | ||
107 | .period_bytes_min = 32, | ||
108 | .period_bytes_max = 131072, | ||
109 | .periods_min = 2, | ||
110 | .periods_max = 220, | ||
111 | /* One page (4k) contains 512 instructions. I don't know if the hw | ||
112 | supports lists longer than this. In this case periods_max=220 is a | ||
113 | safe limit to make sure the list never exceeds 512 instructions. */ | ||
114 | }; | ||
115 | |||
116 | |||
117 | #include "layla24_dsp.c" | ||
118 | #include "echoaudio_dsp.c" | ||
119 | #include "echoaudio_gml.c" | ||
120 | #include "echoaudio.c" | ||
121 | #include "midi.c" | ||
diff --git a/sound/pci/echoaudio/layla24_dsp.c b/sound/pci/echoaudio/layla24_dsp.c new file mode 100644 index 000000000000..7ec5b63d0dce --- /dev/null +++ b/sound/pci/echoaudio/layla24_dsp.c | |||
@@ -0,0 +1,394 @@ | |||
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 Foundation. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | GNU General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU General Public License | ||
19 | along with this program; if not, write to the Free Software | ||
20 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
21 | MA 02111-1307, USA. | ||
22 | |||
23 | ************************************************************************* | ||
24 | |||
25 | Translation from C++ and adaptation for use in ALSA-Driver | ||
26 | were made by Giuliano Pochini <pochini@shiny.it> | ||
27 | |||
28 | ****************************************************************************/ | ||
29 | |||
30 | |||
31 | static int write_control_reg(struct echoaudio *chip, u32 value, char force); | ||
32 | static int set_input_clock(struct echoaudio *chip, u16 clock); | ||
33 | static int set_professional_spdif(struct echoaudio *chip, char prof); | ||
34 | static int set_digital_mode(struct echoaudio *chip, u8 mode); | ||
35 | static int load_asic_generic(struct echoaudio *chip, u32 cmd, | ||
36 | const struct firmware *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 | DE_INIT(("init_hw() - Layla24\n")); | ||
45 | snd_assert((subdevice_id & 0xfff0) == LAYLA24, return -ENODEV); | ||
46 | |||
47 | if ((err = init_dsp_comm_page(chip))) { | ||
48 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
49 | return err; | ||
50 | } | ||
51 | |||
52 | chip->device_id = device_id; | ||
53 | chip->subdevice_id = subdevice_id; | ||
54 | chip->bad_board = TRUE; | ||
55 | chip->has_midi = TRUE; | ||
56 | chip->dsp_code_to_load = &card_fw[FW_LAYLA24_DSP]; | ||
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 | chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; | ||
65 | chip->professional_spdif = FALSE; | ||
66 | chip->digital_in_automute = TRUE; | ||
67 | |||
68 | if ((err = load_firmware(chip)) < 0) | ||
69 | return err; | ||
70 | chip->bad_board = FALSE; | ||
71 | |||
72 | if ((err = init_line_levels(chip)) < 0) | ||
73 | return err; | ||
74 | |||
75 | err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); | ||
76 | snd_assert(err >= 0, return err); | ||
77 | err = set_professional_spdif(chip, TRUE); | ||
78 | |||
79 | DE_INIT(("init_hw done\n")); | ||
80 | return err; | ||
81 | } | ||
82 | |||
83 | |||
84 | |||
85 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
86 | { | ||
87 | u32 clocks_from_dsp, clock_bits; | ||
88 | |||
89 | /* Map the DSP clock detect bits to the generic driver clock detect bits */ | ||
90 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
91 | |||
92 | clock_bits = ECHO_CLOCK_BIT_INTERNAL; | ||
93 | |||
94 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF) | ||
95 | clock_bits |= ECHO_CLOCK_BIT_SPDIF; | ||
96 | |||
97 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT) | ||
98 | clock_bits |= ECHO_CLOCK_BIT_ADAT; | ||
99 | |||
100 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD) | ||
101 | clock_bits |= ECHO_CLOCK_BIT_WORD; | ||
102 | |||
103 | return clock_bits; | ||
104 | } | ||
105 | |||
106 | |||
107 | |||
108 | /* Layla24 has an ASIC on the PCI card and another ASIC in the external box; | ||
109 | both need to be loaded. */ | ||
110 | static int load_asic(struct echoaudio *chip) | ||
111 | { | ||
112 | int err; | ||
113 | |||
114 | if (chip->asic_loaded) | ||
115 | return 1; | ||
116 | |||
117 | DE_INIT(("load_asic\n")); | ||
118 | |||
119 | /* Give the DSP a few milliseconds to settle down */ | ||
120 | mdelay(10); | ||
121 | |||
122 | /* Load the ASIC for the PCI card */ | ||
123 | err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC, | ||
124 | &card_fw[FW_LAYLA24_1_ASIC]); | ||
125 | if (err < 0) | ||
126 | return err; | ||
127 | |||
128 | chip->asic_code = &card_fw[FW_LAYLA24_2S_ASIC]; | ||
129 | |||
130 | /* Now give the new ASIC a little time to set up */ | ||
131 | mdelay(10); | ||
132 | |||
133 | /* Do the external one */ | ||
134 | err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC, | ||
135 | &card_fw[FW_LAYLA24_2S_ASIC]); | ||
136 | if (err < 0) | ||
137 | return FALSE; | ||
138 | |||
139 | /* Now give the external ASIC a little time to set up */ | ||
140 | mdelay(10); | ||
141 | |||
142 | /* See if it worked */ | ||
143 | err = check_asic_status(chip); | ||
144 | |||
145 | /* Set up the control register if the load succeeded - | ||
146 | 48 kHz, internal clock, S/PDIF RCA mode */ | ||
147 | if (!err) | ||
148 | err = write_control_reg(chip, GML_CONVERTER_ENABLE | GML_48KHZ, | ||
149 | TRUE); | ||
150 | |||
151 | DE_INIT(("load_asic() done\n")); | ||
152 | return err; | ||
153 | } | ||
154 | |||
155 | |||
156 | |||
157 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
158 | { | ||
159 | u32 control_reg, clock, base_rate; | ||
160 | |||
161 | snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT, | ||
162 | return -EINVAL); | ||
163 | |||
164 | /* Only set the clock for internal mode. */ | ||
165 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { | ||
166 | DE_ACT(("set_sample_rate: Cannot set sample rate - " | ||
167 | "clock not set to CLK_CLOCKININTERNAL\n")); | ||
168 | /* Save the rate anyhow */ | ||
169 | chip->comm_page->sample_rate = cpu_to_le32(rate); | ||
170 | chip->sample_rate = rate; | ||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | /* Get the control register & clear the appropriate bits */ | ||
175 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
176 | control_reg &= GML_CLOCK_CLEAR_MASK & GML_SPDIF_RATE_CLEAR_MASK; | ||
177 | |||
178 | clock = 0; | ||
179 | |||
180 | switch (rate) { | ||
181 | case 96000: | ||
182 | clock = GML_96KHZ; | ||
183 | break; | ||
184 | case 88200: | ||
185 | clock = GML_88KHZ; | ||
186 | break; | ||
187 | case 48000: | ||
188 | clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1; | ||
189 | break; | ||
190 | case 44100: | ||
191 | clock = GML_44KHZ; | ||
192 | /* Professional mode */ | ||
193 | if (control_reg & GML_SPDIF_PRO_MODE) | ||
194 | clock |= GML_SPDIF_SAMPLE_RATE0; | ||
195 | break; | ||
196 | case 32000: | ||
197 | clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 | | ||
198 | GML_SPDIF_SAMPLE_RATE1; | ||
199 | break; | ||
200 | case 22050: | ||
201 | clock = GML_22KHZ; | ||
202 | break; | ||
203 | case 16000: | ||
204 | clock = GML_16KHZ; | ||
205 | break; | ||
206 | case 11025: | ||
207 | clock = GML_11KHZ; | ||
208 | break; | ||
209 | case 8000: | ||
210 | clock = GML_8KHZ; | ||
211 | break; | ||
212 | default: | ||
213 | /* If this is a non-standard rate, then the driver needs to | ||
214 | use Layla24's special "continuous frequency" mode */ | ||
215 | clock = LAYLA24_CONTINUOUS_CLOCK; | ||
216 | if (rate > 50000) { | ||
217 | base_rate = rate >> 1; | ||
218 | control_reg |= GML_DOUBLE_SPEED_MODE; | ||
219 | } else { | ||
220 | base_rate = rate; | ||
221 | } | ||
222 | |||
223 | if (base_rate < 25000) | ||
224 | base_rate = 25000; | ||
225 | |||
226 | if (wait_handshake(chip)) | ||
227 | return -EIO; | ||
228 | |||
229 | chip->comm_page->sample_rate = | ||
230 | cpu_to_le32(LAYLA24_MAGIC_NUMBER / base_rate - 2); | ||
231 | |||
232 | clear_handshake(chip); | ||
233 | send_vector(chip, DSP_VC_SET_LAYLA24_FREQUENCY_REG); | ||
234 | } | ||
235 | |||
236 | control_reg |= clock; | ||
237 | |||
238 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP ? */ | ||
239 | chip->sample_rate = rate; | ||
240 | DE_ACT(("set_sample_rate: %d clock %d\n", rate, control_reg)); | ||
241 | |||
242 | return write_control_reg(chip, control_reg, FALSE); | ||
243 | } | ||
244 | |||
245 | |||
246 | |||
247 | static int set_input_clock(struct echoaudio *chip, u16 clock) | ||
248 | { | ||
249 | u32 control_reg, clocks_from_dsp; | ||
250 | |||
251 | /* Mask off the clock select bits */ | ||
252 | control_reg = le32_to_cpu(chip->comm_page->control_register) & | ||
253 | GML_CLOCK_CLEAR_MASK; | ||
254 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
255 | |||
256 | /* Pick the new clock */ | ||
257 | switch (clock) { | ||
258 | case ECHO_CLOCK_INTERNAL: | ||
259 | DE_ACT(("Set Layla24 clock to INTERNAL\n")); | ||
260 | chip->input_clock = ECHO_CLOCK_INTERNAL; | ||
261 | return set_sample_rate(chip, chip->sample_rate); | ||
262 | case ECHO_CLOCK_SPDIF: | ||
263 | if (chip->digital_mode == DIGITAL_MODE_ADAT) | ||
264 | return -EAGAIN; | ||
265 | control_reg |= GML_SPDIF_CLOCK; | ||
266 | /* Layla24 doesn't support 96KHz S/PDIF */ | ||
267 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
268 | DE_ACT(("Set Layla24 clock to SPDIF\n")); | ||
269 | break; | ||
270 | case ECHO_CLOCK_WORD: | ||
271 | control_reg |= GML_WORD_CLOCK; | ||
272 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96) | ||
273 | control_reg |= GML_DOUBLE_SPEED_MODE; | ||
274 | else | ||
275 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
276 | DE_ACT(("Set Layla24 clock to WORD\n")); | ||
277 | break; | ||
278 | case ECHO_CLOCK_ADAT: | ||
279 | if (chip->digital_mode != DIGITAL_MODE_ADAT) | ||
280 | return -EAGAIN; | ||
281 | control_reg |= GML_ADAT_CLOCK; | ||
282 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
283 | DE_ACT(("Set Layla24 clock to ADAT\n")); | ||
284 | break; | ||
285 | default: | ||
286 | DE_ACT(("Input clock 0x%x not supported for Layla24\n", clock)); | ||
287 | return -EINVAL; | ||
288 | } | ||
289 | |||
290 | chip->input_clock = clock; | ||
291 | return write_control_reg(chip, control_reg, TRUE); | ||
292 | } | ||
293 | |||
294 | |||
295 | |||
296 | /* Depending on what digital mode you want, Layla24 needs different ASICs | ||
297 | loaded. This function checks the ASIC needed for the new mode and sees | ||
298 | if it matches the one already loaded. */ | ||
299 | static int switch_asic(struct echoaudio *chip, const struct firmware *asic) | ||
300 | { | ||
301 | s8 *monitors; | ||
302 | |||
303 | /* Check to see if this is already loaded */ | ||
304 | if (asic != chip->asic_code) { | ||
305 | monitors = kmalloc(MONITOR_ARRAY_SIZE, GFP_KERNEL); | ||
306 | if (! monitors) | ||
307 | return -ENOMEM; | ||
308 | |||
309 | memcpy(monitors, chip->comm_page->monitors, MONITOR_ARRAY_SIZE); | ||
310 | memset(chip->comm_page->monitors, ECHOGAIN_MUTED, | ||
311 | MONITOR_ARRAY_SIZE); | ||
312 | |||
313 | /* Load the desired ASIC */ | ||
314 | if (load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC, | ||
315 | asic) < 0) { | ||
316 | memcpy(chip->comm_page->monitors, monitors, | ||
317 | MONITOR_ARRAY_SIZE); | ||
318 | kfree(monitors); | ||
319 | return -EIO; | ||
320 | } | ||
321 | chip->asic_code = asic; | ||
322 | memcpy(chip->comm_page->monitors, monitors, MONITOR_ARRAY_SIZE); | ||
323 | kfree(monitors); | ||
324 | } | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | |||
330 | |||
331 | static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | ||
332 | { | ||
333 | u32 control_reg; | ||
334 | int err, incompatible_clock; | ||
335 | const struct firmware *asic; | ||
336 | |||
337 | /* Set clock to "internal" if it's not compatible with the new mode */ | ||
338 | incompatible_clock = FALSE; | ||
339 | switch (mode) { | ||
340 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
341 | case DIGITAL_MODE_SPDIF_RCA: | ||
342 | if (chip->input_clock == ECHO_CLOCK_ADAT) | ||
343 | incompatible_clock = TRUE; | ||
344 | asic = &card_fw[FW_LAYLA24_2S_ASIC]; | ||
345 | break; | ||
346 | case DIGITAL_MODE_ADAT: | ||
347 | if (chip->input_clock == ECHO_CLOCK_SPDIF) | ||
348 | incompatible_clock = TRUE; | ||
349 | asic = &card_fw[FW_LAYLA24_2A_ASIC]; | ||
350 | break; | ||
351 | default: | ||
352 | DE_ACT(("Digital mode not supported: %d\n", mode)); | ||
353 | return -EINVAL; | ||
354 | } | ||
355 | |||
356 | if (incompatible_clock) { /* Switch to 48KHz, internal */ | ||
357 | chip->sample_rate = 48000; | ||
358 | spin_lock_irq(&chip->lock); | ||
359 | set_input_clock(chip, ECHO_CLOCK_INTERNAL); | ||
360 | spin_unlock_irq(&chip->lock); | ||
361 | } | ||
362 | |||
363 | /* switch_asic() can sleep */ | ||
364 | if (switch_asic(chip, asic) < 0) | ||
365 | return -EIO; | ||
366 | |||
367 | spin_lock_irq(&chip->lock); | ||
368 | |||
369 | /* Tweak the control register */ | ||
370 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
371 | control_reg &= GML_DIGITAL_MODE_CLEAR_MASK; | ||
372 | |||
373 | switch (mode) { | ||
374 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
375 | control_reg |= GML_SPDIF_OPTICAL_MODE; | ||
376 | break; | ||
377 | case DIGITAL_MODE_SPDIF_RCA: | ||
378 | /* GML_SPDIF_OPTICAL_MODE bit cleared */ | ||
379 | break; | ||
380 | case DIGITAL_MODE_ADAT: | ||
381 | control_reg |= GML_ADAT_MODE; | ||
382 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
383 | break; | ||
384 | } | ||
385 | |||
386 | err = write_control_reg(chip, control_reg, TRUE); | ||
387 | spin_unlock_irq(&chip->lock); | ||
388 | if (err < 0) | ||
389 | return err; | ||
390 | chip->digital_mode = mode; | ||
391 | |||
392 | DE_ACT(("set_digital_mode to %d\n", mode)); | ||
393 | return incompatible_clock; | ||
394 | } | ||
diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c new file mode 100644 index 000000000000..be40c64263d2 --- /dev/null +++ b/sound/pci/echoaudio/mia.c | |||
@@ -0,0 +1,117 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define ECHO24_FAMILY | ||
20 | #define ECHOCARD_MIA | ||
21 | #define ECHOCARD_NAME "Mia" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | #define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL | ||
24 | #define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL | ||
25 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
26 | #define ECHOCARD_HAS_VMIXER | ||
27 | #define ECHOCARD_HAS_DIGITAL_IO | ||
28 | #define ECHOCARD_HAS_EXTERNAL_CLOCK | ||
29 | #define ECHOCARD_HAS_ADAT FALSE | ||
30 | #define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
31 | #define ECHOCARD_HAS_MIDI | ||
32 | |||
33 | /* Pipe indexes */ | ||
34 | #define PX_ANALOG_OUT 0 /* 8 */ | ||
35 | #define PX_DIGITAL_OUT 8 /* 0 */ | ||
36 | #define PX_ANALOG_IN 8 /* 2 */ | ||
37 | #define PX_DIGITAL_IN 10 /* 2 */ | ||
38 | #define PX_NUM 12 | ||
39 | |||
40 | /* Bus indexes */ | ||
41 | #define BX_ANALOG_OUT 0 /* 2 */ | ||
42 | #define BX_DIGITAL_OUT 2 /* 2 */ | ||
43 | #define BX_ANALOG_IN 4 /* 2 */ | ||
44 | #define BX_DIGITAL_IN 6 /* 2 */ | ||
45 | #define BX_NUM 8 | ||
46 | |||
47 | |||
48 | #include <sound/driver.h> | ||
49 | #include <linux/delay.h> | ||
50 | #include <linux/init.h> | ||
51 | #include <linux/interrupt.h> | ||
52 | #include <linux/pci.h> | ||
53 | #include <linux/slab.h> | ||
54 | #include <linux/moduleparam.h> | ||
55 | #include <linux/firmware.h> | ||
56 | #include <sound/core.h> | ||
57 | #include <sound/info.h> | ||
58 | #include <sound/control.h> | ||
59 | #include <sound/pcm.h> | ||
60 | #include <sound/pcm_params.h> | ||
61 | #include <sound/asoundef.h> | ||
62 | #include <sound/initval.h> | ||
63 | #include <sound/rawmidi.h> | ||
64 | #include <asm/io.h> | ||
65 | #include <asm/atomic.h> | ||
66 | #include "echoaudio.h" | ||
67 | |||
68 | #define FW_361_LOADER 0 | ||
69 | #define FW_MIA_DSP 1 | ||
70 | |||
71 | static const struct firmware card_fw[] = { | ||
72 | {0, "loader_dsp.fw"}, | ||
73 | {0, "mia_dsp.fw"} | ||
74 | }; | ||
75 | |||
76 | static struct pci_device_id snd_echo_ids[] = { | ||
77 | {0x1057, 0x3410, 0xECC0, 0x0080, 0, 0, 0}, /* DSP 56361 Mia rev.0 */ | ||
78 | {0x1057, 0x3410, 0xECC0, 0x0081, 0, 0, 0}, /* DSP 56361 Mia rev.1 */ | ||
79 | {0,} | ||
80 | }; | ||
81 | |||
82 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
83 | .info = SNDRV_PCM_INFO_MMAP | | ||
84 | SNDRV_PCM_INFO_INTERLEAVED | | ||
85 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
86 | SNDRV_PCM_INFO_MMAP_VALID | | ||
87 | SNDRV_PCM_INFO_PAUSE | | ||
88 | SNDRV_PCM_INFO_SYNC_START, | ||
89 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
90 | SNDRV_PCM_FMTBIT_S16_LE | | ||
91 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
92 | SNDRV_PCM_FMTBIT_S32_LE | | ||
93 | SNDRV_PCM_FMTBIT_S32_BE, | ||
94 | .rates = SNDRV_PCM_RATE_32000 | | ||
95 | SNDRV_PCM_RATE_44100 | | ||
96 | SNDRV_PCM_RATE_48000 | | ||
97 | SNDRV_PCM_RATE_88200 | | ||
98 | SNDRV_PCM_RATE_96000, | ||
99 | .rate_min = 8000, | ||
100 | .rate_max = 96000, | ||
101 | .channels_min = 1, | ||
102 | .channels_max = 8, | ||
103 | .buffer_bytes_max = 262144, | ||
104 | .period_bytes_min = 32, | ||
105 | .period_bytes_max = 131072, | ||
106 | .periods_min = 2, | ||
107 | .periods_max = 220, | ||
108 | /* One page (4k) contains 512 instructions. I don't know if the hw | ||
109 | supports lists longer than this. In this case periods_max=220 is a | ||
110 | safe limit to make sure the list never exceeds 512 instructions. */ | ||
111 | }; | ||
112 | |||
113 | |||
114 | #include "mia_dsp.c" | ||
115 | #include "echoaudio_dsp.c" | ||
116 | #include "echoaudio.c" | ||
117 | #include "midi.c" | ||
diff --git a/sound/pci/echoaudio/mia_dsp.c b/sound/pci/echoaudio/mia_dsp.c new file mode 100644 index 000000000000..891c70519096 --- /dev/null +++ b/sound/pci/echoaudio/mia_dsp.c | |||
@@ -0,0 +1,229 @@ | |||
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 set_input_clock(struct echoaudio *chip, u16 clock); | ||
33 | static int set_professional_spdif(struct echoaudio *chip, char prof); | ||
34 | static int update_flags(struct echoaudio *chip); | ||
35 | static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | ||
36 | int gain); | ||
37 | static int update_vmixer_level(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 | DE_INIT(("init_hw() - Mia\n")); | ||
45 | snd_assert((subdevice_id & 0xfff0) == MIA, return -ENODEV); | ||
46 | |||
47 | if ((err = init_dsp_comm_page(chip))) { | ||
48 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
49 | return err; | ||
50 | } | ||
51 | |||
52 | chip->device_id = device_id; | ||
53 | chip->subdevice_id = subdevice_id; | ||
54 | chip->bad_board = TRUE; | ||
55 | chip->dsp_code_to_load = &card_fw[FW_MIA_DSP]; | ||
56 | /* Since this card has no ASIC, mark it as loaded so everything | ||
57 | works OK */ | ||
58 | chip->asic_loaded = TRUE; | ||
59 | if ((subdevice_id & 0x0000f) == MIA_MIDI_REV) | ||
60 | chip->has_midi = TRUE; | ||
61 | chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | | ||
62 | ECHO_CLOCK_BIT_SPDIF; | ||
63 | |||
64 | if ((err = load_firmware(chip)) < 0) | ||
65 | return err; | ||
66 | chip->bad_board = FALSE; | ||
67 | |||
68 | if ((err = init_line_levels(chip))) | ||
69 | return err; | ||
70 | |||
71 | /* Default routing of the virtual channels: vchannels 0-3 go to analog | ||
72 | outputs and vchannels 4-7 go to S/PDIF outputs */ | ||
73 | set_vmixer_gain(chip, 0, 0, 0); | ||
74 | set_vmixer_gain(chip, 1, 1, 0); | ||
75 | set_vmixer_gain(chip, 0, 2, 0); | ||
76 | set_vmixer_gain(chip, 1, 3, 0); | ||
77 | set_vmixer_gain(chip, 2, 4, 0); | ||
78 | set_vmixer_gain(chip, 3, 5, 0); | ||
79 | set_vmixer_gain(chip, 2, 6, 0); | ||
80 | set_vmixer_gain(chip, 3, 7, 0); | ||
81 | err = update_vmixer_level(chip); | ||
82 | |||
83 | DE_INIT(("init_hw done\n")); | ||
84 | return err; | ||
85 | } | ||
86 | |||
87 | |||
88 | |||
89 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
90 | { | ||
91 | u32 clocks_from_dsp, clock_bits; | ||
92 | |||
93 | /* Map the DSP clock detect bits to the generic driver clock | ||
94 | detect bits */ | ||
95 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
96 | |||
97 | clock_bits = ECHO_CLOCK_BIT_INTERNAL; | ||
98 | |||
99 | if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF) | ||
100 | clock_bits |= ECHO_CLOCK_BIT_SPDIF; | ||
101 | |||
102 | return clock_bits; | ||
103 | } | ||
104 | |||
105 | |||
106 | |||
107 | /* The Mia has no ASIC. Just do nothing */ | ||
108 | static int load_asic(struct echoaudio *chip) | ||
109 | { | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | |||
114 | |||
115 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
116 | { | ||
117 | u32 control_reg; | ||
118 | |||
119 | switch (rate) { | ||
120 | case 96000: | ||
121 | control_reg = MIA_96000; | ||
122 | break; | ||
123 | case 88200: | ||
124 | control_reg = MIA_88200; | ||
125 | break; | ||
126 | case 48000: | ||
127 | control_reg = MIA_48000; | ||
128 | break; | ||
129 | case 44100: | ||
130 | control_reg = MIA_44100; | ||
131 | break; | ||
132 | case 32000: | ||
133 | control_reg = MIA_32000; | ||
134 | break; | ||
135 | default: | ||
136 | DE_ACT(("set_sample_rate: %d invalid!\n", rate)); | ||
137 | return -EINVAL; | ||
138 | } | ||
139 | |||
140 | /* Override the clock setting if this Mia is set to S/PDIF clock */ | ||
141 | if (chip->input_clock == ECHO_CLOCK_SPDIF) | ||
142 | control_reg |= MIA_SPDIF; | ||
143 | |||
144 | /* Set the control register if it has changed */ | ||
145 | if (control_reg != le32_to_cpu(chip->comm_page->control_register)) { | ||
146 | if (wait_handshake(chip)) | ||
147 | return -EIO; | ||
148 | |||
149 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ | ||
150 | chip->comm_page->control_register = cpu_to_le32(control_reg); | ||
151 | chip->sample_rate = rate; | ||
152 | |||
153 | clear_handshake(chip); | ||
154 | return send_vector(chip, DSP_VC_UPDATE_CLOCKS); | ||
155 | } | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | |||
160 | |||
161 | static int set_input_clock(struct echoaudio *chip, u16 clock) | ||
162 | { | ||
163 | DE_ACT(("set_input_clock(%d)\n", clock)); | ||
164 | snd_assert(clock == ECHO_CLOCK_INTERNAL || clock == ECHO_CLOCK_SPDIF, | ||
165 | return -EINVAL); | ||
166 | |||
167 | chip->input_clock = clock; | ||
168 | return set_sample_rate(chip, chip->sample_rate); | ||
169 | } | ||
170 | |||
171 | |||
172 | |||
173 | /* This function routes the sound from a virtual channel to a real output */ | ||
174 | static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | ||
175 | int gain) | ||
176 | { | ||
177 | int index; | ||
178 | |||
179 | snd_assert(pipe < num_pipes_out(chip) && | ||
180 | output < num_busses_out(chip), return -EINVAL); | ||
181 | |||
182 | if (wait_handshake(chip)) | ||
183 | return -EIO; | ||
184 | |||
185 | chip->vmixer_gain[output][pipe] = gain; | ||
186 | index = output * num_pipes_out(chip) + pipe; | ||
187 | chip->comm_page->vmixer[index] = gain; | ||
188 | |||
189 | DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | |||
194 | |||
195 | /* Tell the DSP to read and update virtual mixer levels in comm page. */ | ||
196 | static int update_vmixer_level(struct echoaudio *chip) | ||
197 | { | ||
198 | if (wait_handshake(chip)) | ||
199 | return -EIO; | ||
200 | clear_handshake(chip); | ||
201 | return send_vector(chip, DSP_VC_SET_VMIXER_GAIN); | ||
202 | } | ||
203 | |||
204 | |||
205 | |||
206 | /* Tell the DSP to reread the flags from the comm page */ | ||
207 | static int update_flags(struct echoaudio *chip) | ||
208 | { | ||
209 | if (wait_handshake(chip)) | ||
210 | return -EIO; | ||
211 | clear_handshake(chip); | ||
212 | return send_vector(chip, DSP_VC_UPDATE_FLAGS); | ||
213 | } | ||
214 | |||
215 | |||
216 | |||
217 | static int set_professional_spdif(struct echoaudio *chip, char prof) | ||
218 | { | ||
219 | DE_ACT(("set_professional_spdif %d\n", prof)); | ||
220 | if (prof) | ||
221 | chip->comm_page->flags |= | ||
222 | __constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); | ||
223 | else | ||
224 | chip->comm_page->flags &= | ||
225 | ~__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); | ||
226 | chip->professional_spdif = prof; | ||
227 | return update_flags(chip); | ||
228 | } | ||
229 | |||
diff --git a/sound/pci/echoaudio/midi.c b/sound/pci/echoaudio/midi.c new file mode 100644 index 000000000000..e31f0f11e3a8 --- /dev/null +++ b/sound/pci/echoaudio/midi.c | |||
@@ -0,0 +1,327 @@ | |||
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 | MIDI lowlevel code | ||
34 | ******************************************************************************/ | ||
35 | |||
36 | /* Start and stop Midi input */ | ||
37 | static int enable_midi_input(struct echoaudio *chip, char enable) | ||
38 | { | ||
39 | DE_MID(("enable_midi_input(%d)\n", enable)); | ||
40 | |||
41 | if (wait_handshake(chip)) | ||
42 | return -EIO; | ||
43 | |||
44 | if (enable) { | ||
45 | chip->mtc_state = MIDI_IN_STATE_NORMAL; | ||
46 | chip->comm_page->flags |= | ||
47 | __constant_cpu_to_le32(DSP_FLAG_MIDI_INPUT); | ||
48 | } else | ||
49 | chip->comm_page->flags &= | ||
50 | ~__constant_cpu_to_le32(DSP_FLAG_MIDI_INPUT); | ||
51 | |||
52 | clear_handshake(chip); | ||
53 | return send_vector(chip, DSP_VC_UPDATE_FLAGS); | ||
54 | } | ||
55 | |||
56 | |||
57 | |||
58 | /* Send a buffer full of MIDI data to the DSP | ||
59 | Returns how many actually written or < 0 on error */ | ||
60 | static int write_midi(struct echoaudio *chip, u8 *data, int bytes) | ||
61 | { | ||
62 | snd_assert(bytes > 0 && bytes < MIDI_OUT_BUFFER_SIZE, return -EINVAL); | ||
63 | |||
64 | if (wait_handshake(chip)) | ||
65 | return -EIO; | ||
66 | |||
67 | /* HF4 indicates that it is safe to write MIDI output data */ | ||
68 | if (! (get_dsp_register(chip, CHI32_STATUS_REG) & CHI32_STATUS_REG_HF4)) | ||
69 | return 0; | ||
70 | |||
71 | chip->comm_page->midi_output[0] = bytes; | ||
72 | memcpy(&chip->comm_page->midi_output[1], data, bytes); | ||
73 | chip->comm_page->midi_out_free_count = 0; | ||
74 | clear_handshake(chip); | ||
75 | send_vector(chip, DSP_VC_MIDI_WRITE); | ||
76 | DE_MID(("write_midi: %d\n", bytes)); | ||
77 | return bytes; | ||
78 | } | ||
79 | |||
80 | |||
81 | |||
82 | /* Run the state machine for MIDI input data | ||
83 | MIDI time code sync isn't supported by this code right now, but you still need | ||
84 | this state machine to parse the incoming MIDI data stream. Every time the DSP | ||
85 | sees a 0xF1 byte come in, it adds the DSP sample position to the MIDI data | ||
86 | stream. The DSP sample position is represented as a 32 bit unsigned value, | ||
87 | with the high 16 bits first, followed by the low 16 bits. Since these aren't | ||
88 | real MIDI bytes, the following logic is needed to skip them. */ | ||
89 | static inline int mtc_process_data(struct echoaudio *chip, short midi_byte) | ||
90 | { | ||
91 | switch (chip->mtc_state) { | ||
92 | case MIDI_IN_STATE_NORMAL: | ||
93 | if (midi_byte == 0xF1) | ||
94 | chip->mtc_state = MIDI_IN_STATE_TS_HIGH; | ||
95 | break; | ||
96 | case MIDI_IN_STATE_TS_HIGH: | ||
97 | chip->mtc_state = MIDI_IN_STATE_TS_LOW; | ||
98 | return MIDI_IN_SKIP_DATA; | ||
99 | break; | ||
100 | case MIDI_IN_STATE_TS_LOW: | ||
101 | chip->mtc_state = MIDI_IN_STATE_F1_DATA; | ||
102 | return MIDI_IN_SKIP_DATA; | ||
103 | break; | ||
104 | case MIDI_IN_STATE_F1_DATA: | ||
105 | chip->mtc_state = MIDI_IN_STATE_NORMAL; | ||
106 | break; | ||
107 | } | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | |||
112 | |||
113 | /* This function is called from the IRQ handler and it reads the midi data | ||
114 | from the DSP's buffer. It returns the number of bytes received. */ | ||
115 | static int midi_service_irq(struct echoaudio *chip) | ||
116 | { | ||
117 | short int count, midi_byte, i, received; | ||
118 | |||
119 | /* The count is at index 0, followed by actual data */ | ||
120 | count = le16_to_cpu(chip->comm_page->midi_input[0]); | ||
121 | |||
122 | snd_assert(count < MIDI_IN_BUFFER_SIZE, return 0); | ||
123 | |||
124 | /* Get the MIDI data from the comm page */ | ||
125 | i = 1; | ||
126 | received = 0; | ||
127 | for (i = 1; i <= count; i++) { | ||
128 | /* Get the MIDI byte */ | ||
129 | midi_byte = le16_to_cpu(chip->comm_page->midi_input[i]); | ||
130 | |||
131 | /* Parse the incoming MIDI stream. The incoming MIDI data | ||
132 | consists of MIDI bytes and timestamps for the MIDI time code | ||
133 | 0xF1 bytes. mtc_process_data() is a little state machine that | ||
134 | parses the stream. If you get MIDI_IN_SKIP_DATA back, then | ||
135 | this is a timestamp byte, not a MIDI byte, so don't store it | ||
136 | in the MIDI input buffer. */ | ||
137 | if (mtc_process_data(chip, midi_byte) == MIDI_IN_SKIP_DATA) | ||
138 | continue; | ||
139 | |||
140 | chip->midi_buffer[received++] = (u8)midi_byte; | ||
141 | } | ||
142 | |||
143 | return received; | ||
144 | } | ||
145 | |||
146 | |||
147 | |||
148 | |||
149 | /****************************************************************************** | ||
150 | MIDI interface | ||
151 | ******************************************************************************/ | ||
152 | |||
153 | static int snd_echo_midi_input_open(struct snd_rawmidi_substream *substream) | ||
154 | { | ||
155 | struct echoaudio *chip = substream->rmidi->private_data; | ||
156 | |||
157 | chip->midi_in = substream; | ||
158 | DE_MID(("rawmidi_iopen\n")); | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | |||
163 | |||
164 | static void snd_echo_midi_input_trigger(struct snd_rawmidi_substream *substream, | ||
165 | int up) | ||
166 | { | ||
167 | struct echoaudio *chip = substream->rmidi->private_data; | ||
168 | |||
169 | if (up != chip->midi_input_enabled) { | ||
170 | spin_lock_irq(&chip->lock); | ||
171 | enable_midi_input(chip, up); | ||
172 | spin_unlock_irq(&chip->lock); | ||
173 | chip->midi_input_enabled = up; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | |||
178 | |||
179 | static int snd_echo_midi_input_close(struct snd_rawmidi_substream *substream) | ||
180 | { | ||
181 | struct echoaudio *chip = substream->rmidi->private_data; | ||
182 | |||
183 | chip->midi_in = NULL; | ||
184 | DE_MID(("rawmidi_iclose\n")); | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | |||
189 | |||
190 | static int snd_echo_midi_output_open(struct snd_rawmidi_substream *substream) | ||
191 | { | ||
192 | struct echoaudio *chip = substream->rmidi->private_data; | ||
193 | |||
194 | chip->tinuse = 0; | ||
195 | chip->midi_full = 0; | ||
196 | chip->midi_out = substream; | ||
197 | DE_MID(("rawmidi_oopen\n")); | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | |||
202 | |||
203 | static void snd_echo_midi_output_write(unsigned long data) | ||
204 | { | ||
205 | struct echoaudio *chip = (struct echoaudio *)data; | ||
206 | unsigned long flags; | ||
207 | int bytes, sent, time; | ||
208 | unsigned char buf[MIDI_OUT_BUFFER_SIZE - 1]; | ||
209 | |||
210 | DE_MID(("snd_echo_midi_output_write\n")); | ||
211 | /* No interrupts are involved: we have to check at regular intervals | ||
212 | if the card's output buffer has room for new data. */ | ||
213 | sent = bytes = 0; | ||
214 | spin_lock_irqsave(&chip->lock, flags); | ||
215 | chip->midi_full = 0; | ||
216 | if (chip->midi_out && !snd_rawmidi_transmit_empty(chip->midi_out)) { | ||
217 | bytes = snd_rawmidi_transmit_peek(chip->midi_out, buf, | ||
218 | MIDI_OUT_BUFFER_SIZE - 1); | ||
219 | DE_MID(("Try to send %d bytes...\n", bytes)); | ||
220 | sent = write_midi(chip, buf, bytes); | ||
221 | if (sent < 0) { | ||
222 | snd_printk(KERN_ERR "write_midi() error %d\n", sent); | ||
223 | /* retry later */ | ||
224 | sent = 9000; | ||
225 | chip->midi_full = 1; | ||
226 | } else if (sent > 0) { | ||
227 | DE_MID(("%d bytes sent\n", sent)); | ||
228 | snd_rawmidi_transmit_ack(chip->midi_out, sent); | ||
229 | } else { | ||
230 | /* Buffer is full. DSP's internal buffer is 64 (128 ?) | ||
231 | bytes long. Let's wait until half of them are sent */ | ||
232 | DE_MID(("Full\n")); | ||
233 | sent = 32; | ||
234 | chip->midi_full = 1; | ||
235 | } | ||
236 | } | ||
237 | |||
238 | /* We restart the timer only if there is some data left to send */ | ||
239 | if (!snd_rawmidi_transmit_empty(chip->midi_out) && chip->tinuse) { | ||
240 | /* The timer will expire slightly after the data has been | ||
241 | sent */ | ||
242 | time = (sent << 3) / 25 + 1; /* 8/25=0.32ms to send a byte */ | ||
243 | mod_timer(&chip->timer, jiffies + (time * HZ + 999) / 1000); | ||
244 | DE_MID(("Timer armed(%d)\n", ((time * HZ + 999) / 1000))); | ||
245 | } | ||
246 | spin_unlock_irqrestore(&chip->lock, flags); | ||
247 | } | ||
248 | |||
249 | |||
250 | |||
251 | static void snd_echo_midi_output_trigger(struct snd_rawmidi_substream *substream, | ||
252 | int up) | ||
253 | { | ||
254 | struct echoaudio *chip = substream->rmidi->private_data; | ||
255 | |||
256 | DE_MID(("snd_echo_midi_output_trigger(%d)\n", up)); | ||
257 | spin_lock_irq(&chip->lock); | ||
258 | if (up) { | ||
259 | if (!chip->tinuse) { | ||
260 | init_timer(&chip->timer); | ||
261 | chip->timer.function = snd_echo_midi_output_write; | ||
262 | chip->timer.data = (unsigned long)chip; | ||
263 | chip->tinuse = 1; | ||
264 | } | ||
265 | } else { | ||
266 | if (chip->tinuse) { | ||
267 | del_timer(&chip->timer); | ||
268 | chip->tinuse = 0; | ||
269 | DE_MID(("Timer removed\n")); | ||
270 | } | ||
271 | } | ||
272 | spin_unlock_irq(&chip->lock); | ||
273 | |||
274 | if (up && !chip->midi_full) | ||
275 | snd_echo_midi_output_write((unsigned long)chip); | ||
276 | } | ||
277 | |||
278 | |||
279 | |||
280 | static int snd_echo_midi_output_close(struct snd_rawmidi_substream *substream) | ||
281 | { | ||
282 | struct echoaudio *chip = substream->rmidi->private_data; | ||
283 | |||
284 | chip->midi_out = NULL; | ||
285 | DE_MID(("rawmidi_oclose\n")); | ||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | |||
290 | |||
291 | static struct snd_rawmidi_ops snd_echo_midi_input = { | ||
292 | .open = snd_echo_midi_input_open, | ||
293 | .close = snd_echo_midi_input_close, | ||
294 | .trigger = snd_echo_midi_input_trigger, | ||
295 | }; | ||
296 | |||
297 | static struct snd_rawmidi_ops snd_echo_midi_output = { | ||
298 | .open = snd_echo_midi_output_open, | ||
299 | .close = snd_echo_midi_output_close, | ||
300 | .trigger = snd_echo_midi_output_trigger, | ||
301 | }; | ||
302 | |||
303 | |||
304 | |||
305 | /* <--snd_echo_probe() */ | ||
306 | static int __devinit snd_echo_midi_create(struct snd_card *card, | ||
307 | struct echoaudio *chip) | ||
308 | { | ||
309 | int err; | ||
310 | |||
311 | if ((err = snd_rawmidi_new(card, card->shortname, 0, 1, 1, | ||
312 | &chip->rmidi)) < 0) | ||
313 | return err; | ||
314 | |||
315 | strcpy(chip->rmidi->name, card->shortname); | ||
316 | chip->rmidi->private_data = chip; | ||
317 | |||
318 | snd_rawmidi_set_ops(chip->rmidi, SNDRV_RAWMIDI_STREAM_INPUT, | ||
319 | &snd_echo_midi_input); | ||
320 | snd_rawmidi_set_ops(chip->rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, | ||
321 | &snd_echo_midi_output); | ||
322 | |||
323 | chip->rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | | ||
324 | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; | ||
325 | DE_INIT(("MIDI ok\n")); | ||
326 | return 0; | ||
327 | } | ||
diff --git a/sound/pci/echoaudio/mona.c b/sound/pci/echoaudio/mona.c new file mode 100644 index 000000000000..5dc512add372 --- /dev/null +++ b/sound/pci/echoaudio/mona.c | |||
@@ -0,0 +1,129 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define ECHO24_FAMILY | ||
20 | #define ECHOCARD_MONA | ||
21 | #define ECHOCARD_NAME "Mona" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | #define ECHOCARD_HAS_ASIC | ||
24 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
25 | #define ECHOCARD_HAS_DIGITAL_IO | ||
26 | #define ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE | ||
27 | #define ECHOCARD_HAS_DIGITAL_MODE_SWITCH | ||
28 | #define ECHOCARD_HAS_EXTERNAL_CLOCK | ||
29 | #define ECHOCARD_HAS_ADAT 6 | ||
30 | #define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
31 | |||
32 | /* Pipe indexes */ | ||
33 | #define PX_ANALOG_OUT 0 /* 6 */ | ||
34 | #define PX_DIGITAL_OUT 6 /* 8 */ | ||
35 | #define PX_ANALOG_IN 14 /* 4 */ | ||
36 | #define PX_DIGITAL_IN 18 /* 8 */ | ||
37 | #define PX_NUM 26 | ||
38 | |||
39 | /* Bus indexes */ | ||
40 | #define BX_ANALOG_OUT 0 /* 6 */ | ||
41 | #define BX_DIGITAL_OUT 6 /* 8 */ | ||
42 | #define BX_ANALOG_IN 14 /* 4 */ | ||
43 | #define BX_DIGITAL_IN 18 /* 8 */ | ||
44 | #define BX_NUM 26 | ||
45 | |||
46 | |||
47 | #include <sound/driver.h> | ||
48 | #include <linux/delay.h> | ||
49 | #include <linux/init.h> | ||
50 | #include <linux/interrupt.h> | ||
51 | #include <linux/pci.h> | ||
52 | #include <linux/slab.h> | ||
53 | #include <linux/moduleparam.h> | ||
54 | #include <linux/firmware.h> | ||
55 | #include <sound/core.h> | ||
56 | #include <sound/info.h> | ||
57 | #include <sound/control.h> | ||
58 | #include <sound/pcm.h> | ||
59 | #include <sound/pcm_params.h> | ||
60 | #include <sound/asoundef.h> | ||
61 | #include <sound/initval.h> | ||
62 | #include <asm/io.h> | ||
63 | #include <asm/atomic.h> | ||
64 | #include "echoaudio.h" | ||
65 | |||
66 | #define FW_361_LOADER 0 | ||
67 | #define FW_MONA_301_DSP 1 | ||
68 | #define FW_MONA_361_DSP 2 | ||
69 | #define FW_MONA_301_1_ASIC48 3 | ||
70 | #define FW_MONA_301_1_ASIC96 4 | ||
71 | #define FW_MONA_361_1_ASIC48 5 | ||
72 | #define FW_MONA_361_1_ASIC96 6 | ||
73 | #define FW_MONA_2_ASIC 7 | ||
74 | |||
75 | static const struct firmware card_fw[] = { | ||
76 | {0, "loader_dsp.fw"}, | ||
77 | {0, "mona_301_dsp.fw"}, | ||
78 | {0, "mona_361_dsp.fw"}, | ||
79 | {0, "mona_301_1_asic_48.fw"}, | ||
80 | {0, "mona_301_1_asic_96.fw"}, | ||
81 | {0, "mona_361_1_asic_48.fw"}, | ||
82 | {0, "mona_361_1_asic_96.fw"}, | ||
83 | {0, "mona_2_asic.fw"} | ||
84 | }; | ||
85 | |||
86 | static struct pci_device_id snd_echo_ids[] = { | ||
87 | {0x1057, 0x1801, 0xECC0, 0x0070, 0, 0, 0}, /* DSP 56301 Mona rev.0 */ | ||
88 | {0x1057, 0x1801, 0xECC0, 0x0071, 0, 0, 0}, /* DSP 56301 Mona rev.1 */ | ||
89 | {0x1057, 0x1801, 0xECC0, 0x0072, 0, 0, 0}, /* DSP 56301 Mona rev.2 */ | ||
90 | {0x1057, 0x3410, 0xECC0, 0x0070, 0, 0, 0}, /* DSP 56361 Mona rev.0 */ | ||
91 | {0x1057, 0x3410, 0xECC0, 0x0071, 0, 0, 0}, /* DSP 56361 Mona rev.1 */ | ||
92 | {0x1057, 0x3410, 0xECC0, 0x0072, 0, 0, 0}, /* DSP 56361 Mona rev.2 */ | ||
93 | {0,} | ||
94 | }; | ||
95 | |||
96 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
97 | .info = SNDRV_PCM_INFO_MMAP | | ||
98 | SNDRV_PCM_INFO_INTERLEAVED | | ||
99 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
100 | SNDRV_PCM_INFO_MMAP_VALID | | ||
101 | SNDRV_PCM_INFO_PAUSE | | ||
102 | SNDRV_PCM_INFO_SYNC_START, | ||
103 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
104 | SNDRV_PCM_FMTBIT_S16_LE | | ||
105 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
106 | SNDRV_PCM_FMTBIT_S32_LE | | ||
107 | SNDRV_PCM_FMTBIT_S32_BE, | ||
108 | .rates = SNDRV_PCM_RATE_8000_48000 | | ||
109 | SNDRV_PCM_RATE_88200 | | ||
110 | SNDRV_PCM_RATE_96000, | ||
111 | .rate_min = 8000, | ||
112 | .rate_max = 96000, | ||
113 | .channels_min = 1, | ||
114 | .channels_max = 8, | ||
115 | .buffer_bytes_max = 262144, | ||
116 | .period_bytes_min = 32, | ||
117 | .period_bytes_max = 131072, | ||
118 | .periods_min = 2, | ||
119 | .periods_max = 220, | ||
120 | /* One page (4k) contains 512 instructions. I don't know if the hw | ||
121 | supports lists longer than this. In this case periods_max=220 is a | ||
122 | safe limit to make sure the list never exceeds 512 instructions. */ | ||
123 | }; | ||
124 | |||
125 | |||
126 | #include "mona_dsp.c" | ||
127 | #include "echoaudio_dsp.c" | ||
128 | #include "echoaudio_gml.c" | ||
129 | #include "echoaudio.c" | ||
diff --git a/sound/pci/echoaudio/mona_dsp.c b/sound/pci/echoaudio/mona_dsp.c new file mode 100644 index 000000000000..c0b4bf0be7d1 --- /dev/null +++ b/sound/pci/echoaudio/mona_dsp.c | |||
@@ -0,0 +1,428 @@ | |||
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, | ||
37 | const struct firmware *asic); | ||
38 | static int check_asic_status(struct echoaudio *chip); | ||
39 | |||
40 | |||
41 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
42 | { | ||
43 | int err; | ||
44 | |||
45 | DE_INIT(("init_hw() - Mona\n")); | ||
46 | snd_assert((subdevice_id & 0xfff0) == MONA, return -ENODEV); | ||
47 | |||
48 | if ((err = init_dsp_comm_page(chip))) { | ||
49 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
50 | return err; | ||
51 | } | ||
52 | |||
53 | chip->device_id = device_id; | ||
54 | chip->subdevice_id = subdevice_id; | ||
55 | chip->bad_board = TRUE; | ||
56 | chip->input_clock_types = | ||
57 | ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | | ||
58 | ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT; | ||
59 | chip->digital_modes = | ||
60 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | | ||
61 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | | ||
62 | ECHOCAPS_HAS_DIGITAL_MODE_ADAT; | ||
63 | |||
64 | /* Mona comes in both '301 and '361 flavors */ | ||
65 | if (chip->device_id == DEVICE_ID_56361) | ||
66 | chip->dsp_code_to_load = &card_fw[FW_MONA_361_DSP]; | ||
67 | else | ||
68 | chip->dsp_code_to_load = &card_fw[FW_MONA_301_DSP]; | ||
69 | |||
70 | chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; | ||
71 | chip->professional_spdif = FALSE; | ||
72 | chip->digital_in_automute = TRUE; | ||
73 | |||
74 | if ((err = load_firmware(chip)) < 0) | ||
75 | return err; | ||
76 | chip->bad_board = FALSE; | ||
77 | |||
78 | if ((err = init_line_levels(chip)) < 0) | ||
79 | return err; | ||
80 | |||
81 | err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); | ||
82 | snd_assert(err >= 0, return err); | ||
83 | err = set_professional_spdif(chip, TRUE); | ||
84 | |||
85 | DE_INIT(("init_hw done\n")); | ||
86 | return err; | ||
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 | const struct firmware *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 = &card_fw[FW_MONA_361_1_ASIC48]; | ||
130 | else | ||
131 | asic = &card_fw[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 | &card_fw[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 | const struct firmware *asic; | ||
167 | int err; | ||
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 = &card_fw[FW_MONA_361_1_ASIC96]; | ||
175 | else | ||
176 | asic = &card_fw[FW_MONA_361_1_ASIC48]; | ||
177 | } else { | ||
178 | if (double_speed) | ||
179 | asic = &card_fw[FW_MONA_301_1_ASIC96]; | ||
180 | else | ||
181 | asic = &card_fw[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 | const struct firmware *asic; | ||
202 | char force_write; | ||
203 | |||
204 | /* Only set the clock for internal mode. */ | ||
205 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { | ||
206 | DE_ACT(("set_sample_rate: Cannot set sample rate - " | ||
207 | "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 = &card_fw[FW_MONA_361_1_ASIC96]; | ||
220 | else | ||
221 | asic = &card_fw[FW_MONA_301_1_ASIC96]; | ||
222 | } else { | ||
223 | if (chip->device_id == DEVICE_ID_56361) | ||
224 | asic = &card_fw[FW_MONA_361_1_ASIC48]; | ||
225 | else | ||
226 | asic = &card_fw[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 | DE_ACT(("set_sample_rate: %d invalid!\n", rate)); | ||
284 | return -EINVAL; | ||
285 | } | ||
286 | |||
287 | control_reg |= clock; | ||
288 | |||
289 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ | ||
290 | chip->sample_rate = rate; | ||
291 | DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); | ||
292 | |||
293 | return write_control_reg(chip, control_reg, force_write); | ||
294 | } | ||
295 | |||
296 | |||
297 | |||
298 | static int set_input_clock(struct echoaudio *chip, u16 clock) | ||
299 | { | ||
300 | u32 control_reg, clocks_from_dsp; | ||
301 | int err; | ||
302 | |||
303 | DE_ACT(("set_input_clock:\n")); | ||
304 | |||
305 | /* Prevent two simultaneous calls to switch_asic() */ | ||
306 | if (atomic_read(&chip->opencount)) | ||
307 | return -EAGAIN; | ||
308 | |||
309 | /* Mask off the clock select bits */ | ||
310 | control_reg = le32_to_cpu(chip->comm_page->control_register) & | ||
311 | GML_CLOCK_CLEAR_MASK; | ||
312 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
313 | |||
314 | switch (clock) { | ||
315 | case ECHO_CLOCK_INTERNAL: | ||
316 | DE_ACT(("Set Mona clock to INTERNAL\n")); | ||
317 | chip->input_clock = ECHO_CLOCK_INTERNAL; | ||
318 | return set_sample_rate(chip, chip->sample_rate); | ||
319 | case ECHO_CLOCK_SPDIF: | ||
320 | if (chip->digital_mode == DIGITAL_MODE_ADAT) | ||
321 | return -EAGAIN; | ||
322 | spin_unlock_irq(&chip->lock); | ||
323 | err = switch_asic(chip, clocks_from_dsp & | ||
324 | GML_CLOCK_DETECT_BIT_SPDIF96); | ||
325 | spin_lock_irq(&chip->lock); | ||
326 | if (err < 0) | ||
327 | return err; | ||
328 | DE_ACT(("Set Mona clock to SPDIF\n")); | ||
329 | control_reg |= GML_SPDIF_CLOCK; | ||
330 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96) | ||
331 | control_reg |= GML_DOUBLE_SPEED_MODE; | ||
332 | else | ||
333 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
334 | break; | ||
335 | case ECHO_CLOCK_WORD: | ||
336 | DE_ACT(("Set Mona clock to WORD\n")); | ||
337 | spin_unlock_irq(&chip->lock); | ||
338 | err = switch_asic(chip, clocks_from_dsp & | ||
339 | GML_CLOCK_DETECT_BIT_WORD96); | ||
340 | spin_lock_irq(&chip->lock); | ||
341 | if (err < 0) | ||
342 | return err; | ||
343 | control_reg |= GML_WORD_CLOCK; | ||
344 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96) | ||
345 | control_reg |= GML_DOUBLE_SPEED_MODE; | ||
346 | else | ||
347 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
348 | break; | ||
349 | case ECHO_CLOCK_ADAT: | ||
350 | DE_ACT(("Set Mona clock to ADAT\n")); | ||
351 | if (chip->digital_mode != DIGITAL_MODE_ADAT) | ||
352 | return -EAGAIN; | ||
353 | control_reg |= GML_ADAT_CLOCK; | ||
354 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
355 | break; | ||
356 | default: | ||
357 | DE_ACT(("Input clock 0x%x not supported for Mona\n", clock)); | ||
358 | return -EINVAL; | ||
359 | } | ||
360 | |||
361 | chip->input_clock = clock; | ||
362 | return write_control_reg(chip, control_reg, TRUE); | ||
363 | } | ||
364 | |||
365 | |||
366 | |||
367 | static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | ||
368 | { | ||
369 | u32 control_reg; | ||
370 | int err, incompatible_clock; | ||
371 | |||
372 | /* Set clock to "internal" if it's not compatible with the new mode */ | ||
373 | incompatible_clock = FALSE; | ||
374 | switch (mode) { | ||
375 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
376 | case DIGITAL_MODE_SPDIF_RCA: | ||
377 | if (chip->input_clock == ECHO_CLOCK_ADAT) | ||
378 | incompatible_clock = TRUE; | ||
379 | break; | ||
380 | case DIGITAL_MODE_ADAT: | ||
381 | if (chip->input_clock == ECHO_CLOCK_SPDIF) | ||
382 | incompatible_clock = TRUE; | ||
383 | break; | ||
384 | default: | ||
385 | DE_ACT(("Digital mode not supported: %d\n", mode)); | ||
386 | return -EINVAL; | ||
387 | } | ||
388 | |||
389 | spin_lock_irq(&chip->lock); | ||
390 | |||
391 | if (incompatible_clock) { /* Switch to 48KHz, internal */ | ||
392 | chip->sample_rate = 48000; | ||
393 | set_input_clock(chip, ECHO_CLOCK_INTERNAL); | ||
394 | } | ||
395 | |||
396 | /* Clear the current digital mode */ | ||
397 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
398 | control_reg &= GML_DIGITAL_MODE_CLEAR_MASK; | ||
399 | |||
400 | /* Tweak the control reg */ | ||
401 | switch (mode) { | ||
402 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
403 | control_reg |= GML_SPDIF_OPTICAL_MODE; | ||
404 | break; | ||
405 | case DIGITAL_MODE_SPDIF_RCA: | ||
406 | /* GML_SPDIF_OPTICAL_MODE bit cleared */ | ||
407 | break; | ||
408 | case DIGITAL_MODE_ADAT: | ||
409 | /* If the current ASIC is the 96KHz ASIC, switch the ASIC | ||
410 | and set to 48 KHz */ | ||
411 | if (chip->asic_code == &card_fw[FW_MONA_361_1_ASIC96] || | ||
412 | chip->asic_code == &card_fw[FW_MONA_301_1_ASIC96]) { | ||
413 | set_sample_rate(chip, 48000); | ||
414 | } | ||
415 | control_reg |= GML_ADAT_MODE; | ||
416 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
417 | break; | ||
418 | } | ||
419 | |||
420 | err = write_control_reg(chip, control_reg, FALSE); | ||
421 | spin_unlock_irq(&chip->lock); | ||
422 | if (err < 0) | ||
423 | return err; | ||
424 | chip->digital_mode = mode; | ||
425 | |||
426 | DE_ACT(("set_digital_mode to %d\n", mode)); | ||
427 | return incompatible_clock; | ||
428 | } | ||
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 8c2a8174ece1..23201f3eeb12 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -408,7 +408,9 @@ static const struct hda_codec_preset *find_codec_preset(struct hda_codec *codec) | |||
408 | u32 mask = preset->mask; | 408 | u32 mask = preset->mask; |
409 | if (! mask) | 409 | if (! mask) |
410 | mask = ~0; | 410 | mask = ~0; |
411 | if (preset->id == (codec->vendor_id & mask)) | 411 | if (preset->id == (codec->vendor_id & mask) && |
412 | (! preset->rev || | ||
413 | preset->rev == codec->revision_id)) | ||
412 | return preset; | 414 | return preset; |
413 | } | 415 | } |
414 | } | 416 | } |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index dd4e00a82b55..33b7d5806469 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -799,6 +799,8 @@ static struct hda_board_config ad1986a_cfg_tbl[] = { | |||
799 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x818f, | 799 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x818f, |
800 | .config = AD1986A_LAPTOP }, /* ASUS P5GV-MX */ | 800 | .config = AD1986A_LAPTOP }, /* ASUS P5GV-MX */ |
801 | { .modelname = "laptop-eapd", .config = AD1986A_LAPTOP_EAPD }, | 801 | { .modelname = "laptop-eapd", .config = AD1986A_LAPTOP_EAPD }, |
802 | { .pci_subvendor = 0x144d, .pci_subdevice = 0xc023, | ||
803 | .config = AD1986A_LAPTOP_EAPD }, /* Samsung X60 Chane */ | ||
802 | { .pci_subvendor = 0x144d, .pci_subdevice = 0xc024, | 804 | { .pci_subvendor = 0x144d, .pci_subdevice = 0xc024, |
803 | .config = AD1986A_LAPTOP_EAPD }, /* Samsung R65-T2300 Charis */ | 805 | .config = AD1986A_LAPTOP_EAPD }, /* Samsung R65-T2300 Charis */ |
804 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1153, | 806 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1153, |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 98b9f16c26ff..18d105263fea 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -78,6 +78,7 @@ enum { | |||
78 | enum { | 78 | enum { |
79 | ALC262_BASIC, | 79 | ALC262_BASIC, |
80 | ALC262_FUJITSU, | 80 | ALC262_FUJITSU, |
81 | ALC262_HP_BPC, | ||
81 | ALC262_AUTO, | 82 | ALC262_AUTO, |
82 | ALC262_MODEL_LAST /* last tag */ | 83 | ALC262_MODEL_LAST /* last tag */ |
83 | }; | 84 | }; |
@@ -85,6 +86,7 @@ enum { | |||
85 | /* ALC861 models */ | 86 | /* ALC861 models */ |
86 | enum { | 87 | enum { |
87 | ALC861_3ST, | 88 | ALC861_3ST, |
89 | ALC660_3ST, | ||
88 | ALC861_3ST_DIG, | 90 | ALC861_3ST_DIG, |
89 | ALC861_6ST_DIG, | 91 | ALC861_6ST_DIG, |
90 | ALC861_AUTO, | 92 | ALC861_AUTO, |
@@ -99,6 +101,17 @@ enum { | |||
99 | ALC882_MODEL_LAST, | 101 | ALC882_MODEL_LAST, |
100 | }; | 102 | }; |
101 | 103 | ||
104 | /* ALC883 models */ | ||
105 | enum { | ||
106 | ALC883_3ST_2ch_DIG, | ||
107 | ALC883_3ST_6ch_DIG, | ||
108 | ALC883_3ST_6ch, | ||
109 | ALC883_6ST_DIG, | ||
110 | ALC888_DEMO_BOARD, | ||
111 | ALC883_AUTO, | ||
112 | ALC883_MODEL_LAST, | ||
113 | }; | ||
114 | |||
102 | /* for GPIO Poll */ | 115 | /* for GPIO Poll */ |
103 | #define GPIO_MASK 0x03 | 116 | #define GPIO_MASK 0x03 |
104 | 117 | ||
@@ -108,7 +121,8 @@ struct alc_spec { | |||
108 | unsigned int num_mixers; | 121 | unsigned int num_mixers; |
109 | 122 | ||
110 | const struct hda_verb *init_verbs[5]; /* initialization verbs | 123 | const struct hda_verb *init_verbs[5]; /* initialization verbs |
111 | * don't forget NULL termination! | 124 | * don't forget NULL |
125 | * termination! | ||
112 | */ | 126 | */ |
113 | unsigned int num_init_verbs; | 127 | unsigned int num_init_verbs; |
114 | 128 | ||
@@ -163,7 +177,9 @@ struct alc_spec { | |||
163 | * configuration template - to be copied to the spec instance | 177 | * configuration template - to be copied to the spec instance |
164 | */ | 178 | */ |
165 | struct alc_config_preset { | 179 | struct alc_config_preset { |
166 | struct snd_kcontrol_new *mixers[5]; /* should be identical size with spec */ | 180 | struct snd_kcontrol_new *mixers[5]; /* should be identical size |
181 | * with spec | ||
182 | */ | ||
167 | const struct hda_verb *init_verbs[5]; | 183 | const struct hda_verb *init_verbs[5]; |
168 | unsigned int num_dacs; | 184 | unsigned int num_dacs; |
169 | hda_nid_t *dac_nids; | 185 | hda_nid_t *dac_nids; |
@@ -184,7 +200,8 @@ struct alc_config_preset { | |||
184 | /* | 200 | /* |
185 | * input MUX handling | 201 | * input MUX handling |
186 | */ | 202 | */ |
187 | static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 203 | static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, |
204 | struct snd_ctl_elem_info *uinfo) | ||
188 | { | 205 | { |
189 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 206 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
190 | struct alc_spec *spec = codec->spec; | 207 | struct alc_spec *spec = codec->spec; |
@@ -194,7 +211,8 @@ static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
194 | return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); | 211 | return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); |
195 | } | 212 | } |
196 | 213 | ||
197 | static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 214 | static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, |
215 | struct snd_ctl_elem_value *ucontrol) | ||
198 | { | 216 | { |
199 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 217 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
200 | struct alc_spec *spec = codec->spec; | 218 | struct alc_spec *spec = codec->spec; |
@@ -204,21 +222,24 @@ static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
204 | return 0; | 222 | return 0; |
205 | } | 223 | } |
206 | 224 | ||
207 | static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 225 | static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, |
226 | struct snd_ctl_elem_value *ucontrol) | ||
208 | { | 227 | { |
209 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 228 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
210 | struct alc_spec *spec = codec->spec; | 229 | struct alc_spec *spec = codec->spec; |
211 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 230 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); |
212 | unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; | 231 | unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; |
213 | return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol, | 232 | return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol, |
214 | spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]); | 233 | spec->adc_nids[adc_idx], |
234 | &spec->cur_mux[adc_idx]); | ||
215 | } | 235 | } |
216 | 236 | ||
217 | 237 | ||
218 | /* | 238 | /* |
219 | * channel mode setting | 239 | * channel mode setting |
220 | */ | 240 | */ |
221 | static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 241 | static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, |
242 | struct snd_ctl_elem_info *uinfo) | ||
222 | { | 243 | { |
223 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 244 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
224 | struct alc_spec *spec = codec->spec; | 245 | struct alc_spec *spec = codec->spec; |
@@ -226,20 +247,24 @@ static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_i | |||
226 | spec->num_channel_mode); | 247 | spec->num_channel_mode); |
227 | } | 248 | } |
228 | 249 | ||
229 | static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 250 | static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, |
251 | struct snd_ctl_elem_value *ucontrol) | ||
230 | { | 252 | { |
231 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 253 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
232 | struct alc_spec *spec = codec->spec; | 254 | struct alc_spec *spec = codec->spec; |
233 | return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, | 255 | return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, |
234 | spec->num_channel_mode, spec->multiout.max_channels); | 256 | spec->num_channel_mode, |
257 | spec->multiout.max_channels); | ||
235 | } | 258 | } |
236 | 259 | ||
237 | static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 260 | static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, |
261 | struct snd_ctl_elem_value *ucontrol) | ||
238 | { | 262 | { |
239 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 263 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
240 | struct alc_spec *spec = codec->spec; | 264 | struct alc_spec *spec = codec->spec; |
241 | return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, | 265 | return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, |
242 | spec->num_channel_mode, &spec->multiout.max_channels); | 266 | spec->num_channel_mode, |
267 | &spec->multiout.max_channels); | ||
243 | } | 268 | } |
244 | 269 | ||
245 | /* | 270 | /* |
@@ -290,7 +315,8 @@ static signed char alc_pin_mode_dir_info[5][2] = { | |||
290 | #define alc_pin_mode_n_items(_dir) \ | 315 | #define alc_pin_mode_n_items(_dir) \ |
291 | (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) | 316 | (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) |
292 | 317 | ||
293 | static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 318 | static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, |
319 | struct snd_ctl_elem_info *uinfo) | ||
294 | { | 320 | { |
295 | unsigned int item_num = uinfo->value.enumerated.item; | 321 | unsigned int item_num = uinfo->value.enumerated.item; |
296 | unsigned char dir = (kcontrol->private_value >> 16) & 0xff; | 322 | unsigned char dir = (kcontrol->private_value >> 16) & 0xff; |
@@ -305,40 +331,46 @@ static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
305 | return 0; | 331 | return 0; |
306 | } | 332 | } |
307 | 333 | ||
308 | static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 334 | static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, |
335 | struct snd_ctl_elem_value *ucontrol) | ||
309 | { | 336 | { |
310 | unsigned int i; | 337 | unsigned int i; |
311 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 338 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
312 | hda_nid_t nid = kcontrol->private_value & 0xffff; | 339 | hda_nid_t nid = kcontrol->private_value & 0xffff; |
313 | unsigned char dir = (kcontrol->private_value >> 16) & 0xff; | 340 | unsigned char dir = (kcontrol->private_value >> 16) & 0xff; |
314 | long *valp = ucontrol->value.integer.value; | 341 | long *valp = ucontrol->value.integer.value; |
315 | unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00); | 342 | unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, |
343 | AC_VERB_GET_PIN_WIDGET_CONTROL, | ||
344 | 0x00); | ||
316 | 345 | ||
317 | /* Find enumerated value for current pinctl setting */ | 346 | /* Find enumerated value for current pinctl setting */ |
318 | i = alc_pin_mode_min(dir); | 347 | i = alc_pin_mode_min(dir); |
319 | while (alc_pin_mode_values[i]!=pinctl && i<=alc_pin_mode_max(dir)) | 348 | while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir)) |
320 | i++; | 349 | i++; |
321 | *valp = i<=alc_pin_mode_max(dir)?i:alc_pin_mode_min(dir); | 350 | *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir); |
322 | return 0; | 351 | return 0; |
323 | } | 352 | } |
324 | 353 | ||
325 | static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 354 | static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, |
355 | struct snd_ctl_elem_value *ucontrol) | ||
326 | { | 356 | { |
327 | signed int change; | 357 | signed int change; |
328 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 358 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
329 | hda_nid_t nid = kcontrol->private_value & 0xffff; | 359 | hda_nid_t nid = kcontrol->private_value & 0xffff; |
330 | unsigned char dir = (kcontrol->private_value >> 16) & 0xff; | 360 | unsigned char dir = (kcontrol->private_value >> 16) & 0xff; |
331 | long val = *ucontrol->value.integer.value; | 361 | long val = *ucontrol->value.integer.value; |
332 | unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00); | 362 | unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, |
363 | AC_VERB_GET_PIN_WIDGET_CONTROL, | ||
364 | 0x00); | ||
333 | 365 | ||
334 | if (val<alc_pin_mode_min(dir) || val>alc_pin_mode_max(dir)) | 366 | if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) |
335 | val = alc_pin_mode_min(dir); | 367 | val = alc_pin_mode_min(dir); |
336 | 368 | ||
337 | change = pinctl != alc_pin_mode_values[val]; | 369 | change = pinctl != alc_pin_mode_values[val]; |
338 | if (change) { | 370 | if (change) { |
339 | /* Set pin mode to that requested */ | 371 | /* Set pin mode to that requested */ |
340 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL, | 372 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL, |
341 | alc_pin_mode_values[val]); | 373 | alc_pin_mode_values[val]); |
342 | 374 | ||
343 | /* Also enable the retasking pin's input/output as required | 375 | /* Also enable the retasking pin's input/output as required |
344 | * for the requested pin mode. Enum values of 2 or less are | 376 | * for the requested pin mode. Enum values of 2 or less are |
@@ -351,15 +383,19 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
351 | * this turns out to be necessary in the future. | 383 | * this turns out to be necessary in the future. |
352 | */ | 384 | */ |
353 | if (val <= 2) { | 385 | if (val <= 2) { |
354 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, | 386 | snd_hda_codec_write(codec, nid, 0, |
355 | AMP_OUT_MUTE); | 387 | AC_VERB_SET_AMP_GAIN_MUTE, |
356 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, | 388 | AMP_OUT_MUTE); |
357 | AMP_IN_UNMUTE(0)); | 389 | snd_hda_codec_write(codec, nid, 0, |
390 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
391 | AMP_IN_UNMUTE(0)); | ||
358 | } else { | 392 | } else { |
359 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, | 393 | snd_hda_codec_write(codec, nid, 0, |
360 | AMP_IN_MUTE(0)); | 394 | AC_VERB_SET_AMP_GAIN_MUTE, |
361 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, | 395 | AMP_IN_MUTE(0)); |
362 | AMP_OUT_UNMUTE); | 396 | snd_hda_codec_write(codec, nid, 0, |
397 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
398 | AMP_OUT_UNMUTE); | ||
363 | } | 399 | } |
364 | } | 400 | } |
365 | return change; | 401 | return change; |
@@ -378,7 +414,8 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
378 | * needed for any "production" models. | 414 | * needed for any "production" models. |
379 | */ | 415 | */ |
380 | #ifdef CONFIG_SND_DEBUG | 416 | #ifdef CONFIG_SND_DEBUG |
381 | static int alc_gpio_data_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 417 | static int alc_gpio_data_info(struct snd_kcontrol *kcontrol, |
418 | struct snd_ctl_elem_info *uinfo) | ||
382 | { | 419 | { |
383 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | 420 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
384 | uinfo->count = 1; | 421 | uinfo->count = 1; |
@@ -386,33 +423,38 @@ static int alc_gpio_data_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem | |||
386 | uinfo->value.integer.max = 1; | 423 | uinfo->value.integer.max = 1; |
387 | return 0; | 424 | return 0; |
388 | } | 425 | } |
389 | static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 426 | static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, |
427 | struct snd_ctl_elem_value *ucontrol) | ||
390 | { | 428 | { |
391 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 429 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
392 | hda_nid_t nid = kcontrol->private_value & 0xffff; | 430 | hda_nid_t nid = kcontrol->private_value & 0xffff; |
393 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | 431 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; |
394 | long *valp = ucontrol->value.integer.value; | 432 | long *valp = ucontrol->value.integer.value; |
395 | unsigned int val = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_GPIO_DATA,0x00); | 433 | unsigned int val = snd_hda_codec_read(codec, nid, 0, |
434 | AC_VERB_GET_GPIO_DATA, 0x00); | ||
396 | 435 | ||
397 | *valp = (val & mask) != 0; | 436 | *valp = (val & mask) != 0; |
398 | return 0; | 437 | return 0; |
399 | } | 438 | } |
400 | static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 439 | static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, |
440 | struct snd_ctl_elem_value *ucontrol) | ||
401 | { | 441 | { |
402 | signed int change; | 442 | signed int change; |
403 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 443 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
404 | hda_nid_t nid = kcontrol->private_value & 0xffff; | 444 | hda_nid_t nid = kcontrol->private_value & 0xffff; |
405 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | 445 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; |
406 | long val = *ucontrol->value.integer.value; | 446 | long val = *ucontrol->value.integer.value; |
407 | unsigned int gpio_data = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_GPIO_DATA,0x00); | 447 | unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, |
448 | AC_VERB_GET_GPIO_DATA, | ||
449 | 0x00); | ||
408 | 450 | ||
409 | /* Set/unset the masked GPIO bit(s) as needed */ | 451 | /* Set/unset the masked GPIO bit(s) as needed */ |
410 | change = (val==0?0:mask) != (gpio_data & mask); | 452 | change = (val == 0 ? 0 : mask) != (gpio_data & mask); |
411 | if (val==0) | 453 | if (val == 0) |
412 | gpio_data &= ~mask; | 454 | gpio_data &= ~mask; |
413 | else | 455 | else |
414 | gpio_data |= mask; | 456 | gpio_data |= mask; |
415 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_GPIO_DATA,gpio_data); | 457 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data); |
416 | 458 | ||
417 | return change; | 459 | return change; |
418 | } | 460 | } |
@@ -432,7 +474,8 @@ static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
432 | * necessary. | 474 | * necessary. |
433 | */ | 475 | */ |
434 | #ifdef CONFIG_SND_DEBUG | 476 | #ifdef CONFIG_SND_DEBUG |
435 | static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 477 | static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol, |
478 | struct snd_ctl_elem_info *uinfo) | ||
436 | { | 479 | { |
437 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | 480 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
438 | uinfo->count = 1; | 481 | uinfo->count = 1; |
@@ -440,33 +483,39 @@ static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ele | |||
440 | uinfo->value.integer.max = 1; | 483 | uinfo->value.integer.max = 1; |
441 | return 0; | 484 | return 0; |
442 | } | 485 | } |
443 | static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 486 | static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, |
487 | struct snd_ctl_elem_value *ucontrol) | ||
444 | { | 488 | { |
445 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 489 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
446 | hda_nid_t nid = kcontrol->private_value & 0xffff; | 490 | hda_nid_t nid = kcontrol->private_value & 0xffff; |
447 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | 491 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; |
448 | long *valp = ucontrol->value.integer.value; | 492 | long *valp = ucontrol->value.integer.value; |
449 | unsigned int val = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_DIGI_CONVERT,0x00); | 493 | unsigned int val = snd_hda_codec_read(codec, nid, 0, |
494 | AC_VERB_GET_DIGI_CONVERT, 0x00); | ||
450 | 495 | ||
451 | *valp = (val & mask) != 0; | 496 | *valp = (val & mask) != 0; |
452 | return 0; | 497 | return 0; |
453 | } | 498 | } |
454 | static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 499 | static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, |
500 | struct snd_ctl_elem_value *ucontrol) | ||
455 | { | 501 | { |
456 | signed int change; | 502 | signed int change; |
457 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 503 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
458 | hda_nid_t nid = kcontrol->private_value & 0xffff; | 504 | hda_nid_t nid = kcontrol->private_value & 0xffff; |
459 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | 505 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; |
460 | long val = *ucontrol->value.integer.value; | 506 | long val = *ucontrol->value.integer.value; |
461 | unsigned int ctrl_data = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_DIGI_CONVERT,0x00); | 507 | unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, |
508 | AC_VERB_GET_DIGI_CONVERT, | ||
509 | 0x00); | ||
462 | 510 | ||
463 | /* Set/unset the masked control bit(s) as needed */ | 511 | /* Set/unset the masked control bit(s) as needed */ |
464 | change = (val==0?0:mask) != (ctrl_data & mask); | 512 | change = (val == 0 ? 0 : mask) != (ctrl_data & mask); |
465 | if (val==0) | 513 | if (val==0) |
466 | ctrl_data &= ~mask; | 514 | ctrl_data &= ~mask; |
467 | else | 515 | else |
468 | ctrl_data |= mask; | 516 | ctrl_data |= mask; |
469 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_DIGI_CONVERT_1,ctrl_data); | 517 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, |
518 | ctrl_data); | ||
470 | 519 | ||
471 | return change; | 520 | return change; |
472 | } | 521 | } |
@@ -481,14 +530,17 @@ static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem | |||
481 | /* | 530 | /* |
482 | * set up from the preset table | 531 | * set up from the preset table |
483 | */ | 532 | */ |
484 | static void setup_preset(struct alc_spec *spec, const struct alc_config_preset *preset) | 533 | static void setup_preset(struct alc_spec *spec, |
534 | const struct alc_config_preset *preset) | ||
485 | { | 535 | { |
486 | int i; | 536 | int i; |
487 | 537 | ||
488 | for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) | 538 | for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) |
489 | spec->mixers[spec->num_mixers++] = preset->mixers[i]; | 539 | spec->mixers[spec->num_mixers++] = preset->mixers[i]; |
490 | for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; i++) | 540 | for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; |
491 | spec->init_verbs[spec->num_init_verbs++] = preset->init_verbs[i]; | 541 | i++) |
542 | spec->init_verbs[spec->num_init_verbs++] = | ||
543 | preset->init_verbs[i]; | ||
492 | 544 | ||
493 | spec->channel_mode = preset->channel_mode; | 545 | spec->channel_mode = preset->channel_mode; |
494 | spec->num_channel_mode = preset->num_channel_mode; | 546 | spec->num_channel_mode = preset->num_channel_mode; |
@@ -517,8 +569,8 @@ static void setup_preset(struct alc_spec *spec, const struct alc_config_preset * | |||
517 | * ALC880 3-stack model | 569 | * ALC880 3-stack model |
518 | * | 570 | * |
519 | * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) | 571 | * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) |
520 | * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, F-Mic = 0x1b | 572 | * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, |
521 | * HP = 0x19 | 573 | * F-Mic = 0x1b, HP = 0x19 |
522 | */ | 574 | */ |
523 | 575 | ||
524 | static hda_nid_t alc880_dac_nids[4] = { | 576 | static hda_nid_t alc880_dac_nids[4] = { |
@@ -662,7 +714,8 @@ static struct snd_kcontrol_new alc880_capture_alt_mixer[] = { | |||
662 | /* | 714 | /* |
663 | * ALC880 5-stack model | 715 | * ALC880 5-stack model |
664 | * | 716 | * |
665 | * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), Side = 0x02 (0xd) | 717 | * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), |
718 | * Side = 0x02 (0xd) | ||
666 | * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16 | 719 | * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16 |
667 | * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19 | 720 | * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19 |
668 | */ | 721 | */ |
@@ -700,7 +753,8 @@ static struct hda_channel_mode alc880_fivestack_modes[2] = { | |||
700 | /* | 753 | /* |
701 | * ALC880 6-stack model | 754 | * ALC880 6-stack model |
702 | * | 755 | * |
703 | * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), Side = 0x05 (0x0f) | 756 | * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), |
757 | * Side = 0x05 (0x0f) | ||
704 | * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17, | 758 | * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17, |
705 | * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b | 759 | * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b |
706 | */ | 760 | */ |
@@ -811,7 +865,8 @@ static struct snd_kcontrol_new alc880_w810_base_mixer[] = { | |||
811 | * Z710V model | 865 | * Z710V model |
812 | * | 866 | * |
813 | * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d) | 867 | * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d) |
814 | * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), Line = 0x1a | 868 | * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), |
869 | * Line = 0x1a | ||
815 | */ | 870 | */ |
816 | 871 | ||
817 | static hda_nid_t alc880_z71v_dac_nids[1] = { | 872 | static hda_nid_t alc880_z71v_dac_nids[1] = { |
@@ -966,7 +1021,8 @@ static int alc_build_controls(struct hda_codec *codec) | |||
966 | } | 1021 | } |
967 | 1022 | ||
968 | if (spec->multiout.dig_out_nid) { | 1023 | if (spec->multiout.dig_out_nid) { |
969 | err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); | 1024 | err = snd_hda_create_spdif_out_ctls(codec, |
1025 | spec->multiout.dig_out_nid); | ||
970 | if (err < 0) | 1026 | if (err < 0) |
971 | return err; | 1027 | return err; |
972 | } | 1028 | } |
@@ -999,8 +1055,8 @@ static struct hda_verb alc880_volume_init_verbs[] = { | |||
999 | 1055 | ||
1000 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | 1056 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback |
1001 | * mixer widget | 1057 | * mixer widget |
1002 | * Note: PASD motherboards uses the Line In 2 as the input for front panel | 1058 | * Note: PASD motherboards uses the Line In 2 as the input for front |
1003 | * mic (mic 2) | 1059 | * panel mic (mic 2) |
1004 | */ | 1060 | */ |
1005 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | 1061 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ |
1006 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 1062 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -1154,8 +1210,8 @@ static struct hda_verb alc880_pin_z71v_init_verbs[] = { | |||
1154 | 1210 | ||
1155 | /* | 1211 | /* |
1156 | * 6-stack pin configuration: | 1212 | * 6-stack pin configuration: |
1157 | * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, f-mic = 0x19, | 1213 | * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, |
1158 | * line = 0x1a, HP = 0x1b | 1214 | * f-mic = 0x19, line = 0x1a, HP = 0x1b |
1159 | */ | 1215 | */ |
1160 | static struct hda_verb alc880_pin_6stack_init_verbs[] = { | 1216 | static struct hda_verb alc880_pin_6stack_init_verbs[] = { |
1161 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | 1217 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ |
@@ -1587,8 +1643,8 @@ static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1587 | struct snd_pcm_substream *substream) | 1643 | struct snd_pcm_substream *substream) |
1588 | { | 1644 | { |
1589 | struct alc_spec *spec = codec->spec; | 1645 | struct alc_spec *spec = codec->spec; |
1590 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, | 1646 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, |
1591 | format, substream); | 1647 | stream_tag, format, substream); |
1592 | } | 1648 | } |
1593 | 1649 | ||
1594 | static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | 1650 | static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, |
@@ -1640,7 +1696,8 @@ static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
1640 | { | 1696 | { |
1641 | struct alc_spec *spec = codec->spec; | 1697 | struct alc_spec *spec = codec->spec; |
1642 | 1698 | ||
1643 | snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0); | 1699 | snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], |
1700 | 0, 0, 0); | ||
1644 | return 0; | 1701 | return 0; |
1645 | } | 1702 | } |
1646 | 1703 | ||
@@ -1822,7 +1879,8 @@ static struct hda_channel_mode alc880_test_modes[4] = { | |||
1822 | { 8, NULL }, | 1879 | { 8, NULL }, |
1823 | }; | 1880 | }; |
1824 | 1881 | ||
1825 | static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1882 | static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, |
1883 | struct snd_ctl_elem_info *uinfo) | ||
1826 | { | 1884 | { |
1827 | static char *texts[] = { | 1885 | static char *texts[] = { |
1828 | "N/A", "Line Out", "HP Out", | 1886 | "N/A", "Line Out", "HP Out", |
@@ -1837,7 +1895,8 @@ static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1837 | return 0; | 1895 | return 0; |
1838 | } | 1896 | } |
1839 | 1897 | ||
1840 | static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1898 | static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, |
1899 | struct snd_ctl_elem_value *ucontrol) | ||
1841 | { | 1900 | { |
1842 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1901 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1843 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; | 1902 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; |
@@ -1863,7 +1922,8 @@ static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_el | |||
1863 | return 0; | 1922 | return 0; |
1864 | } | 1923 | } |
1865 | 1924 | ||
1866 | static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1925 | static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, |
1926 | struct snd_ctl_elem_value *ucontrol) | ||
1867 | { | 1927 | { |
1868 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1928 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1869 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; | 1929 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; |
@@ -1881,15 +1941,18 @@ static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el | |||
1881 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | 1941 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); |
1882 | new_ctl = ctls[ucontrol->value.enumerated.item[0]]; | 1942 | new_ctl = ctls[ucontrol->value.enumerated.item[0]]; |
1883 | if (old_ctl != new_ctl) { | 1943 | if (old_ctl != new_ctl) { |
1884 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl); | 1944 | snd_hda_codec_write(codec, nid, 0, |
1945 | AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl); | ||
1885 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 1946 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
1886 | ucontrol->value.enumerated.item[0] >= 3 ? 0xb080 : 0xb000); | 1947 | (ucontrol->value.enumerated.item[0] >= 3 ? |
1948 | 0xb080 : 0xb000)); | ||
1887 | return 1; | 1949 | return 1; |
1888 | } | 1950 | } |
1889 | return 0; | 1951 | return 0; |
1890 | } | 1952 | } |
1891 | 1953 | ||
1892 | static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1954 | static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, |
1955 | struct snd_ctl_elem_info *uinfo) | ||
1893 | { | 1956 | { |
1894 | static char *texts[] = { | 1957 | static char *texts[] = { |
1895 | "Front", "Surround", "CLFE", "Side" | 1958 | "Front", "Surround", "CLFE", "Side" |
@@ -1903,7 +1966,8 @@ static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1903 | return 0; | 1966 | return 0; |
1904 | } | 1967 | } |
1905 | 1968 | ||
1906 | static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1969 | static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, |
1970 | struct snd_ctl_elem_value *ucontrol) | ||
1907 | { | 1971 | { |
1908 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1972 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1909 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; | 1973 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; |
@@ -1914,7 +1978,8 @@ static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, struct snd_ctl_el | |||
1914 | return 0; | 1978 | return 0; |
1915 | } | 1979 | } |
1916 | 1980 | ||
1917 | static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1981 | static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, |
1982 | struct snd_ctl_elem_value *ucontrol) | ||
1918 | { | 1983 | { |
1919 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1984 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1920 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; | 1985 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; |
@@ -2739,7 +2804,8 @@ static int patch_alc880(struct hda_codec *codec) | |||
2739 | 2804 | ||
2740 | board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl); | 2805 | board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl); |
2741 | if (board_config < 0 || board_config >= ALC880_MODEL_LAST) { | 2806 | if (board_config < 0 || board_config >= ALC880_MODEL_LAST) { |
2742 | printk(KERN_INFO "hda_codec: Unknown model for ALC880, trying auto-probe from BIOS...\n"); | 2807 | printk(KERN_INFO "hda_codec: Unknown model for ALC880, " |
2808 | "trying auto-probe from BIOS...\n"); | ||
2743 | board_config = ALC880_AUTO; | 2809 | board_config = ALC880_AUTO; |
2744 | } | 2810 | } |
2745 | 2811 | ||
@@ -2750,7 +2816,9 @@ static int patch_alc880(struct hda_codec *codec) | |||
2750 | alc_free(codec); | 2816 | alc_free(codec); |
2751 | return err; | 2817 | return err; |
2752 | } else if (! err) { | 2818 | } else if (! err) { |
2753 | printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using 3-stack mode...\n"); | 2819 | printk(KERN_INFO |
2820 | "hda_codec: Cannot set up configuration " | ||
2821 | "from BIOS. Using 3-stack mode...\n"); | ||
2754 | board_config = ALC880_3ST; | 2822 | board_config = ALC880_3ST; |
2755 | } | 2823 | } |
2756 | } | 2824 | } |
@@ -3947,7 +4015,8 @@ static int patch_alc260(struct hda_codec *codec) | |||
3947 | 4015 | ||
3948 | board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl); | 4016 | board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl); |
3949 | if (board_config < 0 || board_config >= ALC260_MODEL_LAST) { | 4017 | if (board_config < 0 || board_config >= ALC260_MODEL_LAST) { |
3950 | snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260\n"); | 4018 | snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, " |
4019 | "trying auto-probe from BIOS...\n"); | ||
3951 | board_config = ALC260_AUTO; | 4020 | board_config = ALC260_AUTO; |
3952 | } | 4021 | } |
3953 | 4022 | ||
@@ -3958,7 +4027,9 @@ static int patch_alc260(struct hda_codec *codec) | |||
3958 | alc_free(codec); | 4027 | alc_free(codec); |
3959 | return err; | 4028 | return err; |
3960 | } else if (! err) { | 4029 | } else if (! err) { |
3961 | printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n"); | 4030 | printk(KERN_INFO |
4031 | "hda_codec: Cannot set up configuration " | ||
4032 | "from BIOS. Using base mode...\n"); | ||
3962 | board_config = ALC260_BASIC; | 4033 | board_config = ALC260_BASIC; |
3963 | } | 4034 | } |
3964 | } | 4035 | } |
@@ -4320,9 +4391,12 @@ static struct snd_kcontrol_new alc882_capture_mixer[] = { | |||
4320 | static struct hda_board_config alc882_cfg_tbl[] = { | 4391 | static struct hda_board_config alc882_cfg_tbl[] = { |
4321 | { .modelname = "3stack-dig", .config = ALC882_3ST_DIG }, | 4392 | { .modelname = "3stack-dig", .config = ALC882_3ST_DIG }, |
4322 | { .modelname = "6stack-dig", .config = ALC882_6ST_DIG }, | 4393 | { .modelname = "6stack-dig", .config = ALC882_6ST_DIG }, |
4323 | { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* MSI */ | 4394 | { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, |
4324 | { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* Foxconn */ | 4395 | .config = ALC882_6ST_DIG }, /* MSI */ |
4325 | { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* ECS */ | 4396 | { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, |
4397 | .config = ALC882_6ST_DIG }, /* Foxconn */ | ||
4398 | { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, | ||
4399 | .config = ALC882_6ST_DIG }, /* ECS to Intel*/ | ||
4326 | { .modelname = "auto", .config = ALC882_AUTO }, | 4400 | { .modelname = "auto", .config = ALC882_AUTO }, |
4327 | {} | 4401 | {} |
4328 | }; | 4402 | }; |
@@ -4439,10 +4513,6 @@ static void alc882_auto_init(struct hda_codec *codec) | |||
4439 | alc882_auto_init_analog_input(codec); | 4513 | alc882_auto_init_analog_input(codec); |
4440 | } | 4514 | } |
4441 | 4515 | ||
4442 | /* | ||
4443 | * ALC882 Headphone poll in 3.5.1a or 3.5.2 | ||
4444 | */ | ||
4445 | |||
4446 | static int patch_alc882(struct hda_codec *codec) | 4516 | static int patch_alc882(struct hda_codec *codec) |
4447 | { | 4517 | { |
4448 | struct alc_spec *spec; | 4518 | struct alc_spec *spec; |
@@ -4457,7 +4527,8 @@ static int patch_alc882(struct hda_codec *codec) | |||
4457 | board_config = snd_hda_check_board_config(codec, alc882_cfg_tbl); | 4527 | board_config = snd_hda_check_board_config(codec, alc882_cfg_tbl); |
4458 | 4528 | ||
4459 | if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { | 4529 | if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { |
4460 | printk(KERN_INFO "hda_codec: Unknown model for ALC882, trying auto-probe from BIOS...\n"); | 4530 | printk(KERN_INFO "hda_codec: Unknown model for ALC882, " |
4531 | "trying auto-probe from BIOS...\n"); | ||
4461 | board_config = ALC882_AUTO; | 4532 | board_config = ALC882_AUTO; |
4462 | } | 4533 | } |
4463 | 4534 | ||
@@ -4468,7 +4539,9 @@ static int patch_alc882(struct hda_codec *codec) | |||
4468 | alc_free(codec); | 4539 | alc_free(codec); |
4469 | return err; | 4540 | return err; |
4470 | } else if (! err) { | 4541 | } else if (! err) { |
4471 | printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n"); | 4542 | printk(KERN_INFO |
4543 | "hda_codec: Cannot set up configuration " | ||
4544 | "from BIOS. Using base mode...\n"); | ||
4472 | board_config = ALC882_3ST_DIG; | 4545 | board_config = ALC882_3ST_DIG; |
4473 | } | 4546 | } |
4474 | } | 4547 | } |
@@ -4509,6 +4582,652 @@ static int patch_alc882(struct hda_codec *codec) | |||
4509 | } | 4582 | } |
4510 | 4583 | ||
4511 | /* | 4584 | /* |
4585 | * ALC883 support | ||
4586 | * | ||
4587 | * ALC883 is almost identical with ALC880 but has cleaner and more flexible | ||
4588 | * configuration. Each pin widget can choose any input DACs and a mixer. | ||
4589 | * Each ADC is connected from a mixer of all inputs. This makes possible | ||
4590 | * 6-channel independent captures. | ||
4591 | * | ||
4592 | * In addition, an independent DAC for the multi-playback (not used in this | ||
4593 | * driver yet). | ||
4594 | */ | ||
4595 | #define ALC883_DIGOUT_NID 0x06 | ||
4596 | #define ALC883_DIGIN_NID 0x0a | ||
4597 | |||
4598 | static hda_nid_t alc883_dac_nids[4] = { | ||
4599 | /* front, rear, clfe, rear_surr */ | ||
4600 | 0x02, 0x04, 0x03, 0x05 | ||
4601 | }; | ||
4602 | |||
4603 | static hda_nid_t alc883_adc_nids[2] = { | ||
4604 | /* ADC1-2 */ | ||
4605 | 0x08, 0x09, | ||
4606 | }; | ||
4607 | /* input MUX */ | ||
4608 | /* FIXME: should be a matrix-type input source selection */ | ||
4609 | |||
4610 | static struct hda_input_mux alc883_capture_source = { | ||
4611 | .num_items = 4, | ||
4612 | .items = { | ||
4613 | { "Mic", 0x0 }, | ||
4614 | { "Front Mic", 0x1 }, | ||
4615 | { "Line", 0x2 }, | ||
4616 | { "CD", 0x4 }, | ||
4617 | }, | ||
4618 | }; | ||
4619 | #define alc883_mux_enum_info alc_mux_enum_info | ||
4620 | #define alc883_mux_enum_get alc_mux_enum_get | ||
4621 | |||
4622 | static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, | ||
4623 | struct snd_ctl_elem_value *ucontrol) | ||
4624 | { | ||
4625 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
4626 | struct alc_spec *spec = codec->spec; | ||
4627 | const struct hda_input_mux *imux = spec->input_mux; | ||
4628 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
4629 | static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; | ||
4630 | hda_nid_t nid = capture_mixers[adc_idx]; | ||
4631 | unsigned int *cur_val = &spec->cur_mux[adc_idx]; | ||
4632 | unsigned int i, idx; | ||
4633 | |||
4634 | idx = ucontrol->value.enumerated.item[0]; | ||
4635 | if (idx >= imux->num_items) | ||
4636 | idx = imux->num_items - 1; | ||
4637 | if (*cur_val == idx && ! codec->in_resume) | ||
4638 | return 0; | ||
4639 | for (i = 0; i < imux->num_items; i++) { | ||
4640 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; | ||
4641 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
4642 | v | (imux->items[i].index << 8)); | ||
4643 | } | ||
4644 | *cur_val = idx; | ||
4645 | return 1; | ||
4646 | } | ||
4647 | /* | ||
4648 | * 2ch mode | ||
4649 | */ | ||
4650 | static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { | ||
4651 | { 2, NULL } | ||
4652 | }; | ||
4653 | |||
4654 | /* | ||
4655 | * 2ch mode | ||
4656 | */ | ||
4657 | static struct hda_verb alc883_3ST_ch2_init[] = { | ||
4658 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
4659 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
4660 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
4661 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
4662 | { } /* end */ | ||
4663 | }; | ||
4664 | |||
4665 | /* | ||
4666 | * 6ch mode | ||
4667 | */ | ||
4668 | static struct hda_verb alc883_3ST_ch6_init[] = { | ||
4669 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
4670 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
4671 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, | ||
4672 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
4673 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
4674 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
4675 | { } /* end */ | ||
4676 | }; | ||
4677 | |||
4678 | static struct hda_channel_mode alc883_3ST_6ch_modes[2] = { | ||
4679 | { 2, alc883_3ST_ch2_init }, | ||
4680 | { 6, alc883_3ST_ch6_init }, | ||
4681 | }; | ||
4682 | |||
4683 | /* | ||
4684 | * 6ch mode | ||
4685 | */ | ||
4686 | static struct hda_verb alc883_sixstack_ch6_init[] = { | ||
4687 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | ||
4688 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
4689 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
4690 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
4691 | { } /* end */ | ||
4692 | }; | ||
4693 | |||
4694 | /* | ||
4695 | * 8ch mode | ||
4696 | */ | ||
4697 | static struct hda_verb alc883_sixstack_ch8_init[] = { | ||
4698 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
4699 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
4700 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
4701 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
4702 | { } /* end */ | ||
4703 | }; | ||
4704 | |||
4705 | static struct hda_channel_mode alc883_sixstack_modes[2] = { | ||
4706 | { 6, alc883_sixstack_ch6_init }, | ||
4707 | { 8, alc883_sixstack_ch8_init }, | ||
4708 | }; | ||
4709 | |||
4710 | /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 | ||
4711 | * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b | ||
4712 | */ | ||
4713 | |||
4714 | static struct snd_kcontrol_new alc883_base_mixer[] = { | ||
4715 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
4716 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
4717 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
4718 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | ||
4719 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | ||
4720 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
4721 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
4722 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
4723 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | ||
4724 | HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), | ||
4725 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
4726 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
4727 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
4728 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
4729 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
4730 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
4731 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
4732 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
4733 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
4734 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
4735 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
4736 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
4737 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
4738 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), | ||
4739 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), | ||
4740 | { | ||
4741 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
4742 | /* .name = "Capture Source", */ | ||
4743 | .name = "Input Source", | ||
4744 | .count = 2, | ||
4745 | .info = alc883_mux_enum_info, | ||
4746 | .get = alc883_mux_enum_get, | ||
4747 | .put = alc883_mux_enum_put, | ||
4748 | }, | ||
4749 | { } /* end */ | ||
4750 | }; | ||
4751 | |||
4752 | static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { | ||
4753 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
4754 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
4755 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
4756 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
4757 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
4758 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
4759 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
4760 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
4761 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
4762 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
4763 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
4764 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
4765 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
4766 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
4767 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
4768 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), | ||
4769 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), | ||
4770 | { | ||
4771 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
4772 | /* .name = "Capture Source", */ | ||
4773 | .name = "Input Source", | ||
4774 | .count = 2, | ||
4775 | .info = alc883_mux_enum_info, | ||
4776 | .get = alc883_mux_enum_get, | ||
4777 | .put = alc883_mux_enum_put, | ||
4778 | }, | ||
4779 | { } /* end */ | ||
4780 | }; | ||
4781 | |||
4782 | static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { | ||
4783 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
4784 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
4785 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
4786 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | ||
4787 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | ||
4788 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
4789 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
4790 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
4791 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
4792 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
4793 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
4794 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
4795 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
4796 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
4797 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
4798 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
4799 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
4800 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
4801 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
4802 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
4803 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
4804 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), | ||
4805 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), | ||
4806 | { | ||
4807 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
4808 | /* .name = "Capture Source", */ | ||
4809 | .name = "Input Source", | ||
4810 | .count = 2, | ||
4811 | .info = alc883_mux_enum_info, | ||
4812 | .get = alc883_mux_enum_get, | ||
4813 | .put = alc883_mux_enum_put, | ||
4814 | }, | ||
4815 | { } /* end */ | ||
4816 | }; | ||
4817 | |||
4818 | static struct snd_kcontrol_new alc883_chmode_mixer[] = { | ||
4819 | { | ||
4820 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
4821 | .name = "Channel Mode", | ||
4822 | .info = alc_ch_mode_info, | ||
4823 | .get = alc_ch_mode_get, | ||
4824 | .put = alc_ch_mode_put, | ||
4825 | }, | ||
4826 | { } /* end */ | ||
4827 | }; | ||
4828 | |||
4829 | static struct hda_verb alc883_init_verbs[] = { | ||
4830 | /* ADC1: mute amp left and right */ | ||
4831 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
4832 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
4833 | /* ADC2: mute amp left and right */ | ||
4834 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
4835 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
4836 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ | ||
4837 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
4838 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
4839 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
4840 | /* Rear mixer */ | ||
4841 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
4842 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
4843 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
4844 | /* CLFE mixer */ | ||
4845 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
4846 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
4847 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
4848 | /* Side mixer */ | ||
4849 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
4850 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
4851 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
4852 | |||
4853 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4854 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4855 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
4856 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
4857 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
4858 | |||
4859 | /* Front Pin: output 0 (0x0c) */ | ||
4860 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
4861 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
4862 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
4863 | /* Rear Pin: output 1 (0x0d) */ | ||
4864 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
4865 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
4866 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
4867 | /* CLFE Pin: output 2 (0x0e) */ | ||
4868 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
4869 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
4870 | {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
4871 | /* Side Pin: output 3 (0x0f) */ | ||
4872 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
4873 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
4874 | {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, | ||
4875 | /* Mic (rear) pin: input vref at 80% */ | ||
4876 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
4877 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
4878 | /* Front Mic pin: input vref at 80% */ | ||
4879 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
4880 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
4881 | /* Line In pin: input */ | ||
4882 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
4883 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
4884 | /* Line-2 In: Headphone output (output 0 - 0x0c) */ | ||
4885 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
4886 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
4887 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
4888 | /* CD pin widget for input */ | ||
4889 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
4890 | |||
4891 | /* FIXME: use matrix-type input source selection */ | ||
4892 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | ||
4893 | /* Input mixer2 */ | ||
4894 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4895 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4896 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
4897 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
4898 | /* Input mixer3 */ | ||
4899 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4900 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4901 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
4902 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
4903 | { } | ||
4904 | }; | ||
4905 | |||
4906 | /* | ||
4907 | * generic initialization of ADC, input mixers and output mixers | ||
4908 | */ | ||
4909 | static struct hda_verb alc883_auto_init_verbs[] = { | ||
4910 | /* | ||
4911 | * Unmute ADC0-2 and set the default input to mic-in | ||
4912 | */ | ||
4913 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
4914 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4915 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
4916 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4917 | |||
4918 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | ||
4919 | * mixer widget | ||
4920 | * Note: PASD motherboards uses the Line In 2 as the input for front panel | ||
4921 | * mic (mic 2) | ||
4922 | */ | ||
4923 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | ||
4924 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4925 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4926 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
4927 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
4928 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
4929 | |||
4930 | /* | ||
4931 | * Set up output mixers (0x0c - 0x0f) | ||
4932 | */ | ||
4933 | /* set vol=0 to output mixers */ | ||
4934 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
4935 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
4936 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
4937 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
4938 | /* set up input amps for analog loopback */ | ||
4939 | /* Amp Indices: DAC = 0, mixer = 1 */ | ||
4940 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4941 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4942 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4943 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4944 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4945 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4946 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4947 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4948 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4949 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4950 | |||
4951 | /* FIXME: use matrix-type input source selection */ | ||
4952 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | ||
4953 | /* Input mixer1 */ | ||
4954 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4955 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4956 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
4957 | //{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
4958 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
4959 | /* Input mixer2 */ | ||
4960 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4961 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4962 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
4963 | //{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
4964 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
4965 | |||
4966 | { } | ||
4967 | }; | ||
4968 | |||
4969 | /* capture mixer elements */ | ||
4970 | static struct snd_kcontrol_new alc883_capture_mixer[] = { | ||
4971 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
4972 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
4973 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), | ||
4974 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), | ||
4975 | { | ||
4976 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
4977 | /* The multiple "Capture Source" controls confuse alsamixer | ||
4978 | * So call somewhat different.. | ||
4979 | * FIXME: the controls appear in the "playback" view! | ||
4980 | */ | ||
4981 | /* .name = "Capture Source", */ | ||
4982 | .name = "Input Source", | ||
4983 | .count = 2, | ||
4984 | .info = alc882_mux_enum_info, | ||
4985 | .get = alc882_mux_enum_get, | ||
4986 | .put = alc882_mux_enum_put, | ||
4987 | }, | ||
4988 | { } /* end */ | ||
4989 | }; | ||
4990 | |||
4991 | /* pcm configuration: identiacal with ALC880 */ | ||
4992 | #define alc883_pcm_analog_playback alc880_pcm_analog_playback | ||
4993 | #define alc883_pcm_analog_capture alc880_pcm_analog_capture | ||
4994 | #define alc883_pcm_digital_playback alc880_pcm_digital_playback | ||
4995 | #define alc883_pcm_digital_capture alc880_pcm_digital_capture | ||
4996 | |||
4997 | /* | ||
4998 | * configuration and preset | ||
4999 | */ | ||
5000 | static struct hda_board_config alc883_cfg_tbl[] = { | ||
5001 | { .modelname = "3stack-dig", .config = ALC883_3ST_2ch_DIG }, | ||
5002 | { .modelname = "6stack-dig", .config = ALC883_6ST_DIG }, | ||
5003 | { .modelname = "6stack-dig-demo", .config = ALC888_DEMO_BOARD }, | ||
5004 | { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, | ||
5005 | .config = ALC883_6ST_DIG }, /* MSI */ | ||
5006 | { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, | ||
5007 | .config = ALC883_6ST_DIG }, /* Foxconn */ | ||
5008 | { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, | ||
5009 | .config = ALC883_3ST_6ch_DIG }, /* ECS to Intel*/ | ||
5010 | { .pci_subvendor = 0x108e, .pci_subdevice = 0x534d, | ||
5011 | .config = ALC883_3ST_6ch }, | ||
5012 | { .modelname = "auto", .config = ALC883_AUTO }, | ||
5013 | {} | ||
5014 | }; | ||
5015 | |||
5016 | static struct alc_config_preset alc883_presets[] = { | ||
5017 | [ALC883_3ST_2ch_DIG] = { | ||
5018 | .mixers = { alc883_3ST_2ch_mixer }, | ||
5019 | .init_verbs = { alc883_init_verbs }, | ||
5020 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
5021 | .dac_nids = alc883_dac_nids, | ||
5022 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
5023 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
5024 | .adc_nids = alc883_adc_nids, | ||
5025 | .dig_in_nid = ALC883_DIGIN_NID, | ||
5026 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | ||
5027 | .channel_mode = alc883_3ST_2ch_modes, | ||
5028 | .input_mux = &alc883_capture_source, | ||
5029 | }, | ||
5030 | [ALC883_3ST_6ch_DIG] = { | ||
5031 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, | ||
5032 | .init_verbs = { alc883_init_verbs }, | ||
5033 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
5034 | .dac_nids = alc883_dac_nids, | ||
5035 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
5036 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
5037 | .adc_nids = alc883_adc_nids, | ||
5038 | .dig_in_nid = ALC883_DIGIN_NID, | ||
5039 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), | ||
5040 | .channel_mode = alc883_3ST_6ch_modes, | ||
5041 | .input_mux = &alc883_capture_source, | ||
5042 | }, | ||
5043 | [ALC883_3ST_6ch] = { | ||
5044 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, | ||
5045 | .init_verbs = { alc883_init_verbs }, | ||
5046 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
5047 | .dac_nids = alc883_dac_nids, | ||
5048 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
5049 | .adc_nids = alc883_adc_nids, | ||
5050 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), | ||
5051 | .channel_mode = alc883_3ST_6ch_modes, | ||
5052 | .input_mux = &alc883_capture_source, | ||
5053 | }, | ||
5054 | [ALC883_6ST_DIG] = { | ||
5055 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, | ||
5056 | .init_verbs = { alc883_init_verbs }, | ||
5057 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
5058 | .dac_nids = alc883_dac_nids, | ||
5059 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
5060 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
5061 | .adc_nids = alc883_adc_nids, | ||
5062 | .dig_in_nid = ALC883_DIGIN_NID, | ||
5063 | .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), | ||
5064 | .channel_mode = alc883_sixstack_modes, | ||
5065 | .input_mux = &alc883_capture_source, | ||
5066 | }, | ||
5067 | [ALC888_DEMO_BOARD] = { | ||
5068 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, | ||
5069 | .init_verbs = { alc883_init_verbs }, | ||
5070 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
5071 | .dac_nids = alc883_dac_nids, | ||
5072 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
5073 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
5074 | .adc_nids = alc883_adc_nids, | ||
5075 | .dig_in_nid = ALC883_DIGIN_NID, | ||
5076 | .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), | ||
5077 | .channel_mode = alc883_sixstack_modes, | ||
5078 | .input_mux = &alc883_capture_source, | ||
5079 | }, | ||
5080 | }; | ||
5081 | |||
5082 | |||
5083 | /* | ||
5084 | * BIOS auto configuration | ||
5085 | */ | ||
5086 | static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, | ||
5087 | hda_nid_t nid, int pin_type, | ||
5088 | int dac_idx) | ||
5089 | { | ||
5090 | /* set as output */ | ||
5091 | struct alc_spec *spec = codec->spec; | ||
5092 | int idx; | ||
5093 | |||
5094 | if (spec->multiout.dac_nids[dac_idx] == 0x25) | ||
5095 | idx = 4; | ||
5096 | else | ||
5097 | idx = spec->multiout.dac_nids[dac_idx] - 2; | ||
5098 | |||
5099 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
5100 | pin_type); | ||
5101 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
5102 | AMP_OUT_UNMUTE); | ||
5103 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); | ||
5104 | |||
5105 | } | ||
5106 | |||
5107 | static void alc883_auto_init_multi_out(struct hda_codec *codec) | ||
5108 | { | ||
5109 | struct alc_spec *spec = codec->spec; | ||
5110 | int i; | ||
5111 | |||
5112 | for (i = 0; i <= HDA_SIDE; i++) { | ||
5113 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | ||
5114 | if (nid) | ||
5115 | alc883_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); | ||
5116 | } | ||
5117 | } | ||
5118 | |||
5119 | static void alc883_auto_init_hp_out(struct hda_codec *codec) | ||
5120 | { | ||
5121 | struct alc_spec *spec = codec->spec; | ||
5122 | hda_nid_t pin; | ||
5123 | |||
5124 | pin = spec->autocfg.hp_pin; | ||
5125 | if (pin) /* connect to front */ | ||
5126 | /* use dac 0 */ | ||
5127 | alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); | ||
5128 | } | ||
5129 | |||
5130 | #define alc883_is_input_pin(nid) alc880_is_input_pin(nid) | ||
5131 | #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID | ||
5132 | |||
5133 | static void alc883_auto_init_analog_input(struct hda_codec *codec) | ||
5134 | { | ||
5135 | struct alc_spec *spec = codec->spec; | ||
5136 | int i; | ||
5137 | |||
5138 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
5139 | hda_nid_t nid = spec->autocfg.input_pins[i]; | ||
5140 | if (alc883_is_input_pin(nid)) { | ||
5141 | snd_hda_codec_write(codec, nid, 0, | ||
5142 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
5143 | (i <= AUTO_PIN_FRONT_MIC ? | ||
5144 | PIN_VREF80 : PIN_IN)); | ||
5145 | if (nid != ALC883_PIN_CD_NID) | ||
5146 | snd_hda_codec_write(codec, nid, 0, | ||
5147 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
5148 | AMP_OUT_MUTE); | ||
5149 | } | ||
5150 | } | ||
5151 | } | ||
5152 | |||
5153 | /* almost identical with ALC880 parser... */ | ||
5154 | static int alc883_parse_auto_config(struct hda_codec *codec) | ||
5155 | { | ||
5156 | struct alc_spec *spec = codec->spec; | ||
5157 | int err = alc880_parse_auto_config(codec); | ||
5158 | |||
5159 | if (err < 0) | ||
5160 | return err; | ||
5161 | else if (err > 0) | ||
5162 | /* hack - override the init verbs */ | ||
5163 | spec->init_verbs[0] = alc883_auto_init_verbs; | ||
5164 | spec->mixers[spec->num_mixers] = alc883_capture_mixer; | ||
5165 | spec->num_mixers++; | ||
5166 | return err; | ||
5167 | } | ||
5168 | |||
5169 | /* additional initialization for auto-configuration model */ | ||
5170 | static void alc883_auto_init(struct hda_codec *codec) | ||
5171 | { | ||
5172 | alc883_auto_init_multi_out(codec); | ||
5173 | alc883_auto_init_hp_out(codec); | ||
5174 | alc883_auto_init_analog_input(codec); | ||
5175 | } | ||
5176 | |||
5177 | static int patch_alc883(struct hda_codec *codec) | ||
5178 | { | ||
5179 | struct alc_spec *spec; | ||
5180 | int err, board_config; | ||
5181 | |||
5182 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
5183 | if (spec == NULL) | ||
5184 | return -ENOMEM; | ||
5185 | |||
5186 | codec->spec = spec; | ||
5187 | |||
5188 | board_config = snd_hda_check_board_config(codec, alc883_cfg_tbl); | ||
5189 | if (board_config < 0 || board_config >= ALC883_MODEL_LAST) { | ||
5190 | printk(KERN_INFO "hda_codec: Unknown model for ALC883, " | ||
5191 | "trying auto-probe from BIOS...\n"); | ||
5192 | board_config = ALC883_AUTO; | ||
5193 | } | ||
5194 | |||
5195 | if (board_config == ALC883_AUTO) { | ||
5196 | /* automatic parse from the BIOS config */ | ||
5197 | err = alc883_parse_auto_config(codec); | ||
5198 | if (err < 0) { | ||
5199 | alc_free(codec); | ||
5200 | return err; | ||
5201 | } else if (! err) { | ||
5202 | printk(KERN_INFO | ||
5203 | "hda_codec: Cannot set up configuration " | ||
5204 | "from BIOS. Using base mode...\n"); | ||
5205 | board_config = ALC883_3ST_2ch_DIG; | ||
5206 | } | ||
5207 | } | ||
5208 | |||
5209 | if (board_config != ALC883_AUTO) | ||
5210 | setup_preset(spec, &alc883_presets[board_config]); | ||
5211 | |||
5212 | spec->stream_name_analog = "ALC883 Analog"; | ||
5213 | spec->stream_analog_playback = &alc883_pcm_analog_playback; | ||
5214 | spec->stream_analog_capture = &alc883_pcm_analog_capture; | ||
5215 | |||
5216 | spec->stream_name_digital = "ALC883 Digital"; | ||
5217 | spec->stream_digital_playback = &alc883_pcm_digital_playback; | ||
5218 | spec->stream_digital_capture = &alc883_pcm_digital_capture; | ||
5219 | |||
5220 | spec->adc_nids = alc883_adc_nids; | ||
5221 | spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); | ||
5222 | |||
5223 | codec->patch_ops = alc_patch_ops; | ||
5224 | if (board_config == ALC883_AUTO) | ||
5225 | spec->init_hook = alc883_auto_init; | ||
5226 | |||
5227 | return 0; | ||
5228 | } | ||
5229 | |||
5230 | /* | ||
4512 | * ALC262 support | 5231 | * ALC262 support |
4513 | */ | 5232 | */ |
4514 | 5233 | ||
@@ -4542,6 +5261,28 @@ static struct snd_kcontrol_new alc262_base_mixer[] = { | |||
4542 | { } /* end */ | 5261 | { } /* end */ |
4543 | }; | 5262 | }; |
4544 | 5263 | ||
5264 | static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { | ||
5265 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
5266 | HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
5267 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
5268 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
5269 | HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), | ||
5270 | |||
5271 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
5272 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
5273 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
5274 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
5275 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
5276 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
5277 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
5278 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
5279 | HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
5280 | HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
5281 | HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), | ||
5282 | HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), | ||
5283 | { } /* end */ | ||
5284 | }; | ||
5285 | |||
4545 | #define alc262_capture_mixer alc882_capture_mixer | 5286 | #define alc262_capture_mixer alc882_capture_mixer |
4546 | #define alc262_capture_alt_mixer alc882_capture_alt_mixer | 5287 | #define alc262_capture_alt_mixer alc882_capture_alt_mixer |
4547 | 5288 | ||
@@ -4645,6 +5386,17 @@ static struct hda_input_mux alc262_fujitsu_capture_source = { | |||
4645 | }, | 5386 | }, |
4646 | }; | 5387 | }; |
4647 | 5388 | ||
5389 | static struct hda_input_mux alc262_HP_capture_source = { | ||
5390 | .num_items = 5, | ||
5391 | .items = { | ||
5392 | { "Mic", 0x0 }, | ||
5393 | { "Front Mic", 0x3 }, | ||
5394 | { "Line", 0x2 }, | ||
5395 | { "CD", 0x4 }, | ||
5396 | { "AUX IN", 0x6 }, | ||
5397 | }, | ||
5398 | }; | ||
5399 | |||
4648 | /* mute/unmute internal speaker according to the hp jack and mute state */ | 5400 | /* mute/unmute internal speaker according to the hp jack and mute state */ |
4649 | static void alc262_fujitsu_automute(struct hda_codec *codec, int force) | 5401 | static void alc262_fujitsu_automute(struct hda_codec *codec, int force) |
4650 | { | 5402 | { |
@@ -4868,6 +5620,93 @@ static struct hda_verb alc262_volume_init_verbs[] = { | |||
4868 | { } | 5620 | { } |
4869 | }; | 5621 | }; |
4870 | 5622 | ||
5623 | static struct hda_verb alc262_HP_BPC_init_verbs[] = { | ||
5624 | /* | ||
5625 | * Unmute ADC0-2 and set the default input to mic-in | ||
5626 | */ | ||
5627 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5628 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5629 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5630 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5631 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5632 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5633 | |||
5634 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | ||
5635 | * mixer widget | ||
5636 | * Note: PASD motherboards uses the Line In 2 as the input for front panel | ||
5637 | * mic (mic 2) | ||
5638 | */ | ||
5639 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | ||
5640 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5641 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
5642 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
5643 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
5644 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
5645 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, | ||
5646 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)}, | ||
5647 | |||
5648 | /* | ||
5649 | * Set up output mixers (0x0c - 0x0e) | ||
5650 | */ | ||
5651 | /* set vol=0 to output mixers */ | ||
5652 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
5653 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
5654 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
5655 | |||
5656 | /* set up input amps for analog loopback */ | ||
5657 | /* Amp Indices: DAC = 0, mixer = 1 */ | ||
5658 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5659 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
5660 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5661 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
5662 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5663 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
5664 | |||
5665 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, | ||
5666 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
5667 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
5668 | |||
5669 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
5670 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
5671 | |||
5672 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5673 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5674 | |||
5675 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
5676 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
5677 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
5678 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
5679 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
5680 | |||
5681 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, | ||
5682 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
5683 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
5684 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, | ||
5685 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
5686 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
5687 | |||
5688 | |||
5689 | /* FIXME: use matrix-type input source selection */ | ||
5690 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | ||
5691 | /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ | ||
5692 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
5693 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, | ||
5694 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, | ||
5695 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, | ||
5696 | /* Input mixer2 */ | ||
5697 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
5698 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, | ||
5699 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, | ||
5700 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, | ||
5701 | /* Input mixer3 */ | ||
5702 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
5703 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, | ||
5704 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, | ||
5705 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, | ||
5706 | |||
5707 | { } | ||
5708 | }; | ||
5709 | |||
4871 | /* pcm configuration: identiacal with ALC880 */ | 5710 | /* pcm configuration: identiacal with ALC880 */ |
4872 | #define alc262_pcm_analog_playback alc880_pcm_analog_playback | 5711 | #define alc262_pcm_analog_playback alc880_pcm_analog_playback |
4873 | #define alc262_pcm_analog_capture alc880_pcm_analog_capture | 5712 | #define alc262_pcm_analog_capture alc880_pcm_analog_capture |
@@ -4928,7 +5767,16 @@ static void alc262_auto_init(struct hda_codec *codec) | |||
4928 | static struct hda_board_config alc262_cfg_tbl[] = { | 5767 | static struct hda_board_config alc262_cfg_tbl[] = { |
4929 | { .modelname = "basic", .config = ALC262_BASIC }, | 5768 | { .modelname = "basic", .config = ALC262_BASIC }, |
4930 | { .modelname = "fujitsu", .config = ALC262_FUJITSU }, | 5769 | { .modelname = "fujitsu", .config = ALC262_FUJITSU }, |
4931 | { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397, .config = ALC262_FUJITSU }, | 5770 | { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397, |
5771 | .config = ALC262_FUJITSU }, | ||
5772 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x208c, | ||
5773 | .config = ALC262_HP_BPC }, /* xw4400 */ | ||
5774 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, | ||
5775 | .config = ALC262_HP_BPC }, /* xw6400 */ | ||
5776 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, | ||
5777 | .config = ALC262_HP_BPC }, /* xw8400 */ | ||
5778 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x12fe, | ||
5779 | .config = ALC262_HP_BPC }, /* xw9400 */ | ||
4932 | { .modelname = "auto", .config = ALC262_AUTO }, | 5780 | { .modelname = "auto", .config = ALC262_AUTO }, |
4933 | {} | 5781 | {} |
4934 | }; | 5782 | }; |
@@ -4956,6 +5804,16 @@ static struct alc_config_preset alc262_presets[] = { | |||
4956 | .input_mux = &alc262_fujitsu_capture_source, | 5804 | .input_mux = &alc262_fujitsu_capture_source, |
4957 | .unsol_event = alc262_fujitsu_unsol_event, | 5805 | .unsol_event = alc262_fujitsu_unsol_event, |
4958 | }, | 5806 | }, |
5807 | [ALC262_HP_BPC] = { | ||
5808 | .mixers = { alc262_HP_BPC_mixer }, | ||
5809 | .init_verbs = { alc262_HP_BPC_init_verbs }, | ||
5810 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | ||
5811 | .dac_nids = alc262_dac_nids, | ||
5812 | .hp_nid = 0x03, | ||
5813 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | ||
5814 | .channel_mode = alc262_modes, | ||
5815 | .input_mux = &alc262_HP_capture_source, | ||
5816 | }, | ||
4959 | }; | 5817 | }; |
4960 | 5818 | ||
4961 | static int patch_alc262(struct hda_codec *codec) | 5819 | static int patch_alc262(struct hda_codec *codec) |
@@ -4981,8 +5839,10 @@ static int patch_alc262(struct hda_codec *codec) | |||
4981 | #endif | 5839 | #endif |
4982 | 5840 | ||
4983 | board_config = snd_hda_check_board_config(codec, alc262_cfg_tbl); | 5841 | board_config = snd_hda_check_board_config(codec, alc262_cfg_tbl); |
5842 | |||
4984 | if (board_config < 0 || board_config >= ALC262_MODEL_LAST) { | 5843 | if (board_config < 0 || board_config >= ALC262_MODEL_LAST) { |
4985 | printk(KERN_INFO "hda_codec: Unknown model for ALC262, trying auto-probe from BIOS...\n"); | 5844 | printk(KERN_INFO "hda_codec: Unknown model for ALC262, " |
5845 | "trying auto-probe from BIOS...\n"); | ||
4986 | board_config = ALC262_AUTO; | 5846 | board_config = ALC262_AUTO; |
4987 | } | 5847 | } |
4988 | 5848 | ||
@@ -4993,7 +5853,9 @@ static int patch_alc262(struct hda_codec *codec) | |||
4993 | alc_free(codec); | 5853 | alc_free(codec); |
4994 | return err; | 5854 | return err; |
4995 | } else if (! err) { | 5855 | } else if (! err) { |
4996 | printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n"); | 5856 | printk(KERN_INFO |
5857 | "hda_codec: Cannot set up configuration " | ||
5858 | "from BIOS. Using base mode...\n"); | ||
4997 | board_config = ALC262_BASIC; | 5859 | board_config = ALC262_BASIC; |
4998 | } | 5860 | } |
4999 | } | 5861 | } |
@@ -5034,7 +5896,6 @@ static int patch_alc262(struct hda_codec *codec) | |||
5034 | return 0; | 5896 | return 0; |
5035 | } | 5897 | } |
5036 | 5898 | ||
5037 | |||
5038 | /* | 5899 | /* |
5039 | * ALC861 channel source setting (2/6 channel selection for 3-stack) | 5900 | * ALC861 channel source setting (2/6 channel selection for 3-stack) |
5040 | */ | 5901 | */ |
@@ -5049,9 +5910,11 @@ static struct hda_verb alc861_threestack_ch2_init[] = { | |||
5049 | /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */ | 5910 | /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */ |
5050 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | 5911 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, |
5051 | 5912 | ||
5052 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, | 5913 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, |
5053 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, //mic | 5914 | #if 0 |
5054 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, //line in | 5915 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ |
5916 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ | ||
5917 | #endif | ||
5055 | { } /* end */ | 5918 | { } /* end */ |
5056 | }; | 5919 | }; |
5057 | /* | 5920 | /* |
@@ -5065,11 +5928,13 @@ static struct hda_verb alc861_threestack_ch6_init[] = { | |||
5065 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | 5928 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, |
5066 | 5929 | ||
5067 | { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 5930 | { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
5068 | { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 5931 | { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
5069 | 5932 | ||
5070 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, | 5933 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, |
5071 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, //mic | 5934 | #if 0 |
5072 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, //line in | 5935 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ |
5936 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ | ||
5937 | #endif | ||
5073 | { } /* end */ | 5938 | { } /* end */ |
5074 | }; | 5939 | }; |
5075 | 5940 | ||
@@ -5353,6 +6218,11 @@ static hda_nid_t alc861_dac_nids[4] = { | |||
5353 | 0x03, 0x06, 0x05, 0x04 | 6218 | 0x03, 0x06, 0x05, 0x04 |
5354 | }; | 6219 | }; |
5355 | 6220 | ||
6221 | static hda_nid_t alc660_dac_nids[3] = { | ||
6222 | /* front, clfe, surround */ | ||
6223 | 0x03, 0x05, 0x06 | ||
6224 | }; | ||
6225 | |||
5356 | static hda_nid_t alc861_adc_nids[1] = { | 6226 | static hda_nid_t alc861_adc_nids[1] = { |
5357 | /* ADC0-2 */ | 6227 | /* ADC0-2 */ |
5358 | 0x08, | 6228 | 0x08, |
@@ -5605,7 +6475,10 @@ static void alc861_auto_init(struct hda_codec *codec) | |||
5605 | */ | 6475 | */ |
5606 | static struct hda_board_config alc861_cfg_tbl[] = { | 6476 | static struct hda_board_config alc861_cfg_tbl[] = { |
5607 | { .modelname = "3stack", .config = ALC861_3ST }, | 6477 | { .modelname = "3stack", .config = ALC861_3ST }, |
5608 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xd600, .config = ALC861_3ST }, | 6478 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xd600, |
6479 | .config = ALC861_3ST }, | ||
6480 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x81e7, | ||
6481 | .config = ALC660_3ST }, | ||
5609 | { .modelname = "3stack-dig", .config = ALC861_3ST_DIG }, | 6482 | { .modelname = "3stack-dig", .config = ALC861_3ST_DIG }, |
5610 | { .modelname = "6stack-dig", .config = ALC861_6ST_DIG }, | 6483 | { .modelname = "6stack-dig", .config = ALC861_6ST_DIG }, |
5611 | { .modelname = "auto", .config = ALC861_AUTO }, | 6484 | { .modelname = "auto", .config = ALC861_AUTO }, |
@@ -5648,6 +6521,17 @@ static struct alc_config_preset alc861_presets[] = { | |||
5648 | .adc_nids = alc861_adc_nids, | 6521 | .adc_nids = alc861_adc_nids, |
5649 | .input_mux = &alc861_capture_source, | 6522 | .input_mux = &alc861_capture_source, |
5650 | }, | 6523 | }, |
6524 | [ALC660_3ST] = { | ||
6525 | .mixers = { alc861_3ST_mixer }, | ||
6526 | .init_verbs = { alc861_threestack_init_verbs }, | ||
6527 | .num_dacs = ARRAY_SIZE(alc660_dac_nids), | ||
6528 | .dac_nids = alc660_dac_nids, | ||
6529 | .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), | ||
6530 | .channel_mode = alc861_threestack_modes, | ||
6531 | .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), | ||
6532 | .adc_nids = alc861_adc_nids, | ||
6533 | .input_mux = &alc861_capture_source, | ||
6534 | }, | ||
5651 | }; | 6535 | }; |
5652 | 6536 | ||
5653 | 6537 | ||
@@ -5664,8 +6548,10 @@ static int patch_alc861(struct hda_codec *codec) | |||
5664 | codec->spec = spec; | 6548 | codec->spec = spec; |
5665 | 6549 | ||
5666 | board_config = snd_hda_check_board_config(codec, alc861_cfg_tbl); | 6550 | board_config = snd_hda_check_board_config(codec, alc861_cfg_tbl); |
6551 | |||
5667 | if (board_config < 0 || board_config >= ALC861_MODEL_LAST) { | 6552 | if (board_config < 0 || board_config >= ALC861_MODEL_LAST) { |
5668 | printk(KERN_INFO "hda_codec: Unknown model for ALC861, trying auto-probe from BIOS...\n"); | 6553 | printk(KERN_INFO "hda_codec: Unknown model for ALC861, " |
6554 | "trying auto-probe from BIOS...\n"); | ||
5669 | board_config = ALC861_AUTO; | 6555 | board_config = ALC861_AUTO; |
5670 | } | 6556 | } |
5671 | 6557 | ||
@@ -5676,7 +6562,9 @@ static int patch_alc861(struct hda_codec *codec) | |||
5676 | alc_free(codec); | 6562 | alc_free(codec); |
5677 | return err; | 6563 | return err; |
5678 | } else if (! err) { | 6564 | } else if (! err) { |
5679 | printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n"); | 6565 | printk(KERN_INFO |
6566 | "hda_codec: Cannot set up configuration " | ||
6567 | "from BIOS. Using base mode...\n"); | ||
5680 | board_config = ALC861_3ST_DIG; | 6568 | board_config = ALC861_3ST_DIG; |
5681 | } | 6569 | } |
5682 | } | 6570 | } |
@@ -5707,8 +6595,12 @@ struct hda_codec_preset snd_hda_preset_realtek[] = { | |||
5707 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, | 6595 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, |
5708 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, | 6596 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, |
5709 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, | 6597 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, |
5710 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, | 6598 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, |
5711 | { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, | 6599 | { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, |
5712 | { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, | 6600 | { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, |
6601 | { .id = 0x10ec0861, .rev = 0x100300, .name = "ALC861", | ||
6602 | .patch = patch_alc861 }, | ||
6603 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", | ||
6604 | .patch = patch_alc861 }, | ||
5713 | {} /* terminator */ | 6605 | {} /* terminator */ |
5714 | }; | 6606 | }; |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 36f199442fdc..fb4bed0759d1 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -42,6 +42,9 @@ | |||
42 | #define STAC_D945GTP3 1 | 42 | #define STAC_D945GTP3 1 |
43 | #define STAC_D945GTP5 2 | 43 | #define STAC_D945GTP5 2 |
44 | #define STAC_MACMINI 3 | 44 | #define STAC_MACMINI 3 |
45 | #define STAC_D965_2112 4 | ||
46 | #define STAC_D965_284B 5 | ||
47 | #define STAC_922X_MODELS 6 /* number of 922x models */ | ||
45 | 48 | ||
46 | struct sigmatel_spec { | 49 | struct sigmatel_spec { |
47 | struct snd_kcontrol_new *mixers[4]; | 50 | struct snd_kcontrol_new *mixers[4]; |
@@ -107,10 +110,24 @@ static hda_nid_t stac922x_adc_nids[2] = { | |||
107 | 0x06, 0x07, | 110 | 0x06, 0x07, |
108 | }; | 111 | }; |
109 | 112 | ||
113 | static hda_nid_t stac9227_adc_nids[2] = { | ||
114 | 0x07, 0x08, | ||
115 | }; | ||
116 | |||
117 | #if 0 | ||
118 | static hda_nid_t d965_2112_dac_nids[3] = { | ||
119 | 0x02, 0x03, 0x05, | ||
120 | }; | ||
121 | #endif | ||
122 | |||
110 | static hda_nid_t stac922x_mux_nids[2] = { | 123 | static hda_nid_t stac922x_mux_nids[2] = { |
111 | 0x12, 0x13, | 124 | 0x12, 0x13, |
112 | }; | 125 | }; |
113 | 126 | ||
127 | static hda_nid_t stac9227_mux_nids[2] = { | ||
128 | 0x15, 0x16, | ||
129 | }; | ||
130 | |||
114 | static hda_nid_t stac927x_adc_nids[3] = { | 131 | static hda_nid_t stac927x_adc_nids[3] = { |
115 | 0x07, 0x08, 0x09 | 132 | 0x07, 0x08, 0x09 |
116 | }; | 133 | }; |
@@ -173,6 +190,24 @@ static struct hda_verb stac922x_core_init[] = { | |||
173 | {} | 190 | {} |
174 | }; | 191 | }; |
175 | 192 | ||
193 | static struct hda_verb stac9227_core_init[] = { | ||
194 | /* set master volume and direct control */ | ||
195 | { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | ||
196 | /* unmute node 0x1b */ | ||
197 | { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
198 | {} | ||
199 | }; | ||
200 | |||
201 | static struct hda_verb d965_2112_core_init[] = { | ||
202 | /* set master volume and direct control */ | ||
203 | { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | ||
204 | /* unmute node 0x1b */ | ||
205 | { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
206 | /* select node 0x03 as DAC */ | ||
207 | { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
208 | {} | ||
209 | }; | ||
210 | |||
176 | static struct hda_verb stac927x_core_init[] = { | 211 | static struct hda_verb stac927x_core_init[] = { |
177 | /* set master volume and direct control */ | 212 | /* set master volume and direct control */ |
178 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 213 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
@@ -212,6 +247,21 @@ static struct snd_kcontrol_new stac922x_mixer[] = { | |||
212 | { } /* end */ | 247 | { } /* end */ |
213 | }; | 248 | }; |
214 | 249 | ||
250 | /* This needs to be generated dynamically based on sequence */ | ||
251 | static struct snd_kcontrol_new stac9227_mixer[] = { | ||
252 | { | ||
253 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
254 | .name = "Input Source", | ||
255 | .count = 1, | ||
256 | .info = stac92xx_mux_enum_info, | ||
257 | .get = stac92xx_mux_enum_get, | ||
258 | .put = stac92xx_mux_enum_put, | ||
259 | }, | ||
260 | HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), | ||
261 | HDA_CODEC_MUTE("Capture Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
262 | { } /* end */ | ||
263 | }; | ||
264 | |||
215 | static snd_kcontrol_new_t stac927x_mixer[] = { | 265 | static snd_kcontrol_new_t stac927x_mixer[] = { |
216 | { | 266 | { |
217 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 267 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -291,11 +341,17 @@ static unsigned int d945gtp5_pin_configs[10] = { | |||
291 | 0x02a19320, 0x40000100, | 341 | 0x02a19320, 0x40000100, |
292 | }; | 342 | }; |
293 | 343 | ||
294 | static unsigned int *stac922x_brd_tbl[] = { | 344 | static unsigned int d965_2112_pin_configs[10] = { |
295 | ref922x_pin_configs, | 345 | 0x0221401f, 0x40000100, 0x40000100, 0x01014011, |
296 | d945gtp3_pin_configs, | 346 | 0x01a19021, 0x01813024, 0x01452130, 0x40000100, |
297 | d945gtp5_pin_configs, | 347 | 0x02a19320, 0x40000100, |
298 | NULL, /* STAC_MACMINI */ | 348 | }; |
349 | |||
350 | static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { | ||
351 | [STAC_REF] = ref922x_pin_configs, | ||
352 | [STAC_D945GTP3] = d945gtp3_pin_configs, | ||
353 | [STAC_D945GTP5] = d945gtp5_pin_configs, | ||
354 | [STAC_D965_2112] = d965_2112_pin_configs, | ||
299 | }; | 355 | }; |
300 | 356 | ||
301 | static struct hda_board_config stac922x_cfg_tbl[] = { | 357 | static struct hda_board_config stac922x_cfg_tbl[] = { |
@@ -330,6 +386,12 @@ static struct hda_board_config stac922x_cfg_tbl[] = { | |||
330 | { .pci_subvendor = 0x8384, | 386 | { .pci_subvendor = 0x8384, |
331 | .pci_subdevice = 0x7680, | 387 | .pci_subdevice = 0x7680, |
332 | .config = STAC_MACMINI }, /* Apple Mac Mini (early 2006) */ | 388 | .config = STAC_MACMINI }, /* Apple Mac Mini (early 2006) */ |
389 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
390 | .pci_subdevice = 0x2112, | ||
391 | .config = STAC_D965_2112 }, | ||
392 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
393 | .pci_subdevice = 0x284b, | ||
394 | .config = STAC_D965_284B }, | ||
333 | {} /* terminator */ | 395 | {} /* terminator */ |
334 | }; | 396 | }; |
335 | 397 | ||
@@ -713,7 +775,8 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf | |||
713 | * A and B is not supported. | 775 | * A and B is not supported. |
714 | */ | 776 | */ |
715 | /* fill in the dac_nids table from the parsed pin configuration */ | 777 | /* fill in the dac_nids table from the parsed pin configuration */ |
716 | static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, const struct auto_pin_cfg *cfg) | 778 | static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, |
779 | const struct auto_pin_cfg *cfg) | ||
717 | { | 780 | { |
718 | struct sigmatel_spec *spec = codec->spec; | 781 | struct sigmatel_spec *spec = codec->spec; |
719 | hda_nid_t nid; | 782 | hda_nid_t nid; |
@@ -732,10 +795,13 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, const struct aut | |||
732 | } | 795 | } |
733 | 796 | ||
734 | /* add playback controls from the parsed DAC table */ | 797 | /* add playback controls from the parsed DAC table */ |
735 | static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, const struct auto_pin_cfg *cfg) | 798 | static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, |
799 | const struct auto_pin_cfg *cfg) | ||
736 | { | 800 | { |
737 | char name[32]; | 801 | char name[32]; |
738 | static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; | 802 | static const char *chname[4] = { |
803 | "Front", "Surround", NULL /*CLFE*/, "Side" | ||
804 | }; | ||
739 | hda_nid_t nid; | 805 | hda_nid_t nid; |
740 | int i, err; | 806 | int i, err; |
741 | 807 | ||
@@ -893,10 +959,12 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
893 | return err; | 959 | return err; |
894 | if (! spec->autocfg.line_outs) | 960 | if (! spec->autocfg.line_outs) |
895 | return 0; /* can't find valid pin config */ | 961 | return 0; /* can't find valid pin config */ |
962 | |||
896 | if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) | 963 | if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) |
897 | return err; | 964 | return err; |
898 | if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) | 965 | if (spec->multiout.num_dacs == 0) |
899 | return err; | 966 | if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) |
967 | return err; | ||
900 | 968 | ||
901 | if ((err = stac92xx_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || | 969 | if ((err = stac92xx_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || |
902 | (err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg)) < 0 || | 970 | (err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg)) < 0 || |
@@ -1194,7 +1262,8 @@ static int patch_stac922x(struct hda_codec *codec) | |||
1194 | codec->spec = spec; | 1262 | codec->spec = spec; |
1195 | spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl); | 1263 | spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl); |
1196 | if (spec->board_config < 0) | 1264 | if (spec->board_config < 0) |
1197 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, using BIOS defaults\n"); | 1265 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " |
1266 | "using BIOS defaults\n"); | ||
1198 | else if (stac922x_brd_tbl[spec->board_config] != NULL) { | 1267 | else if (stac922x_brd_tbl[spec->board_config] != NULL) { |
1199 | spec->num_pins = 10; | 1268 | spec->num_pins = 10; |
1200 | spec->pin_nids = stac922x_pin_nids; | 1269 | spec->pin_nids = stac922x_pin_nids; |
@@ -1210,6 +1279,25 @@ static int patch_stac922x(struct hda_codec *codec) | |||
1210 | spec->mixer = stac922x_mixer; | 1279 | spec->mixer = stac922x_mixer; |
1211 | 1280 | ||
1212 | spec->multiout.dac_nids = spec->dac_nids; | 1281 | spec->multiout.dac_nids = spec->dac_nids; |
1282 | |||
1283 | switch (spec->board_config) { | ||
1284 | case STAC_D965_2112: | ||
1285 | spec->adc_nids = stac9227_adc_nids; | ||
1286 | spec->mux_nids = stac9227_mux_nids; | ||
1287 | #if 0 | ||
1288 | spec->multiout.dac_nids = d965_2112_dac_nids; | ||
1289 | spec->multiout.num_dacs = ARRAY_SIZE(d965_2112_dac_nids); | ||
1290 | #endif | ||
1291 | spec->init = d965_2112_core_init; | ||
1292 | spec->mixer = stac9227_mixer; | ||
1293 | break; | ||
1294 | case STAC_D965_284B: | ||
1295 | spec->adc_nids = stac9227_adc_nids; | ||
1296 | spec->mux_nids = stac9227_mux_nids; | ||
1297 | spec->init = stac9227_core_init; | ||
1298 | spec->mixer = stac9227_mixer; | ||
1299 | break; | ||
1300 | } | ||
1213 | 1301 | ||
1214 | err = stac92xx_parse_auto_config(codec, 0x08, 0x09); | 1302 | err = stac92xx_parse_auto_config(codec, 0x08, 0x09); |
1215 | if (err < 0) { | 1303 | if (err < 0) { |
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index b5754b32b802..fec9440cb310 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c | |||
@@ -87,12 +87,25 @@ static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) | |||
87 | * initialize the chips on M-Audio Revolution cards | 87 | * initialize the chips on M-Audio Revolution cards |
88 | */ | 88 | */ |
89 | 89 | ||
90 | static unsigned int revo71_num_stereo_front[] = {2}; | ||
91 | static char *revo71_channel_names_front[] = {"PCM Playback Volume"}; | ||
92 | |||
93 | static unsigned int revo71_num_stereo_surround[] = {1, 1, 2, 2}; | ||
94 | static char *revo71_channel_names_surround[] = {"PCM Center Playback Volume", "PCM LFE Playback Volume", | ||
95 | "PCM Side Playback Volume", "PCM Rear Playback Volume"}; | ||
96 | |||
97 | static unsigned int revo51_num_stereo[] = {2, 1, 1, 2}; | ||
98 | static char *revo51_channel_names[] = {"PCM Playback Volume", "PCM Center Playback Volume", | ||
99 | "PCM LFE Playback Volume", "PCM Rear Playback Volume"}; | ||
100 | |||
90 | static struct snd_akm4xxx akm_revo_front __devinitdata = { | 101 | static struct snd_akm4xxx akm_revo_front __devinitdata = { |
91 | .type = SND_AK4381, | 102 | .type = SND_AK4381, |
92 | .num_dacs = 2, | 103 | .num_dacs = 2, |
93 | .ops = { | 104 | .ops = { |
94 | .set_rate_val = revo_set_rate_val | 105 | .set_rate_val = revo_set_rate_val |
95 | } | 106 | }, |
107 | .num_stereo = revo71_num_stereo_front, | ||
108 | .channel_names = revo71_channel_names_front | ||
96 | }; | 109 | }; |
97 | 110 | ||
98 | static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { | 111 | static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { |
@@ -113,7 +126,9 @@ static struct snd_akm4xxx akm_revo_surround __devinitdata = { | |||
113 | .num_dacs = 6, | 126 | .num_dacs = 6, |
114 | .ops = { | 127 | .ops = { |
115 | .set_rate_val = revo_set_rate_val | 128 | .set_rate_val = revo_set_rate_val |
116 | } | 129 | }, |
130 | .num_stereo = revo71_num_stereo_surround, | ||
131 | .channel_names = revo71_channel_names_surround | ||
117 | }; | 132 | }; |
118 | 133 | ||
119 | static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { | 134 | static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { |
@@ -133,7 +148,9 @@ static struct snd_akm4xxx akm_revo51 __devinitdata = { | |||
133 | .num_dacs = 6, | 148 | .num_dacs = 6, |
134 | .ops = { | 149 | .ops = { |
135 | .set_rate_val = revo_set_rate_val | 150 | .set_rate_val = revo_set_rate_val |
136 | } | 151 | }, |
152 | .num_stereo = revo51_num_stereo, | ||
153 | .channel_names = revo51_channel_names | ||
137 | }; | 154 | }; |
138 | 155 | ||
139 | static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { | 156 | static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { |
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index dcf402948347..e5511606af04 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c | |||
@@ -1441,10 +1441,10 @@ static int __devinit snd_sonic_probe(struct pci_dev *pci, | |||
1441 | 1441 | ||
1442 | strcpy(card->driver, "SonicVibes"); | 1442 | strcpy(card->driver, "SonicVibes"); |
1443 | strcpy(card->shortname, "S3 SonicVibes"); | 1443 | strcpy(card->shortname, "S3 SonicVibes"); |
1444 | sprintf(card->longname, "%s rev %i at 0x%lx, irq %i", | 1444 | sprintf(card->longname, "%s rev %i at 0x%llx, irq %i", |
1445 | card->shortname, | 1445 | card->shortname, |
1446 | sonic->revision, | 1446 | sonic->revision, |
1447 | pci_resource_start(pci, 1), | 1447 | (unsigned long long)pci_resource_start(pci, 1), |
1448 | sonic->irq); | 1448 | sonic->irq); |
1449 | 1449 | ||
1450 | if ((err = snd_sonicvibes_pcm(sonic, 0, NULL)) < 0) { | 1450 | if ((err = snd_sonicvibes_pcm(sonic, 0, NULL)) < 0) { |