diff options
Diffstat (limited to 'sound/sparc')
-rw-r--r-- | sound/sparc/cs4231.c | 204 |
1 files changed, 73 insertions, 131 deletions
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index f2950cab74a6..ddc0f2e082d6 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c | |||
@@ -30,17 +30,11 @@ | |||
30 | 30 | ||
31 | #ifdef CONFIG_SBUS | 31 | #ifdef CONFIG_SBUS |
32 | #define SBUS_SUPPORT | 32 | #define SBUS_SUPPORT |
33 | #endif | ||
34 | |||
35 | #ifdef SBUS_SUPPORT | ||
36 | #include <asm/sbus.h> | 33 | #include <asm/sbus.h> |
37 | #endif | 34 | #endif |
38 | 35 | ||
39 | #if defined(CONFIG_PCI) && defined(CONFIG_SPARC64) | 36 | #if defined(CONFIG_PCI) && defined(CONFIG_SPARC64) |
40 | #define EBUS_SUPPORT | 37 | #define EBUS_SUPPORT |
41 | #endif | ||
42 | |||
43 | #ifdef EBUS_SUPPORT | ||
44 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
45 | #include <asm/ebus.h> | 39 | #include <asm/ebus.h> |
46 | #endif | 40 | #endif |
@@ -339,7 +333,7 @@ static unsigned int rates[14] = { | |||
339 | }; | 333 | }; |
340 | 334 | ||
341 | static struct snd_pcm_hw_constraint_list hw_constraints_rates = { | 335 | static struct snd_pcm_hw_constraint_list hw_constraints_rates = { |
342 | .count = 14, | 336 | .count = ARRAY_SIZE(rates), |
343 | .list = rates, | 337 | .list = rates, |
344 | }; | 338 | }; |
345 | 339 | ||
@@ -389,116 +383,85 @@ static unsigned char snd_cs4231_original_image[32] = | |||
389 | static u8 __cs4231_readb(struct snd_cs4231 *cp, void __iomem *reg_addr) | 383 | static u8 __cs4231_readb(struct snd_cs4231 *cp, void __iomem *reg_addr) |
390 | { | 384 | { |
391 | #ifdef EBUS_SUPPORT | 385 | #ifdef EBUS_SUPPORT |
392 | if (cp->flags & CS4231_FLAG_EBUS) { | 386 | if (cp->flags & CS4231_FLAG_EBUS) |
393 | return readb(reg_addr); | 387 | return readb(reg_addr); |
394 | } else { | 388 | else |
395 | #endif | 389 | #endif |
396 | #ifdef SBUS_SUPPORT | 390 | #ifdef SBUS_SUPPORT |
397 | return sbus_readb(reg_addr); | 391 | return sbus_readb(reg_addr); |
398 | #endif | 392 | #endif |
399 | #ifdef EBUS_SUPPORT | ||
400 | } | ||
401 | #endif | ||
402 | } | 393 | } |
403 | 394 | ||
404 | static void __cs4231_writeb(struct snd_cs4231 *cp, u8 val, void __iomem *reg_addr) | 395 | static void __cs4231_writeb(struct snd_cs4231 *cp, u8 val, void __iomem *reg_addr) |
405 | { | 396 | { |
406 | #ifdef EBUS_SUPPORT | 397 | #ifdef EBUS_SUPPORT |
407 | if (cp->flags & CS4231_FLAG_EBUS) { | 398 | if (cp->flags & CS4231_FLAG_EBUS) |
408 | return writeb(val, reg_addr); | 399 | return writeb(val, reg_addr); |
409 | } else { | 400 | else |
410 | #endif | 401 | #endif |
411 | #ifdef SBUS_SUPPORT | 402 | #ifdef SBUS_SUPPORT |
412 | return sbus_writeb(val, reg_addr); | 403 | return sbus_writeb(val, reg_addr); |
413 | #endif | 404 | #endif |
414 | #ifdef EBUS_SUPPORT | ||
415 | } | ||
416 | #endif | ||
417 | } | 405 | } |
418 | 406 | ||
419 | /* | 407 | /* |
420 | * Basic I/O functions | 408 | * Basic I/O functions |
421 | */ | 409 | */ |
422 | 410 | ||
423 | static void snd_cs4231_outm(struct snd_cs4231 *chip, unsigned char reg, | 411 | static void snd_cs4231_ready(struct snd_cs4231 *chip) |
424 | unsigned char mask, unsigned char value) | ||
425 | { | 412 | { |
426 | int timeout; | 413 | int timeout; |
427 | unsigned char tmp; | ||
428 | 414 | ||
429 | for (timeout = 250; | 415 | for (timeout = 250; |
430 | timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT); | 416 | timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT); |
431 | timeout--) | 417 | timeout--) |
432 | udelay(100); | 418 | udelay(100); |
433 | #ifdef CONFIG_SND_DEBUG | ||
434 | if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) | ||
435 | snd_printdd("outm: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value); | ||
436 | #endif | ||
437 | if (chip->calibrate_mute) { | ||
438 | chip->image[reg] &= mask; | ||
439 | chip->image[reg] |= value; | ||
440 | } else { | ||
441 | __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL)); | ||
442 | mb(); | ||
443 | tmp = (chip->image[reg] & mask) | value; | ||
444 | __cs4231_writeb(chip, tmp, CS4231P(chip, REG)); | ||
445 | chip->image[reg] = tmp; | ||
446 | mb(); | ||
447 | } | ||
448 | } | 419 | } |
449 | 420 | ||
450 | static void snd_cs4231_dout(struct snd_cs4231 *chip, unsigned char reg, unsigned char value) | 421 | static void snd_cs4231_dout(struct snd_cs4231 *chip, unsigned char reg, unsigned char value) |
451 | { | 422 | { |
452 | int timeout; | 423 | snd_cs4231_ready(chip); |
453 | |||
454 | for (timeout = 250; | ||
455 | timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT); | ||
456 | timeout--) | ||
457 | udelay(100); | ||
458 | #ifdef CONFIG_SND_DEBUG | 424 | #ifdef CONFIG_SND_DEBUG |
459 | if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) | 425 | if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) |
460 | snd_printdd("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value); | 426 | snd_printdd("out: auto calibration time out - reg = 0x%x, " |
427 | "value = 0x%x\n", | ||
428 | reg, value); | ||
461 | #endif | 429 | #endif |
462 | __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL)); | 430 | __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL)); |
431 | wmb(); | ||
463 | __cs4231_writeb(chip, value, CS4231P(chip, REG)); | 432 | __cs4231_writeb(chip, value, CS4231P(chip, REG)); |
464 | mb(); | 433 | mb(); |
465 | } | 434 | } |
466 | 435 | ||
467 | static void snd_cs4231_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char value) | 436 | static inline void snd_cs4231_outm(struct snd_cs4231 *chip, unsigned char reg, |
437 | unsigned char mask, unsigned char value) | ||
468 | { | 438 | { |
469 | int timeout; | 439 | unsigned char tmp = (chip->image[reg] & mask) | value; |
470 | 440 | ||
471 | for (timeout = 250; | 441 | chip->image[reg] = tmp; |
472 | timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT); | 442 | if (!chip->calibrate_mute) |
473 | timeout--) | 443 | snd_cs4231_dout(chip, reg, tmp); |
474 | udelay(100); | 444 | } |
475 | #ifdef CONFIG_SND_DEBUG | 445 | |
476 | if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) | 446 | static void snd_cs4231_out(struct snd_cs4231 *chip, unsigned char reg, |
477 | snd_printdd("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value); | 447 | unsigned char value) |
478 | #endif | 448 | { |
479 | __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL)); | 449 | snd_cs4231_dout(chip, reg, value); |
480 | __cs4231_writeb(chip, value, CS4231P(chip, REG)); | ||
481 | chip->image[reg] = value; | 450 | chip->image[reg] = value; |
482 | mb(); | 451 | mb(); |
483 | } | 452 | } |
484 | 453 | ||
485 | static unsigned char snd_cs4231_in(struct snd_cs4231 *chip, unsigned char reg) | 454 | static unsigned char snd_cs4231_in(struct snd_cs4231 *chip, unsigned char reg) |
486 | { | 455 | { |
487 | int timeout; | 456 | snd_cs4231_ready(chip); |
488 | unsigned char ret; | ||
489 | |||
490 | for (timeout = 250; | ||
491 | timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT); | ||
492 | timeout--) | ||
493 | udelay(100); | ||
494 | #ifdef CONFIG_SND_DEBUG | 457 | #ifdef CONFIG_SND_DEBUG |
495 | if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) | 458 | if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) |
496 | snd_printdd("in: auto calibration time out - reg = 0x%x\n", reg); | 459 | snd_printdd("in: auto calibration time out - reg = 0x%x\n", |
460 | reg); | ||
497 | #endif | 461 | #endif |
498 | __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL)); | 462 | __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL)); |
499 | mb(); | 463 | mb(); |
500 | ret = __cs4231_readb(chip, CS4231P(chip, REG)); | 464 | return __cs4231_readb(chip, CS4231P(chip, REG)); |
501 | return ret; | ||
502 | } | 465 | } |
503 | 466 | ||
504 | /* | 467 | /* |
@@ -517,7 +480,7 @@ static void snd_cs4231_busy_wait(struct snd_cs4231 *chip) | |||
517 | for (timeout = 500; | 480 | for (timeout = 500; |
518 | timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT); | 481 | timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT); |
519 | timeout--) | 482 | timeout--) |
520 | udelay(1000); | 483 | msleep(1); |
521 | } | 484 | } |
522 | 485 | ||
523 | static void snd_cs4231_mce_up(struct snd_cs4231 *chip) | 486 | static void snd_cs4231_mce_up(struct snd_cs4231 *chip) |
@@ -526,8 +489,7 @@ static void snd_cs4231_mce_up(struct snd_cs4231 *chip) | |||
526 | int timeout; | 489 | int timeout; |
527 | 490 | ||
528 | spin_lock_irqsave(&chip->lock, flags); | 491 | spin_lock_irqsave(&chip->lock, flags); |
529 | for (timeout = 250; timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT); timeout--) | 492 | snd_cs4231_ready(chip); |
530 | udelay(100); | ||
531 | #ifdef CONFIG_SND_DEBUG | 493 | #ifdef CONFIG_SND_DEBUG |
532 | if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) | 494 | if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) |
533 | snd_printdd("mce_up - auto calibration time out (0)\n"); | 495 | snd_printdd("mce_up - auto calibration time out (0)\n"); |
@@ -565,8 +527,8 @@ static void snd_cs4231_mce_down(struct snd_cs4231 *chip) | |||
565 | 527 | ||
566 | /* calibration process */ | 528 | /* calibration process */ |
567 | 529 | ||
568 | for (timeout = 500; timeout > 0 && (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) == 0; timeout--) | 530 | snd_cs4231_ready(chip); |
569 | udelay(100); | 531 | snd_cs4231_ready(chip); |
570 | if ((snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) == 0) { | 532 | if ((snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) == 0) { |
571 | snd_printd("cs4231_mce_down - auto calibration time out (1)\n"); | 533 | snd_printd("cs4231_mce_down - auto calibration time out (1)\n"); |
572 | spin_unlock_irqrestore(&chip->lock, flags); | 534 | spin_unlock_irqrestore(&chip->lock, flags); |
@@ -1058,11 +1020,6 @@ static int snd_cs4231_playback_hw_params(struct snd_pcm_substream *substream, | |||
1058 | return 0; | 1020 | return 0; |
1059 | } | 1021 | } |
1060 | 1022 | ||
1061 | static int snd_cs4231_playback_hw_free(struct snd_pcm_substream *substream) | ||
1062 | { | ||
1063 | return snd_pcm_lib_free_pages(substream); | ||
1064 | } | ||
1065 | |||
1066 | static int snd_cs4231_playback_prepare(struct snd_pcm_substream *substream) | 1023 | static int snd_cs4231_playback_prepare(struct snd_pcm_substream *substream) |
1067 | { | 1024 | { |
1068 | struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); | 1025 | struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); |
@@ -1100,11 +1057,6 @@ static int snd_cs4231_capture_hw_params(struct snd_pcm_substream *substream, | |||
1100 | return 0; | 1057 | return 0; |
1101 | } | 1058 | } |
1102 | 1059 | ||
1103 | static int snd_cs4231_capture_hw_free(struct snd_pcm_substream *substream) | ||
1104 | { | ||
1105 | return snd_pcm_lib_free_pages(substream); | ||
1106 | } | ||
1107 | |||
1108 | static int snd_cs4231_capture_prepare(struct snd_pcm_substream *substream) | 1060 | static int snd_cs4231_capture_prepare(struct snd_pcm_substream *substream) |
1109 | { | 1061 | { |
1110 | struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); | 1062 | struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); |
@@ -1182,10 +1134,6 @@ static snd_pcm_uframes_t snd_cs4231_capture_pointer(struct snd_pcm_substream *su | |||
1182 | return bytes_to_frames(substream->runtime, ptr); | 1134 | return bytes_to_frames(substream->runtime, ptr); |
1183 | } | 1135 | } |
1184 | 1136 | ||
1185 | /* | ||
1186 | |||
1187 | */ | ||
1188 | |||
1189 | static int __init snd_cs4231_probe(struct snd_cs4231 *chip) | 1137 | static int __init snd_cs4231_probe(struct snd_cs4231 *chip) |
1190 | { | 1138 | { |
1191 | unsigned long flags; | 1139 | unsigned long flags; |
@@ -1356,7 +1304,7 @@ static struct snd_pcm_ops snd_cs4231_playback_ops = { | |||
1356 | .close = snd_cs4231_playback_close, | 1304 | .close = snd_cs4231_playback_close, |
1357 | .ioctl = snd_pcm_lib_ioctl, | 1305 | .ioctl = snd_pcm_lib_ioctl, |
1358 | .hw_params = snd_cs4231_playback_hw_params, | 1306 | .hw_params = snd_cs4231_playback_hw_params, |
1359 | .hw_free = snd_cs4231_playback_hw_free, | 1307 | .hw_free = snd_pcm_lib_free_pages, |
1360 | .prepare = snd_cs4231_playback_prepare, | 1308 | .prepare = snd_cs4231_playback_prepare, |
1361 | .trigger = snd_cs4231_trigger, | 1309 | .trigger = snd_cs4231_trigger, |
1362 | .pointer = snd_cs4231_playback_pointer, | 1310 | .pointer = snd_cs4231_playback_pointer, |
@@ -1367,18 +1315,20 @@ static struct snd_pcm_ops snd_cs4231_capture_ops = { | |||
1367 | .close = snd_cs4231_capture_close, | 1315 | .close = snd_cs4231_capture_close, |
1368 | .ioctl = snd_pcm_lib_ioctl, | 1316 | .ioctl = snd_pcm_lib_ioctl, |
1369 | .hw_params = snd_cs4231_capture_hw_params, | 1317 | .hw_params = snd_cs4231_capture_hw_params, |
1370 | .hw_free = snd_cs4231_capture_hw_free, | 1318 | .hw_free = snd_pcm_lib_free_pages, |
1371 | .prepare = snd_cs4231_capture_prepare, | 1319 | .prepare = snd_cs4231_capture_prepare, |
1372 | .trigger = snd_cs4231_trigger, | 1320 | .trigger = snd_cs4231_trigger, |
1373 | .pointer = snd_cs4231_capture_pointer, | 1321 | .pointer = snd_cs4231_capture_pointer, |
1374 | }; | 1322 | }; |
1375 | 1323 | ||
1376 | static int __init snd_cs4231_pcm(struct snd_cs4231 *chip) | 1324 | static int __init snd_cs4231_pcm(struct snd_card *card) |
1377 | { | 1325 | { |
1326 | struct snd_cs4231 *chip = card->private_data; | ||
1378 | struct snd_pcm *pcm; | 1327 | struct snd_pcm *pcm; |
1379 | int err; | 1328 | int err; |
1380 | 1329 | ||
1381 | if ((err = snd_pcm_new(chip->card, "CS4231", 0, 1, 1, &pcm)) < 0) | 1330 | err = snd_pcm_new(card, "CS4231", 0, 1, 1, &pcm); |
1331 | if (err < 0) | ||
1382 | return err; | 1332 | return err; |
1383 | 1333 | ||
1384 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs4231_playback_ops); | 1334 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs4231_playback_ops); |
@@ -1396,8 +1346,9 @@ static int __init snd_cs4231_pcm(struct snd_cs4231 *chip) | |||
1396 | return 0; | 1346 | return 0; |
1397 | } | 1347 | } |
1398 | 1348 | ||
1399 | static int __init snd_cs4231_timer(struct snd_cs4231 *chip) | 1349 | static int __init snd_cs4231_timer(struct snd_card *card) |
1400 | { | 1350 | { |
1351 | struct snd_cs4231 *chip = card->private_data; | ||
1401 | struct snd_timer *timer; | 1352 | struct snd_timer *timer; |
1402 | struct snd_timer_id tid; | 1353 | struct snd_timer_id tid; |
1403 | int err; | 1354 | int err; |
@@ -1405,10 +1356,11 @@ static int __init snd_cs4231_timer(struct snd_cs4231 *chip) | |||
1405 | /* Timer initialization */ | 1356 | /* Timer initialization */ |
1406 | tid.dev_class = SNDRV_TIMER_CLASS_CARD; | 1357 | tid.dev_class = SNDRV_TIMER_CLASS_CARD; |
1407 | tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE; | 1358 | tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE; |
1408 | tid.card = chip->card->number; | 1359 | tid.card = card->number; |
1409 | tid.device = 0; | 1360 | tid.device = 0; |
1410 | tid.subdevice = 0; | 1361 | tid.subdevice = 0; |
1411 | if ((err = snd_timer_new(chip->card, "CS4231", &tid, &timer)) < 0) | 1362 | err = snd_timer_new(card, "CS4231", &tid, &timer); |
1363 | if (err < 0) | ||
1412 | return err; | 1364 | return err; |
1413 | strcpy(timer->name, "CS4231"); | 1365 | strcpy(timer->name, "CS4231"); |
1414 | timer->private_data = chip; | 1366 | timer->private_data = chip; |
@@ -1428,9 +1380,7 @@ static int snd_cs4231_info_mux(struct snd_kcontrol *kcontrol, | |||
1428 | static char *texts[4] = { | 1380 | static char *texts[4] = { |
1429 | "Line", "CD", "Mic", "Mix" | 1381 | "Line", "CD", "Mic", "Mix" |
1430 | }; | 1382 | }; |
1431 | struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); | ||
1432 | 1383 | ||
1433 | snd_assert(chip->card != NULL, return -EINVAL); | ||
1434 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1384 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
1435 | uinfo->count = 2; | 1385 | uinfo->count = 2; |
1436 | uinfo->value.enumerated.items = 4; | 1386 | uinfo->value.enumerated.items = 4; |
@@ -1670,21 +1620,19 @@ CS4231_SINGLE("Line Out Switch", 0, CS4231_PIN_CTRL, 6, 1, 1), | |||
1670 | CS4231_SINGLE("Headphone Out Switch", 0, CS4231_PIN_CTRL, 7, 1, 1) | 1620 | CS4231_SINGLE("Headphone Out Switch", 0, CS4231_PIN_CTRL, 7, 1, 1) |
1671 | }; | 1621 | }; |
1672 | 1622 | ||
1673 | static int __init snd_cs4231_mixer(struct snd_cs4231 *chip) | 1623 | static int __init snd_cs4231_mixer(struct snd_card *card) |
1674 | { | 1624 | { |
1675 | struct snd_card *card; | 1625 | struct snd_cs4231 *chip = card->private_data; |
1676 | int err, idx; | 1626 | int err, idx; |
1677 | 1627 | ||
1678 | snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL); | 1628 | snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL); |
1679 | 1629 | ||
1680 | card = chip->card; | ||
1681 | |||
1682 | strcpy(card->mixername, chip->pcm->name); | 1630 | strcpy(card->mixername, chip->pcm->name); |
1683 | 1631 | ||
1684 | for (idx = 0; idx < ARRAY_SIZE(snd_cs4231_controls); idx++) { | 1632 | for (idx = 0; idx < ARRAY_SIZE(snd_cs4231_controls); idx++) { |
1685 | if ((err = snd_ctl_add(card, | 1633 | err = snd_ctl_add(card, |
1686 | snd_ctl_new1(&snd_cs4231_controls[idx], | 1634 | snd_ctl_new1(&snd_cs4231_controls[idx], chip)); |
1687 | chip))) < 0) | 1635 | if (err < 0) |
1688 | return err; | 1636 | return err; |
1689 | } | 1637 | } |
1690 | return 0; | 1638 | return 0; |
@@ -1695,6 +1643,7 @@ static int dev; | |||
1695 | static int __init cs4231_attach_begin(struct snd_card **rcard) | 1643 | static int __init cs4231_attach_begin(struct snd_card **rcard) |
1696 | { | 1644 | { |
1697 | struct snd_card *card; | 1645 | struct snd_card *card; |
1646 | struct snd_cs4231 *chip; | ||
1698 | 1647 | ||
1699 | *rcard = NULL; | 1648 | *rcard = NULL; |
1700 | 1649 | ||
@@ -1706,31 +1655,40 @@ static int __init cs4231_attach_begin(struct snd_card **rcard) | |||
1706 | return -ENOENT; | 1655 | return -ENOENT; |
1707 | } | 1656 | } |
1708 | 1657 | ||
1709 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 1658 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, |
1659 | sizeof(struct snd_cs4231)); | ||
1710 | if (card == NULL) | 1660 | if (card == NULL) |
1711 | return -ENOMEM; | 1661 | return -ENOMEM; |
1712 | 1662 | ||
1713 | strcpy(card->driver, "CS4231"); | 1663 | strcpy(card->driver, "CS4231"); |
1714 | strcpy(card->shortname, "Sun CS4231"); | 1664 | strcpy(card->shortname, "Sun CS4231"); |
1715 | 1665 | ||
1666 | chip = card->private_data; | ||
1667 | chip->card = card; | ||
1668 | |||
1716 | *rcard = card; | 1669 | *rcard = card; |
1717 | return 0; | 1670 | return 0; |
1718 | } | 1671 | } |
1719 | 1672 | ||
1720 | static int __init cs4231_attach_finish(struct snd_card *card, struct snd_cs4231 *chip) | 1673 | static int __init cs4231_attach_finish(struct snd_card *card) |
1721 | { | 1674 | { |
1675 | struct snd_cs4231 *chip = card->private_data; | ||
1722 | int err; | 1676 | int err; |
1723 | 1677 | ||
1724 | if ((err = snd_cs4231_pcm(chip)) < 0) | 1678 | err = snd_cs4231_pcm(card); |
1679 | if (err < 0) | ||
1725 | goto out_err; | 1680 | goto out_err; |
1726 | 1681 | ||
1727 | if ((err = snd_cs4231_mixer(chip)) < 0) | 1682 | err = snd_cs4231_mixer(card); |
1683 | if (err < 0) | ||
1728 | goto out_err; | 1684 | goto out_err; |
1729 | 1685 | ||
1730 | if ((err = snd_cs4231_timer(chip)) < 0) | 1686 | err = snd_cs4231_timer(card); |
1687 | if (err < 0) | ||
1731 | goto out_err; | 1688 | goto out_err; |
1732 | 1689 | ||
1733 | if ((err = snd_card_register(card)) < 0) | 1690 | err = snd_card_register(card); |
1691 | if (err < 0) | ||
1734 | goto out_err; | 1692 | goto out_err; |
1735 | 1693 | ||
1736 | chip->next = cs4231_list; | 1694 | chip->next = cs4231_list; |
@@ -1925,23 +1883,16 @@ static struct snd_device_ops snd_cs4231_sbus_dev_ops = { | |||
1925 | 1883 | ||
1926 | static int __init snd_cs4231_sbus_create(struct snd_card *card, | 1884 | static int __init snd_cs4231_sbus_create(struct snd_card *card, |
1927 | struct sbus_dev *sdev, | 1885 | struct sbus_dev *sdev, |
1928 | int dev, | 1886 | int dev) |
1929 | struct snd_cs4231 **rchip) | ||
1930 | { | 1887 | { |
1931 | struct snd_cs4231 *chip; | 1888 | struct snd_cs4231 *chip = card->private_data; |
1932 | int err; | 1889 | int err; |
1933 | 1890 | ||
1934 | *rchip = NULL; | ||
1935 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
1936 | if (chip == NULL) | ||
1937 | return -ENOMEM; | ||
1938 | |||
1939 | spin_lock_init(&chip->lock); | 1891 | spin_lock_init(&chip->lock); |
1940 | spin_lock_init(&chip->c_dma.sbus_info.lock); | 1892 | spin_lock_init(&chip->c_dma.sbus_info.lock); |
1941 | spin_lock_init(&chip->p_dma.sbus_info.lock); | 1893 | spin_lock_init(&chip->p_dma.sbus_info.lock); |
1942 | mutex_init(&chip->mce_mutex); | 1894 | mutex_init(&chip->mce_mutex); |
1943 | mutex_init(&chip->open_mutex); | 1895 | mutex_init(&chip->open_mutex); |
1944 | chip->card = card; | ||
1945 | chip->dev_u.sdev = sdev; | 1896 | chip->dev_u.sdev = sdev; |
1946 | chip->regs_size = sdev->reg_addrs[0].reg_size; | 1897 | chip->regs_size = sdev->reg_addrs[0].reg_size; |
1947 | memcpy(&chip->image, &snd_cs4231_original_image, | 1898 | memcpy(&chip->image, &snd_cs4231_original_image, |
@@ -1992,14 +1943,12 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card, | |||
1992 | return err; | 1943 | return err; |
1993 | } | 1944 | } |
1994 | 1945 | ||
1995 | *rchip = chip; | ||
1996 | return 0; | 1946 | return 0; |
1997 | } | 1947 | } |
1998 | 1948 | ||
1999 | static int __init cs4231_sbus_attach(struct sbus_dev *sdev) | 1949 | static int __init cs4231_sbus_attach(struct sbus_dev *sdev) |
2000 | { | 1950 | { |
2001 | struct resource *rp = &sdev->resource[0]; | 1951 | struct resource *rp = &sdev->resource[0]; |
2002 | struct snd_cs4231 *cp; | ||
2003 | struct snd_card *card; | 1952 | struct snd_card *card; |
2004 | int err; | 1953 | int err; |
2005 | 1954 | ||
@@ -2013,12 +1962,13 @@ static int __init cs4231_sbus_attach(struct sbus_dev *sdev) | |||
2013 | (unsigned long long)rp->start, | 1962 | (unsigned long long)rp->start, |
2014 | sdev->irqs[0]); | 1963 | sdev->irqs[0]); |
2015 | 1964 | ||
2016 | if ((err = snd_cs4231_sbus_create(card, sdev, dev, &cp)) < 0) { | 1965 | err = snd_cs4231_sbus_create(card, sdev, dev); |
1966 | if (err < 0) { | ||
2017 | snd_card_free(card); | 1967 | snd_card_free(card); |
2018 | return err; | 1968 | return err; |
2019 | } | 1969 | } |
2020 | 1970 | ||
2021 | return cs4231_attach_finish(card, cp); | 1971 | return cs4231_attach_finish(card); |
2022 | } | 1972 | } |
2023 | #endif | 1973 | #endif |
2024 | 1974 | ||
@@ -2105,24 +2055,17 @@ static struct snd_device_ops snd_cs4231_ebus_dev_ops = { | |||
2105 | 2055 | ||
2106 | static int __init snd_cs4231_ebus_create(struct snd_card *card, | 2056 | static int __init snd_cs4231_ebus_create(struct snd_card *card, |
2107 | struct linux_ebus_device *edev, | 2057 | struct linux_ebus_device *edev, |
2108 | int dev, | 2058 | int dev) |
2109 | struct snd_cs4231 **rchip) | ||
2110 | { | 2059 | { |
2111 | struct snd_cs4231 *chip; | 2060 | struct snd_cs4231 *chip = card->private_data; |
2112 | int err; | 2061 | int err; |
2113 | 2062 | ||
2114 | *rchip = NULL; | ||
2115 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
2116 | if (chip == NULL) | ||
2117 | return -ENOMEM; | ||
2118 | |||
2119 | spin_lock_init(&chip->lock); | 2063 | spin_lock_init(&chip->lock); |
2120 | spin_lock_init(&chip->c_dma.ebus_info.lock); | 2064 | spin_lock_init(&chip->c_dma.ebus_info.lock); |
2121 | spin_lock_init(&chip->p_dma.ebus_info.lock); | 2065 | spin_lock_init(&chip->p_dma.ebus_info.lock); |
2122 | mutex_init(&chip->mce_mutex); | 2066 | mutex_init(&chip->mce_mutex); |
2123 | mutex_init(&chip->open_mutex); | 2067 | mutex_init(&chip->open_mutex); |
2124 | chip->flags |= CS4231_FLAG_EBUS; | 2068 | chip->flags |= CS4231_FLAG_EBUS; |
2125 | chip->card = card; | ||
2126 | chip->dev_u.pdev = edev->bus->self; | 2069 | chip->dev_u.pdev = edev->bus->self; |
2127 | memcpy(&chip->image, &snd_cs4231_original_image, | 2070 | memcpy(&chip->image, &snd_cs4231_original_image, |
2128 | sizeof(snd_cs4231_original_image)); | 2071 | sizeof(snd_cs4231_original_image)); |
@@ -2192,14 +2135,12 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card, | |||
2192 | return err; | 2135 | return err; |
2193 | } | 2136 | } |
2194 | 2137 | ||
2195 | *rchip = chip; | ||
2196 | return 0; | 2138 | return 0; |
2197 | } | 2139 | } |
2198 | 2140 | ||
2199 | static int __init cs4231_ebus_attach(struct linux_ebus_device *edev) | 2141 | static int __init cs4231_ebus_attach(struct linux_ebus_device *edev) |
2200 | { | 2142 | { |
2201 | struct snd_card *card; | 2143 | struct snd_card *card; |
2202 | struct snd_cs4231 *chip; | ||
2203 | int err; | 2144 | int err; |
2204 | 2145 | ||
2205 | err = cs4231_attach_begin(&card); | 2146 | err = cs4231_attach_begin(&card); |
@@ -2211,12 +2152,13 @@ static int __init cs4231_ebus_attach(struct linux_ebus_device *edev) | |||
2211 | edev->resource[0].start, | 2152 | edev->resource[0].start, |
2212 | edev->irqs[0]); | 2153 | edev->irqs[0]); |
2213 | 2154 | ||
2214 | if ((err = snd_cs4231_ebus_create(card, edev, dev, &chip)) < 0) { | 2155 | err = snd_cs4231_ebus_create(card, edev, dev); |
2156 | if (err < 0) { | ||
2215 | snd_card_free(card); | 2157 | snd_card_free(card); |
2216 | return err; | 2158 | return err; |
2217 | } | 2159 | } |
2218 | 2160 | ||
2219 | return cs4231_attach_finish(card, chip); | 2161 | return cs4231_attach_finish(card); |
2220 | } | 2162 | } |
2221 | #endif | 2163 | #endif |
2222 | 2164 | ||