diff options
| author | Giuliano Pochini <pochini@shiny.it> | 2006-06-28 07:53:41 -0400 |
|---|---|---|
| committer | Jaroslav Kysela <perex@suse.cz> | 2006-06-28 13:31:20 -0400 |
| commit | dd7b254d8dd3a9528f423ac3bf875e6f0c8da561 (patch) | |
| tree | 923ac13451c796b730f21c7260beba9f74acff63 | |
| parent | cb9d24e4349013628259b5fee97e692173731b07 (diff) | |
[ALSA] Add echoaudio sound drivers
From: Giuliano Pochini <pochini@shiny.it>Add echoaudio sound drivers (darla20, darla24, echo3g, gina20, gina24,
indigo, indigodj, indigoio, layla20, lala24, mia, mona)
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
35 files changed, 9949 insertions, 0 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 87d76a5c73d0..0846b455bcf2 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt | |||
| @@ -472,6 +472,22 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
| 472 | 472 | ||
| 473 | The power-management is supported. | 473 | The power-management is supported. |
| 474 | 474 | ||
| 475 | Module snd-darla20 | ||
| 476 | ------------------ | ||
| 477 | |||
| 478 | Module for Echoaudio Darla20 | ||
| 479 | |||
| 480 | This module supports multiple cards. | ||
| 481 | The driver requires the firmware loader support on kernel. | ||
| 482 | |||
| 483 | Module snd-darla24 | ||
| 484 | ------------------ | ||
| 485 | |||
| 486 | Module for Echoaudio Darla24 | ||
| 487 | |||
| 488 | This module supports multiple cards. | ||
| 489 | The driver requires the firmware loader support on kernel. | ||
| 490 | |||
| 475 | Module snd-dt019x | 491 | Module snd-dt019x |
| 476 | ----------------- | 492 | ----------------- |
| 477 | 493 | ||
| @@ -499,6 +515,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
| 499 | 515 | ||
| 500 | The power-management is supported. | 516 | The power-management is supported. |
| 501 | 517 | ||
| 518 | Module snd-echo3g | ||
| 519 | ----------------- | ||
| 520 | |||
| 521 | Module for Echoaudio 3G cards (Gina3G/Layla3G) | ||
| 522 | |||
| 523 | This module supports multiple cards. | ||
| 524 | The driver requires the firmware loader support on kernel. | ||
| 525 | |||
| 502 | Module snd-emu10k1 | 526 | Module snd-emu10k1 |
| 503 | ------------------ | 527 | ------------------ |
| 504 | 528 | ||
| @@ -657,6 +681,22 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
| 657 | 681 | ||
| 658 | The power-management is supported. | 682 | The power-management is supported. |
| 659 | 683 | ||
| 684 | Module snd-gina20 | ||
| 685 | ----------------- | ||
| 686 | |||
| 687 | Module for Echoaudio Gina20 | ||
| 688 | |||
| 689 | This module supports multiple cards. | ||
| 690 | The driver requires the firmware loader support on kernel. | ||
| 691 | |||
| 692 | Module snd-gina24 | ||
| 693 | ----------------- | ||
| 694 | |||
| 695 | Module for Echoaudio Gina24 | ||
| 696 | |||
| 697 | This module supports multiple cards. | ||
| 698 | The driver requires the firmware loader support on kernel. | ||
| 699 | |||
| 660 | Module snd-gusclassic | 700 | Module snd-gusclassic |
| 661 | --------------------- | 701 | --------------------- |
| 662 | 702 | ||
| @@ -937,6 +977,30 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
| 937 | driver isn't configured properly or you want to try another | 977 | driver isn't configured properly or you want to try another |
| 938 | type for testing. | 978 | type for testing. |
| 939 | 979 | ||
| 980 | Module snd-indigo | ||
| 981 | ----------------- | ||
| 982 | |||
| 983 | Module for Echoaudio Indigo | ||
| 984 | |||
| 985 | This module supports multiple cards. | ||
| 986 | The driver requires the firmware loader support on kernel. | ||
| 987 | |||
| 988 | Module snd-indigodj | ||
| 989 | ------------------- | ||
| 990 | |||
| 991 | Module for Echoaudio Indigo DJ | ||
| 992 | |||
| 993 | This module supports multiple cards. | ||
| 994 | The driver requires the firmware loader support on kernel. | ||
| 995 | |||
| 996 | Module snd-indigoio | ||
| 997 | ------------------- | ||
| 998 | |||
| 999 | Module for Echoaudio Indigo IO | ||
| 1000 | |||
| 1001 | This module supports multiple cards. | ||
| 1002 | The driver requires the firmware loader support on kernel. | ||
| 1003 | |||
| 940 | Module snd-intel8x0 | 1004 | Module snd-intel8x0 |
| 941 | ------------------- | 1005 | ------------------- |
| 942 | 1006 | ||
| @@ -1036,6 +1100,22 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
| 1036 | 1100 | ||
| 1037 | This module supports multiple cards. | 1101 | This module supports multiple cards. |
| 1038 | 1102 | ||
| 1103 | Module snd-layla20 | ||
| 1104 | ------------------ | ||
| 1105 | |||
| 1106 | Module for Echoaudio Layla20 | ||
| 1107 | |||
| 1108 | This module supports multiple cards. | ||
| 1109 | The driver requires the firmware loader support on kernel. | ||
| 1110 | |||
| 1111 | Module snd-layla24 | ||
| 1112 | ------------------ | ||
| 1113 | |||
| 1114 | Module for Echoaudio Layla24 | ||
| 1115 | |||
| 1116 | This module supports multiple cards. | ||
| 1117 | The driver requires the firmware loader support on kernel. | ||
| 1118 | |||
| 1039 | Module snd-maestro3 | 1119 | Module snd-maestro3 |
| 1040 | ------------------- | 1120 | ------------------- |
| 1041 | 1121 | ||
| @@ -1056,6 +1136,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
| 1056 | 1136 | ||
| 1057 | The power-management is supported. | 1137 | The power-management is supported. |
| 1058 | 1138 | ||
| 1139 | Module snd-mia | ||
| 1140 | --------------- | ||
| 1141 | |||
| 1142 | Module for Echoaudio Mia | ||
| 1143 | |||
| 1144 | This module supports multiple cards. | ||
| 1145 | The driver requires the firmware loader support on kernel. | ||
| 1146 | |||
| 1059 | Module snd-miro | 1147 | Module snd-miro |
| 1060 | --------------- | 1148 | --------------- |
| 1061 | 1149 | ||
| @@ -1088,6 +1176,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
| 1088 | When no hotplug fw loader is available, you need to load the | 1176 | When no hotplug fw loader is available, you need to load the |
| 1089 | firmware via mixartloader utility in alsa-tools package. | 1177 | firmware via mixartloader utility in alsa-tools package. |
| 1090 | 1178 | ||
| 1179 | Module snd-mona | ||
| 1180 | --------------- | ||
| 1181 | |||
| 1182 | Module for Echoaudio Mona | ||
| 1183 | |||
| 1184 | This module supports multiple cards. | ||
| 1185 | The driver requires the firmware loader support on kernel. | ||
| 1186 | |||
| 1091 | Module snd-mpu401 | 1187 | Module snd-mpu401 |
| 1092 | ----------------- | 1188 | ----------------- |
| 1093 | 1189 | ||
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 39162af7f19e..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 |
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/echoaudio/Makefile b/sound/pci/echoaudio/Makefile new file mode 100644 index 000000000000..02ab0e5232b2 --- /dev/null +++ b/sound/pci/echoaudio/Makefile | |||
| @@ -0,0 +1,17 @@ | |||
| 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 | ||
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..e695502f7135 --- /dev/null +++ b/sound/pci/echoaudio/echoaudio.c | |||
| @@ -0,0 +1,2197 @@ | |||
| 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_resource(chip->iores); | ||
| 1883 | kfree_nocheck(chip->iores); | ||
| 1884 | } | ||
| 1885 | DE_INIT(("MMIO freed.\n")); | ||
| 1886 | |||
| 1887 | pci_disable_device(chip->pci); | ||
| 1888 | |||
| 1889 | /* release chip data */ | ||
| 1890 | kfree(chip); | ||
| 1891 | DE_INIT(("Chip freed.\n")); | ||
| 1892 | return 0; | ||
| 1893 | } | ||
| 1894 | |||
| 1895 | |||
| 1896 | |||
| 1897 | static int snd_echo_dev_free(struct snd_device *device) | ||
| 1898 | { | ||
| 1899 | struct echoaudio *chip = device->device_data; | ||
| 1900 | |||
| 1901 | DE_INIT(("snd_echo_dev_free()...\n")); | ||
| 1902 | return snd_echo_free(chip); | ||
| 1903 | } | ||
| 1904 | |||
| 1905 | |||
| 1906 | |||
| 1907 | /* <--snd_echo_probe() */ | ||
| 1908 | static __devinit int snd_echo_create(struct snd_card *card, | ||
| 1909 | struct pci_dev *pci, | ||
| 1910 | struct echoaudio **rchip) | ||
| 1911 | { | ||
| 1912 | struct echoaudio *chip; | ||
| 1913 | int err; | ||
| 1914 | size_t sz; | ||
| 1915 | static struct snd_device_ops ops = { | ||
| 1916 | .dev_free = snd_echo_dev_free, | ||
| 1917 | }; | ||
| 1918 | |||
| 1919 | *rchip = NULL; | ||
| 1920 | |||
| 1921 | pci_write_config_byte(pci, PCI_LATENCY_TIMER, 0xC0); | ||
| 1922 | |||
| 1923 | if ((err = pci_enable_device(pci)) < 0) | ||
| 1924 | return err; | ||
| 1925 | pci_set_master(pci); | ||
| 1926 | |||
| 1927 | /* allocate a chip-specific data */ | ||
| 1928 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
| 1929 | if (!chip) { | ||
| 1930 | pci_disable_device(pci); | ||
| 1931 | return -ENOMEM; | ||
| 1932 | } | ||
| 1933 | DE_INIT(("chip=%p\n", chip)); | ||
| 1934 | |||
| 1935 | spin_lock_init(&chip->lock); | ||
| 1936 | chip->card = card; | ||
| 1937 | chip->pci = pci; | ||
| 1938 | chip->irq = -1; | ||
| 1939 | |||
| 1940 | /* PCI resource allocation */ | ||
| 1941 | chip->dsp_registers_phys = pci_resource_start(pci, 0); | ||
| 1942 | sz = pci_resource_len(pci, 0); | ||
| 1943 | if (sz > PAGE_SIZE) | ||
| 1944 | sz = PAGE_SIZE; /* We map only the required part */ | ||
| 1945 | |||
| 1946 | if ((chip->iores = request_mem_region(chip->dsp_registers_phys, sz, | ||
| 1947 | ECHOCARD_NAME)) == NULL) { | ||
| 1948 | snd_echo_free(chip); | ||
| 1949 | snd_printk(KERN_ERR "cannot get memory region\n"); | ||
| 1950 | return -EBUSY; | ||
| 1951 | } | ||
| 1952 | chip->dsp_registers = (volatile u32 __iomem *) | ||
| 1953 | ioremap_nocache(chip->dsp_registers_phys, sz); | ||
| 1954 | |||
| 1955 | if (request_irq(pci->irq, snd_echo_interrupt, SA_INTERRUPT | SA_SHIRQ, | ||
| 1956 | ECHOCARD_NAME, (void *)chip)) { | ||
| 1957 | snd_echo_free(chip); | ||
| 1958 | snd_printk(KERN_ERR "cannot grab irq\n"); | ||
| 1959 | return -EBUSY; | ||
| 1960 | } | ||
| 1961 | chip->irq = pci->irq; | ||
| 1962 | DE_INIT(("pci=%p irq=%d subdev=%04x Init hardware...\n", | ||
| 1963 | chip->pci, chip->irq, chip->pci->subsystem_device)); | ||
| 1964 | |||
| 1965 | /* Create the DSP comm page - this is the area of memory used for most | ||
| 1966 | of the communication with the DSP, which accesses it via bus mastering */ | ||
| 1967 | if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), | ||
| 1968 | sizeof(struct comm_page), | ||
| 1969 | &chip->commpage_dma_buf) < 0) { | ||
| 1970 | snd_echo_free(chip); | ||
| 1971 | snd_printk(KERN_ERR "cannot allocate the comm page\n"); | ||
| 1972 | return -ENOMEM; | ||
| 1973 | } | ||
| 1974 | chip->comm_page_phys = chip->commpage_dma_buf.addr; | ||
| 1975 | chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area; | ||
| 1976 | |||
| 1977 | err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); | ||
| 1978 | if (err) { | ||
| 1979 | DE_INIT(("init_hw err=%d\n", err)); | ||
| 1980 | snd_echo_free(chip); | ||
| 1981 | return err; | ||
| 1982 | } | ||
| 1983 | DE_INIT(("Card init OK\n")); | ||
| 1984 | |||
| 1985 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { | ||
| 1986 | snd_echo_free(chip); | ||
| 1987 | return err; | ||
| 1988 | } | ||
| 1989 | atomic_set(&chip->opencount, 0); | ||
| 1990 | init_MUTEX(&chip->mode_mutex); | ||
| 1991 | chip->can_set_rate = 1; | ||
| 1992 | *rchip = chip; | ||
| 1993 | /* Init done ! */ | ||
| 1994 | return 0; | ||
| 1995 | } | ||
| 1996 | |||
| 1997 | |||
| 1998 | |||
| 1999 | /* constructor */ | ||
| 2000 | static int __devinit snd_echo_probe(struct pci_dev *pci, | ||
| 2001 | const struct pci_device_id *pci_id) | ||
| 2002 | { | ||
| 2003 | static int dev; | ||
| 2004 | struct snd_card *card; | ||
| 2005 | struct echoaudio *chip; | ||
| 2006 | char *dsp; | ||
| 2007 | int i, err; | ||
| 2008 | |||
| 2009 | if (dev >= SNDRV_CARDS) | ||
| 2010 | return -ENODEV; | ||
| 2011 | if (!enable[dev]) { | ||
| 2012 | dev++; | ||
| 2013 | return -ENOENT; | ||
| 2014 | } | ||
| 2015 | |||
| 2016 | DE_INIT(("Echoaudio driver starting...\n")); | ||
| 2017 | i = 0; | ||
| 2018 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | ||
| 2019 | if (card == NULL) | ||
| 2020 | return -ENOMEM; | ||
| 2021 | |||
| 2022 | if ((err = snd_echo_create(card, pci, &chip)) < 0) { | ||
| 2023 | snd_card_free(card); | ||
| 2024 | return err; | ||
| 2025 | } | ||
| 2026 | |||
| 2027 | strcpy(card->driver, "Echo_" ECHOCARD_NAME); | ||
| 2028 | strcpy(card->shortname, chip->card_name); | ||
| 2029 | |||
| 2030 | dsp = "56301"; | ||
| 2031 | if (pci_id->device == 0x3410) | ||
| 2032 | dsp = "56361"; | ||
| 2033 | |||
| 2034 | sprintf(card->longname, "%s rev.%d (DSP%s) at 0x%lx irq %i", | ||
| 2035 | card->shortname, pci_id->subdevice & 0x000f, dsp, | ||
| 2036 | chip->dsp_registers_phys, chip->irq); | ||
| 2037 | |||
| 2038 | if ((err = snd_echo_new_pcm(chip)) < 0) { | ||
| 2039 | snd_printk(KERN_ERR "new pcm error %d\n", err); | ||
| 2040 | snd_card_free(card); | ||
| 2041 | return err; | ||
| 2042 | } | ||
| 2043 | |||
| 2044 | #ifdef ECHOCARD_HAS_MIDI | ||
| 2045 | if (chip->has_midi) { /* Some Mia's do not have midi */ | ||
| 2046 | if ((err = snd_echo_midi_create(card, chip)) < 0) { | ||
| 2047 | snd_printk(KERN_ERR "new midi error %d\n", err); | ||
| 2048 | snd_card_free(card); | ||
| 2049 | return err; | ||
| 2050 | } | ||
| 2051 | } | ||
| 2052 | #endif | ||
| 2053 | |||
| 2054 | #ifdef ECHOCARD_HAS_VMIXER | ||
| 2055 | snd_echo_vmixer.count = num_pipes_out(chip) * num_busses_out(chip); | ||
| 2056 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_output_gain, chip))) < 0) | ||
| 2057 | goto ctl_error; | ||
| 2058 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vmixer, chip))) < 0) | ||
| 2059 | goto ctl_error; | ||
| 2060 | #else | ||
| 2061 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_pcm_output_gain, chip))) < 0) | ||
| 2062 | goto ctl_error; | ||
| 2063 | #endif | ||
| 2064 | |||
| 2065 | #ifdef ECHOCARD_HAS_INPUT_GAIN | ||
| 2066 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_input_gain, chip))) < 0) | ||
| 2067 | goto ctl_error; | ||
| 2068 | #endif | ||
| 2069 | |||
| 2070 | #ifdef ECHOCARD_HAS_INPUT_NOMINAL_LEVEL | ||
| 2071 | if (!chip->hasnt_input_nominal_level) | ||
| 2072 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_intput_nominal_level, chip))) < 0) | ||
| 2073 | goto ctl_error; | ||
| 2074 | #endif | ||
| 2075 | |||
| 2076 | #ifdef ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL | ||
| 2077 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_output_nominal_level, chip))) < 0) | ||
| 2078 | goto ctl_error; | ||
| 2079 | #endif | ||
| 2080 | |||
| 2081 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters_switch, chip))) < 0) | ||
| 2082 | goto ctl_error; | ||
| 2083 | |||
| 2084 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters, chip))) < 0) | ||
| 2085 | goto ctl_error; | ||
| 2086 | |||
| 2087 | #ifdef ECHOCARD_HAS_MONITOR | ||
| 2088 | snd_echo_monitor_mixer.count = num_busses_in(chip) * num_busses_out(chip); | ||
| 2089 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_monitor_mixer, chip))) < 0) | ||
| 2090 | goto ctl_error; | ||
| 2091 | #endif | ||
| 2092 | |||
| 2093 | #ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE | ||
| 2094 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_automute_switch, chip))) < 0) | ||
| 2095 | goto ctl_error; | ||
| 2096 | #endif | ||
| 2097 | |||
| 2098 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_channels_info, chip))) < 0) | ||
| 2099 | goto ctl_error; | ||
| 2100 | |||
| 2101 | #ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH | ||
| 2102 | /* Creates a list of available digital modes */ | ||
| 2103 | chip->num_digital_modes = 0; | ||
| 2104 | for (i = 0; i < 6; i++) | ||
| 2105 | if (chip->digital_modes & (1 << i)) | ||
| 2106 | chip->digital_mode_list[chip->num_digital_modes++] = i; | ||
| 2107 | |||
| 2108 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_digital_mode_switch, chip))) < 0) | ||
| 2109 | goto ctl_error; | ||
| 2110 | #endif /* ECHOCARD_HAS_DIGITAL_MODE_SWITCH */ | ||
| 2111 | |||
| 2112 | #ifdef ECHOCARD_HAS_EXTERNAL_CLOCK | ||
| 2113 | /* Creates a list of available clock sources */ | ||
| 2114 | chip->num_clock_sources = 0; | ||
| 2115 | for (i = 0; i < 10; i++) | ||
| 2116 | if (chip->input_clock_types & (1 << i)) | ||
| 2117 | chip->clock_source_list[chip->num_clock_sources++] = i; | ||
| 2118 | |||
| 2119 | if (chip->num_clock_sources > 1) { | ||
| 2120 | chip->clock_src_ctl = snd_ctl_new1(&snd_echo_clock_source_switch, chip); | ||
| 2121 | if ((err = snd_ctl_add(chip->card, chip->clock_src_ctl)) < 0) | ||
| 2122 | goto ctl_error; | ||
| 2123 | } | ||
| 2124 | #endif /* ECHOCARD_HAS_EXTERNAL_CLOCK */ | ||
| 2125 | |||
| 2126 | #ifdef ECHOCARD_HAS_DIGITAL_IO | ||
| 2127 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_spdif_mode_switch, chip))) < 0) | ||
| 2128 | goto ctl_error; | ||
| 2129 | #endif | ||
| 2130 | |||
| 2131 | #ifdef ECHOCARD_HAS_PHANTOM_POWER | ||
| 2132 | if (chip->has_phantom_power) | ||
| 2133 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_phantom_power_switch, chip))) < 0) | ||
| 2134 | goto ctl_error; | ||
| 2135 | #endif | ||
| 2136 | |||
| 2137 | if ((err = snd_card_register(card)) < 0) { | ||
| 2138 | snd_card_free(card); | ||
| 2139 | goto ctl_error; | ||
| 2140 | } | ||
| 2141 | snd_printk(KERN_INFO "Card registered: %s\n", card->longname); | ||
| 2142 | |||
| 2143 | pci_set_drvdata(pci, chip); | ||
| 2144 | dev++; | ||
| 2145 | return 0; | ||
| 2146 | |||
| 2147 | ctl_error: | ||
| 2148 | snd_printk(KERN_ERR "new control error %d\n", err); | ||
| 2149 | snd_card_free(card); | ||
| 2150 | return err; | ||
| 2151 | } | ||
| 2152 | |||
| 2153 | |||
| 2154 | |||
| 2155 | static void __devexit snd_echo_remove(struct pci_dev *pci) | ||
| 2156 | { | ||
| 2157 | struct echoaudio *chip; | ||
| 2158 | |||
| 2159 | chip = pci_get_drvdata(pci); | ||
| 2160 | if (chip) | ||
| 2161 | snd_card_free(chip->card); | ||
| 2162 | pci_set_drvdata(pci, NULL); | ||
| 2163 | } | ||
| 2164 | |||
| 2165 | |||
| 2166 | |||
| 2167 | /****************************************************************************** | ||
| 2168 | Everything starts and ends here | ||
| 2169 | ******************************************************************************/ | ||
| 2170 | |||
| 2171 | /* pci_driver definition */ | ||
| 2172 | static struct pci_driver driver = { | ||
| 2173 | .name = "Echoaudio " ECHOCARD_NAME, | ||
| 2174 | .id_table = snd_echo_ids, | ||
| 2175 | .probe = snd_echo_probe, | ||
| 2176 | .remove = __devexit_p(snd_echo_remove), | ||
| 2177 | }; | ||
| 2178 | |||
| 2179 | |||
| 2180 | |||
| 2181 | /* initialization of the module */ | ||
| 2182 | static int __init alsa_card_echo_init(void) | ||
| 2183 | { | ||
| 2184 | return pci_register_driver(&driver); | ||
| 2185 | } | ||
| 2186 | |||
| 2187 | |||
| 2188 | |||
| 2189 | /* clean up the module */ | ||
| 2190 | static void __exit alsa_card_echo_exit(void) | ||
| 2191 | { | ||
| 2192 | pci_unregister_driver(&driver); | ||
| 2193 | } | ||
| 2194 | |||
| 2195 | |||
| 2196 | module_init(alsa_card_echo_init) | ||
| 2197 | 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..5919b5c879a4 --- /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 | } | ||
