diff options
Diffstat (limited to 'sound/spi/at73c213.c')
-rw-r--r-- | sound/spi/at73c213.c | 46 |
1 files changed, 20 insertions, 26 deletions
diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c index fee869bcc959..89d6e9c35140 100644 --- a/sound/spi/at73c213.c +++ b/sound/spi/at73c213.c | |||
@@ -18,10 +18,10 @@ | |||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/mutex.h> | ||
21 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
22 | #include <linux/io.h> | 23 | #include <linux/io.h> |
23 | 24 | ||
24 | #include <sound/driver.h> | ||
25 | #include <sound/initval.h> | 25 | #include <sound/initval.h> |
26 | #include <sound/control.h> | 26 | #include <sound/control.h> |
27 | #include <sound/core.h> | 27 | #include <sound/core.h> |
@@ -76,8 +76,10 @@ struct snd_at73c213 { | |||
76 | u8 spi_rbuffer[2]; | 76 | u8 spi_rbuffer[2]; |
77 | /* Image of the SPI registers in AT73C213. */ | 77 | /* Image of the SPI registers in AT73C213. */ |
78 | u8 reg_image[18]; | 78 | u8 reg_image[18]; |
79 | /* Protect registers against concurrent access. */ | 79 | /* Protect SSC registers against concurrent access. */ |
80 | spinlock_t lock; | 80 | spinlock_t lock; |
81 | /* Protect mixer registers against concurrent access. */ | ||
82 | struct mutex mixer_lock; | ||
81 | }; | 83 | }; |
82 | 84 | ||
83 | #define get_chip(card) ((struct snd_at73c213 *)card->private_data) | 85 | #define get_chip(card) ((struct snd_at73c213 *)card->private_data) |
@@ -398,7 +400,7 @@ static int snd_at73c213_mono_get(struct snd_kcontrol *kcontrol, | |||
398 | int mask = (kcontrol->private_value >> 16) & 0xff; | 400 | int mask = (kcontrol->private_value >> 16) & 0xff; |
399 | int invert = (kcontrol->private_value >> 24) & 0xff; | 401 | int invert = (kcontrol->private_value >> 24) & 0xff; |
400 | 402 | ||
401 | spin_lock_irq(&chip->lock); | 403 | mutex_lock(&chip->mixer_lock); |
402 | 404 | ||
403 | ucontrol->value.integer.value[0] = | 405 | ucontrol->value.integer.value[0] = |
404 | (chip->reg_image[reg] >> shift) & mask; | 406 | (chip->reg_image[reg] >> shift) & mask; |
@@ -407,7 +409,7 @@ static int snd_at73c213_mono_get(struct snd_kcontrol *kcontrol, | |||
407 | ucontrol->value.integer.value[0] = | 409 | ucontrol->value.integer.value[0] = |
408 | mask - ucontrol->value.integer.value[0]; | 410 | mask - ucontrol->value.integer.value[0]; |
409 | 411 | ||
410 | spin_unlock_irq(&chip->lock); | 412 | mutex_unlock(&chip->mixer_lock); |
411 | 413 | ||
412 | return 0; | 414 | return 0; |
413 | } | 415 | } |
@@ -428,13 +430,13 @@ static int snd_at73c213_mono_put(struct snd_kcontrol *kcontrol, | |||
428 | val = mask - val; | 430 | val = mask - val; |
429 | val <<= shift; | 431 | val <<= shift; |
430 | 432 | ||
431 | spin_lock_irq(&chip->lock); | 433 | mutex_lock(&chip->mixer_lock); |
432 | 434 | ||
433 | val = (chip->reg_image[reg] & ~(mask << shift)) | val; | 435 | val = (chip->reg_image[reg] & ~(mask << shift)) | val; |
434 | change = val != chip->reg_image[reg]; | 436 | change = val != chip->reg_image[reg]; |
435 | retval = snd_at73c213_write_reg(chip, reg, val); | 437 | retval = snd_at73c213_write_reg(chip, reg, val); |
436 | 438 | ||
437 | spin_unlock_irq(&chip->lock); | 439 | mutex_unlock(&chip->mixer_lock); |
438 | 440 | ||
439 | if (retval) | 441 | if (retval) |
440 | return retval; | 442 | return retval; |
@@ -470,7 +472,7 @@ static int snd_at73c213_stereo_get(struct snd_kcontrol *kcontrol, | |||
470 | int mask = (kcontrol->private_value >> 24) & 0xff; | 472 | int mask = (kcontrol->private_value >> 24) & 0xff; |
471 | int invert = (kcontrol->private_value >> 22) & 1; | 473 | int invert = (kcontrol->private_value >> 22) & 1; |
472 | 474 | ||
473 | spin_lock_irq(&chip->lock); | 475 | mutex_lock(&chip->mixer_lock); |
474 | 476 | ||
475 | ucontrol->value.integer.value[0] = | 477 | ucontrol->value.integer.value[0] = |
476 | (chip->reg_image[left_reg] >> shift_left) & mask; | 478 | (chip->reg_image[left_reg] >> shift_left) & mask; |
@@ -484,7 +486,7 @@ static int snd_at73c213_stereo_get(struct snd_kcontrol *kcontrol, | |||
484 | mask - ucontrol->value.integer.value[1]; | 486 | mask - ucontrol->value.integer.value[1]; |
485 | } | 487 | } |
486 | 488 | ||
487 | spin_unlock_irq(&chip->lock); | 489 | mutex_unlock(&chip->mixer_lock); |
488 | 490 | ||
489 | return 0; | 491 | return 0; |
490 | } | 492 | } |
@@ -511,7 +513,7 @@ static int snd_at73c213_stereo_put(struct snd_kcontrol *kcontrol, | |||
511 | val1 <<= shift_left; | 513 | val1 <<= shift_left; |
512 | val2 <<= shift_right; | 514 | val2 <<= shift_right; |
513 | 515 | ||
514 | spin_lock_irq(&chip->lock); | 516 | mutex_lock(&chip->mixer_lock); |
515 | 517 | ||
516 | val1 = (chip->reg_image[left_reg] & ~(mask << shift_left)) | val1; | 518 | val1 = (chip->reg_image[left_reg] & ~(mask << shift_left)) | val1; |
517 | val2 = (chip->reg_image[right_reg] & ~(mask << shift_right)) | val2; | 519 | val2 = (chip->reg_image[right_reg] & ~(mask << shift_right)) | val2; |
@@ -519,16 +521,16 @@ static int snd_at73c213_stereo_put(struct snd_kcontrol *kcontrol, | |||
519 | || val2 != chip->reg_image[right_reg]; | 521 | || val2 != chip->reg_image[right_reg]; |
520 | retval = snd_at73c213_write_reg(chip, left_reg, val1); | 522 | retval = snd_at73c213_write_reg(chip, left_reg, val1); |
521 | if (retval) { | 523 | if (retval) { |
522 | spin_unlock_irq(&chip->lock); | 524 | mutex_unlock(&chip->mixer_lock); |
523 | goto out; | 525 | goto out; |
524 | } | 526 | } |
525 | retval = snd_at73c213_write_reg(chip, right_reg, val2); | 527 | retval = snd_at73c213_write_reg(chip, right_reg, val2); |
526 | if (retval) { | 528 | if (retval) { |
527 | spin_unlock_irq(&chip->lock); | 529 | mutex_unlock(&chip->mixer_lock); |
528 | goto out; | 530 | goto out; |
529 | } | 531 | } |
530 | 532 | ||
531 | spin_unlock_irq(&chip->lock); | 533 | mutex_unlock(&chip->mixer_lock); |
532 | 534 | ||
533 | return change; | 535 | return change; |
534 | 536 | ||
@@ -536,16 +538,7 @@ out: | |||
536 | return retval; | 538 | return retval; |
537 | } | 539 | } |
538 | 540 | ||
539 | static int snd_at73c213_mono_switch_info(struct snd_kcontrol *kcontrol, | 541 | #define snd_at73c213_mono_switch_info snd_ctl_boolean_mono_info |
540 | struct snd_ctl_elem_info *uinfo) | ||
541 | { | ||
542 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
543 | uinfo->count = 1; | ||
544 | uinfo->value.integer.min = 0; | ||
545 | uinfo->value.integer.max = 1; | ||
546 | |||
547 | return 0; | ||
548 | } | ||
549 | 542 | ||
550 | static int snd_at73c213_mono_switch_get(struct snd_kcontrol *kcontrol, | 543 | static int snd_at73c213_mono_switch_get(struct snd_kcontrol *kcontrol, |
551 | struct snd_ctl_elem_value *ucontrol) | 544 | struct snd_ctl_elem_value *ucontrol) |
@@ -555,7 +548,7 @@ static int snd_at73c213_mono_switch_get(struct snd_kcontrol *kcontrol, | |||
555 | int shift = (kcontrol->private_value >> 8) & 0xff; | 548 | int shift = (kcontrol->private_value >> 8) & 0xff; |
556 | int invert = (kcontrol->private_value >> 24) & 0xff; | 549 | int invert = (kcontrol->private_value >> 24) & 0xff; |
557 | 550 | ||
558 | spin_lock_irq(&chip->lock); | 551 | mutex_lock(&chip->mixer_lock); |
559 | 552 | ||
560 | ucontrol->value.integer.value[0] = | 553 | ucontrol->value.integer.value[0] = |
561 | (chip->reg_image[reg] >> shift) & 0x01; | 554 | (chip->reg_image[reg] >> shift) & 0x01; |
@@ -564,7 +557,7 @@ static int snd_at73c213_mono_switch_get(struct snd_kcontrol *kcontrol, | |||
564 | ucontrol->value.integer.value[0] = | 557 | ucontrol->value.integer.value[0] = |
565 | 0x01 - ucontrol->value.integer.value[0]; | 558 | 0x01 - ucontrol->value.integer.value[0]; |
566 | 559 | ||
567 | spin_unlock_irq(&chip->lock); | 560 | mutex_unlock(&chip->mixer_lock); |
568 | 561 | ||
569 | return 0; | 562 | return 0; |
570 | } | 563 | } |
@@ -589,14 +582,14 @@ static int snd_at73c213_mono_switch_put(struct snd_kcontrol *kcontrol, | |||
589 | val = mask - val; | 582 | val = mask - val; |
590 | val <<= shift; | 583 | val <<= shift; |
591 | 584 | ||
592 | spin_lock_irq(&chip->lock); | 585 | mutex_lock(&chip->mixer_lock); |
593 | 586 | ||
594 | val |= (chip->reg_image[reg] & ~(mask << shift)); | 587 | val |= (chip->reg_image[reg] & ~(mask << shift)); |
595 | change = val != chip->reg_image[reg]; | 588 | change = val != chip->reg_image[reg]; |
596 | 589 | ||
597 | retval = snd_at73c213_write_reg(chip, reg, val); | 590 | retval = snd_at73c213_write_reg(chip, reg, val); |
598 | 591 | ||
599 | spin_unlock_irq(&chip->lock); | 592 | mutex_unlock(&chip->mixer_lock); |
600 | 593 | ||
601 | if (retval) | 594 | if (retval) |
602 | return retval; | 595 | return retval; |
@@ -893,6 +886,7 @@ static int __devinit snd_at73c213_dev_init(struct snd_card *card, | |||
893 | return irq; | 886 | return irq; |
894 | 887 | ||
895 | spin_lock_init(&chip->lock); | 888 | spin_lock_init(&chip->lock); |
889 | mutex_init(&chip->mixer_lock); | ||
896 | chip->card = card; | 890 | chip->card = card; |
897 | chip->irq = -1; | 891 | chip->irq = -1; |
898 | 892 | ||