aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2009-11-22 11:26:34 -0500
committerTakashi Iwai <tiwai@suse.de>2009-11-23 03:41:55 -0500
commit9dc9120c774e1d7e3d939542200bd44829c0059d (patch)
treebea8fba16b39633911bdd99606e318a24f9a0ef5
parent9aeba6297151abcb1b34f3237e4c028aae500ce4 (diff)
ALSA: opti-miro: expose ACI mixer to outside drivers
The ACI mixer is used to control the radio FM module installed on the Miro PCM20 sound card. Expose ACI mixer outside the sound card driver. Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--include/sound/aci.h17
-rw-r--r--sound/isa/opti9xx/miro.c250
2 files changed, 162 insertions, 105 deletions
diff --git a/include/sound/aci.h b/include/sound/aci.h
index bb796d06d0f..ee639d355ef 100644
--- a/include/sound/aci.h
+++ b/include/sound/aci.h
@@ -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
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
73#endif /* _ACI_H_ */ 89#endif /* _ACI_H_ */
90
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index 932a067ef98..40b64cd54c8 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -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,7 @@ 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 miro->aci->aci_port = 0;
1194 release_and_free_resource(miro->res_mc_base); 1233 release_and_free_resource(miro->res_mc_base);
1195} 1234}
1196 1235
@@ -1250,7 +1289,6 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
1250 } 1289 }
1251 1290
1252 miro->wss_base = port; 1291 miro->wss_base = port;
1253 miro->mpu_port = mpu_port;
1254 miro->irq = irq; 1292 miro->irq = irq;
1255 miro->mpu_irq = mpu_irq; 1293 miro->mpu_irq = mpu_irq;
1256 miro->dma1 = dma1; 1294 miro->dma1 = dma1;
@@ -1272,6 +1310,8 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
1272 return -EBUSY; 1310 return -EBUSY;
1273 } 1311 }
1274 } 1312 }
1313 miro->mpu_port = mpu_port;
1314
1275 if (miro->irq == SNDRV_AUTO_IRQ) { 1315 if (miro->irq == SNDRV_AUTO_IRQ) {
1276 if ((miro->irq = snd_legacy_find_free_irq(possible_irqs)) < 0) { 1316 if ((miro->irq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
1277 snd_card_free(card); 1317 snd_card_free(card);
@@ -1339,9 +1379,9 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
1339 return error; 1379 return error;
1340 } 1380 }
1341 1381
1342 if (miro->aci_vendor == 'm') { 1382 if (miro->aci->aci_vendor == 'm') {
1343 /* It looks like a miro sound card. */ 1383 /* It looks like a miro sound card. */
1344 switch (miro->aci_product) { 1384 switch (miro->aci->aci_product) {
1345 case 'A': 1385 case 'A':
1346 sprintf(card->shortname, 1386 sprintf(card->shortname,
1347 "miroSOUND PCM1 pro / PCM12"); 1387 "miroSOUND PCM1 pro / PCM12");