aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-11-27 07:27:03 -0500
committerTakashi Iwai <tiwai@suse.de>2009-11-27 07:27:03 -0500
commitabe6becb7c603991b925c0d2dd908e31dd6611f5 (patch)
treed5bfdd328f87b82fbf50e338b227c54be05245b9
parentbbb3c644bd9967753ce8c214c5e64b27c361d2a4 (diff)
parent8366fc390865bfb1497fe19a518fe5713f96ba3b (diff)
Merge branch 'next/isa' into topic/misc
-rw-r--r--drivers/media/radio/Kconfig18
-rw-r--r--drivers/media/radio/Makefile1
-rw-r--r--drivers/media/radio/radio-miropcm20.c270
-rw-r--r--include/sound/aci.h (renamed from sound/isa/opti9xx/miro.h)23
-rw-r--r--sound/isa/opti9xx/miro.c253
5 files changed, 456 insertions, 109 deletions
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index a87a477c87f2..b134553eb3b5 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -195,6 +195,24 @@ config RADIO_MAESTRO
195 To compile this driver as a module, choose M here: the 195 To compile this driver as a module, choose M here: the
196 module will be called radio-maestro. 196 module will be called radio-maestro.
197 197
198config RADIO_MIROPCM20
199 tristate "miroSOUND PCM20 radio"
200 depends on ISA && VIDEO_V4L2
201 select SND_MIRO
202 ---help---
203 Choose Y here if you have this FM radio card. You also need to enable
204 the ALSA sound system. This choice automatically selects the ALSA
205 sound card driver "Miro miroSOUND PCM1pro/PCM12/PCM20radio" as this
206 is required for the radio-miropcm20.
207
208 In order to control your radio card, you will need to use programs
209 that are compatible with the Video For Linux API. Information on
210 this API and pointers to "v4l" programs may be found at
211 <file:Documentation/video4linux/API.html>.
212
213 To compile this driver as a module, choose M here: the
214 module will be called radio-miropcm20.
215
198config RADIO_SF16FMI 216config RADIO_SF16FMI
199 tristate "SF16FMI Radio" 217 tristate "SF16FMI Radio"
200 depends on ISA && VIDEO_V4L2 218 depends on ISA && VIDEO_V4L2
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 2a1be3bf4f7c..8a63d543ae41 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
18obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o 18obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o
19obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o 19obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o
20obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o 20obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o
21obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o
21obj-$(CONFIG_USB_DSBR) += dsbr100.o 22obj-$(CONFIG_USB_DSBR) += dsbr100.o
22obj-$(CONFIG_RADIO_SI470X) += si470x/ 23obj-$(CONFIG_RADIO_SI470X) += si470x/
23obj-$(CONFIG_USB_MR800) += radio-mr800.o 24obj-$(CONFIG_USB_MR800) += radio-mr800.o
diff --git a/drivers/media/radio/radio-miropcm20.c b/drivers/media/radio/radio-miropcm20.c
new file mode 100644
index 000000000000..4ff885445fd4
--- /dev/null
+++ b/drivers/media/radio/radio-miropcm20.c
@@ -0,0 +1,270 @@
1/* Miro PCM20 radio driver for Linux radio support
2 * (c) 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
3 * Thanks to Norberto Pellici for the ACI device interface specification
4 * The API part is based on the radiotrack driver by M. Kirkwood
5 * This driver relies on the aci mixer provided by the snd-miro
6 * ALSA driver.
7 * Look there for further info...
8 */
9
10/* What ever you think about the ACI, version 0x07 is not very well!
11 * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono
12 * conditions... Robert
13 */
14
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/videodev2.h>
18#include <media/v4l2-device.h>
19#include <media/v4l2-ioctl.h>
20#include <sound/aci.h>
21
22static int radio_nr = -1;
23module_param(radio_nr, int, 0);
24MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)");
25
26static int mono;
27module_param(mono, bool, 0);
28MODULE_PARM_DESC(mono, "Force tuner into mono mode.");
29
30struct pcm20 {
31 struct v4l2_device v4l2_dev;
32 struct video_device vdev;
33 unsigned long freq;
34 int muted;
35 struct snd_miro_aci *aci;
36};
37
38static struct pcm20 pcm20_card = {
39 .freq = 87*16000,
40 .muted = 1,
41};
42
43static int pcm20_mute(struct pcm20 *dev, unsigned char mute)
44{
45 dev->muted = mute;
46 return snd_aci_cmd(dev->aci, ACI_SET_TUNERMUTE, mute, -1);
47}
48
49static int pcm20_stereo(struct pcm20 *dev, unsigned char stereo)
50{
51 return snd_aci_cmd(dev->aci, ACI_SET_TUNERMONO, !stereo, -1);
52}
53
54static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq)
55{
56 unsigned char freql;
57 unsigned char freqh;
58 struct snd_miro_aci *aci = dev->aci;
59
60 dev->freq = freq;
61
62 freq /= 160;
63 if (!(aci->aci_version == 0x07 || aci->aci_version >= 0xb0))
64 freq /= 10; /* I don't know exactly which version
65 * needs this hack */
66 freql = freq & 0xff;
67 freqh = freq >> 8;
68
69 pcm20_stereo(dev, !mono);
70 return snd_aci_cmd(aci, ACI_WRITE_TUNE, freql, freqh);
71}
72
73static const struct v4l2_file_operations pcm20_fops = {
74 .owner = THIS_MODULE,
75 .ioctl = video_ioctl2,
76};
77
78static int vidioc_querycap(struct file *file, void *priv,
79 struct v4l2_capability *v)
80{
81 strlcpy(v->driver, "Miro PCM20", sizeof(v->driver));
82 strlcpy(v->card, "Miro PCM20", sizeof(v->card));
83 strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
84 v->version = 0x1;
85 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
86 return 0;
87}
88
89static int vidioc_g_tuner(struct file *file, void *priv,
90 struct v4l2_tuner *v)
91{
92 if (v->index) /* Only 1 tuner */
93 return -EINVAL;
94 strlcpy(v->name, "FM", sizeof(v->name));
95 v->type = V4L2_TUNER_RADIO;
96 v->rangelow = 87*16000;
97 v->rangehigh = 108*16000;
98 v->signal = 0xffff;
99 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
100 v->capability = V4L2_TUNER_CAP_LOW;
101 v->audmode = V4L2_TUNER_MODE_MONO;
102 return 0;
103}
104
105static int vidioc_s_tuner(struct file *file, void *priv,
106 struct v4l2_tuner *v)
107{
108 return v->index ? -EINVAL : 0;
109}
110
111static int vidioc_g_frequency(struct file *file, void *priv,
112 struct v4l2_frequency *f)
113{
114 struct pcm20 *dev = video_drvdata(file);
115
116 if (f->tuner != 0)
117 return -EINVAL;
118
119 f->type = V4L2_TUNER_RADIO;
120 f->frequency = dev->freq;
121 return 0;
122}
123
124
125static int vidioc_s_frequency(struct file *file, void *priv,
126 struct v4l2_frequency *f)
127{
128 struct pcm20 *dev = video_drvdata(file);
129
130 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
131 return -EINVAL;
132
133 dev->freq = f->frequency;
134 pcm20_setfreq(dev, f->frequency);
135 return 0;
136}
137
138static int vidioc_queryctrl(struct file *file, void *priv,
139 struct v4l2_queryctrl *qc)
140{
141 switch (qc->id) {
142 case V4L2_CID_AUDIO_MUTE:
143 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
144 }
145 return -EINVAL;
146}
147
148static int vidioc_g_ctrl(struct file *file, void *priv,
149 struct v4l2_control *ctrl)
150{
151 struct pcm20 *dev = video_drvdata(file);
152
153 switch (ctrl->id) {
154 case V4L2_CID_AUDIO_MUTE:
155 ctrl->value = dev->muted;
156 break;
157 default:
158 return -EINVAL;
159 }
160 return 0;
161}
162
163static int vidioc_s_ctrl(struct file *file, void *priv,
164 struct v4l2_control *ctrl)
165{
166 struct pcm20 *dev = video_drvdata(file);
167
168 switch (ctrl->id) {
169 case V4L2_CID_AUDIO_MUTE:
170 pcm20_mute(dev, ctrl->value);
171 break;
172 default:
173 return -EINVAL;
174 }
175 return 0;
176}
177
178static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
179{
180 *i = 0;
181 return 0;
182}
183
184static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
185{
186 return i ? -EINVAL : 0;
187}
188
189static int vidioc_g_audio(struct file *file, void *priv,
190 struct v4l2_audio *a)
191{
192 a->index = 0;
193 strlcpy(a->name, "Radio", sizeof(a->name));
194 a->capability = V4L2_AUDCAP_STEREO;
195 return 0;
196}
197
198static int vidioc_s_audio(struct file *file, void *priv,
199 struct v4l2_audio *a)
200{
201 return a->index ? -EINVAL : 0;
202}
203
204static const struct v4l2_ioctl_ops pcm20_ioctl_ops = {
205 .vidioc_querycap = vidioc_querycap,
206 .vidioc_g_tuner = vidioc_g_tuner,
207 .vidioc_s_tuner = vidioc_s_tuner,
208 .vidioc_g_frequency = vidioc_g_frequency,
209 .vidioc_s_frequency = vidioc_s_frequency,
210 .vidioc_queryctrl = vidioc_queryctrl,
211 .vidioc_g_ctrl = vidioc_g_ctrl,
212 .vidioc_s_ctrl = vidioc_s_ctrl,
213 .vidioc_g_audio = vidioc_g_audio,
214 .vidioc_s_audio = vidioc_s_audio,
215 .vidioc_g_input = vidioc_g_input,
216 .vidioc_s_input = vidioc_s_input,
217};
218
219static int __init pcm20_init(void)
220{
221 struct pcm20 *dev = &pcm20_card;
222 struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
223 int res;
224
225 dev->aci = snd_aci_get_aci();
226 if (dev->aci == NULL) {
227 v4l2_err(v4l2_dev,
228 "you must load the snd-miro driver first!\n");
229 return -ENODEV;
230 }
231 strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name));
232
233
234 res = v4l2_device_register(NULL, v4l2_dev);
235 if (res < 0) {
236 v4l2_err(v4l2_dev, "could not register v4l2_device\n");
237 return -EINVAL;
238 }
239
240 strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
241 dev->vdev.v4l2_dev = v4l2_dev;
242 dev->vdev.fops = &pcm20_fops;
243 dev->vdev.ioctl_ops = &pcm20_ioctl_ops;
244 dev->vdev.release = video_device_release_empty;
245 video_set_drvdata(&dev->vdev, dev);
246
247 if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0)
248 goto fail;
249
250 v4l2_info(v4l2_dev, "Mirosound PCM20 Radio tuner\n");
251 return 0;
252fail:
253 v4l2_device_unregister(v4l2_dev);
254 return -EINVAL;
255}
256
257MODULE_AUTHOR("Ruurd Reitsma, Krzysztof Helt");
258MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card.");
259MODULE_LICENSE("GPL");
260
261static void __exit pcm20_cleanup(void)
262{
263 struct pcm20 *dev = &pcm20_card;
264
265 video_unregister_device(&dev->vdev);
266 v4l2_device_unregister(&dev->v4l2_dev);
267}
268
269module_init(pcm20_init);
270module_exit(pcm20_cleanup);
diff --git a/sound/isa/opti9xx/miro.h b/include/sound/aci.h
index 6e1385b8e07e..ee639d355ef0 100644
--- a/sound/isa/opti9xx/miro.h
+++ b/include/sound/aci.h
@@ -1,5 +1,5 @@
1#ifndef _MIRO_H_ 1#ifndef _ACI_H_
2#define _MIRO_H_ 2#define _ACI_H_
3 3
4#define ACI_REG_COMMAND 0 /* write register offset */ 4#define ACI_REG_COMMAND 0 /* write register offset */
5#define ACI_REG_STATUS 1 /* read register offset */ 5#define ACI_REG_STATUS 1 /* read register offset */
@@ -70,4 +70,21 @@
70#define ACI_SET_EQ6 0x45 70#define ACI_SET_EQ6 0x45
71#define ACI_SET_EQ7 0x46 /* ... to Treble */ 71#define ACI_SET_EQ7 0x46 /* ... to Treble */
72 72
73#endif /* _MIRO_H_ */ 73struct snd_miro_aci {
74 unsigned long aci_port;
75 int aci_vendor;
76 int aci_product;
77 int aci_version;
78 int aci_amp;
79 int aci_preamp;
80 int aci_solomode;
81
82 struct mutex aci_mutex;
83};
84
85int snd_aci_cmd(struct snd_miro_aci *aci, int write1, int write2, int write3);
86
87struct snd_miro_aci *snd_aci_get_aci(void);
88
89#endif /* _ACI_H_ */
90
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index db4a4fbdc5ca..e374869e3e21 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -40,7 +40,7 @@
40#define SNDRV_LEGACY_FIND_FREE_IRQ 40#define SNDRV_LEGACY_FIND_FREE_IRQ
41#define SNDRV_LEGACY_FIND_FREE_DMA 41#define SNDRV_LEGACY_FIND_FREE_DMA
42#include <sound/initval.h> 42#include <sound/initval.h>
43#include "miro.h" 43#include <sound/aci.h>
44 44
45MODULE_AUTHOR("Martin Langer <martin-langer@gmx.de>"); 45MODULE_AUTHOR("Martin Langer <martin-langer@gmx.de>");
46MODULE_LICENSE("GPL"); 46MODULE_LICENSE("GPL");
@@ -96,7 +96,6 @@ MODULE_PARM_DESC(ide, "enable ide port");
96 96
97#define OPTi9XX_MC_REG(n) n 97#define OPTi9XX_MC_REG(n) n
98 98
99
100struct snd_miro { 99struct snd_miro {
101 unsigned short hardware; 100 unsigned short hardware;
102 unsigned char password; 101 unsigned char password;
@@ -120,17 +119,11 @@ struct snd_miro {
120 long mpu_port; 119 long mpu_port;
121 int mpu_irq; 120 int mpu_irq;
122 121
123 unsigned long aci_port; 122 struct snd_miro_aci *aci;
124 int aci_vendor;
125 int aci_product;
126 int aci_version;
127 int aci_amp;
128 int aci_preamp;
129 int aci_solomode;
130
131 struct mutex aci_mutex;
132}; 123};
133 124
125static struct snd_miro_aci aci_device;
126
134static char * snd_opti9xx_names[] = { 127static char * snd_opti9xx_names[] = {
135 "unkown", 128 "unkown",
136 "82C928", "82C929", 129 "82C928", "82C929",
@@ -142,13 +135,14 @@ static char * snd_opti9xx_names[] = {
142 * ACI control 135 * ACI control
143 */ 136 */
144 137
145static int aci_busy_wait(struct snd_miro * miro) 138static int aci_busy_wait(struct snd_miro_aci *aci)
146{ 139{
147 long timeout; 140 long timeout;
148 unsigned char byte; 141 unsigned char byte;
149 142
150 for (timeout = 1; timeout <= ACI_MINTIME+30; timeout++) { 143 for (timeout = 1; timeout <= ACI_MINTIME + 30; timeout++) {
151 if (((byte=inb(miro->aci_port + ACI_REG_BUSY)) & 1) == 0) { 144 byte = inb(aci->aci_port + ACI_REG_BUSY);
145 if ((byte & 1) == 0) {
152 if (timeout >= ACI_MINTIME) 146 if (timeout >= ACI_MINTIME)
153 snd_printd("aci ready in round %ld.\n", 147 snd_printd("aci ready in round %ld.\n",
154 timeout-ACI_MINTIME); 148 timeout-ACI_MINTIME);
@@ -174,10 +168,10 @@ static int aci_busy_wait(struct snd_miro * miro)
174 return -EBUSY; 168 return -EBUSY;
175} 169}
176 170
177static inline int aci_write(struct snd_miro * miro, unsigned char byte) 171static inline int aci_write(struct snd_miro_aci *aci, unsigned char byte)
178{ 172{
179 if (aci_busy_wait(miro) >= 0) { 173 if (aci_busy_wait(aci) >= 0) {
180 outb(byte, miro->aci_port + ACI_REG_COMMAND); 174 outb(byte, aci->aci_port + ACI_REG_COMMAND);
181 return 0; 175 return 0;
182 } else { 176 } else {
183 snd_printk(KERN_ERR "aci busy, aci_write(0x%x) stopped.\n", byte); 177 snd_printk(KERN_ERR "aci busy, aci_write(0x%x) stopped.\n", byte);
@@ -185,12 +179,12 @@ static inline int aci_write(struct snd_miro * miro, unsigned char byte)
185 } 179 }
186} 180}
187 181
188static inline int aci_read(struct snd_miro * miro) 182static inline int aci_read(struct snd_miro_aci *aci)
189{ 183{
190 unsigned char byte; 184 unsigned char byte;
191 185
192 if (aci_busy_wait(miro) >= 0) { 186 if (aci_busy_wait(aci) >= 0) {
193 byte=inb(miro->aci_port + ACI_REG_STATUS); 187 byte = inb(aci->aci_port + ACI_REG_STATUS);
194 return byte; 188 return byte;
195 } else { 189 } else {
196 snd_printk(KERN_ERR "aci busy, aci_read() stopped.\n"); 190 snd_printk(KERN_ERR "aci busy, aci_read() stopped.\n");
@@ -198,39 +192,49 @@ static inline int aci_read(struct snd_miro * miro)
198 } 192 }
199} 193}
200 194
201static int aci_cmd(struct snd_miro * miro, int write1, int write2, int write3) 195int snd_aci_cmd(struct snd_miro_aci *aci, int write1, int write2, int write3)
202{ 196{
203 int write[] = {write1, write2, write3}; 197 int write[] = {write1, write2, write3};
204 int value, i; 198 int value, i;
205 199
206 if (mutex_lock_interruptible(&miro->aci_mutex)) 200 if (mutex_lock_interruptible(&aci->aci_mutex))
207 return -EINTR; 201 return -EINTR;
208 202
209 for (i=0; i<3; i++) { 203 for (i=0; i<3; i++) {
210 if (write[i]< 0 || write[i] > 255) 204 if (write[i]< 0 || write[i] > 255)
211 break; 205 break;
212 else { 206 else {
213 value = aci_write(miro, write[i]); 207 value = aci_write(aci, write[i]);
214 if (value < 0) 208 if (value < 0)
215 goto out; 209 goto out;
216 } 210 }
217 } 211 }
218 212
219 value = aci_read(miro); 213 value = aci_read(aci);
220 214
221out: mutex_unlock(&miro->aci_mutex); 215out: mutex_unlock(&aci->aci_mutex);
222 return value; 216 return value;
223} 217}
218EXPORT_SYMBOL(snd_aci_cmd);
219
220static int aci_getvalue(struct snd_miro_aci *aci, unsigned char index)
221{
222 return snd_aci_cmd(aci, ACI_STATUS, index, -1);
223}
224 224
225static int aci_getvalue(struct snd_miro * miro, unsigned char index) 225static int aci_setvalue(struct snd_miro_aci *aci, unsigned char index,
226 int value)
226{ 227{
227 return aci_cmd(miro, ACI_STATUS, index, -1); 228 return snd_aci_cmd(aci, index, value, -1);
228} 229}
229 230
230static int aci_setvalue(struct snd_miro * miro, unsigned char index, int value) 231struct snd_miro_aci *snd_aci_get_aci(void)
231{ 232{
232 return aci_cmd(miro, index, value, -1); 233 if (aci_device.aci_port == 0)
234 return NULL;
235 return &aci_device;
233} 236}
237EXPORT_SYMBOL(snd_aci_get_aci);
234 238
235/* 239/*
236 * MIXER part 240 * MIXER part
@@ -244,8 +248,10 @@ static int snd_miro_get_capture(struct snd_kcontrol *kcontrol,
244 struct snd_miro *miro = snd_kcontrol_chip(kcontrol); 248 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
245 int value; 249 int value;
246 250
247 if ((value = aci_getvalue(miro, ACI_S_GENERAL)) < 0) { 251 value = aci_getvalue(miro->aci, ACI_S_GENERAL);
248 snd_printk(KERN_ERR "snd_miro_get_capture() failed: %d\n", value); 252 if (value < 0) {
253 snd_printk(KERN_ERR "snd_miro_get_capture() failed: %d\n",
254 value);
249 return value; 255 return value;
250 } 256 }
251 257
@@ -262,13 +268,15 @@ static int snd_miro_put_capture(struct snd_kcontrol *kcontrol,
262 268
263 value = !(ucontrol->value.integer.value[0]); 269 value = !(ucontrol->value.integer.value[0]);
264 270
265 if ((error = aci_setvalue(miro, ACI_SET_SOLOMODE, value)) < 0) { 271 error = aci_setvalue(miro->aci, ACI_SET_SOLOMODE, value);
266 snd_printk(KERN_ERR "snd_miro_put_capture() failed: %d\n", error); 272 if (error < 0) {
273 snd_printk(KERN_ERR "snd_miro_put_capture() failed: %d\n",
274 error);
267 return error; 275 return error;
268 } 276 }
269 277
270 change = (value != miro->aci_solomode); 278 change = (value != miro->aci->aci_solomode);
271 miro->aci_solomode = value; 279 miro->aci->aci_solomode = value;
272 280
273 return change; 281 return change;
274} 282}
@@ -290,7 +298,7 @@ static int snd_miro_get_preamp(struct snd_kcontrol *kcontrol,
290 struct snd_miro *miro = snd_kcontrol_chip(kcontrol); 298 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
291 int value; 299 int value;
292 300
293 if (miro->aci_version <= 176) { 301 if (miro->aci->aci_version <= 176) {
294 302
295 /* 303 /*
296 OSS says it's not readable with versions < 176. 304 OSS says it's not readable with versions < 176.
@@ -298,12 +306,14 @@ static int snd_miro_get_preamp(struct snd_kcontrol *kcontrol,
298 which is a PCM12 with aci_version = 176. 306 which is a PCM12 with aci_version = 176.
299 */ 307 */
300 308
301 ucontrol->value.integer.value[0] = miro->aci_preamp; 309 ucontrol->value.integer.value[0] = miro->aci->aci_preamp;
302 return 0; 310 return 0;
303 } 311 }
304 312
305 if ((value = aci_getvalue(miro, ACI_GET_PREAMP)) < 0) { 313 value = aci_getvalue(miro->aci, ACI_GET_PREAMP);
306 snd_printk(KERN_ERR "snd_miro_get_preamp() failed: %d\n", value); 314 if (value < 0) {
315 snd_printk(KERN_ERR "snd_miro_get_preamp() failed: %d\n",
316 value);
307 return value; 317 return value;
308 } 318 }
309 319
@@ -320,13 +330,15 @@ static int snd_miro_put_preamp(struct snd_kcontrol *kcontrol,
320 330
321 value = ucontrol->value.integer.value[0]; 331 value = ucontrol->value.integer.value[0];
322 332
323 if ((error = aci_setvalue(miro, ACI_SET_PREAMP, value)) < 0) { 333 error = aci_setvalue(miro->aci, ACI_SET_PREAMP, value);
324 snd_printk(KERN_ERR "snd_miro_put_preamp() failed: %d\n", error); 334 if (error < 0) {
335 snd_printk(KERN_ERR "snd_miro_put_preamp() failed: %d\n",
336 error);
325 return error; 337 return error;
326 } 338 }
327 339
328 change = (value != miro->aci_preamp); 340 change = (value != miro->aci->aci_preamp);
329 miro->aci_preamp = value; 341 miro->aci->aci_preamp = value;
330 342
331 return change; 343 return change;
332} 344}
@@ -337,7 +349,7 @@ static int snd_miro_get_amp(struct snd_kcontrol *kcontrol,
337 struct snd_ctl_elem_value *ucontrol) 349 struct snd_ctl_elem_value *ucontrol)
338{ 350{
339 struct snd_miro *miro = snd_kcontrol_chip(kcontrol); 351 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
340 ucontrol->value.integer.value[0] = miro->aci_amp; 352 ucontrol->value.integer.value[0] = miro->aci->aci_amp;
341 353
342 return 0; 354 return 0;
343} 355}
@@ -350,13 +362,14 @@ static int snd_miro_put_amp(struct snd_kcontrol *kcontrol,
350 362
351 value = ucontrol->value.integer.value[0]; 363 value = ucontrol->value.integer.value[0];
352 364
353 if ((error = aci_setvalue(miro, ACI_SET_POWERAMP, value)) < 0) { 365 error = aci_setvalue(miro->aci, ACI_SET_POWERAMP, value);
366 if (error < 0) {
354 snd_printk(KERN_ERR "snd_miro_put_amp() to %d failed: %d\n", value, error); 367 snd_printk(KERN_ERR "snd_miro_put_amp() to %d failed: %d\n", value, error);
355 return error; 368 return error;
356 } 369 }
357 370
358 change = (value != miro->aci_amp); 371 change = (value != miro->aci->aci_amp);
359 miro->aci_amp = value; 372 miro->aci->aci_amp = value;
360 373
361 return change; 374 return change;
362} 375}
@@ -405,12 +418,14 @@ static int snd_miro_get_double(struct snd_kcontrol *kcontrol,
405 int right_reg = kcontrol->private_value & 0xff; 418 int right_reg = kcontrol->private_value & 0xff;
406 int left_reg = right_reg + 1; 419 int left_reg = right_reg + 1;
407 420
408 if ((right_val = aci_getvalue(miro, right_reg)) < 0) { 421 right_val = aci_getvalue(miro->aci, right_reg);
422 if (right_val < 0) {
409 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", right_reg, right_val); 423 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", right_reg, right_val);
410 return right_val; 424 return right_val;
411 } 425 }
412 426
413 if ((left_val = aci_getvalue(miro, left_reg)) < 0) { 427 left_val = aci_getvalue(miro->aci, left_reg);
428 if (left_val < 0) {
414 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", left_reg, left_val); 429 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", left_reg, left_val);
415 return left_val; 430 return left_val;
416 } 431 }
@@ -446,6 +461,7 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
446 struct snd_ctl_elem_value *ucontrol) 461 struct snd_ctl_elem_value *ucontrol)
447{ 462{
448 struct snd_miro *miro = snd_kcontrol_chip(kcontrol); 463 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
464 struct snd_miro_aci *aci = miro->aci;
449 int left, right, left_old, right_old; 465 int left, right, left_old, right_old;
450 int setreg_left, setreg_right, getreg_left, getreg_right; 466 int setreg_left, setreg_right, getreg_left, getreg_right;
451 int change, error; 467 int change, error;
@@ -461,12 +477,14 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
461 getreg_right = kcontrol->private_value & 0xff; 477 getreg_right = kcontrol->private_value & 0xff;
462 getreg_left = getreg_right + 1; 478 getreg_left = getreg_right + 1;
463 479
464 if ((left_old = aci_getvalue(miro, getreg_left)) < 0) { 480 left_old = aci_getvalue(aci, getreg_left);
481 if (left_old < 0) {
465 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_left, left_old); 482 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_left, left_old);
466 return left_old; 483 return left_old;
467 } 484 }
468 485
469 if ((right_old = aci_getvalue(miro, getreg_right)) < 0) { 486 right_old = aci_getvalue(aci, getreg_right);
487 if (right_old < 0) {
470 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_right, right_old); 488 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_right, right_old);
471 return right_old; 489 return right_old;
472 } 490 }
@@ -485,13 +503,15 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
485 right_old = 0x80 - right_old; 503 right_old = 0x80 - right_old;
486 504
487 if (left >= 0) { 505 if (left >= 0) {
488 if ((error = aci_setvalue(miro, setreg_left, left)) < 0) { 506 error = aci_setvalue(aci, setreg_left, left);
507 if (error < 0) {
489 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 508 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
490 left, error); 509 left, error);
491 return error; 510 return error;
492 } 511 }
493 } else { 512 } else {
494 if ((error = aci_setvalue(miro, setreg_left, 0x80 - left)) < 0) { 513 error = aci_setvalue(aci, setreg_left, 0x80 - left);
514 if (error < 0) {
495 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 515 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
496 0x80 - left, error); 516 0x80 - left, error);
497 return error; 517 return error;
@@ -499,13 +519,15 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
499 } 519 }
500 520
501 if (right >= 0) { 521 if (right >= 0) {
502 if ((error = aci_setvalue(miro, setreg_right, right)) < 0) { 522 error = aci_setvalue(aci, setreg_right, right);
523 if (error < 0) {
503 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 524 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
504 right, error); 525 right, error);
505 return error; 526 return error;
506 } 527 }
507 } else { 528 } else {
508 if ((error = aci_setvalue(miro, setreg_right, 0x80 - right)) < 0) { 529 error = aci_setvalue(aci, setreg_right, 0x80 - right);
530 if (error < 0) {
509 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 531 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
510 0x80 - right, error); 532 0x80 - right, error);
511 return error; 533 return error;
@@ -523,12 +545,14 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
523 left_old = 0x20 - left_old; 545 left_old = 0x20 - left_old;
524 right_old = 0x20 - right_old; 546 right_old = 0x20 - right_old;
525 547
526 if ((error = aci_setvalue(miro, setreg_left, 0x20 - left)) < 0) { 548 error = aci_setvalue(aci, setreg_left, 0x20 - left);
549 if (error < 0) {
527 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 550 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
528 0x20 - left, error); 551 0x20 - left, error);
529 return error; 552 return error;
530 } 553 }
531 if ((error = aci_setvalue(miro, setreg_right, 0x20 - right)) < 0) { 554 error = aci_setvalue(aci, setreg_right, 0x20 - right);
555 if (error < 0) {
532 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 556 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
533 0x20 - right, error); 557 0x20 - right, error);
534 return error; 558 return error;
@@ -626,11 +650,13 @@ static unsigned char aci_init_values[][2] __devinitdata = {
626static int __devinit snd_set_aci_init_values(struct snd_miro *miro) 650static int __devinit snd_set_aci_init_values(struct snd_miro *miro)
627{ 651{
628 int idx, error; 652 int idx, error;
653 struct snd_miro_aci *aci = miro->aci;
629 654
630 /* enable WSS on PCM1 */ 655 /* enable WSS on PCM1 */
631 656
632 if ((miro->aci_product == 'A') && wss) { 657 if ((aci->aci_product == 'A') && wss) {
633 if ((error = aci_setvalue(miro, ACI_SET_WSS, wss)) < 0) { 658 error = aci_setvalue(aci, ACI_SET_WSS, wss);
659 if (error < 0) {
634 snd_printk(KERN_ERR "enabling WSS mode failed\n"); 660 snd_printk(KERN_ERR "enabling WSS mode failed\n");
635 return error; 661 return error;
636 } 662 }
@@ -639,7 +665,8 @@ static int __devinit snd_set_aci_init_values(struct snd_miro *miro)
639 /* enable IDE port */ 665 /* enable IDE port */
640 666
641 if (ide) { 667 if (ide) {
642 if ((error = aci_setvalue(miro, ACI_SET_IDE, ide)) < 0) { 668 error = aci_setvalue(aci, ACI_SET_IDE, ide);
669 if (error < 0) {
643 snd_printk(KERN_ERR "enabling IDE port failed\n"); 670 snd_printk(KERN_ERR "enabling IDE port failed\n");
644 return error; 671 return error;
645 } 672 }
@@ -647,17 +674,18 @@ static int __devinit snd_set_aci_init_values(struct snd_miro *miro)
647 674
648 /* set common aci values */ 675 /* set common aci values */
649 676
650 for (idx = 0; idx < ARRAY_SIZE(aci_init_values); idx++) 677 for (idx = 0; idx < ARRAY_SIZE(aci_init_values); idx++) {
651 if ((error = aci_setvalue(miro, aci_init_values[idx][0], 678 error = aci_setvalue(aci, aci_init_values[idx][0],
652 aci_init_values[idx][1])) < 0) { 679 aci_init_values[idx][1]);
680 if (error < 0) {
653 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 681 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
654 aci_init_values[idx][0], error); 682 aci_init_values[idx][0], error);
655 return error; 683 return error;
656 } 684 }
657 685 }
658 miro->aci_amp = 0; 686 aci->aci_amp = 0;
659 miro->aci_preamp = 0; 687 aci->aci_preamp = 0;
660 miro->aci_solomode = 1; 688 aci->aci_solomode = 1;
661 689
662 return 0; 690 return 0;
663} 691}
@@ -688,7 +716,8 @@ static int __devinit snd_miro_mixer(struct snd_card *card,
688 return err; 716 return err;
689 } 717 }
690 718
691 if ((miro->aci_product == 'A') || (miro->aci_product == 'B')) { 719 if ((miro->aci->aci_product == 'A') ||
720 (miro->aci->aci_product == 'B')) {
692 /* PCM1/PCM12 with power-amp and Line 2 */ 721 /* PCM1/PCM12 with power-amp and Line 2 */
693 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_line_control[0], miro))) < 0) 722 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_line_control[0], miro))) < 0)
694 return err; 723 return err;
@@ -696,16 +725,17 @@ static int __devinit snd_miro_mixer(struct snd_card *card,
696 return err; 725 return err;
697 } 726 }
698 727
699 if ((miro->aci_product == 'B') || (miro->aci_product == 'C')) { 728 if ((miro->aci->aci_product == 'B') ||
729 (miro->aci->aci_product == 'C')) {
700 /* PCM12/PCM20 with mic-preamp */ 730 /* PCM12/PCM20 with mic-preamp */
701 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_preamp_control[0], miro))) < 0) 731 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_preamp_control[0], miro))) < 0)
702 return err; 732 return err;
703 if (miro->aci_version >= 176) 733 if (miro->aci->aci_version >= 176)
704 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_capture_control[0], miro))) < 0) 734 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_capture_control[0], miro))) < 0)
705 return err; 735 return err;
706 } 736 }
707 737
708 if (miro->aci_product == 'C') { 738 if (miro->aci->aci_product == 'C') {
709 /* PCM20 with radio and 7 band equalizer */ 739 /* PCM20 with radio and 7 band equalizer */
710 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_radio_control[0], miro))) < 0) 740 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_radio_control[0], miro))) < 0)
711 return err; 741 return err;
@@ -843,14 +873,15 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
843 struct snd_info_buffer *buffer) 873 struct snd_info_buffer *buffer)
844{ 874{
845 struct snd_miro *miro = (struct snd_miro *) entry->private_data; 875 struct snd_miro *miro = (struct snd_miro *) entry->private_data;
876 struct snd_miro_aci *aci = miro->aci;
846 char* model = "unknown"; 877 char* model = "unknown";
847 878
848 /* miroSOUND PCM1 pro, early PCM12 */ 879 /* miroSOUND PCM1 pro, early PCM12 */
849 880
850 if ((miro->hardware == OPTi9XX_HW_82C929) && 881 if ((miro->hardware == OPTi9XX_HW_82C929) &&
851 (miro->aci_vendor == 'm') && 882 (aci->aci_vendor == 'm') &&
852 (miro->aci_product == 'A')) { 883 (aci->aci_product == 'A')) {
853 switch(miro->aci_version) { 884 switch (aci->aci_version) {
854 case 3: 885 case 3:
855 model = "miroSOUND PCM1 pro"; 886 model = "miroSOUND PCM1 pro";
856 break; 887 break;
@@ -863,9 +894,9 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
863 /* miroSOUND PCM12, PCM12 (Rev. E), PCM12 pnp */ 894 /* miroSOUND PCM12, PCM12 (Rev. E), PCM12 pnp */
864 895
865 if ((miro->hardware == OPTi9XX_HW_82C924) && 896 if ((miro->hardware == OPTi9XX_HW_82C924) &&
866 (miro->aci_vendor == 'm') && 897 (aci->aci_vendor == 'm') &&
867 (miro->aci_product == 'B')) { 898 (aci->aci_product == 'B')) {
868 switch(miro->aci_version) { 899 switch (aci->aci_version) {
869 case 4: 900 case 4:
870 model = "miroSOUND PCM12"; 901 model = "miroSOUND PCM12";
871 break; 902 break;
@@ -881,9 +912,9 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
881 /* miroSOUND PCM20 radio */ 912 /* miroSOUND PCM20 radio */
882 913
883 if ((miro->hardware == OPTi9XX_HW_82C924) && 914 if ((miro->hardware == OPTi9XX_HW_82C924) &&
884 (miro->aci_vendor == 'm') && 915 (aci->aci_vendor == 'm') &&
885 (miro->aci_product == 'C')) { 916 (aci->aci_product == 'C')) {
886 switch(miro->aci_version) { 917 switch (aci->aci_version) {
887 case 7: 918 case 7:
888 model = "miroSOUND PCM20 radio (Rev. E)"; 919 model = "miroSOUND PCM20 radio (Rev. E)";
889 break; 920 break;
@@ -907,17 +938,17 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
907 938
908 snd_iprintf(buffer, "ACI information:\n"); 939 snd_iprintf(buffer, "ACI information:\n");
909 snd_iprintf(buffer, " vendor : "); 940 snd_iprintf(buffer, " vendor : ");
910 switch(miro->aci_vendor) { 941 switch (aci->aci_vendor) {
911 case 'm': 942 case 'm':
912 snd_iprintf(buffer, "Miro\n"); 943 snd_iprintf(buffer, "Miro\n");
913 break; 944 break;
914 default: 945 default:
915 snd_iprintf(buffer, "unknown (0x%x)\n", miro->aci_vendor); 946 snd_iprintf(buffer, "unknown (0x%x)\n", aci->aci_vendor);
916 break; 947 break;
917 } 948 }
918 949
919 snd_iprintf(buffer, " product : "); 950 snd_iprintf(buffer, " product : ");
920 switch(miro->aci_product) { 951 switch (aci->aci_product) {
921 case 'A': 952 case 'A':
922 snd_iprintf(buffer, "miroSOUND PCM1 pro / (early) PCM12\n"); 953 snd_iprintf(buffer, "miroSOUND PCM1 pro / (early) PCM12\n");
923 break; 954 break;
@@ -928,19 +959,19 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
928 snd_iprintf(buffer, "miroSOUND PCM20 radio\n"); 959 snd_iprintf(buffer, "miroSOUND PCM20 radio\n");
929 break; 960 break;
930 default: 961 default:
931 snd_iprintf(buffer, "unknown (0x%x)\n", miro->aci_product); 962 snd_iprintf(buffer, "unknown (0x%x)\n", aci->aci_product);
932 break; 963 break;
933 } 964 }
934 965
935 snd_iprintf(buffer, " firmware: %d (0x%x)\n", 966 snd_iprintf(buffer, " firmware: %d (0x%x)\n",
936 miro->aci_version, miro->aci_version); 967 aci->aci_version, aci->aci_version);
937 snd_iprintf(buffer, " port : 0x%lx-0x%lx\n", 968 snd_iprintf(buffer, " port : 0x%lx-0x%lx\n",
938 miro->aci_port, miro->aci_port+2); 969 aci->aci_port, aci->aci_port+2);
939 snd_iprintf(buffer, " wss : 0x%x\n", wss); 970 snd_iprintf(buffer, " wss : 0x%x\n", wss);
940 snd_iprintf(buffer, " ide : 0x%x\n", ide); 971 snd_iprintf(buffer, " ide : 0x%x\n", ide);
941 snd_iprintf(buffer, " solomode: 0x%x\n", miro->aci_solomode); 972 snd_iprintf(buffer, " solomode: 0x%x\n", aci->aci_solomode);
942 snd_iprintf(buffer, " amp : 0x%x\n", miro->aci_amp); 973 snd_iprintf(buffer, " amp : 0x%x\n", aci->aci_amp);
943 snd_iprintf(buffer, " preamp : 0x%x\n", miro->aci_preamp); 974 snd_iprintf(buffer, " preamp : 0x%x\n", aci->aci_preamp);
944} 975}
945 976
946static void __devinit snd_miro_proc_init(struct snd_card *card, 977static void __devinit snd_miro_proc_init(struct snd_card *card,
@@ -1139,46 +1170,53 @@ static int __devinit snd_card_miro_detect(struct snd_card *card,
1139} 1170}
1140 1171
1141static int __devinit snd_card_miro_aci_detect(struct snd_card *card, 1172static int __devinit snd_card_miro_aci_detect(struct snd_card *card,
1142 struct snd_miro * miro) 1173 struct snd_miro *miro)
1143{ 1174{
1144 unsigned char regval; 1175 unsigned char regval;
1145 int i; 1176 int i;
1177 struct snd_miro_aci *aci = &aci_device;
1178
1179 miro->aci = aci;
1146 1180
1147 mutex_init(&miro->aci_mutex); 1181 mutex_init(&aci->aci_mutex);
1148 1182
1149 /* get ACI port from OPTi9xx MC 4 */ 1183 /* get ACI port from OPTi9xx MC 4 */
1150 1184
1151 regval=inb(miro->mc_base + 4); 1185 regval=inb(miro->mc_base + 4);
1152 miro->aci_port = (regval & 0x10) ? 0x344: 0x354; 1186 aci->aci_port = (regval & 0x10) ? 0x344 : 0x354;
1153 1187
1154 if ((miro->res_aci_port = request_region(miro->aci_port, 3, "miro aci")) == NULL) { 1188 miro->res_aci_port = request_region(aci->aci_port, 3, "miro aci");
1189 if (miro->res_aci_port == NULL) {
1155 snd_printk(KERN_ERR "aci i/o area 0x%lx-0x%lx already used.\n", 1190 snd_printk(KERN_ERR "aci i/o area 0x%lx-0x%lx already used.\n",
1156 miro->aci_port, miro->aci_port+2); 1191 aci->aci_port, aci->aci_port+2);
1157 return -ENOMEM; 1192 return -ENOMEM;
1158 } 1193 }
1159 1194
1160 /* force ACI into a known state */ 1195 /* force ACI into a known state */
1161 for (i = 0; i < 3; i++) 1196 for (i = 0; i < 3; i++)
1162 if (aci_cmd(miro, ACI_ERROR_OP, -1, -1) < 0) { 1197 if (snd_aci_cmd(aci, ACI_ERROR_OP, -1, -1) < 0) {
1163 snd_printk(KERN_ERR "can't force aci into known state.\n"); 1198 snd_printk(KERN_ERR "can't force aci into known state.\n");
1164 return -ENXIO; 1199 return -ENXIO;
1165 } 1200 }
1166 1201
1167 if ((miro->aci_vendor=aci_cmd(miro, ACI_READ_IDCODE, -1, -1)) < 0 || 1202 aci->aci_vendor = snd_aci_cmd(aci, ACI_READ_IDCODE, -1, -1);
1168 (miro->aci_product=aci_cmd(miro, ACI_READ_IDCODE, -1, -1)) < 0) { 1203 aci->aci_product = snd_aci_cmd(aci, ACI_READ_IDCODE, -1, -1);
1169 snd_printk(KERN_ERR "can't read aci id on 0x%lx.\n", miro->aci_port); 1204 if (aci->aci_vendor < 0 || aci->aci_product < 0) {
1205 snd_printk(KERN_ERR "can't read aci id on 0x%lx.\n",
1206 aci->aci_port);
1170 return -ENXIO; 1207 return -ENXIO;
1171 } 1208 }
1172 1209
1173 if ((miro->aci_version=aci_cmd(miro, ACI_READ_VERSION, -1, -1)) < 0) { 1210 aci->aci_version = snd_aci_cmd(aci, ACI_READ_VERSION, -1, -1);
1211 if (aci->aci_version < 0) {
1174 snd_printk(KERN_ERR "can't read aci version on 0x%lx.\n", 1212 snd_printk(KERN_ERR "can't read aci version on 0x%lx.\n",
1175 miro->aci_port); 1213 aci->aci_port);
1176 return -ENXIO; 1214 return -ENXIO;
1177 } 1215 }
1178 1216
1179 if (aci_cmd(miro, ACI_INIT, -1, -1) < 0 || 1217 if (snd_aci_cmd(aci, ACI_INIT, -1, -1) < 0 ||
1180 aci_cmd(miro, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0 || 1218 snd_aci_cmd(aci, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0 ||
1181 aci_cmd(miro, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0) { 1219 snd_aci_cmd(aci, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0) {
1182 snd_printk(KERN_ERR "can't initialize aci.\n"); 1220 snd_printk(KERN_ERR "can't initialize aci.\n");
1183 return -ENXIO; 1221 return -ENXIO;
1184 } 1222 }
@@ -1191,6 +1229,8 @@ static void snd_card_miro_free(struct snd_card *card)
1191 struct snd_miro *miro = card->private_data; 1229 struct snd_miro *miro = card->private_data;
1192 1230
1193 release_and_free_resource(miro->res_aci_port); 1231 release_and_free_resource(miro->res_aci_port);
1232 if (miro->aci)
1233 miro->aci->aci_port = 0;
1194 release_and_free_resource(miro->res_mc_base); 1234 release_and_free_resource(miro->res_mc_base);
1195} 1235}
1196 1236
@@ -1250,7 +1290,6 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
1250 } 1290 }
1251 1291
1252 miro->wss_base = port; 1292 miro->wss_base = port;
1253 miro->mpu_port = mpu_port;
1254 miro->irq = irq; 1293 miro->irq = irq;
1255 miro->mpu_irq = mpu_irq; 1294 miro->mpu_irq = mpu_irq;
1256 miro->dma1 = dma1; 1295 miro->dma1 = dma1;
@@ -1272,6 +1311,8 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
1272 return -EBUSY; 1311 return -EBUSY;
1273 } 1312 }
1274 } 1313 }
1314 miro->mpu_port = mpu_port;
1315
1275 if (miro->irq == SNDRV_AUTO_IRQ) { 1316 if (miro->irq == SNDRV_AUTO_IRQ) {
1276 if ((miro->irq = snd_legacy_find_free_irq(possible_irqs)) < 0) { 1317 if ((miro->irq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
1277 snd_card_free(card); 1318 snd_card_free(card);
@@ -1339,9 +1380,9 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
1339 return error; 1380 return error;
1340 } 1381 }
1341 1382
1342 if (miro->aci_vendor == 'm') { 1383 if (miro->aci->aci_vendor == 'm') {
1343 /* It looks like a miro sound card. */ 1384 /* It looks like a miro sound card. */
1344 switch (miro->aci_product) { 1385 switch (miro->aci->aci_product) {
1345 case 'A': 1386 case 'A':
1346 sprintf(card->shortname, 1387 sprintf(card->shortname,
1347 "miroSOUND PCM1 pro / PCM12"); 1388 "miroSOUND PCM1 pro / PCM12");