aboutsummaryrefslogtreecommitdiffstats
path: root/sound/spi/at73c213.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/spi/at73c213.c')
-rw-r--r--sound/spi/at73c213.c46
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
539static 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
550static int snd_at73c213_mono_switch_get(struct snd_kcontrol *kcontrol, 543static 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