^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * ALSA soundcard driver for Miro miroSOUND PCM1 pro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * miroSOUND PCM12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * miroSOUND PCM20 Radio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2004-2005 Martin Langer <martin-langer@gmx.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Based on OSS ACI and ALSA OPTi9xx drivers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/isa.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/pnp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <asm/dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <sound/wss.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <sound/mpu401.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <sound/opl4.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <sound/info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define SNDRV_LEGACY_FIND_FREE_IOPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define SNDRV_LEGACY_FIND_FREE_IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define SNDRV_LEGACY_FIND_FREE_DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <sound/aci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) MODULE_AUTHOR("Martin Langer <martin-langer@gmx.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) MODULE_DESCRIPTION("Miro miroSOUND PCM1 pro, PCM12, PCM20 Radio");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) MODULE_SUPPORTED_DEVICE("{{Miro,miroSOUND PCM1 pro}, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) "{Miro,miroSOUND PCM12}, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) "{Miro,miroSOUND PCM20 Radio}}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static long port = SNDRV_DEFAULT_PORT1; /* 0x530,0xe80,0xf40,0x604 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static long mpu_port = SNDRV_DEFAULT_PORT1; /* 0x300,0x310,0x320,0x330 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static long fm_port = SNDRV_DEFAULT_PORT1; /* 0x388 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static int irq = SNDRV_DEFAULT_IRQ1; /* 5,7,9,10,11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static int mpu_irq = SNDRV_DEFAULT_IRQ1; /* 5,7,9,10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static int dma1 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static int dma2 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static int wss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static int ide;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static bool isapnp = 1; /* Enable ISA PnP detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) module_param(index, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) MODULE_PARM_DESC(index, "Index value for miro soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) module_param(id, charp, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) MODULE_PARM_DESC(id, "ID string for miro soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) module_param_hw(port, long, ioport, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) MODULE_PARM_DESC(port, "WSS port # for miro driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) module_param_hw(mpu_port, long, ioport, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) MODULE_PARM_DESC(mpu_port, "MPU-401 port # for miro driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) module_param_hw(fm_port, long, ioport, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) MODULE_PARM_DESC(fm_port, "FM Port # for miro driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) module_param_hw(irq, int, irq, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) MODULE_PARM_DESC(irq, "WSS irq # for miro driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) module_param_hw(mpu_irq, int, irq, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) MODULE_PARM_DESC(mpu_irq, "MPU-401 irq # for miro driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) module_param_hw(dma1, int, dma, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) MODULE_PARM_DESC(dma1, "1st dma # for miro driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) module_param_hw(dma2, int, dma, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) MODULE_PARM_DESC(dma2, "2nd dma # for miro driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) module_param(wss, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) MODULE_PARM_DESC(wss, "wss mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) module_param(ide, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) MODULE_PARM_DESC(ide, "enable ide port");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) module_param(isapnp, bool, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) MODULE_PARM_DESC(isapnp, "Enable ISA PnP detection for specified soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define OPTi9XX_HW_DETECT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define OPTi9XX_HW_82C928 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define OPTi9XX_HW_82C929 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define OPTi9XX_HW_82C924 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define OPTi9XX_HW_82C925 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define OPTi9XX_HW_82C930 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define OPTi9XX_HW_82C931 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define OPTi9XX_HW_82C933 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define OPTi9XX_HW_LAST OPTi9XX_HW_82C933
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define OPTi9XX_MC_REG(n) n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct snd_miro {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) unsigned short hardware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unsigned char password;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) char name[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct resource *res_mc_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct resource *res_aci_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) unsigned long mc_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) unsigned long mc_base_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) unsigned long pwd_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) long wss_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int dma1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int dma2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) long mpu_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int mpu_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct snd_miro_aci *aci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static struct snd_miro_aci aci_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static const char * const snd_opti9xx_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) "unknown",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) "82C928", "82C929",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) "82C924", "82C925",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) "82C930", "82C931", "82C933"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static int snd_miro_pnp_is_probed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static const struct pnp_card_device_id snd_miro_pnpids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* PCM20 and PCM12 in PnP mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) { .id = "MIR0924",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) .devs = { { "MIR0000" }, { "MIR0002" }, { "MIR0005" } }, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) { .id = "" }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) MODULE_DEVICE_TABLE(pnp_card, snd_miro_pnpids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #endif /* CONFIG_PNP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * ACI control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static int aci_busy_wait(struct snd_miro_aci *aci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) unsigned char byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) for (timeout = 1; timeout <= ACI_MINTIME + 30; timeout++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) byte = inb(aci->aci_port + ACI_REG_BUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if ((byte & 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (timeout >= ACI_MINTIME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) snd_printd("aci ready in round %ld.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) timeout-ACI_MINTIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (timeout >= ACI_MINTIME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) long out=10*HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) switch (timeout-ACI_MINTIME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) case 0 ... 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) out /= 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) case 10 ... 19:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) out /= 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) case 20 ... 30:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) out /= 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) set_current_state(TASK_UNINTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) schedule_timeout(out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) snd_printk(KERN_ERR "aci_busy_wait() time out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static inline int aci_write(struct snd_miro_aci *aci, unsigned char byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (aci_busy_wait(aci) >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) outb(byte, aci->aci_port + ACI_REG_COMMAND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) snd_printk(KERN_ERR "aci busy, aci_write(0x%x) stopped.\n", byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static inline int aci_read(struct snd_miro_aci *aci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) unsigned char byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (aci_busy_wait(aci) >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) byte = inb(aci->aci_port + ACI_REG_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) snd_printk(KERN_ERR "aci busy, aci_read() stopped.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int snd_aci_cmd(struct snd_miro_aci *aci, int write1, int write2, int write3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) int write[] = {write1, write2, write3};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) int value, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (mutex_lock_interruptible(&aci->aci_mutex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) for (i=0; i<3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (write[i]< 0 || write[i] > 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) value = aci_write(aci, write[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (value < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) value = aci_read(aci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) out: mutex_unlock(&aci->aci_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) EXPORT_SYMBOL(snd_aci_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static int aci_getvalue(struct snd_miro_aci *aci, unsigned char index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return snd_aci_cmd(aci, ACI_STATUS, index, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static int aci_setvalue(struct snd_miro_aci *aci, unsigned char index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return snd_aci_cmd(aci, index, value, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct snd_miro_aci *snd_aci_get_aci(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (aci_device.aci_port == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return &aci_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) EXPORT_SYMBOL(snd_aci_get_aci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * MIXER part
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) #define snd_miro_info_capture snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static int snd_miro_get_capture(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) value = aci_getvalue(miro->aci, ACI_S_GENERAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (value < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) snd_printk(KERN_ERR "snd_miro_get_capture() failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) ucontrol->value.integer.value[0] = value & 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static int snd_miro_put_capture(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) int change, value, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) value = !(ucontrol->value.integer.value[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) error = aci_setvalue(miro->aci, ACI_SET_SOLOMODE, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) snd_printk(KERN_ERR "snd_miro_put_capture() failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) change = (value != miro->aci->aci_solomode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) miro->aci->aci_solomode = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static int snd_miro_info_preamp(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) uinfo->value.integer.max = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static int snd_miro_get_preamp(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (miro->aci->aci_version <= 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) OSS says it's not readable with versions < 176.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) But it doesn't work on my card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) which is a PCM12 with aci_version = 176.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) ucontrol->value.integer.value[0] = miro->aci->aci_preamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) value = aci_getvalue(miro->aci, ACI_GET_PREAMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (value < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) snd_printk(KERN_ERR "snd_miro_get_preamp() failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ucontrol->value.integer.value[0] = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static int snd_miro_put_preamp(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) int error, value, change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) value = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) error = aci_setvalue(miro->aci, ACI_SET_PREAMP, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) snd_printk(KERN_ERR "snd_miro_put_preamp() failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) change = (value != miro->aci->aci_preamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) miro->aci->aci_preamp = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) #define snd_miro_info_amp snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static int snd_miro_get_amp(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) ucontrol->value.integer.value[0] = miro->aci->aci_amp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static int snd_miro_put_amp(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) int error, value, change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) value = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) error = aci_setvalue(miro->aci, ACI_SET_POWERAMP, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) snd_printk(KERN_ERR "snd_miro_put_amp() to %d failed: %d\n", value, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) change = (value != miro->aci->aci_amp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) miro->aci->aci_amp = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) #define MIRO_DOUBLE(ctl_name, ctl_index, get_right_reg, set_right_reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) .name = ctl_name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .index = ctl_index, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) .info = snd_miro_info_double, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) .get = snd_miro_get_double, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) .put = snd_miro_put_double, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) .private_value = get_right_reg | (set_right_reg << 8) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static int snd_miro_info_double(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if ((reg >= ACI_GET_EQ1) && (reg <= ACI_GET_EQ7)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /* equalizer elements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) uinfo->value.integer.min = - 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) uinfo->value.integer.max = 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* non-equalizer elements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) uinfo->value.integer.max = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) static int snd_miro_get_double(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct snd_ctl_elem_value *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) int left_val, right_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) int right_reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) int left_reg = right_reg + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) right_val = aci_getvalue(miro->aci, right_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (right_val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", right_reg, right_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return right_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) left_val = aci_getvalue(miro->aci, left_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (left_val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", left_reg, left_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return left_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if ((right_reg >= ACI_GET_EQ1) && (right_reg <= ACI_GET_EQ7)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /* equalizer elements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (left_val < 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) uinfo->value.integer.value[0] = left_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) uinfo->value.integer.value[0] = 0x80 - left_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (right_val < 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) uinfo->value.integer.value[1] = right_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) uinfo->value.integer.value[1] = 0x80 - right_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /* non-equalizer elements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) uinfo->value.integer.value[0] = 0x20 - left_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) uinfo->value.integer.value[1] = 0x20 - right_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct snd_miro_aci *aci = miro->aci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) int left, right, left_old, right_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) int setreg_left, setreg_right, getreg_left, getreg_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) int change, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) left = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) right = ucontrol->value.integer.value[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) setreg_right = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) setreg_left = setreg_right + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (setreg_right == ACI_SET_MASTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) setreg_left -= 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) getreg_right = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) getreg_left = getreg_right + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) left_old = aci_getvalue(aci, getreg_left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (left_old < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_left, left_old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return left_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) right_old = aci_getvalue(aci, getreg_right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (right_old < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_right, right_old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return right_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if ((getreg_right >= ACI_GET_EQ1) && (getreg_right <= ACI_GET_EQ7)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /* equalizer elements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (left < -0x7f || left > 0x7f ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) right < -0x7f || right > 0x7f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (left_old > 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) left_old = 0x80 - left_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (right_old > 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) right_old = 0x80 - right_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (left >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) error = aci_setvalue(aci, setreg_left, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) left, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) error = aci_setvalue(aci, setreg_left, 0x80 - left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 0x80 - left, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (right >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) error = aci_setvalue(aci, setreg_right, right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) right, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) error = aci_setvalue(aci, setreg_right, 0x80 - right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 0x80 - right, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /* non-equalizer elements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (left < 0 || left > 0x20 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) right < 0 || right > 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) left_old = 0x20 - left_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) right_old = 0x20 - right_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) error = aci_setvalue(aci, setreg_left, 0x20 - left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 0x20 - left, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) error = aci_setvalue(aci, setreg_right, 0x20 - right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 0x20 - right, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) change = (left != left_old) || (right != right_old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) static const struct snd_kcontrol_new snd_miro_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) MIRO_DOUBLE("Master Playback Volume", 0, ACI_GET_MASTER, ACI_SET_MASTER),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) MIRO_DOUBLE("Mic Playback Volume", 1, ACI_GET_MIC, ACI_SET_MIC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) MIRO_DOUBLE("Line Playback Volume", 1, ACI_GET_LINE, ACI_SET_LINE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) MIRO_DOUBLE("CD Playback Volume", 0, ACI_GET_CD, ACI_SET_CD),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) MIRO_DOUBLE("Synth Playback Volume", 0, ACI_GET_SYNTH, ACI_SET_SYNTH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) MIRO_DOUBLE("PCM Playback Volume", 1, ACI_GET_PCM, ACI_SET_PCM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) MIRO_DOUBLE("Aux Playback Volume", 2, ACI_GET_LINE2, ACI_SET_LINE2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) /* Equalizer with seven bands (only PCM20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) from -12dB up to +12dB on each band */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static const struct snd_kcontrol_new snd_miro_eq_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) MIRO_DOUBLE("Tone Control - 28 Hz", 0, ACI_GET_EQ1, ACI_SET_EQ1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) MIRO_DOUBLE("Tone Control - 160 Hz", 0, ACI_GET_EQ2, ACI_SET_EQ2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) MIRO_DOUBLE("Tone Control - 400 Hz", 0, ACI_GET_EQ3, ACI_SET_EQ3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) MIRO_DOUBLE("Tone Control - 1 kHz", 0, ACI_GET_EQ4, ACI_SET_EQ4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) MIRO_DOUBLE("Tone Control - 2.5 kHz", 0, ACI_GET_EQ5, ACI_SET_EQ5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) MIRO_DOUBLE("Tone Control - 6.3 kHz", 0, ACI_GET_EQ6, ACI_SET_EQ6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) MIRO_DOUBLE("Tone Control - 16 kHz", 0, ACI_GET_EQ7, ACI_SET_EQ7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) static const struct snd_kcontrol_new snd_miro_radio_control[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) MIRO_DOUBLE("Radio Playback Volume", 0, ACI_GET_LINE1, ACI_SET_LINE1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) static const struct snd_kcontrol_new snd_miro_line_control[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) MIRO_DOUBLE("Line Playback Volume", 2, ACI_GET_LINE1, ACI_SET_LINE1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static const struct snd_kcontrol_new snd_miro_preamp_control[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) .name = "Mic Boost",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) .index = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) .info = snd_miro_info_preamp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) .get = snd_miro_get_preamp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) .put = snd_miro_put_preamp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static const struct snd_kcontrol_new snd_miro_amp_control[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) .name = "Line Boost",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) .index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) .info = snd_miro_info_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) .get = snd_miro_get_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) .put = snd_miro_put_amp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static const struct snd_kcontrol_new snd_miro_capture_control[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) .name = "PCM Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) .index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) .info = snd_miro_info_capture,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) .get = snd_miro_get_capture,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) .put = snd_miro_put_capture,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) static const unsigned char aci_init_values[][2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) { ACI_SET_MUTE, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) { ACI_SET_POWERAMP, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) { ACI_SET_PREAMP, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) { ACI_SET_SOLOMODE, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) { ACI_SET_MIC + 0, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) { ACI_SET_MIC + 8, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) { ACI_SET_LINE + 0, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) { ACI_SET_LINE + 8, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) { ACI_SET_CD + 0, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) { ACI_SET_CD + 8, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) { ACI_SET_PCM + 0, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) { ACI_SET_PCM + 8, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) { ACI_SET_LINE1 + 0, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) { ACI_SET_LINE1 + 8, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) { ACI_SET_LINE2 + 0, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) { ACI_SET_LINE2 + 8, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) { ACI_SET_SYNTH + 0, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) { ACI_SET_SYNTH + 8, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) { ACI_SET_MASTER + 0, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) { ACI_SET_MASTER + 1, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) static int snd_set_aci_init_values(struct snd_miro *miro)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) int idx, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) struct snd_miro_aci *aci = miro->aci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /* enable WSS on PCM1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if ((aci->aci_product == 'A') && wss) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) error = aci_setvalue(aci, ACI_SET_WSS, wss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) snd_printk(KERN_ERR "enabling WSS mode failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) /* enable IDE port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (ide) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) error = aci_setvalue(aci, ACI_SET_IDE, ide);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) snd_printk(KERN_ERR "enabling IDE port failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) /* set common aci values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) for (idx = 0; idx < ARRAY_SIZE(aci_init_values); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) error = aci_setvalue(aci, aci_init_values[idx][0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) aci_init_values[idx][1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) aci_init_values[idx][0], error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) aci->aci_amp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) aci->aci_preamp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) aci->aci_solomode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) static int snd_miro_mixer(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) struct snd_miro *miro)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (snd_BUG_ON(!miro || !card))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) switch (miro->hardware) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) case OPTi9XX_HW_82C924:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) strcpy(card->mixername, "ACI & OPTi924");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) case OPTi9XX_HW_82C929:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) strcpy(card->mixername, "ACI & OPTi929");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) snd_BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) for (idx = 0; idx < ARRAY_SIZE(snd_miro_controls); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_controls[idx], miro))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if ((miro->aci->aci_product == 'A') ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) (miro->aci->aci_product == 'B')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) /* PCM1/PCM12 with power-amp and Line 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_line_control[0], miro))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_amp_control[0], miro))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if ((miro->aci->aci_product == 'B') ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) (miro->aci->aci_product == 'C')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /* PCM12/PCM20 with mic-preamp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_preamp_control[0], miro))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (miro->aci->aci_version >= 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_capture_control[0], miro))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (miro->aci->aci_product == 'C') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) /* PCM20 with radio and 7 band equalizer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_radio_control[0], miro))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) for (idx = 0; idx < ARRAY_SIZE(snd_miro_eq_controls); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_eq_controls[idx], miro))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) static int snd_miro_init(struct snd_miro *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) unsigned short hardware)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) static const int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) chip->hardware = hardware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) strcpy(chip->name, snd_opti9xx_names[hardware]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) chip->mc_base_size = opti9xx_mc_size[hardware];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) spin_lock_init(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) chip->wss_base = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) chip->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) chip->dma1 = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) chip->dma2 = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) chip->mpu_port = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) chip->mpu_irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) chip->pwd_reg = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (isapnp && chip->mc_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) /* PnP resource gives the least 10 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) chip->mc_base |= 0xc00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) chip->mc_base = 0xf8c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) switch (hardware) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) case OPTi9XX_HW_82C929:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) chip->password = 0xe3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) case OPTi9XX_HW_82C924:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) chip->password = 0xe5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) snd_printk(KERN_ERR "sorry, no support for %d\n", hardware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) static unsigned char snd_miro_read(struct snd_miro *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) unsigned char reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) unsigned char retval = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) outb(chip->password, chip->mc_base + chip->pwd_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) switch (chip->hardware) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) case OPTi9XX_HW_82C924:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (reg > 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) outb(reg, chip->mc_base + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) outb(chip->password, chip->mc_base + chip->pwd_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) retval = inb(chip->mc_base + 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) case OPTi9XX_HW_82C929:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) retval = inb(chip->mc_base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) snd_printk(KERN_ERR "sorry, no support for %d\n", chip->hardware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) static void snd_miro_write(struct snd_miro *chip, unsigned char reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) unsigned char value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) outb(chip->password, chip->mc_base + chip->pwd_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) switch (chip->hardware) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) case OPTi9XX_HW_82C924:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if (reg > 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) outb(reg, chip->mc_base + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) outb(chip->password, chip->mc_base + chip->pwd_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) outb(value, chip->mc_base + 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) case OPTi9XX_HW_82C929:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) outb(value, chip->mc_base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) snd_printk(KERN_ERR "sorry, no support for %d\n", chip->hardware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) static inline void snd_miro_write_mask(struct snd_miro *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) unsigned char reg, unsigned char value, unsigned char mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) unsigned char oldval = snd_miro_read(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) snd_miro_write(chip, reg, (oldval & ~mask) | (value & mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) * Proc Interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) static void snd_miro_proc_read(struct snd_info_entry * entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) struct snd_miro *miro = (struct snd_miro *) entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) struct snd_miro_aci *aci = miro->aci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) char* model = "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) /* miroSOUND PCM1 pro, early PCM12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if ((miro->hardware == OPTi9XX_HW_82C929) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) (aci->aci_vendor == 'm') &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) (aci->aci_product == 'A')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) switch (aci->aci_version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) model = "miroSOUND PCM1 pro";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) model = "miroSOUND PCM1 pro / (early) PCM12";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) /* miroSOUND PCM12, PCM12 (Rev. E), PCM12 pnp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if ((miro->hardware == OPTi9XX_HW_82C924) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) (aci->aci_vendor == 'm') &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) (aci->aci_product == 'B')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) switch (aci->aci_version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) model = "miroSOUND PCM12";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) case 176:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) model = "miroSOUND PCM12 (Rev. E)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) model = "miroSOUND PCM12 / PCM12 pnp";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) /* miroSOUND PCM20 radio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if ((miro->hardware == OPTi9XX_HW_82C924) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) (aci->aci_vendor == 'm') &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) (aci->aci_product == 'C')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) switch (aci->aci_version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) model = "miroSOUND PCM20 radio (Rev. E)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) model = "miroSOUND PCM20 radio";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) snd_iprintf(buffer, "\nGeneral information:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) snd_iprintf(buffer, " model : %s\n", model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) snd_iprintf(buffer, " opti : %s\n", miro->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) snd_iprintf(buffer, " codec : %s\n", miro->pcm->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) snd_iprintf(buffer, " port : 0x%lx\n", miro->wss_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) snd_iprintf(buffer, " irq : %d\n", miro->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) snd_iprintf(buffer, " dma : %d,%d\n\n", miro->dma1, miro->dma2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) snd_iprintf(buffer, "MPU-401:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) snd_iprintf(buffer, " port : 0x%lx\n", miro->mpu_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) snd_iprintf(buffer, " irq : %d\n\n", miro->mpu_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) snd_iprintf(buffer, "ACI information:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) snd_iprintf(buffer, " vendor : ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) switch (aci->aci_vendor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) case 'm':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) snd_iprintf(buffer, "Miro\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) snd_iprintf(buffer, "unknown (0x%x)\n", aci->aci_vendor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) snd_iprintf(buffer, " product : ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) switch (aci->aci_product) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) case 'A':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) snd_iprintf(buffer, "miroSOUND PCM1 pro / (early) PCM12\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) case 'B':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) snd_iprintf(buffer, "miroSOUND PCM12\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) case 'C':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) snd_iprintf(buffer, "miroSOUND PCM20 radio\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) snd_iprintf(buffer, "unknown (0x%x)\n", aci->aci_product);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) snd_iprintf(buffer, " firmware: %d (0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) aci->aci_version, aci->aci_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) snd_iprintf(buffer, " port : 0x%lx-0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) aci->aci_port, aci->aci_port+2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) snd_iprintf(buffer, " wss : 0x%x\n", wss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) snd_iprintf(buffer, " ide : 0x%x\n", ide);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) snd_iprintf(buffer, " solomode: 0x%x\n", aci->aci_solomode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) snd_iprintf(buffer, " amp : 0x%x\n", aci->aci_amp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) snd_iprintf(buffer, " preamp : 0x%x\n", aci->aci_preamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) static void snd_miro_proc_init(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) struct snd_miro *miro)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) snd_card_ro_proc_new(card, "miro", miro, snd_miro_proc_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) * Init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) static int snd_miro_configure(struct snd_miro *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) unsigned char wss_base_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) unsigned char irq_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) unsigned char dma_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) unsigned char mpu_port_bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) unsigned char mpu_irq_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) snd_miro_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) snd_miro_write_mask(chip, OPTi9XX_MC_REG(2), 0x20, 0x20); /* OPL4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) snd_miro_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) switch (chip->hardware) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) case OPTi9XX_HW_82C924:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) snd_miro_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) snd_miro_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) case OPTi9XX_HW_82C929:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) /* untested init commands for OPTi929 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) snd_miro_write_mask(chip, OPTi9XX_MC_REG(4), 0x00, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) /* PnP resource says it decodes only 10 bits of address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) switch (chip->wss_base & 0x3ff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) case 0x130:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) chip->wss_base = 0x530;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) wss_base_bits = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) case 0x204:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) chip->wss_base = 0x604;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) wss_base_bits = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) case 0x280:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) chip->wss_base = 0xe80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) wss_base_bits = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) case 0x340:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) chip->wss_base = 0xf40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) wss_base_bits = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) snd_printk(KERN_ERR "WSS port 0x%lx not valid\n", chip->wss_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) goto __skip_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) snd_miro_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) __skip_base:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) switch (chip->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) irq_bits = 0x05;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) irq_bits = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) case 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) irq_bits = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) irq_bits = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) case 11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) irq_bits = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) snd_printk(KERN_ERR "WSS irq # %d not valid\n", chip->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) goto __skip_resources;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) switch (chip->dma1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) dma_bits = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) dma_bits = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) dma_bits = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) snd_printk(KERN_ERR "WSS dma1 # %d not valid\n", chip->dma1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) goto __skip_resources;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (chip->dma1 == chip->dma2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) snd_printk(KERN_ERR "don't want to share dmas\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) switch (chip->dma2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) snd_printk(KERN_ERR "WSS dma2 # %d not valid\n", chip->dma2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) goto __skip_resources;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) dma_bits |= 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) outb(irq_bits << 3 | dma_bits, chip->wss_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) __skip_resources:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (chip->hardware > OPTi9XX_HW_82C928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) switch (chip->mpu_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) case -1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) case 0x300:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) mpu_port_bits = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) case 0x310:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) mpu_port_bits = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) case 0x320:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) mpu_port_bits = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) case 0x330:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) mpu_port_bits = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) snd_printk(KERN_ERR "MPU-401 port 0x%lx not valid\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) chip->mpu_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) goto __skip_mpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) switch (chip->mpu_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) mpu_irq_bits = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) mpu_irq_bits = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) case 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) mpu_irq_bits = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) mpu_irq_bits = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) snd_printk(KERN_ERR "MPU-401 irq # %d not valid\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) chip->mpu_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) goto __skip_mpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) snd_miro_write_mask(chip, OPTi9XX_MC_REG(6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) (chip->mpu_port <= 0) ? 0x00 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 0x80 | mpu_port_bits << 5 | mpu_irq_bits << 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 0xf8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) __skip_mpu:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) static int snd_miro_opti_check(struct snd_miro *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) unsigned char value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) "OPTi9xx MC");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if (chip->res_mc_base == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) value = snd_miro_read(chip, OPTi9XX_MC_REG(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (value != 0xff && value != inb(chip->mc_base + OPTi9XX_MC_REG(1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (value == snd_miro_read(chip, OPTi9XX_MC_REG(1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) release_and_free_resource(chip->res_mc_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) chip->res_mc_base = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) static int snd_card_miro_detect(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) struct snd_miro *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) for (i = OPTi9XX_HW_82C929; i <= OPTi9XX_HW_82C924; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) if ((err = snd_miro_init(chip, i)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) err = snd_miro_opti_check(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) if (err == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) static int snd_card_miro_aci_detect(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) struct snd_miro *miro)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) unsigned char regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) struct snd_miro_aci *aci = &aci_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) miro->aci = aci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) mutex_init(&aci->aci_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) /* get ACI port from OPTi9xx MC 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) regval=inb(miro->mc_base + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) aci->aci_port = (regval & 0x10) ? 0x344 : 0x354;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) miro->res_aci_port = request_region(aci->aci_port, 3, "miro aci");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) if (miro->res_aci_port == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) snd_printk(KERN_ERR "aci i/o area 0x%lx-0x%lx already used.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) aci->aci_port, aci->aci_port+2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) /* force ACI into a known state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) for (i = 0; i < 3; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) if (snd_aci_cmd(aci, ACI_ERROR_OP, -1, -1) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) snd_printk(KERN_ERR "can't force aci into known state.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) aci->aci_vendor = snd_aci_cmd(aci, ACI_READ_IDCODE, -1, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) aci->aci_product = snd_aci_cmd(aci, ACI_READ_IDCODE, -1, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) if (aci->aci_vendor < 0 || aci->aci_product < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) snd_printk(KERN_ERR "can't read aci id on 0x%lx.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) aci->aci_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) aci->aci_version = snd_aci_cmd(aci, ACI_READ_VERSION, -1, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (aci->aci_version < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) snd_printk(KERN_ERR "can't read aci version on 0x%lx.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) aci->aci_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) if (snd_aci_cmd(aci, ACI_INIT, -1, -1) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) snd_aci_cmd(aci, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) snd_aci_cmd(aci, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) snd_printk(KERN_ERR "can't initialize aci.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) static void snd_card_miro_free(struct snd_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) struct snd_miro *miro = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) release_and_free_resource(miro->res_aci_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) if (miro->aci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) miro->aci->aci_port = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) release_and_free_resource(miro->res_mc_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) static int snd_miro_probe(struct snd_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) struct snd_miro *miro = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) struct snd_wss *codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) struct snd_rawmidi *rmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) if (!miro->res_mc_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) miro->res_mc_base = request_region(miro->mc_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) miro->mc_base_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) "miro (OPTi9xx MC)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) if (miro->res_mc_base == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) snd_printk(KERN_ERR "request for OPTI9xx MC failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) error = snd_card_miro_aci_detect(card, miro);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) snd_printk(KERN_ERR "unable to detect aci chip\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) miro->wss_base = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) miro->mpu_port = mpu_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) miro->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) miro->mpu_irq = mpu_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) miro->dma1 = dma1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) miro->dma2 = dma2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) /* init proc interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) snd_miro_proc_init(card, miro);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) error = snd_miro_configure(miro);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) error = snd_wss_create(card, miro->wss_base + 4, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) miro->irq, miro->dma1, miro->dma2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) WSS_HW_DETECT, 0, &codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) error = snd_wss_pcm(codec, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) error = snd_wss_mixer(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) error = snd_wss_timer(codec, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) miro->pcm = codec->pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) error = snd_miro_mixer(card, miro);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) if (miro->aci->aci_vendor == 'm') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) /* It looks like a miro sound card. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) switch (miro->aci->aci_product) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) case 'A':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) sprintf(card->shortname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) "miroSOUND PCM1 pro / PCM12");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) case 'B':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) sprintf(card->shortname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) "miroSOUND PCM12");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) case 'C':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) sprintf(card->shortname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) "miroSOUND PCM20 radio");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) sprintf(card->shortname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) "unknown miro");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) snd_printk(KERN_INFO "unknown miro aci id\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) snd_printk(KERN_INFO "found unsupported aci card\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) sprintf(card->shortname, "unknown Cardinal Technologies");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) strcpy(card->driver, "miro");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) snprintf(card->longname, sizeof(card->longname),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) "%s: OPTi%s, %s at 0x%lx, irq %d, dma %d&%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) card->shortname, miro->name, codec->pcm->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) miro->wss_base + 4, miro->irq, miro->dma1, miro->dma2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) rmidi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) mpu_port, 0, miro->mpu_irq, &rmidi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) mpu_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) struct snd_opl3 *opl3 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) struct snd_opl4 *opl4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) if (snd_opl4_create(card, fm_port, fm_port - 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 2, &opl3, &opl4) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) snd_printk(KERN_WARNING "no OPL4 device at 0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) fm_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) error = snd_set_aci_init_values(miro);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) return snd_card_register(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) static int snd_miro_isa_match(struct device *devptr, unsigned int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) if (snd_miro_pnp_is_probed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) if (isapnp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) static int snd_miro_isa_probe(struct device *devptr, unsigned int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) static const long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) static const long possible_mpu_ports[] = {0x330, 0x300, 0x310, 0x320, -1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) static const int possible_irqs[] = {11, 9, 10, 7, -1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) static const int possible_mpu_irqs[] = {10, 5, 9, 7, -1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) static const int possible_dma1s[] = {3, 1, 0, -1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) static const int possible_dma2s[][2] = { {1, -1}, {0, -1}, {-1, -1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) {0, -1} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) struct snd_miro *miro;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) error = snd_card_new(devptr, index, id, THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) sizeof(struct snd_miro), &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) card->private_free = snd_card_miro_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) miro = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) error = snd_card_miro_detect(card, miro);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) snd_printk(KERN_ERR "unable to detect OPTi9xx chip\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) if (port == SNDRV_AUTO_PORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) port = snd_legacy_find_free_ioport(possible_ports, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) if (port < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) snd_printk(KERN_ERR "unable to find a free WSS port\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) if (mpu_port == SNDRV_AUTO_PORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) if (mpu_port < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) snd_printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) "unable to find a free MPU401 port\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) if (irq == SNDRV_AUTO_IRQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) irq = snd_legacy_find_free_irq(possible_irqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) if (irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) snd_printk(KERN_ERR "unable to find a free IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) if (mpu_irq == SNDRV_AUTO_IRQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) mpu_irq = snd_legacy_find_free_irq(possible_mpu_irqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) if (mpu_irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) snd_printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) "unable to find a free MPU401 IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) if (dma1 == SNDRV_AUTO_DMA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) dma1 = snd_legacy_find_free_dma(possible_dma1s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) if (dma1 < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) snd_printk(KERN_ERR "unable to find a free DMA1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) if (dma2 == SNDRV_AUTO_DMA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) dma2 = snd_legacy_find_free_dma(possible_dma2s[dma1 % 4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) if (dma2 < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) snd_printk(KERN_ERR "unable to find a free DMA2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) error = snd_miro_probe(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) dev_set_drvdata(devptr, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) static int snd_miro_isa_remove(struct device *devptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) unsigned int dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) snd_card_free(dev_get_drvdata(devptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) #define DEV_NAME "miro"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) static struct isa_driver snd_miro_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) .match = snd_miro_isa_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) .probe = snd_miro_isa_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) .remove = snd_miro_isa_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) /* FIXME: suspend/resume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) .name = DEV_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) static int snd_card_miro_pnp(struct snd_miro *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) struct pnp_card_link *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) const struct pnp_card_device_id *pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) struct pnp_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) struct pnp_dev *devmpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) struct pnp_dev *devmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) pdev = pnp_request_card_device(card, pid->devs[0].id, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) if (pdev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) if (devmpu == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) devmc = pnp_request_card_device(card, pid->devs[2].id, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) if (devmc == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) err = pnp_activate_dev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) err = pnp_activate_dev(devmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) snd_printk(KERN_ERR "MC pnp configure failure: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) port = pnp_port_start(pdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) fm_port = pnp_port_start(pdev, 2) + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) * The MC(0) is never accessed and the miroSOUND PCM20 card does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) * include it in the PnP resource range. OPTI93x include it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) chip->mc_base = pnp_port_start(devmc, 0) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) chip->mc_base_size = pnp_port_len(devmc, 0) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) irq = pnp_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) dma1 = pnp_dma(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) dma2 = pnp_dma(pdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) if (mpu_port > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) err = pnp_activate_dev(devmpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) snd_printk(KERN_ERR "MPU401 pnp configure failure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) mpu_port = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) mpu_port = pnp_port_start(devmpu, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) mpu_irq = pnp_irq(devmpu, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) static int snd_miro_pnp_probe(struct pnp_card_link *pcard,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) const struct pnp_card_device_id *pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) struct snd_miro *miro;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) if (snd_miro_pnp_is_probed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) if (!isapnp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) err = snd_card_new(&pcard->card->dev, index, id, THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) sizeof(struct snd_miro), &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) card->private_free = snd_card_miro_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) miro = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) err = snd_card_miro_pnp(miro, pcard, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) /* only miroSOUND PCM20 and PCM12 == OPTi924 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) err = snd_miro_init(miro, OPTi9XX_HW_82C924);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) err = snd_miro_opti_check(miro);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) snd_printk(KERN_ERR "OPTI chip not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) err = snd_miro_probe(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) pnp_set_card_drvdata(pcard, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) snd_miro_pnp_is_probed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) static void snd_miro_pnp_remove(struct pnp_card_link *pcard)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) snd_card_free(pnp_get_card_drvdata(pcard));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) pnp_set_card_drvdata(pcard, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) snd_miro_pnp_is_probed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) static struct pnp_card_driver miro_pnpc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) .flags = PNP_DRIVER_RES_DISABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) .name = "miro",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) .id_table = snd_miro_pnpids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) .probe = snd_miro_pnp_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) .remove = snd_miro_pnp_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) static int __init alsa_card_miro_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) pnp_register_card_driver(&miro_pnpc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) if (snd_miro_pnp_is_probed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) pnp_unregister_card_driver(&miro_pnpc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) return isa_register_driver(&snd_miro_driver, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) static void __exit alsa_card_miro_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) if (!snd_miro_pnp_is_probed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) isa_unregister_driver(&snd_miro_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) pnp_unregister_card_driver(&miro_pnpc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) module_init(alsa_card_miro_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) module_exit(alsa_card_miro_exit)