diff options
-rw-r--r-- | include/sound/aci.h | 17 | ||||
-rw-r--r-- | sound/isa/opti9xx/miro.c | 250 |
2 files changed, 162 insertions, 105 deletions
diff --git a/include/sound/aci.h b/include/sound/aci.h index bb796d06d0f2..ee639d355ef0 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 | ||
73 | struct 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 | |||
85 | int snd_aci_cmd(struct snd_miro_aci *aci, int write1, int write2, int write3); | ||
86 | |||
87 | struct 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 932a067ef980..40b64cd54c85 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 | |||
100 | struct snd_miro { | 99 | struct 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 | ||
125 | static struct snd_miro_aci aci_device; | ||
126 | |||
134 | static char * snd_opti9xx_names[] = { | 127 | static 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 | ||
145 | static int aci_busy_wait(struct snd_miro * miro) | 138 | static 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 | ||
177 | static inline int aci_write(struct snd_miro * miro, unsigned char byte) | 171 | static 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 | ||
188 | static inline int aci_read(struct snd_miro * miro) | 182 | static 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 | ||
201 | static int aci_cmd(struct snd_miro * miro, int write1, int write2, int write3) | 195 | int 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 | ||
221 | out: mutex_unlock(&miro->aci_mutex); | 215 | out: mutex_unlock(&aci->aci_mutex); |
222 | return value; | 216 | return value; |
223 | } | 217 | } |
218 | EXPORT_SYMBOL(snd_aci_cmd); | ||
219 | |||
220 | static 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 | ||
225 | static int aci_getvalue(struct snd_miro * miro, unsigned char index) | 225 | static 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 | ||
230 | static int aci_setvalue(struct snd_miro * miro, unsigned char index, int value) | 231 | struct 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 | } |
237 | EXPORT_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 = { | |||
626 | static int __devinit snd_set_aci_init_values(struct snd_miro *miro) | 650 | static 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 | ||
946 | static void __devinit snd_miro_proc_init(struct snd_card *card, | 977 | static 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 | ||
1141 | static int __devinit snd_card_miro_aci_detect(struct snd_card *card, | 1172 | static 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"); |